yacht 0.1.2 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +3 -0
- data/.yardopts +6 -0
- data/Gemfile +3 -1
- data/README.rdoc +12 -18
- data/Rakefile +1 -1
- data/features/load.feature +80 -0
- data/features/missing_yaml_files.feature +30 -0
- data/features/step_definitions/aruba_extension_steps.rb +5 -0
- data/features/step_definitions/error_handling_steps.rb +27 -0
- data/features/step_definitions/loader_steps.rb +28 -0
- data/features/support/cleanup.rb +9 -0
- data/features/support/env.rb +4 -0
- data/gem_tasks/cucumber.rake +5 -0
- data/lib/yacht/base.rb +14 -0
- data/lib/yacht/classy_struct.rb +32 -0
- data/lib/{yacht_loader/base.rb → yacht/loader.rb} +23 -35
- data/lib/{yacht_loader → yacht}/rails.rb +1 -1
- data/lib/yacht/version.rb +3 -0
- data/lib/yacht.rb +6 -11
- data/spec/spec_helper.rb +3 -96
- data/spec/yacht/base_spec.rb +16 -0
- data/spec/yacht/classy_struct_spec.rb +81 -0
- data/spec/yacht/loader_spec.rb +215 -0
- data/spec/{yacht_loader → yacht}/rails_spec.rb +7 -5
- data/yacht.gemspec +7 -3
- metadata +66 -19
- data/lib/yacht_loader/classy_struct.rb +0 -15
- data/lib/yacht_loader/version.rb +0 -3
- data/spec/yacht_loader/base_spec.rb +0 -179
- data/spec/yacht_loader/classy_struct_spec.rb +0 -39
data/.gitignore
CHANGED
data/.yardopts
ADDED
data/Gemfile
CHANGED
data/README.rdoc
CHANGED
@@ -4,6 +4,7 @@ Yacht is an application configuration gem that lets you define settings for mult
|
|
4
4
|
* use of ClassyStruct for improved performance over OpenStruct
|
5
5
|
* protection of sensitive settings by specifying a whitelist in a YAML file
|
6
6
|
* easy override of nested keys (not pretty with YAML references)
|
7
|
+
* no need for an initializer or constant to store loaded values (just use Yacht.my_key)
|
7
8
|
|
8
9
|
== Installation
|
9
10
|
|
@@ -39,8 +40,13 @@ First create two (or more) YAML files in the same directory to define your setti
|
|
39
40
|
|
40
41
|
# config/yacht/whitelist.yml (required)
|
41
42
|
# any keys specified here can be used as a whitelist filter:
|
42
|
-
#
|
43
|
+
# Yacht::Loader.to_hash(:apply_whitelist? => true)
|
44
|
+
# or
|
45
|
+
# Yacht::Loader.to_classy_struct(:apply_whitelist? => true)
|
43
46
|
# (by default the whitelist is ignored)
|
47
|
+
# NOTE: the whitelist is ignored when using Yacht.my_key or Yacht['my_key']
|
48
|
+
# you have to use Yacht::Loader#to_hash or
|
49
|
+
# Yacht::Loader#to_classy_struct to use the whitelist
|
44
50
|
- super_secret_info
|
45
51
|
|
46
52
|
# config/yacht/local.yml (optional)
|
@@ -49,28 +55,16 @@ First create two (or more) YAML files in the same directory to define your setti
|
|
49
55
|
production:
|
50
56
|
cdn_host: localhost
|
51
57
|
|
52
|
-
=== Step 2:
|
58
|
+
=== Step 2: Use Yacht.my_key or Yacht['my_key']
|
53
59
|
|
54
60
|
* <b>Rails</b>:
|
55
|
-
# config/initializers/01_yacht.rb
|
56
|
-
# Define a constant that will store all settings
|
57
|
-
# looks for the following YAML files:
|
58
|
-
# * config/yacht/base.yml
|
59
|
-
# * config/yacht/local.yml
|
60
|
-
# * config/yacht/whitelist.yml
|
61
|
-
Yacht = YachtLoader.to_classy_struct
|
62
61
|
# now you can access any key set in your YAML files with:
|
63
62
|
# Yacht.my_key
|
64
63
|
|
65
|
-
* Outside of rails, you need to tell +
|
66
|
-
|
67
|
-
|
68
|
-
Yacht
|
69
|
-
|
70
|
-
|
71
|
-
== How it works
|
72
|
-
|
73
|
-
Currently, the +Yacht+ gem defines a class called +YachtLoader+ that will read your YAML files and output them as a regular +Hash+ or a +ClassyStruct+ . Then you use <tt>YachtLoader#to_classy_struct</tt> (or <tt>YachtLoader#to_hash</tt>) to define a constant. You can name the constant whatever you like, but you should use +Yacht+. This is because a planned feature is to have +Yacht+ defined when the gem is required and have everything namespaced under a single +Yacht+ class.
|
64
|
+
* Outside of rails, you need to tell +Yacht+ where your YAML files are stored, and what environment you want to use.
|
65
|
+
Yacht::Loader.dir = '/path/to/YAML/dir'
|
66
|
+
Yacht::Loader.environment = 'my_environment'
|
67
|
+
Yacht.my_key
|
74
68
|
|
75
69
|
== License
|
76
70
|
|
data/Rakefile
CHANGED
@@ -0,0 +1,80 @@
|
|
1
|
+
Feature: Load configuration settings
|
2
|
+
In order to organize my configuration settings
|
3
|
+
As a developer using Yacht
|
4
|
+
I want to load configuration settings from an external source like a YAML file
|
5
|
+
|
6
|
+
Background:
|
7
|
+
Given a file named "base.yml" with:
|
8
|
+
"""
|
9
|
+
default:
|
10
|
+
:api_key: some_fake_key
|
11
|
+
:partner_sites:
|
12
|
+
- twitter
|
13
|
+
- github
|
14
|
+
:mail:
|
15
|
+
:host: localhost
|
16
|
+
:from: Our great company
|
17
|
+
development:
|
18
|
+
:api_key: some_development_key
|
19
|
+
production:
|
20
|
+
:api_key: the_real_mccoy
|
21
|
+
:partner_sites:
|
22
|
+
- facebook
|
23
|
+
:mail:
|
24
|
+
host: example.com
|
25
|
+
reply-to: info@example.com
|
26
|
+
"""
|
27
|
+
|
28
|
+
Scenario: Load from YAML
|
29
|
+
When I load Yacht with environment: "development"
|
30
|
+
Then Yacht should contain the following hash:
|
31
|
+
"""
|
32
|
+
{
|
33
|
+
:api_key => 'some_development_key',
|
34
|
+
:partner_sites => [
|
35
|
+
'twitter',
|
36
|
+
'github'
|
37
|
+
],
|
38
|
+
:mail => {
|
39
|
+
:host => 'localhost',
|
40
|
+
:from => 'Our great company'
|
41
|
+
}
|
42
|
+
}
|
43
|
+
"""
|
44
|
+
|
45
|
+
Scenario: Local overrides with local.yml
|
46
|
+
Given a file named "local.yml" with:
|
47
|
+
"""
|
48
|
+
:api_key: some_crazy_local_key
|
49
|
+
"""
|
50
|
+
When I load Yacht with environment: "development"
|
51
|
+
Then Yacht should contain the following hash:
|
52
|
+
"""
|
53
|
+
{
|
54
|
+
:api_key => 'some_crazy_local_key',
|
55
|
+
:partner_sites => [
|
56
|
+
'twitter',
|
57
|
+
'github'
|
58
|
+
],
|
59
|
+
:mail => {
|
60
|
+
:host => 'localhost',
|
61
|
+
:from => 'Our great company'
|
62
|
+
}
|
63
|
+
}
|
64
|
+
"""
|
65
|
+
|
66
|
+
Scenario: Whitelisting with whitelist.yml
|
67
|
+
Given a file named "whitelist.yml" with:
|
68
|
+
"""
|
69
|
+
- :partner_sites
|
70
|
+
"""
|
71
|
+
When I define the constant "MyYacht" with environment: "development" using a whitelist
|
72
|
+
Then the constant "MyYacht" should contain the following hash:
|
73
|
+
"""
|
74
|
+
{
|
75
|
+
:partner_sites => [
|
76
|
+
'twitter',
|
77
|
+
'github'
|
78
|
+
]
|
79
|
+
}
|
80
|
+
"""
|
@@ -0,0 +1,30 @@
|
|
1
|
+
Feature: Handle missing YAML files reasonably
|
2
|
+
In order to ensure robustness and correctness of data
|
3
|
+
Missing YAML files should cause an error to be raised when reasonable
|
4
|
+
|
5
|
+
Background:
|
6
|
+
Given a file named "base.yml" with:
|
7
|
+
"""
|
8
|
+
development:
|
9
|
+
api_key: some_fake_key
|
10
|
+
"""
|
11
|
+
|
12
|
+
Scenario: No base.yml
|
13
|
+
Given a file named "base.yml" does not exist
|
14
|
+
When I try to use Yacht
|
15
|
+
Then Yacht should raise an error with message: "Couldn't load base config"
|
16
|
+
|
17
|
+
Scenario: No local.yml
|
18
|
+
Given a file named "local.yml" does not exist
|
19
|
+
When I try to use Yacht
|
20
|
+
Then Yacht should not raise an error
|
21
|
+
|
22
|
+
Scenario: No whitelist.yml but whitelist not used
|
23
|
+
Given a file named "whitelist.yml" does not exist
|
24
|
+
When I try to use Yacht
|
25
|
+
Then Yacht should not raise an error
|
26
|
+
|
27
|
+
Scenario: No whitelist.yml and whitelist used
|
28
|
+
Given a file named "whitelist.yml" does not exist
|
29
|
+
When I try to use Yacht with a whitelist
|
30
|
+
Then Yacht should raise an error with message: "Couldn't load whitelist"
|
@@ -0,0 +1,27 @@
|
|
1
|
+
Then /^Yacht should raise an error with message: "([^"]*)"$/ do |message|
|
2
|
+
@last_yacht.class.should be(Yacht::LoadError)
|
3
|
+
@last_yacht.message.should == message
|
4
|
+
end
|
5
|
+
|
6
|
+
When /^I try to use Yacht( with a whitelist)?$/ do |whitelist|
|
7
|
+
@last_yacht = use_yacht(!!whitelist)
|
8
|
+
end
|
9
|
+
|
10
|
+
Then /^Yacht should not raise an error$/ do
|
11
|
+
@last_yacht.class.should_not <= Exception
|
12
|
+
end
|
13
|
+
|
14
|
+
module ErrorHandlingHelpers
|
15
|
+
# Try to use Yacht and return output of Yacht#to_classy_struct if no error raised
|
16
|
+
# If an error is raised, return it instead
|
17
|
+
def use_yacht(whitelist=false)
|
18
|
+
in_current_dir do
|
19
|
+
Yacht::Loader.dir = '.'
|
20
|
+
Yacht::Loader.environment = 'development'
|
21
|
+
Yacht::Loader.to_classy_struct(:apply_whitelist? => whitelist)
|
22
|
+
end
|
23
|
+
rescue Exception => e
|
24
|
+
e
|
25
|
+
end
|
26
|
+
end
|
27
|
+
World(ErrorHandlingHelpers)
|
@@ -0,0 +1,28 @@
|
|
1
|
+
When /^I define the constant "([^"]*)" with environment: "([^"]*)"( using a whitelist)?$/ do |constant_name, env, whitelist|
|
2
|
+
in_current_dir do
|
3
|
+
Yacht::Loader.dir = '.'
|
4
|
+
Yacht::Loader.environment = env
|
5
|
+
Object.const_set( constant_name, Yacht::Loader.to_classy_struct(:apply_whitelist? => whitelist ) )
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
|
10
|
+
Then /^the constant "([^"]*)" should contain the following hash:$/ do |constant_name, stringified|
|
11
|
+
hash = eval(stringified)
|
12
|
+
Object.const_get(constant_name).to_hash.should == hash # don't forget to tack on to_hash to avoid weird errors
|
13
|
+
# TODO: make ClassyStruct more Hash-like so
|
14
|
+
# i t can be compared against hashes using `==`
|
15
|
+
end
|
16
|
+
|
17
|
+
When /^I load Yacht with environment: "([^"]*)"$/ do |env|
|
18
|
+
Yacht::Loader.dir = '.'
|
19
|
+
Yacht::Loader.environment = env
|
20
|
+
end
|
21
|
+
|
22
|
+
Then /^Yacht should contain the following hash:$/ do |stringified|
|
23
|
+
hash = eval(stringified)
|
24
|
+
|
25
|
+
in_current_dir do
|
26
|
+
Yacht::Loader.to_hash.should == hash
|
27
|
+
end
|
28
|
+
end
|
data/lib/yacht/base.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'classy_struct'
|
2
|
+
|
3
|
+
class Yacht < BasicObject
|
4
|
+
class Loader
|
5
|
+
class << self
|
6
|
+
def classy_struct_instance
|
7
|
+
@classy_struct_instance ||= ClassyStruct.new
|
8
|
+
end
|
9
|
+
|
10
|
+
def to_classy_struct(opts={})
|
11
|
+
classy_struct_instance.new( self.to_hash(opts) )
|
12
|
+
rescue StandardError => e
|
13
|
+
# don't do anything to our own custom errors
|
14
|
+
if e.is_a? Yacht::LoadError
|
15
|
+
raise e
|
16
|
+
else
|
17
|
+
raise Yacht::LoadError.new("Error creating ClassyStruct: #{e.message}")
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
class << self
|
24
|
+
def method_missing(method, *args, &block)
|
25
|
+
_classy_struct.send(method)
|
26
|
+
end
|
27
|
+
|
28
|
+
def _classy_struct
|
29
|
+
@_classy_struct ||= Loader.to_classy_struct
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -1,9 +1,6 @@
|
|
1
1
|
# TODO: Rename YachtLoader to Yacht and somehow incorporate ClassyStruct
|
2
2
|
|
3
|
-
class
|
4
|
-
class LoadError < StandardError
|
5
|
-
end
|
6
|
-
|
3
|
+
class Yacht::Loader
|
7
4
|
class << self
|
8
5
|
def environment
|
9
6
|
@environment ||= 'default'
|
@@ -20,7 +17,7 @@ class YachtLoader
|
|
20
17
|
end
|
21
18
|
|
22
19
|
def config_file_for(config_type)
|
23
|
-
raise LoadError.new "#{config_type} is not a valid config type" unless valid_config_types.include?(config_type.to_s)
|
20
|
+
raise Yacht::LoadError.new "#{config_type} is not a valid config type" unless valid_config_types.include?(config_type.to_s)
|
24
21
|
|
25
22
|
full_file_path_for_config(config_type)
|
26
23
|
end
|
@@ -34,7 +31,7 @@ class YachtLoader
|
|
34
31
|
end
|
35
32
|
|
36
33
|
def to_hash(opts={})
|
37
|
-
opts[:apply_whitelist?]
|
34
|
+
opts[:apply_whitelist?] ||= false unless opts.has_key?(:apply_whitelist?)
|
38
35
|
self.environment = opts[:env] if opts.has_key?(:env)
|
39
36
|
|
40
37
|
if opts[:apply_whitelist?]
|
@@ -45,60 +42,47 @@ class YachtLoader
|
|
45
42
|
end
|
46
43
|
|
47
44
|
def whitelist
|
48
|
-
load_config_file(:whitelist, :expect_to_load => Array) ||
|
49
|
-
raise LoadError.new("Couldn't load whitelist")
|
50
|
-
end
|
45
|
+
load_config_file(:whitelist, :expect_to_load => Array) || raise( Yacht::LoadError.new("Couldn't load whitelist") )
|
51
46
|
end
|
52
47
|
|
53
48
|
def base_config
|
54
|
-
load_config_file(:base) ||
|
55
|
-
raise LoadError.new("Couldn't load base config")
|
56
|
-
end
|
49
|
+
load_config_file(:base) || raise( Yacht::LoadError.new("Couldn't load base config") )
|
57
50
|
end
|
58
51
|
|
59
52
|
def local_config
|
60
|
-
load_config_file(:local
|
53
|
+
load_config_file(:local) || {}
|
61
54
|
end
|
62
55
|
|
63
56
|
protected
|
57
|
+
# Wrap the YAML.load for easier mocking
|
58
|
+
def _load_config_file(file_name)
|
59
|
+
YAML.load( File.read(file_name) ) if File.exists?(file_name)
|
60
|
+
end
|
61
|
+
|
62
|
+
# Load a config file with plenty of error-checking
|
64
63
|
def load_config_file(file_type, opts={})
|
65
64
|
# by default, expect a Hash to be loaded
|
66
65
|
expected_class = opts[:expect_to_load] || Hash
|
67
66
|
|
68
|
-
# by default, raise error if file missing or empty
|
69
|
-
presence_required = if opts.has_key?(:require_presence?)
|
70
|
-
opts[:require_presence?]
|
71
|
-
else
|
72
|
-
true
|
73
|
-
end
|
74
|
-
|
75
67
|
file_name = self.config_file_for(file_type)
|
76
|
-
|
77
|
-
loaded = if File.exists?(file_name)
|
78
|
-
YAML.load( File.read(file_name) )
|
79
|
-
else
|
80
|
-
nil
|
81
|
-
end
|
82
|
-
|
83
|
-
# an empty YAML file will be converted to boolean false
|
84
|
-
raise LoadError.new "#{file_name} cannot be empty" if presence_required && loaded === false
|
68
|
+
loaded = self._load_config_file(file_name)
|
85
69
|
|
86
70
|
# YAML contained the wrong type
|
87
|
-
raise LoadError.new "#{file_name} must contain #{expected_class} (got #{loaded.class})" if loaded && !loaded.is_a?(expected_class)
|
71
|
+
raise Yacht::LoadError.new "#{file_name} must contain #{expected_class} (got #{loaded.class})" if loaded && !loaded.is_a?(expected_class)
|
88
72
|
|
89
73
|
loaded
|
90
74
|
rescue => e
|
91
75
|
# don't do anything to our own custom errors
|
92
|
-
if e.is_a?
|
76
|
+
if e.is_a? Yacht::LoadError
|
93
77
|
raise e
|
94
78
|
else
|
95
|
-
# convert other errors to YachtLoader::LoadError
|
96
|
-
raise LoadError.new "ERROR: loading config file: '#{file_type}': #{e}"
|
79
|
+
# convert other errors to YachtLoader::Yacht::LoadError
|
80
|
+
raise Yacht::LoadError.new "ERROR: loading config file: '#{file_type}': #{e}"
|
97
81
|
end
|
98
82
|
end
|
99
83
|
|
100
84
|
def chain_configs(config, env)
|
101
|
-
raise LoadError.new "environment '#{env}' does not exist" unless config.has_key?(env)
|
85
|
+
raise Yacht::LoadError.new "environment '#{env}' does not exist" unless config.has_key?(env)
|
102
86
|
|
103
87
|
parent = if config[env]['_parent']
|
104
88
|
chain_configs(config, config[env]['_parent'])
|
@@ -109,4 +93,8 @@ class YachtLoader
|
|
109
93
|
parent.deep_merge(config[env])
|
110
94
|
end
|
111
95
|
end
|
112
|
-
|
96
|
+
|
97
|
+
end
|
98
|
+
|
99
|
+
# Alias for Yacht::Loader for backwards compatibility
|
100
|
+
Object.const_set(:YachtLoader, Yacht::Loader)
|
data/lib/yacht.rb
CHANGED
@@ -1,12 +1,7 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
# YachtLoader will be renamed to Yacht
|
1
|
+
require "yacht/base"
|
2
|
+
require "yacht/loader"
|
3
|
+
require "yacht/classy_struct"
|
4
|
+
require "yacht/version"
|
6
5
|
|
7
|
-
require "
|
8
|
-
require
|
9
|
-
require "yacht_loader/version"
|
10
|
-
|
11
|
-
require "yacht_loader/rails" if Object.const_defined?(:Rails)
|
12
|
-
require 'monkeypatches/hash'
|
6
|
+
require "yacht/rails" if Object.const_defined?(:Rails)
|
7
|
+
require 'monkeypatches/hash'
|
data/spec/spec_helper.rb
CHANGED
@@ -15,101 +15,8 @@ require 'yacht'
|
|
15
15
|
|
16
16
|
RSpec.configure do |config|
|
17
17
|
config.after :each do
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
BASE_CONFIG_FILE = <<EOF
|
25
|
-
default:
|
26
|
-
name: default
|
27
|
-
defaultkey: defaultvalue
|
28
|
-
dog: schnauzer
|
29
|
-
hashkey:
|
30
|
-
foo: bar
|
31
|
-
baz: wurble
|
32
|
-
xyzzy: thud
|
33
|
-
an_environment:
|
34
|
-
name: an_environment
|
35
|
-
hashkey:
|
36
|
-
baz: yay
|
37
|
-
dog: terrier
|
38
|
-
a_child_environment:
|
39
|
-
_parent: an_environment
|
40
|
-
name: a_child_environment
|
41
|
-
hashkey:
|
42
|
-
foo: kung
|
43
|
-
test:
|
44
|
-
baloney: delicious
|
45
|
-
EOF
|
46
|
-
|
47
|
-
WHITELIST_CONFIG_FILE = <<EOF
|
48
|
-
- defaultkey
|
49
|
-
- hashkey
|
50
|
-
EOF
|
51
|
-
|
52
|
-
EMPTY_WHITELIST_CONFIG_FILE = <<EOF
|
53
|
-
EOF
|
54
|
-
|
55
|
-
INVALID_WHITELIST_CONFIG_FILE = <<EOF
|
56
|
-
somenonsenseorother
|
57
|
-
EOF
|
58
|
-
|
59
|
-
LOCAL_CONFIG_FILE = <<EOF
|
60
|
-
localkey: localvalue
|
61
|
-
EOF
|
62
|
-
|
63
|
-
EMPTY_LOCAL_CONFIG_FILE = <<EOF
|
64
|
-
EOF
|
65
|
-
|
66
|
-
INVALID_LOCAL_CONFIG_FILE = <<EOF
|
67
|
-
someinvalidstufforother
|
68
|
-
EOF
|
69
|
-
|
70
|
-
|
71
|
-
# ===================================
|
72
|
-
# = Helpers to mock file operations =
|
73
|
-
# ===================================
|
74
|
-
def banish_config_file_from_prefix(prefix)
|
75
|
-
file_name = YachtLoader.config_file_for(prefix)
|
76
|
-
banish_file(file_name)
|
77
|
-
end
|
78
|
-
|
79
|
-
# shortcut to mock config file
|
80
|
-
def conjure_config_file_from_prefix(prefix, file_contents=nil)
|
81
|
-
file_name = YachtLoader.config_file_for(prefix)
|
82
|
-
file_contents ||= "#{prefix.upcase}_CONFIG_FILE".constantize
|
83
|
-
|
84
|
-
conjure_file(file_name, file_contents)
|
85
|
-
end
|
86
|
-
|
87
|
-
def conjure_bad_config_file_from_prefix(prefix)
|
88
|
-
file_name = "#{prefix}_config_file"
|
89
|
-
file_contents = file_name.upcase.constantize
|
90
|
-
|
91
|
-
conjure_file(file_name, file_contents)
|
92
|
-
end
|
93
|
-
|
94
|
-
# mock file existence & contents
|
95
|
-
def conjure_file(file_name, file_contents)
|
96
|
-
File.stub!(:exists?).with(file_name).and_return true
|
97
|
-
File.stub!(:read).with(file_name).and_return file_contents
|
98
|
-
end
|
99
|
-
|
100
|
-
# mock file non-existence
|
101
|
-
def banish_file(file_name)
|
102
|
-
File.stub!(:exists?).with(file_name).and_return(false)
|
103
|
-
File.stub!(:read).with(file_name).and_raise Errno::ENOENT.new("No such file or directory - #{file_name}")
|
104
|
-
end
|
105
|
-
|
106
|
-
# ================================================
|
107
|
-
# = Railsy helper to turn strings into constants =
|
108
|
-
# ================================================
|
109
|
-
if !String.instance_methods.include?(:constantize)
|
110
|
-
class String
|
111
|
-
def constantize # NOT as awesome as ActiveSupport::Inflector#constantize
|
112
|
-
Object.const_get(self)
|
113
|
-
end
|
18
|
+
Yacht::Loader.environment = nil
|
19
|
+
Yacht::Loader.dir = nil
|
20
|
+
Yacht::Loader.instance_variable_set(:@config_file_names, nil)
|
114
21
|
end
|
115
22
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Yacht do
|
4
|
+
subject { Yacht }
|
5
|
+
|
6
|
+
describe :[] do
|
7
|
+
it "should retrieve value of key from Yacht::Loader.to_hash" do
|
8
|
+
mock_hash = {}
|
9
|
+
|
10
|
+
Yacht::Loader.should_receive(:to_hash).and_return(mock_hash)
|
11
|
+
mock_hash.should_receive(:[]).with(:foo)
|
12
|
+
|
13
|
+
subject[:foo]
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|