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 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 `environment` method on 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
- environment { MyApp::find_out_environment }
112
+ take_environment_from { MyApp::find_out_environment }
113
113
  # ...
114
114
  end
115
115
  ```
@@ -1,11 +1,19 @@
1
1
  # Coconut release changes
2
2
 
3
- ## Version 0.0.1
4
- - Single file configuration preview.
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.1.1
11
- - Add *file list flavour* support.
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
@@ -0,0 +1,5 @@
1
+ class DummyFtp
2
+ class << self
3
+ attr_accessor :user, :pass
4
+ end
5
+ end
@@ -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
- define_config_method namespace, Application.configure(environment, &config)
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 @__coconut_environment.() unless @__coconut_environment.nil?
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
- @__coconut_environment = block
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) { @__coconut_configuration ||= configuration }
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
@@ -1,8 +1,10 @@
1
1
  module Coconut
2
2
  class Config
3
- def initialize(properties)
4
- @properties = properties
5
- @config = config_from(properties)
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
- private
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.new(value) if value.is_a? Hash
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 property?(name)
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.new(@assets_config)
19
+ Config.with(@assets_config)
19
20
  end
20
21
 
21
22
  private
22
23
 
23
24
  def asset_folder(path)
24
- instance_eval AssetFolder.config_from(path, IGNORED_FILES)
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
- instance_eval AssetFileList.config_from(*files)
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, __taken_error_message(asset, 'asset name') if __taken?(asset)
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
 
@@ -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| __configure(environment, config) }
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 __configure(environment, config)
32
- @properties.merge! Environment.configure(&config) if __current?(environment)
35
+ def _configure(environment, config)
36
+ @properties.merge! Environment.configure(&config) if _current?(environment)
33
37
  end
34
38
 
35
- def __current?(environment)
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
- @files = file_paths.map { |file| AssetFile.new(file) }
5
+ @paths = file_paths
12
6
  end
13
7
 
14
- def assets_config
15
- @files.map { |file| file.asset_config }.join("\n")
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 assets_config
16
- AssetFileList.new(*asset_files_in_folder).assets_config
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 < Exception; end
5
+ class InvalidName < RuntimeError; end
6
6
 
7
7
  class BlankSlate < BasicObject
8
8
  def self.__forbidden_names
9
- Config.instance_methods + PERMANENT_METHODS
9
+ Config.instance_methods + PERMANENT_PUBLIC_METHODS
10
10
  end
11
11
 
12
12
  private
13
13
 
14
- def __taken?(name)
14
+ def _taken?(name)
15
15
  Config.instance_methods.include? name
16
16
  end
17
17
 
18
- def __taken_error_message(name, usage)
19
- "#{name} can't be used as #{usage}: it will collide with Coconut::Config methods"
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
- __eraseable_methods.each{ |method_name| undef_method method_name }
24
+ _eraseable_methods.each{ |method_name| undef_method method_name }
24
25
  end
25
26
 
26
- def self.__eraseable_methods
27
- instance_methods - PERMANENT_METHODS
27
+ def self._eraseable_methods
28
+ instance_methods - PERMANENT_PUBLIC_METHODS
28
29
  end
29
30
 
30
- PERMANENT_METHODS = [:instance_eval, :__send__, :object_id, :__taken?, :__taken_error_message, :asset_folder]
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, __taken_error_message(name, 'property name') if __taken?(name)
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
@@ -1,3 +1,3 @@
1
1
  module Coconut
2
- VERSION = "0.1.1"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -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(:@__coconut_environment, nil) }
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 }
@@ -1,34 +1,47 @@
1
1
  require 'coconut/config'
2
2
 
3
3
  describe Coconut::Config do
4
- subject { described_class.new(application) }
5
- let(:application) { Hash[twitter: properties] }
6
- let(:properties) { Hash[property: 'value', other: 'other'] }
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.methods - Object.instance_methods).should eq [:to_hash]
10
+ (subject.public_methods - Class.public_methods).should eq [:with, :to_hash]
11
11
  end
12
12
 
13
- it 'responds to every property' do
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
- it 'returns the property value' do
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
- it 'defines a new method to access the property' do
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
- it 'can be transformed to a hash' do
32
- subject.to_hash.should eq application
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
- path = '.'
19
- Coconut::Dsl::AssetFolder.stub(:config_from).with(path, ['config.rb']).
20
- and_return("asset { environment(:current) { property 'value' } }")
21
- config = described_class.configure(:current) { asset_folder path }
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
- Coconut::Dsl::AssetFileList.stub(:config_from).with('/file/path.rb').
27
- and_return("asset { environment(:current) { property 'value' } }")
28
- config = described_class.configure(:current) { asset_files '/file/path.rb' }
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 'reads the content of the asset file at path' do
19
- described_class.config_from(path1, path2).should eq "#{config1}\n#{config2}"
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 :all do
12
- `rm -rf #{path}`
11
+ before do
13
12
  Dir::mkdir path
14
- File.open(File.join(path, 'config.rb'), 'w+') { |f| f.write '' }
15
- File.open(File.join(path, 's3.rb'), 'w+') { |f| f.write s3_config }
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
- it 'evals every asset file in the folder as application config' do
20
- configuration_from_folder.should eq "#{db_config}\n#{s3_config}"
17
+ after do
18
+ `rm -rf #{path}`
21
19
  end
22
20
 
23
- context 'with other files that are not Ruby files' do
24
- before do
25
- File.open(File.join(path, 'readme.md'), 'w+') { |f| f.write 'readme' }
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
- it 'ignores non Ruby files' do
29
- configuration_from_folder.should eq "#{db_config}\n#{s3_config}"
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
- def configuration_from_folder
34
- Coconut::Dsl::AssetFolder.config_from(path, ignored)
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::PERMANENT_METHODS + [:one]
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.1.1
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: 2012-12-26 00:00:00.000000000 Z
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: -2312631787946944813
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: -2312631787946944813
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,13 +0,0 @@
1
- module Coconut
2
- module Dsl
3
- class AssetFile
4
- def initialize(path)
5
- @path = path
6
- end
7
-
8
- def asset_config
9
- ::File.read(@path)
10
- end
11
- end
12
- end
13
- end
@@ -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