coconut 0.1.1 → 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/README.md +3 -3
- data/changelog.md +12 -4
- data/features/setup.feature +25 -0
- data/features/step_definitions/configuration_steps.rb +5 -0
- data/features/support/dummy_ftp.rb +5 -0
- data/lib/coconut.rb +28 -4
- data/lib/coconut/config.rb +33 -13
- data/lib/coconut/dsl/application.rb +9 -4
- data/lib/coconut/dsl/asset.rb +9 -5
- data/lib/coconut/dsl/asset_file_list.rb +3 -9
- data/lib/coconut/dsl/asset_folder.rb +3 -8
- data/lib/coconut/dsl/asset_setup.rb +16 -0
- data/lib/coconut/dsl/blank_slate.rb +10 -9
- data/lib/coconut/dsl/environment.rb +1 -1
- data/lib/coconut/version.rb +1 -1
- data/spec/coconut/coconut_spec.rb +34 -3
- data/spec/coconut/config_spec.rb +23 -10
- data/spec/coconut/dsl/application_spec.rb +17 -8
- data/spec/coconut/dsl/asset_file_list_spec.rb +6 -2
- data/spec/coconut/dsl/asset_folder_spec.rb +32 -15
- data/spec/coconut/dsl/asset_spec.rb +11 -0
- data/spec/coconut/dsl/blank_slate_spec.rb +7 -1
- metadata +9 -7
- data/lib/coconut/dsl/asset_file.rb +0 -13
- data/spec/coconut/dsl/asset_file_spec.rb +0 -19
data/README.md
CHANGED
@@ -63,8 +63,8 @@ environment the app is running on. If this variable is not set or is empty it
|
|
63
63
|
will default to `:development`.
|
64
64
|
|
65
65
|
If your ecosystem uses something that is not RACK based you can specify how
|
66
|
-
Coconut should find out the environment with the `
|
67
|
-
**Application** level
|
66
|
+
Coconut should find out the environment with the `take_environment_from` method
|
67
|
+
on the **Application** level
|
68
68
|
(See the *Specifying how the environment should be found* section on
|
69
69
|
*Application* under *Coconut Anatomy*).
|
70
70
|
|
@@ -109,7 +109,7 @@ determine which configuration to use you can tell Coconut how to find out:
|
|
109
109
|
|
110
110
|
```ruby
|
111
111
|
Coconut.configure MyApp do
|
112
|
-
|
112
|
+
take_environment_from { MyApp::find_out_environment }
|
113
113
|
# ...
|
114
114
|
end
|
115
115
|
```
|
data/changelog.md
CHANGED
@@ -1,11 +1,19 @@
|
|
1
1
|
# Coconut release changes
|
2
2
|
|
3
|
-
## Version 0.0
|
4
|
-
-
|
3
|
+
## Version 0.2.0
|
4
|
+
- Including `Coconut` as a module to define the `configure` method.
|
5
|
+
- Querying the configuration using constants.
|
6
|
+
- Asset setup hook.
|
7
|
+
- Improved error messages and warnings.
|
8
|
+
- Improved constant resolution.
|
9
|
+
|
10
|
+
## Version 0.1.1
|
11
|
+
- Add *file list flavour* support.
|
5
12
|
|
6
13
|
## Version 0.1.0
|
7
14
|
- Remove Hashie dependency.
|
8
15
|
- Add *folder flavour* support.
|
9
16
|
|
10
|
-
## Version 0.
|
11
|
-
-
|
17
|
+
## Version 0.0.1
|
18
|
+
- Single file configuration preview.
|
19
|
+
|
@@ -0,0 +1,25 @@
|
|
1
|
+
Feature: Setting up an asset in the configuration
|
2
|
+
|
3
|
+
Many times you use your configuration values to setup a gem or external
|
4
|
+
library. Coconut will allow you to put this code where it belongs: your
|
5
|
+
configuration files.
|
6
|
+
|
7
|
+
Scenario: Setting up an asset
|
8
|
+
Given I have my application config in "/tmp/coconut_config/config.rb" with content:
|
9
|
+
"""
|
10
|
+
Coconut.configure(MyApp) do
|
11
|
+
ftp do
|
12
|
+
environment(:development) do
|
13
|
+
user 'root'
|
14
|
+
pass '1234'
|
15
|
+
end
|
16
|
+
setup do
|
17
|
+
DummyFtp.user = user
|
18
|
+
DummyFtp.pass = pass
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
"""
|
23
|
+
When I run my application on the "development" environment
|
24
|
+
Then my setup block should have been called with the correct values
|
25
|
+
|
@@ -19,3 +19,8 @@ end
|
|
19
19
|
Then /^the configured value should be "(.*?)"$/ do |expected_result|
|
20
20
|
eval(@query).should eq expected_result
|
21
21
|
end
|
22
|
+
|
23
|
+
Then /^my setup block should have been called with the correct values$/ do
|
24
|
+
DummyFtp.user.should eq 'root'
|
25
|
+
DummyFtp.pass.should eq '1234'
|
26
|
+
end
|
data/lib/coconut.rb
CHANGED
@@ -4,24 +4,48 @@ require_relative 'coconut/dsl/application'
|
|
4
4
|
module Coconut
|
5
5
|
include Dsl
|
6
6
|
|
7
|
+
def self.included(base)
|
8
|
+
configure_method = method(:configure)
|
9
|
+
base.singleton_class.instance_eval do
|
10
|
+
define_method(:configure) { |*args, &block| configure_method.(base, &block) }
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
7
14
|
def self.configure(namespace, &config)
|
8
|
-
|
15
|
+
config = Application.configure(environment, &config)
|
16
|
+
check_for_unconfigured_assets(config)
|
17
|
+
define_config_method(namespace, config)
|
18
|
+
define_config_constant(namespace, config)
|
9
19
|
end
|
10
20
|
|
11
21
|
def self.environment
|
12
|
-
return @
|
22
|
+
return @_coconut_environment.() unless @_coconut_environment.nil?
|
13
23
|
ENV['RACK_ENV'] || :development
|
14
24
|
end
|
15
25
|
|
16
26
|
def self.take_environment_from(&block)
|
17
|
-
@
|
27
|
+
@_coconut_environment = block
|
18
28
|
end
|
19
29
|
|
20
30
|
private
|
21
31
|
|
22
32
|
def self.define_config_method(namespace, configuration)
|
23
33
|
namespace.singleton_class.instance_eval do
|
24
|
-
define_method(:config) { @
|
34
|
+
define_method(:config) { @_coconut_configuration ||= configuration }
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.define_config_constant(namespace, configuration)
|
39
|
+
namespace.instance_eval do
|
40
|
+
remove_const(:CONFIG) if const_defined?(:CONFIG, false)
|
41
|
+
const_set(:CONFIG, configuration)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.check_for_unconfigured_assets(config)
|
46
|
+
config.to_hash.each do |asset, properties|
|
47
|
+
Kernel.warn "WARNING: \"#{asset}\" asset has no properties set up for \
|
48
|
+
current environment (#{environment})" if properties.empty?
|
25
49
|
end
|
26
50
|
end
|
27
51
|
end
|
data/lib/coconut/config.rb
CHANGED
@@ -1,8 +1,10 @@
|
|
1
1
|
module Coconut
|
2
2
|
class Config
|
3
|
-
def
|
4
|
-
|
5
|
-
|
3
|
+
def self.with(properties)
|
4
|
+
dup.tap do |new_config|
|
5
|
+
new_config.instance_variable_set('@properties', properties)
|
6
|
+
new_config.instance_variable_set('@config', config_from(properties))
|
7
|
+
end
|
6
8
|
end
|
7
9
|
|
8
10
|
# Coconut::Config objects will respond to methods if its name is
|
@@ -10,29 +12,27 @@ module Coconut
|
|
10
12
|
# make its behaviour consistent with Coconut::Config#method_missing
|
11
13
|
#
|
12
14
|
# @return [Boolean] whether a config object knows how to respond to method "name"
|
13
|
-
def respond_to?(name)
|
15
|
+
def self.respond_to?(name)
|
14
16
|
property?(name) or super
|
15
17
|
end
|
16
18
|
|
17
19
|
# @return [Hash] a Hash representation of the configuration object
|
18
|
-
def to_hash
|
20
|
+
def self.to_hash
|
19
21
|
@properties.dup
|
20
22
|
end
|
21
23
|
|
22
|
-
|
23
|
-
|
24
|
-
def config_from(properties)
|
24
|
+
def self.config_from(properties)
|
25
25
|
properties.each_with_object({}) do |(property, value), config|
|
26
26
|
config[property]= config_value_for(value)
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
30
|
-
def config_value_for(value)
|
31
|
-
return Config.
|
30
|
+
def self.config_value_for(value)
|
31
|
+
return Config.with(value) if value.is_a? Hash
|
32
32
|
value
|
33
33
|
end
|
34
34
|
|
35
|
-
def method_missing(name, *args, &block)
|
35
|
+
def self.method_missing(name, *args, &block)
|
36
36
|
if property?(name)
|
37
37
|
define_property_accessor(name)
|
38
38
|
return @config[name]
|
@@ -40,14 +40,34 @@ module Coconut
|
|
40
40
|
super
|
41
41
|
end
|
42
42
|
|
43
|
-
def
|
43
|
+
def self.const_missing(name)
|
44
|
+
if property?(name.downcase)
|
45
|
+
define_constant(name)
|
46
|
+
return @config[name.downcase]
|
47
|
+
end
|
48
|
+
super
|
49
|
+
end
|
50
|
+
|
51
|
+
def self.property?(name)
|
52
|
+
return false if @config.nil?
|
44
53
|
@config.has_key?(name)
|
45
54
|
end
|
46
55
|
|
47
|
-
def define_property_accessor(name)
|
56
|
+
def self.define_property_accessor(name)
|
48
57
|
singleton_class.instance_eval do
|
49
58
|
define_method(name) { @config[name] }
|
50
59
|
end
|
51
60
|
end
|
61
|
+
|
62
|
+
def self.define_constant(name)
|
63
|
+
self.const_set(name, @config[name.downcase])
|
64
|
+
end
|
65
|
+
|
66
|
+
private_class_method :config_from,
|
67
|
+
:config_value_for,
|
68
|
+
:define_constant,
|
69
|
+
:define_property_accessor,
|
70
|
+
:method_missing,
|
71
|
+
:property?
|
52
72
|
end
|
53
73
|
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require_relative 'asset'
|
2
2
|
require_relative 'asset_folder'
|
3
|
+
require_relative 'asset_file_list'
|
3
4
|
|
4
5
|
module Coconut
|
5
6
|
module Dsl
|
@@ -15,21 +16,25 @@ module Coconut
|
|
15
16
|
def run(&config)
|
16
17
|
@assets_config = {}
|
17
18
|
instance_eval &config
|
18
|
-
Config.
|
19
|
+
Config.with(@assets_config)
|
19
20
|
end
|
20
21
|
|
21
22
|
private
|
22
23
|
|
23
24
|
def asset_folder(path)
|
24
|
-
|
25
|
+
AssetFolder.new(path, IGNORED_FILES).each do |asset_config, path|
|
26
|
+
instance_eval(asset_config, path)
|
27
|
+
end
|
25
28
|
end
|
26
29
|
|
27
30
|
def asset_files(*files)
|
28
|
-
|
31
|
+
AssetFileList.new(*files).each do |asset_config, path|
|
32
|
+
instance_eval(asset_config, path)
|
33
|
+
end
|
29
34
|
end
|
30
35
|
|
31
36
|
def method_missing(asset, *args, &config)
|
32
|
-
::Kernel::raise InvalidName,
|
37
|
+
::Kernel::raise InvalidName, "#{asset} can't be used as asset name" if _taken?(asset)
|
33
38
|
@assets_config[asset] = Asset.configure(@current_environment, &config)
|
34
39
|
end
|
35
40
|
|
data/lib/coconut/dsl/asset.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
require_relative '../config'
|
2
1
|
require_relative './environment'
|
2
|
+
require_relative './asset_setup'
|
3
3
|
|
4
4
|
module Coconut
|
5
5
|
module Dsl
|
@@ -20,19 +20,23 @@ module Coconut
|
|
20
20
|
|
21
21
|
private
|
22
22
|
|
23
|
+
def setup(&code)
|
24
|
+
AssetSetup.new(@properties).instance_eval(&code)
|
25
|
+
end
|
26
|
+
|
23
27
|
def environment(*environments, &config)
|
24
|
-
environments.each { |environment|
|
28
|
+
environments.each { |environment| _configure(environment, config) }
|
25
29
|
end
|
26
30
|
|
27
31
|
alias :env :environment
|
28
32
|
alias :envs :environment
|
29
33
|
alias :environments :environment
|
30
34
|
|
31
|
-
def
|
32
|
-
@properties.merge! Environment.configure(&config) if
|
35
|
+
def _configure(environment, config)
|
36
|
+
@properties.merge! Environment.configure(&config) if _current?(environment)
|
33
37
|
end
|
34
38
|
|
35
|
-
def
|
39
|
+
def _current?(environment)
|
36
40
|
@current_environment.to_sym == environment.to_sym
|
37
41
|
end
|
38
42
|
end
|
@@ -1,18 +1,12 @@
|
|
1
|
-
require_relative 'asset_file'
|
2
|
-
|
3
1
|
module Coconut
|
4
2
|
module Dsl
|
5
3
|
class AssetFileList
|
6
|
-
def self.config_from(*file_paths)
|
7
|
-
new(*file_paths).assets_config
|
8
|
-
end
|
9
|
-
|
10
4
|
def initialize(*file_paths)
|
11
|
-
@
|
5
|
+
@paths = file_paths
|
12
6
|
end
|
13
7
|
|
14
|
-
def
|
15
|
-
@
|
8
|
+
def each(&block)
|
9
|
+
@paths.each { |path| yield File.read(path), path }
|
16
10
|
end
|
17
11
|
end
|
18
12
|
end
|
@@ -3,17 +3,13 @@ require_relative 'asset_file_list'
|
|
3
3
|
module Coconut
|
4
4
|
module Dsl
|
5
5
|
class AssetFolder
|
6
|
-
def self.config_from(path, ignored_files)
|
7
|
-
new(path, ignored_files).assets_config
|
8
|
-
end
|
9
|
-
|
10
6
|
def initialize(path, ignored_files)
|
11
7
|
@path = path
|
12
8
|
@ignored_files = ignored_files.map(&method(:path_to))
|
13
9
|
end
|
14
10
|
|
15
|
-
def
|
16
|
-
AssetFileList.new(*asset_files_in_folder).
|
11
|
+
def each(&block)
|
12
|
+
AssetFileList.new(*asset_files_in_folder).each(&block)
|
17
13
|
end
|
18
14
|
|
19
15
|
private
|
@@ -38,6 +34,5 @@ module Coconut
|
|
38
34
|
File.expand_path(File.join(@path, file))
|
39
35
|
end
|
40
36
|
end
|
41
|
-
|
42
|
-
end
|
37
|
+
end
|
43
38
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require_relative 'blank_slate'
|
2
|
+
|
3
|
+
module Coconut
|
4
|
+
module Dsl
|
5
|
+
class AssetSetup < BlankSlate
|
6
|
+
def initialize(properties)
|
7
|
+
@properties = properties
|
8
|
+
end
|
9
|
+
|
10
|
+
def method_missing(name, *args, &block)
|
11
|
+
return @properties[name] if @properties.has_key? name
|
12
|
+
super
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -2,32 +2,33 @@ require_relative '../config'
|
|
2
2
|
|
3
3
|
module Coconut
|
4
4
|
module Dsl
|
5
|
-
class InvalidName <
|
5
|
+
class InvalidName < RuntimeError; end
|
6
6
|
|
7
7
|
class BlankSlate < BasicObject
|
8
8
|
def self.__forbidden_names
|
9
|
-
Config.instance_methods +
|
9
|
+
Config.instance_methods + PERMANENT_PUBLIC_METHODS
|
10
10
|
end
|
11
11
|
|
12
12
|
private
|
13
13
|
|
14
|
-
def
|
14
|
+
def _taken?(name)
|
15
15
|
Config.instance_methods.include? name
|
16
16
|
end
|
17
17
|
|
18
|
-
def
|
19
|
-
|
18
|
+
def self.const_missing(name)
|
19
|
+
super unless self.class.const_defined?(name)
|
20
|
+
self.class.const_get(name)
|
20
21
|
end
|
21
22
|
|
22
23
|
def self.inherited(subclass)
|
23
|
-
|
24
|
+
_eraseable_methods.each{ |method_name| undef_method method_name }
|
24
25
|
end
|
25
26
|
|
26
|
-
def self.
|
27
|
-
instance_methods -
|
27
|
+
def self._eraseable_methods
|
28
|
+
instance_methods - PERMANENT_PUBLIC_METHODS
|
28
29
|
end
|
29
30
|
|
30
|
-
|
31
|
+
PERMANENT_PUBLIC_METHODS = [:instance_eval, :__send__, :object_id, :__forbidden_names]
|
31
32
|
end
|
32
33
|
end
|
33
34
|
end
|
@@ -20,7 +20,7 @@ module Coconut
|
|
20
20
|
private
|
21
21
|
|
22
22
|
def method_missing(name, *args, &block)
|
23
|
-
::Kernel::raise InvalidName,
|
23
|
+
::Kernel::raise InvalidName, "#{name} can't be used as property name" if _taken?(name)
|
24
24
|
@properties[name] = args.first
|
25
25
|
end
|
26
26
|
end
|
data/lib/coconut/version.rb
CHANGED
@@ -1,9 +1,19 @@
|
|
1
1
|
require 'coconut'
|
2
2
|
|
3
|
-
class MyClass; end
|
4
|
-
module MyModule; end
|
5
3
|
|
6
4
|
describe Coconut do
|
5
|
+
before do
|
6
|
+
class MyClass; end
|
7
|
+
module MyModule; end
|
8
|
+
end
|
9
|
+
|
10
|
+
after do
|
11
|
+
Object.instance_eval do
|
12
|
+
remove_const(:MyClass)
|
13
|
+
remove_const(:MyModule)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
7
17
|
it 'defines a config method in the provided namespace' do
|
8
18
|
Coconut.configure(MyClass){}
|
9
19
|
MyClass.should respond_to(:config)
|
@@ -11,14 +21,35 @@ describe Coconut do
|
|
11
21
|
MyModule.should respond_to(:config)
|
12
22
|
end
|
13
23
|
|
24
|
+
it 'defines a config constant in the provided namespace' do
|
25
|
+
Coconut.configure(MyClass){}
|
26
|
+
MyClass::CONFIG.should_not be_nil
|
27
|
+
Coconut.configure(MyModule){}
|
28
|
+
MyModule::CONFIG.should_not be_nil
|
29
|
+
end
|
30
|
+
|
14
31
|
it "allows the app's configuration to be run twice" do
|
15
32
|
Coconut.configure(MyClass) { asset { env(:development){ property 'initial value' } } }
|
16
33
|
Coconut.configure(MyClass) { asset { env(:development){ property 'latest value' } } }
|
17
34
|
MyClass::config.asset.property.should eq 'latest value'
|
18
35
|
end
|
19
36
|
|
37
|
+
it 'checks the configuration for assets without properties' do
|
38
|
+
Kernel.should_receive(:warn).with(/asset|current environment|development/)
|
39
|
+
Coconut.configure MyClass do
|
40
|
+
asset {}
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
context 'when included' do
|
45
|
+
it 'defines a configure method' do
|
46
|
+
module MyModule; include Coconut; end
|
47
|
+
expect { module MyModule; configure{}; end }.not_to raise_error
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
20
51
|
context 'finding out the environment' do
|
21
|
-
before { Coconut.instance_variable_set(:@
|
52
|
+
before { Coconut.instance_variable_set(:@_coconut_environment, nil) }
|
22
53
|
|
23
54
|
it 'uses the expression provided by the user if any' do
|
24
55
|
Coconut.take_environment_from { :somewhere }
|
data/spec/coconut/config_spec.rb
CHANGED
@@ -1,34 +1,47 @@
|
|
1
1
|
require 'coconut/config'
|
2
2
|
|
3
3
|
describe Coconut::Config do
|
4
|
-
subject
|
5
|
-
let(:
|
6
|
-
let(:properties)
|
4
|
+
subject { described_class.with(assets) }
|
5
|
+
let(:assets) { Hash[twitter: properties] }
|
6
|
+
let(:properties) { Hash[property: 'value', other: 'other'] }
|
7
7
|
|
8
8
|
context 'newly created' do
|
9
9
|
it 'has no property methods' do
|
10
|
-
(subject.
|
10
|
+
(subject.public_methods - Class.public_methods).should eq [:with, :to_hash]
|
11
11
|
end
|
12
12
|
|
13
|
-
|
13
|
+
it 'responds to every property' do
|
14
14
|
subject.should respond_to :twitter
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
18
|
-
context 'when a property is queried' do
|
19
|
-
|
18
|
+
context 'when a property is queried as a method' do
|
19
|
+
it 'returns the property value' do
|
20
20
|
subject.twitter.property.should eq 'value'
|
21
21
|
subject.twitter.other.should eq 'other'
|
22
22
|
end
|
23
23
|
|
24
|
-
|
24
|
+
it 'defines a new method to access the property' do
|
25
25
|
subject.methods.should_not include(:twitter)
|
26
26
|
subject.twitter
|
27
27
|
subject.methods.should include(:twitter)
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
31
|
-
|
32
|
-
|
31
|
+
context 'when a property is queried as a constant' do
|
32
|
+
it 'returns the property value' do
|
33
|
+
subject::TWITTER::PROPERTY.should eq 'value'
|
34
|
+
subject::TWITTER::OTHER.should eq 'other'
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'defines a new constant to access the property' do
|
38
|
+
subject.constants.should_not include(:TWITTER)
|
39
|
+
subject::TWITTER
|
40
|
+
subject.constants.should include(:TWITTER)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'can be transformed to a hash' do
|
45
|
+
subject.to_hash.should eq assets
|
33
46
|
end
|
34
47
|
end
|
@@ -15,17 +15,26 @@ describe Coconut::Dsl::Application do
|
|
15
15
|
end
|
16
16
|
|
17
17
|
it 'can load the asset configuration from a folder' do
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
18
|
+
asset_path = '/file/path.rb'
|
19
|
+
asset_config = "asset { environment(:current) { property 'value' } }"
|
20
|
+
|
21
|
+
asset_folder = stub(:asset_folder)
|
22
|
+
Coconut::Dsl::AssetFolder.stub(:new).and_return(asset_folder)
|
23
|
+
asset_folder.stub(:each).and_yield(asset_config, asset_path)
|
24
|
+
|
25
|
+
config = described_class.configure(:current) { asset_folder '.' }
|
22
26
|
config.asset.property.should eq 'value'
|
23
27
|
end
|
24
28
|
|
25
|
-
it 'can load asset configuration from a list of files' do
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
+
it 'can load asset configuration from a list of asset files' do
|
30
|
+
asset_path = '/file/path.rb'
|
31
|
+
asset_config = "asset { environment(:current) { property 'value' } }"
|
32
|
+
|
33
|
+
asset_file_list = stub(:asset_file_list)
|
34
|
+
Coconut::Dsl::AssetFileList.stub(:new).and_return(asset_file_list)
|
35
|
+
asset_file_list.stub(:each).and_yield(asset_config, asset_path)
|
36
|
+
|
37
|
+
config = described_class.configure(:current) { asset_files asset_path }
|
29
38
|
config.asset.property.should eq 'value'
|
30
39
|
end
|
31
40
|
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'coconut/dsl/asset_file_list'
|
2
2
|
|
3
3
|
describe Coconut::Dsl::AssetFileList do
|
4
|
+
subject { described_class.new(path1, path2) }
|
4
5
|
let(:path1) { '/tmp/asset1.rb' }
|
5
6
|
let(:path2) { '/tmp/asset2.rb' }
|
6
7
|
let(:config1) { "asset1 { env(:current) { property 'value for asset1' } }" }
|
@@ -15,7 +16,10 @@ describe Coconut::Dsl::AssetFileList do
|
|
15
16
|
File.delete('/tmp/asset1.rb', '/tmp/asset2.rb')
|
16
17
|
end
|
17
18
|
|
18
|
-
it
|
19
|
-
|
19
|
+
it "yields each asset file's config and path in the list" do
|
20
|
+
configs, paths = [], []
|
21
|
+
subject.each { |config, path| paths << path and configs << config }
|
22
|
+
paths.should include(path1, path2)
|
23
|
+
configs.should include(config1, config2)
|
20
24
|
end
|
21
25
|
end
|
@@ -1,36 +1,53 @@
|
|
1
1
|
require 'coconut/dsl/asset_folder'
|
2
2
|
|
3
3
|
describe 'Assets configuration from files in folder', integration: true do
|
4
|
+
subject { Coconut::Dsl::AssetFolder.new(path, ignored) }
|
4
5
|
let(:path) { '/tmp/coconut-testing/' }
|
5
6
|
let(:ignored) { ['config.rb'] }
|
6
7
|
|
7
|
-
let(:config) { "" }
|
8
8
|
let(:s3_config) { "s3 { environment(:current) { property 'p1' } }" }
|
9
9
|
let(:db_config) { "database { environment(:current) { property 'p2' } }" }
|
10
10
|
|
11
|
-
before
|
12
|
-
`rm -rf #{path}`
|
11
|
+
before do
|
13
12
|
Dir::mkdir path
|
14
|
-
File.open(File.join(path, '
|
15
|
-
File.open(File.join(path, '
|
16
|
-
File.open(File.join(path, 'db.rb'), 'w+') { |f| f.write db_config }
|
13
|
+
File.open(File.join(path, 's3.rb'), 'w+') { |f| f.write s3_config }
|
14
|
+
File.open(File.join(path, 'db.rb'), 'w+') { |f| f.write db_config }
|
17
15
|
end
|
18
16
|
|
19
|
-
|
20
|
-
|
17
|
+
after do
|
18
|
+
`rm -rf #{path}`
|
21
19
|
end
|
22
20
|
|
23
|
-
|
24
|
-
|
25
|
-
|
21
|
+
shared_examples_for 'a folder with asset files only' do
|
22
|
+
let(:paths) { [] }
|
23
|
+
let(:configs) { [] }
|
24
|
+
|
25
|
+
it "yields every asset file's config and path" do
|
26
|
+
subject.each { |config, path| paths << path and configs << config }
|
27
|
+
paths.length.should be 2
|
28
|
+
paths.should include('/tmp/coconut-testing/s3.rb', '/tmp/coconut-testing/db.rb')
|
29
|
+
configs.length.should be 2
|
30
|
+
configs.should include(s3_config, db_config)
|
26
31
|
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context 'with asset files only' do
|
35
|
+
it_behaves_like 'a folder with asset files only'
|
36
|
+
end
|
27
37
|
|
28
|
-
|
29
|
-
|
38
|
+
context 'with asset files and a config.rb file' do
|
39
|
+
before do
|
40
|
+
File.open(File.join(path, 'config.rb'), 'w+') { |f| f.write '#config' }
|
30
41
|
end
|
42
|
+
|
43
|
+
it_behaves_like 'a folder with asset files only'
|
31
44
|
end
|
32
45
|
|
33
|
-
|
34
|
-
|
46
|
+
context 'with asset files and non Ruby files' do
|
47
|
+
before do
|
48
|
+
File.open(File.join(path, 'readme.md'), 'w+') { |f| f.write 'readme' }
|
49
|
+
end
|
50
|
+
|
51
|
+
it_behaves_like 'a folder with asset files only'
|
35
52
|
end
|
36
53
|
end
|
@@ -46,4 +46,15 @@ describe Coconut::Dsl::Asset do
|
|
46
46
|
asset_config.fetch(:property3).should eq 3
|
47
47
|
asset_config.fetch(:property4).should eq 4
|
48
48
|
end
|
49
|
+
|
50
|
+
it 'has a setup hook' do
|
51
|
+
setup_value = nil
|
52
|
+
asset_config = described_class.configure(:current) do
|
53
|
+
env(:current) { property 'value' }
|
54
|
+
setup do
|
55
|
+
setup_value = property
|
56
|
+
end
|
57
|
+
end
|
58
|
+
setup_value.should eq 'value'
|
59
|
+
end
|
49
60
|
end
|
@@ -2,8 +2,14 @@ require 'coconut/dsl/blank_slate'
|
|
2
2
|
|
3
3
|
describe Coconut::Dsl::BlankSlate do
|
4
4
|
it 'knows the forbidden names' do
|
5
|
-
expected_names = described_class::
|
5
|
+
expected_names = described_class::PERMANENT_PUBLIC_METHODS + [:one]
|
6
6
|
Coconut::Config.stub(:instance_methods).and_return([:one])
|
7
7
|
described_class.__forbidden_names.should include(*expected_names)
|
8
8
|
end
|
9
|
+
|
10
|
+
it 'can look up for constants on the global namespace' do
|
11
|
+
context = described_class.new
|
12
|
+
expect { context.instance_eval('Kernel') }.not_to raise_error NameError
|
13
|
+
end
|
9
14
|
end
|
15
|
+
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: coconut
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2013-01-22 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: cucumber
|
@@ -92,16 +92,18 @@ files:
|
|
92
92
|
- coconut.gemspec
|
93
93
|
- features/folder_configuration.feature
|
94
94
|
- features/multiple_file_configuration.feature
|
95
|
+
- features/setup.feature
|
95
96
|
- features/single_file_configuration.feature
|
96
97
|
- features/step_definitions/configuration_steps.rb
|
98
|
+
- features/support/dummy_ftp.rb
|
97
99
|
- features/support/env.rb
|
98
100
|
- lib/coconut.rb
|
99
101
|
- lib/coconut/config.rb
|
100
102
|
- lib/coconut/dsl/application.rb
|
101
103
|
- lib/coconut/dsl/asset.rb
|
102
|
-
- lib/coconut/dsl/asset_file.rb
|
103
104
|
- lib/coconut/dsl/asset_file_list.rb
|
104
105
|
- lib/coconut/dsl/asset_folder.rb
|
106
|
+
- lib/coconut/dsl/asset_setup.rb
|
105
107
|
- lib/coconut/dsl/blank_slate.rb
|
106
108
|
- lib/coconut/dsl/environment.rb
|
107
109
|
- lib/coconut/version.rb
|
@@ -109,7 +111,6 @@ files:
|
|
109
111
|
- spec/coconut/config_spec.rb
|
110
112
|
- spec/coconut/dsl/application_spec.rb
|
111
113
|
- spec/coconut/dsl/asset_file_list_spec.rb
|
112
|
-
- spec/coconut/dsl/asset_file_spec.rb
|
113
114
|
- spec/coconut/dsl/asset_folder_spec.rb
|
114
115
|
- spec/coconut/dsl/asset_spec.rb
|
115
116
|
- spec/coconut/dsl/blank_slate_spec.rb
|
@@ -128,7 +129,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
128
129
|
version: '0'
|
129
130
|
segments:
|
130
131
|
- 0
|
131
|
-
hash:
|
132
|
+
hash: 2150013374139596454
|
132
133
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
133
134
|
none: false
|
134
135
|
requirements:
|
@@ -137,7 +138,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
137
138
|
version: '0'
|
138
139
|
segments:
|
139
140
|
- 0
|
140
|
-
hash:
|
141
|
+
hash: 2150013374139596454
|
141
142
|
requirements: []
|
142
143
|
rubyforge_project:
|
143
144
|
rubygems_version: 1.8.24
|
@@ -148,14 +149,15 @@ summary: Coconut is a simple DSL that allows you to easily write and query your
|
|
148
149
|
test_files:
|
149
150
|
- features/folder_configuration.feature
|
150
151
|
- features/multiple_file_configuration.feature
|
152
|
+
- features/setup.feature
|
151
153
|
- features/single_file_configuration.feature
|
152
154
|
- features/step_definitions/configuration_steps.rb
|
155
|
+
- features/support/dummy_ftp.rb
|
153
156
|
- features/support/env.rb
|
154
157
|
- spec/coconut/coconut_spec.rb
|
155
158
|
- spec/coconut/config_spec.rb
|
156
159
|
- spec/coconut/dsl/application_spec.rb
|
157
160
|
- spec/coconut/dsl/asset_file_list_spec.rb
|
158
|
-
- spec/coconut/dsl/asset_file_spec.rb
|
159
161
|
- spec/coconut/dsl/asset_folder_spec.rb
|
160
162
|
- spec/coconut/dsl/asset_spec.rb
|
161
163
|
- spec/coconut/dsl/blank_slate_spec.rb
|
@@ -1,19 +0,0 @@
|
|
1
|
-
require 'coconut/dsl/asset_file'
|
2
|
-
|
3
|
-
describe Coconut::Dsl::AssetFile do
|
4
|
-
subject { described_class.new(path) }
|
5
|
-
let(:path) { '/tmp/asset.rb' }
|
6
|
-
let(:config) { "asset { env(:current) { property 'value' } }" }
|
7
|
-
|
8
|
-
before do
|
9
|
-
File.open('/tmp/asset.rb', 'w+') { |f| f.write(config) }
|
10
|
-
end
|
11
|
-
|
12
|
-
after do
|
13
|
-
File.delete('/tmp/asset.rb')
|
14
|
-
end
|
15
|
-
|
16
|
-
it 'reads the content of the asset file at path' do
|
17
|
-
subject.asset_config.should eq config
|
18
|
-
end
|
19
|
-
end
|