Skip to content

Commit

Permalink
Adds environment boolean checks (#302)
Browse files Browse the repository at this point in the history
Amber currently ships with 3 different environments: development, test
and production.

As a developer I would like to sometimes run code conditionally
depending on the environment that the application is.

```crystal
if Amber.env.development?
  # ... code here ...
end

```

This PR addresses the issue by creating a Amber::Env module that
contains 3 module methods:

```crystal
Amber.env.development?
Amber.env.test?
Amber.env.production?
Amber.env.integration?
Amber.env.staging?
Amber.env.sandbox?

Amber.env.in? %w(development test)
Amber.env.in? %i(development test)

Amber.env.is? "test"
Amber.env.is? :test
```

With the changes in this PR a developer should be able to call the
appropriate method to check for the desired environment.

Adds Additional Module methods

`in?` and `is?` methods to check for inclusion of the environments

Uses rails style for Amber environment checks
  • Loading branch information
eliasjpr committed Oct 13, 2017
1 parent 7ce0d08 commit 2ace4dd
Show file tree
Hide file tree
Showing 6 changed files with 103 additions and 6 deletions.
7 changes: 3 additions & 4 deletions spec/amber/amber_spec.cr
Expand Up @@ -6,14 +6,13 @@ struct RoomSocket < Amber::WebSockets::ClientSocket; end

describe Amber::Server do
describe ".configure" do
it "it loads environment settings from test.yml" do
it "loads environment settings from test.yml" do
settings = Amber::Server.settings

settings.name.should eq "amber_test_app"
settings.port_reuse.should eq true
settings.redis_url.should eq "#{ENV["REDIS_URL"]? || "redis://localhost:6379"}"
settings.port.should eq 3000
settings.env.should eq "test"
settings.color.should eq true
settings.secret_key_base.should eq "mV6kTmG3k1yVFh-fPYpugSn0wbZveDvrvfQuv88DPF8"
# Sometimes settings get over written by other tests first and this fails
Expand All @@ -26,7 +25,7 @@ describe Amber::Server do
settings.secrets.should eq expected_secrets
end

it "allows you to overide enviroment settings" do
it "overrides enviroment settings" do
Amber::Server.configure do |server|
server.name = "Hello World App"
server.port = 8080
Expand All @@ -45,7 +44,7 @@ describe Amber::Server do
settings.secret_key_base.should eq "mV6kTmG3k1yVFh-fPYpugSn0wbZveDvrvfQuv88DPF8"
end

it "should still retain environment.yml settings that haven't been overwritten" do
it "retains environment.yml settings that haven't been overwritten" do
# NOTE: Any changes to settings here remain for all specs run afterwards.
# This is a problem.

Expand Down
5 changes: 4 additions & 1 deletion spec/amber/cli/commands/generator_spec.cr
Expand Up @@ -5,6 +5,8 @@ module Amber::CLI
describe MainCommand::Generate do
context "scaffold" do
it "generates and compile generated app" do
ENV["AMBER_ENV"] = "test"

MainCommand.run ["new", TESTING_APP]
Dir.cd(TESTING_APP)
MainCommand.run ["generate", "scaffold", "Animal", "name:string"]
Expand All @@ -17,7 +19,8 @@ module Amber::CLI
end

context "controllers" do
it "should generate controller with correct verbs and actions" do
it "generates controller with correct verbs and actions" do
ENV["AMBER_ENV"] = "test"
MainCommand.run ["new", TESTING_APP]
Dir.cd(TESTING_APP)
MainCommand.run ["generate", "controller", "Animal", "add:post", "list:get", "remove:delete"]
Expand Down
59 changes: 59 additions & 0 deletions spec/amber/server/env_spec.cr
@@ -0,0 +1,59 @@
require "../../../spec_helper"

describe Amber do
{% for env in %w(development staging test sandbox production) %}
describe ".{{env.id}}?" do
it "returns true when the environment is {{env.id}}" do
Amber::Settings.env = {{env}}
Amber.env.{{env.id}}?.should be_truthy
end

it "returns false when the environment does not match" do
Amber::Settings.env = "invalid environment"
Amber.env.{{env.id}}?.should be_falsey
end
end
{% end %}

describe ".is?" do
it "returns true when the environment matches the argument" do
Amber::Settings.env = "staging"
result = Amber.env.is? :staging

result.should be_truthy
end

it "returns true when the environment matches the argument" do
Amber::Settings.env = "invalid"
result = Amber.env.is? :staging

result.should be_falsey
end
end

describe ".in?" do
context "when settings environment is in list" do
it "returns true" do
Amber::Settings.env = "development"

symbols_result = Amber.env.in? %i(development test production)
strings_result = Amber.env.in? %w(development test production)

symbols_result.should be_truthy
strings_result.should be_truthy
end
end

context "when settings environment is not in list" do
it "returns false" do
Amber::Settings.env = "invalid"

symbols_result = Amber.env.in? %w(development test production)
strings_result = Amber.env.in? %w(development test production)

symbols_result.should be_falsey
strings_result.should be_falsey
end
end
end
end
1 change: 1 addition & 0 deletions src/amber.cr
Expand Up @@ -13,6 +13,7 @@ require "./amber/exceptions/**"
require "./amber/extensions/**"
require "./amber/router/**"
require "./amber/server/settings"
require "./amber/server/env"
require "./amber/validations/**"
require "./amber/websockets/**"

Expand Down
34 changes: 34 additions & 0 deletions src/amber/server/env.cr
@@ -0,0 +1,34 @@
module Amber
def self.env
Env.new(Settings.env.not_nil!.downcase)
end

class Env
def initialize(@env : String | Symbol)
end

def in?(environment_list : Array(String | Symbol))
(environment_list.map &.to_s.downcase).includes? @env
end

def is?(environment : String | Symbol)
@env == environment.to_s.downcase
end

def to_s(io)
io << @env
end

private def environments
(Dir.entries(CONFIG_DIR).map &.downcase.tr(".yml", "") + ENVIRONMENTS).to_set
end

macro method_missing(call)
environment = {{call.name.id.stringify.downcase}}
if environment.chars.last == '?'
environment = environment.downcase.tr("?", "")
(@env == environment)
end
end
end
end
3 changes: 2 additions & 1 deletion src/amber/server/settings.cr
Expand Up @@ -23,7 +23,8 @@ module Amber
class_property redis_url = ""
class_property session : Hash(Symbol, Symbol | String | Int32)

# loads settings from environment yaml
# Loads environment yml settings from the current AMBER_ENV environment variable
# and defaults to development environment
{{ run("./environment.cr") }}
end
end

0 comments on commit 2ace4dd

Please sign in to comment.