taketo 0.0.6 → 0.0.7

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.
Files changed (51) hide show
  1. data/Gemfile +1 -1
  2. data/Gemfile.lock +3 -3
  3. data/README.md +20 -7
  4. data/VERSION +1 -1
  5. data/bin/taketo +30 -31
  6. data/features/config.feature +33 -3
  7. data/features/config_validation.feature +29 -4
  8. data/features/connect_to_server.feature +2 -1
  9. data/features/error_handling.feature +1 -0
  10. data/features/help.feature +5 -3
  11. data/features/support/env.rb +2 -0
  12. data/lib/taketo/associated_nodes.rb +90 -0
  13. data/lib/taketo/commands/ssh_command.rb +0 -4
  14. data/lib/taketo/config_printer_visitor.rb +68 -0
  15. data/lib/taketo/config_traverser.rb +55 -0
  16. data/lib/taketo/config_validator.rb +33 -34
  17. data/lib/taketo/config_visitor.rb +29 -0
  18. data/lib/taketo/constructs/base_construct.rb +9 -54
  19. data/lib/taketo/constructs/command.rb +9 -1
  20. data/lib/taketo/constructs/environment.rb +11 -1
  21. data/lib/taketo/constructs/project.rb +5 -0
  22. data/lib/taketo/constructs/server.rb +7 -4
  23. data/lib/taketo/dsl.rb +13 -2
  24. data/lib/taketo/support/named_nodes_collection.rb +10 -0
  25. data/lib/taketo/support.rb +0 -1
  26. data/lib/taketo.rb +2 -1
  27. data/spec/integration/dsl_integration_spec.rb +1 -1
  28. data/spec/lib/taketo/associated_nodes_spec.rb +101 -0
  29. data/spec/lib/taketo/commands/ssh_command_spec.rb +5 -15
  30. data/spec/lib/taketo/config_printer_visitor_spec.rb +112 -0
  31. data/spec/lib/taketo/config_traverser_spec.rb +63 -0
  32. data/spec/lib/taketo/config_validator_spec.rb +53 -39
  33. data/spec/lib/taketo/config_visitor_spec.rb +51 -0
  34. data/spec/lib/taketo/constructs/base_construct_spec.rb +7 -70
  35. data/spec/lib/taketo/constructs/command_spec.rb +20 -8
  36. data/spec/lib/taketo/constructs/config_spec.rb +2 -6
  37. data/spec/lib/taketo/constructs/environment_spec.rb +12 -7
  38. data/spec/lib/taketo/constructs/project_spec.rb +10 -4
  39. data/spec/lib/taketo/constructs/server_spec.rb +25 -16
  40. data/spec/lib/taketo/constructs_factory_spec.rb +12 -12
  41. data/spec/lib/taketo/destination_resolver_spec.rb +32 -32
  42. data/spec/lib/taketo/dsl_spec.rb +115 -98
  43. data/spec/lib/taketo/support/named_nodes_collection_spec.rb +49 -21
  44. data/spec/support/helpers/construct_spec_helper.rb +5 -5
  45. data/spec/support/matchers/be_appropriate_construct_matcher.rb +9 -1
  46. data/spec/support/matchers/have_accessor_matcher.rb +6 -3
  47. metadata +18 -7
  48. data/lib/taketo/config_printer.rb +0 -84
  49. data/lib/taketo/support/eval_delegator.rb +0 -25
  50. data/spec/lib/taketo/config_printer_spec.rb +0 -116
  51. data/spec/lib/taketo/support/eval_delegator_spec.rb +0 -43
@@ -1,4 +1,4 @@
1
- require File.expand_path('../../../spec_helper', __FILE__)
1
+ require 'spec_helper'
2
2
  require 'taketo/destination_resolver'
3
3
  require 'taketo/support/named_nodes_collection'
4
4
 
@@ -50,29 +50,29 @@ describe "DestinationResolver" do
50
50
  let(:config) { TestNode.new(:config, nil, project1, project2, project3, project4) }
51
51
 
52
52
  context "when project, environment and server specified" do
53
- it "should return server if it exists" do
54
- resolver(config, "foo:bar:s1").resolve.should == server1
53
+ it "returns server if it exists" do
54
+ expect(resolver(config, "foo:bar:s1").resolve).to eq(server1)
55
55
  end
56
56
 
57
- it "should raise error if server does not exist" do
57
+ it "raises error if server does not exist" do
58
58
  expect { resolver(config, "foo:bar:noserver").resolve }.to raise_error(NonExistentDestinationError)
59
59
  end
60
60
  end
61
61
 
62
62
  context "when there are 2 segments in path" do
63
63
  context "when there is matching project - environment pair" do
64
- it "should return server if only one specified" do
65
- resolver(config, "foo:bar").resolve.should == server1
66
- resolver(config, "baz:qux").resolve.should == server2
64
+ it "returns server if only one specified" do
65
+ expect(resolver(config, "foo:bar").resolve).to eq(server1)
66
+ expect(resolver(config, "baz:qux").resolve).to eq(server2)
67
67
  end
68
68
 
69
- it "should raise error if there are multiple servers" do
69
+ it "raises error if there are multiple servers" do
70
70
  expect { resolver(config, "quux:corge").resolve }.to raise_error(AmbiguousDestinationError)
71
71
  end
72
72
  end
73
73
 
74
74
  context "when there is no matching project - environment pair" do
75
- it "should raise error if no such project - environment pair exist" do
75
+ it "raises error if no such project - environment pair exist" do
76
76
  expect { resolver(config, "chunky:bacon").resolve }.to raise_error(NonExistentDestinationError)
77
77
  end
78
78
  end
@@ -82,27 +82,27 @@ describe "DestinationResolver" do
82
82
  context "when project with given name exists" do
83
83
  context "when there's one environment" do
84
84
  context "when there's one server" do
85
- it "should return the server" do
86
- resolver(config, "foo").resolve.should == server1
85
+ it "returns the server" do
86
+ expect(resolver(config, "foo").resolve).to eq(server1)
87
87
  end
88
88
  end
89
89
 
90
90
  context "when there are multiple servers" do
91
- it "should raise error" do
91
+ it "raises error" do
92
92
  expect { resolver(config, "quux").resolve }.to raise_error(AmbiguousDestinationError)
93
93
  end
94
94
  end
95
95
  end
96
96
 
97
97
  context "when there are multiple environments" do
98
- it "should raise error" do
98
+ it "raises error" do
99
99
  expect { resolver(config, "grault").resolve }.to raise_error(AmbiguousDestinationError)
100
100
  end
101
101
  end
102
102
  end
103
103
 
104
104
  context "when there is no such project" do
105
- it "should raise error" do
105
+ it "raises error" do
106
106
  expect { resolver(config, "chunky").resolve }.to raise_error(NonExistentDestinationError)
107
107
  end
108
108
  end
@@ -113,15 +113,15 @@ describe "DestinationResolver" do
113
113
  context "when there's one project" do
114
114
  context "when there's one environment" do
115
115
  context "when there's one server" do
116
- it "should execute command without asking project/environment/server" do
116
+ it "executes command without asking project/environment/server" do
117
117
  config = TestNode.new(:config, nil, project1)
118
118
  config.stub(:default_destination => nil)
119
- resolver(config, "").resolve.should == server1
119
+ expect(resolver(config, "").resolve).to eq(server1)
120
120
  end
121
121
  end
122
122
 
123
123
  context "when there are multiple servers" do
124
- it "should ask for server" do
124
+ it "asks for server" do
125
125
  config = TestNode.new(:config, nil, project3)
126
126
  config.stub(:default_destination => nil)
127
127
  expect { resolver(config, "").resolve }.to raise_error AmbiguousDestinationError, /server/i
@@ -130,7 +130,7 @@ describe "DestinationResolver" do
130
130
  end
131
131
 
132
132
  context "when there are multiple environments" do
133
- it "should ask for environment" do
133
+ it "asks for environment" do
134
134
  config = TestNode.new(:config, nil, project4)
135
135
  config.stub(:default_destination => nil)
136
136
  expect { resolver(config, "").resolve }.to raise_error AmbiguousDestinationError, /environment/i
@@ -139,7 +139,7 @@ describe "DestinationResolver" do
139
139
  end
140
140
 
141
141
  context "when there are multiple projects" do
142
- it "should ask for project" do
142
+ it "asks for project" do
143
143
  config = TestNode.new(:config, nil, project3, project4)
144
144
  config.stub(:default_destination => nil)
145
145
 
@@ -149,38 +149,38 @@ describe "DestinationResolver" do
149
149
  end
150
150
 
151
151
  context "when there is default destination" do
152
- it "should resolve by default destination" do
152
+ it "resolves by default destination" do
153
153
  config.stub(:default_destination => "foo:bar:s1")
154
- resolver(config, "").resolve.should == server1
154
+ expect(resolver(config, "").resolve).to eq(server1)
155
155
  end
156
156
  end
157
157
  end
158
158
 
159
159
  context "when there is global matching server alias" do
160
- it "should resolve by alias" do
161
- resolver(config, "the_alias").resolve.should == server1
160
+ it "resolves by alias" do
161
+ expect(resolver(config, "the_alias").resolve).to eq(server1)
162
162
  end
163
163
  end
164
164
 
165
165
  describe "#get_node" do
166
- it "should return server when path has 3 segments and is correct" do
167
- resolver(config, "foo:bar:s1").get_node.should == server1
166
+ it "returns server when path has 3 segments and is correct" do
167
+ expect(resolver(config, "foo:bar:s1").get_node).to eq(server1)
168
168
  end
169
169
 
170
- it "should return environment when path has 2 segments and is correct" do
171
- resolver(config, "foo:bar").get_node.should == environment1
170
+ it "returns environment when path has 2 segments and is correct" do
171
+ expect(resolver(config, "foo:bar").get_node).to eq(environment1)
172
172
  end
173
173
 
174
- it "should return project when path has 1 segment and is correct" do
175
- resolver(config, "foo").get_node.should == project1
174
+ it "returns project when path has 1 segment and is correct" do
175
+ expect(resolver(config, "foo").get_node).to eq(project1)
176
176
  end
177
177
 
178
- it "should return the config if path has is empty and there's no default destination" do
178
+ it "returns the config if path has is empty and there's no default destination" do
179
179
  config.stub(:default_destination => nil)
180
- resolver(config, "").get_node.should == config
180
+ expect(resolver(config, "").get_node).to eq(config)
181
181
  end
182
182
 
183
- it "should raise NonExistentDestinationError when path is not correct" do
183
+ it "raises NonExistentDestinationError when path is not correct" do
184
184
  config.should_receive(:find).with(:project, :i).and_raise(KeyError)
185
185
  expect { resolver(config, "i").get_node }.to raise_error(NonExistentDestinationError)
186
186
  end
@@ -1,4 +1,4 @@
1
- require File.expand_path('../../../spec_helper', __FILE__)
1
+ require 'spec_helper'
2
2
  require 'support/helpers/dsl_spec_helper'
3
3
  require 'taketo/dsl'
4
4
 
@@ -8,57 +8,57 @@ describe "DSL" do
8
8
  extend DSLSpec
9
9
  include DSLSpec
10
10
 
11
- shared_examples "a scope" do |scope_name, parent_scope_name|
11
+ shared_examples "a scoped construct" do |name, parent_scope_name, with_block|
12
12
  parent_scope = scopes[parent_scope_name]
13
-
14
- it { should enclose_scope(scope_name).under(parent_scope) }
15
- it { should be_appropriate_construct(scope_name, :foo).under(parent_scope) }
13
+ it { should be_appropriate_construct(name, :foo).with_block(with_block).under(parent_scope) }
16
14
 
17
15
  scopes.except(parent_scope_name).each do |inappropriate_scope|
18
- it { should_not be_appropriate_construct(scope_name, :foo).under(inappropriate_scope) }
16
+ it { should_not be_appropriate_construct(name, :foo).with_block(with_block).under(inappropriate_scope) }
19
17
  end
18
+ end
19
+
20
+ shared_examples "a scope" do |scope_name, parent_scope_name|
21
+ parent_scope = scopes[parent_scope_name]
22
+
23
+ it_behaves_like "a scoped construct", scope_name, parent_scope_name, true
24
+
25
+ it { should enclose_scope(scope_name).under(parent_scope) }
20
26
 
21
- it "should create a #{scope_name} and set it as current scope object" do # it "should create project and set it as current scope object"
27
+ it "creates a #{scope_name} and set it as current scope object" do # it "creates project and set it as current scope object"
22
28
  dsl(parent_scope, factory.create(parent_scope_name)) do |c| # dsl([:config], factory.create(:config)) do |c|
23
29
  stub_find_or_create_scope_object(c, scope_name, :bar) # stub_find_or_create_scope_object(c, :project, :bar)
24
30
  c.send(scope_name, :bar) do # c.project(:bar) do
25
- c.current_scope_object.should_not be_nil # c.current_scope_object.should_not be_nil
26
- c.current_scope_object.should == factory.send(scope_name) # c.current_scope_object.should == factory.project
31
+ expect(c.current_scope_object).not_to be_nil # expect(c.current_scope_object).not_to be_nil
32
+ expect(c.current_scope_object).to eq(factory.send(scope_name)) # expect(c.current_scope_object).to eq(factory.project)
27
33
  end # end
28
34
  end # end
29
35
  end # end
30
36
 
31
- it "should not leak #{scope_name} as current scope object" do # it "should not leak project as current scope object"
37
+ it "does not leak #{scope_name} as current scope object" do # it "does not leak project as current scope object"
32
38
  dsl(parent_scope, factory.create(parent_scope_name)) do |c| # dsl([:config], factory.create(:config)) do |c|
33
39
  stub_find_or_create_scope_object(c, scope_name, :bar) # stub_find_or_create_scope_object(c, :project, :bar)
34
40
  c.send(scope_name, :bar) do # c.project(:bar) do
35
- c.current_scope_object.should == factory.send(scope_name) # c.current_scope_object.should == factory.project
41
+ expect(c.current_scope_object).to eq(factory.send(scope_name)) # expect(c.current_scope_object).to eq(factory.project)
36
42
  end # end
37
- c.current_scope_object.should_not == factory.send(scope_name) # c.current_scope_object.should_not == factory.project
43
+ expect(c.current_scope_object).not_to eq(factory.send(scope_name)) # expect(c.current_scope_object).not_to eq(factory.project)
38
44
  end # end
39
45
  end # end
40
46
 
41
- it "should add a #{scope_name} to the #{parent_scope_name}'s #{scope_name}s collection" do # it "should add a project to the config's projects collection" do
42
- dsl(parent_scope, factory.create(parent_scope_name)) do |c| # dsl([:config], factory.create(:config)) do |c|
43
- stub_find_or_create_scope_object(c, scope_name, :bar) # stub_find_or_create_scope_object(c, :project, :bar)
44
- c.current_scope_object.should_receive("append_#{scope_name}"). # c.current_scope_object.should_receive(:append_project).
45
- with(factory.send(scope_name)) # with(factory.project)
46
- c.send(scope_name, :bar) {} # c.project(:bar) {}
47
- end # end
48
- end # end
47
+ it "adds a #{scope_name} to the #{parent_scope_name}'s #{scope_name}s collection" do # it "adds a project to the config's projects collection" do
48
+ dsl(parent_scope, factory.create(parent_scope_name)) do |c| # dsl([:config], factory.create(:config)) do |c|
49
+ stub_find_or_create_scope_object(c, scope_name, :bar) # stub_find_or_create_scope_object(c, :project, :bar)
50
+ c.current_scope_object.should_receive("append_#{scope_name}"). # c.current_scope_object.should_receive(:append_project).
51
+ with(factory.send(scope_name)) # with(factory.project)
52
+ c.send(scope_name, :bar) {} # c.project(:bar) {}
53
+ end # end
54
+ end # end
49
55
  end
50
56
 
51
57
  shared_examples "a scoped method" do |attribute_name, parent_scope_name, parent_scope_method, example_value|
52
- parent_scope = scopes[parent_scope_name]
53
-
54
- it { should be_appropriate_construct(attribute_name, example_value).under(parent_scope) }
58
+ it_behaves_like "a scoped construct", attribute_name, parent_scope_name, false
55
59
 
56
- scopes.except(parent_scope_name).each do |inaproppriate_scope|
57
- it { should_not be_appropriate_construct(attribute_name, example_value).under(inaproppriate_scope) }
58
- end
59
-
60
- it "should call #{parent_scope_method} on current #{parent_scope_name}" do # it "should call default_location= on current server" do
61
- dsl(parent_scope, factory.create(parent_scope_name, :foo)) do |c| # dsl([:config, :project, :environment, :server], factory.create(:server, :foo)) do |c|
60
+ it "calls #{parent_scope_method} on current #{parent_scope_name}" do # it "calls default_location= on current server" do
61
+ dsl(scopes[parent_scope_name], factory.create(parent_scope_name, :foo)) do |c| # dsl([:config, :project, :environment, :server], factory.create(:server, :foo)) do |c|
62
62
  factory.send(parent_scope_name).should_receive(parent_scope_method).with(example_value) # factory.server.should_receive(:default_location=).with('/var/app/')
63
63
  c.send(attribute_name, example_value) # c.location "/var/app"
64
64
  end # end
@@ -69,143 +69,160 @@ describe "DSL" do
69
69
  it_behaves_like "a scoped method", :default_destination, :config, :default_destination=, "foo:bar:baz"
70
70
  end
71
71
 
72
- describe "Shared server config" do
73
- specify "#shared_server_config should store a block" do
72
+ describe "#shared_server_config" do
73
+ it_behaves_like "a scoped construct", :shared_server_config, :config
74
+
75
+ it "stores a block" do
74
76
  dsl(scopes[:config], factory.create(:config)) do |c|
75
77
  cfg = proc { any_method_call_here }
76
78
  c.shared_server_config(:foo, &cfg)
77
- c.shared_server_configs[:foo].should == cfg
79
+ expect(c.shared_server_configs[:foo]).to eq(cfg)
78
80
  end
79
81
  end
82
+ end
80
83
 
81
- describe "#include_shared_server_config" do
82
- it "should execute the block on dsl object in server scope" do
83
- dsl(scopes[:server], factory.create(:server)) do |c|
84
- c.stub(:shared_server_configs => { :foo => proc { any_method_call_here } })
85
- c.should_receive(:any_method_call_here)
86
- c.include_shared_server_config(:foo)
87
- end
84
+ describe "#include_shared_server_config" do
85
+ it "executes the block on dsl object in server scope for given shared config names" do
86
+ dsl(scopes[:server], factory.create(:server)) do |c|
87
+ c.stub(:shared_server_configs => { :foo => proc { any_method_call_here }, :bar => proc { second_method_call_here } })
88
+ c.should_receive(:any_method_call_here)
89
+ c.should_receive(:second_method_call_here)
90
+ c.include_shared_server_config(:foo, :bar)
88
91
  end
92
+ end
89
93
 
90
- it "should accept arguments" do
91
- dsl(scopes[:server], factory.create(:server)) do |c|
92
- c.stub(:shared_server_configs => { :foo => proc { |qux| any_method_call_here(qux) } })
93
- c.should_receive(:any_method_call_here).with(321)
94
- c.include_shared_server_config(:foo, 321)
94
+ context "when the only argument is hash where shared config names are keys" do
95
+ context "when hash values are arrays" do
96
+ it "includes config corresponding to hash key and passes exploded arguments" do
97
+ dsl(scopes[:server], factory.create(:server)) do |c|
98
+ c.stub(:shared_server_configs => { :foo => proc { |a, b| any_method_call_here(a, b) } })
99
+ c.should_receive(:any_method_call_here).with(321, 322)
100
+ c.include_shared_server_config(:foo => [321, 322])
101
+ end
95
102
  end
96
103
  end
97
104
 
98
- it "should raise ConfigError if non-existent config included" do
99
- dsl(scopes[:server], factory.create(:server)) do |c|
100
- expect { c.include_shared_server_config(:foo) }.to raise_error(Taketo::DSL::ConfigError, "Shared server config 'foo' is not defined!")
105
+ context "when hash values are single values" do
106
+ it "includes config corresponding to hash key and passes the argument" do
107
+ dsl(scopes[:server], factory.create(:server)) do |c|
108
+ c.stub(:shared_server_configs => { :foo => proc { |qux| any_method_call_here(qux) } })
109
+ c.should_receive(:any_method_call_here).with(321)
110
+ c.include_shared_server_config(:foo => 321)
111
+ end
101
112
  end
102
113
  end
103
114
  end
115
+
116
+ it "raises ConfigError if non-existent config included" do
117
+ dsl(scopes[:server], factory.create(:server)) do |c|
118
+ expect { c.include_shared_server_config(:foo) }.to raise_error(Taketo::DSL::ConfigError, "Shared server config 'foo' is not defined!")
119
+ end
120
+ end
104
121
  end
105
122
 
106
123
  describe "#project" do
107
124
  it_behaves_like "a scope", :project, :config
125
+ end
108
126
 
109
- describe "#environment" do
110
- it_behaves_like "a scope", :environment, :project
127
+ describe "#environment" do
128
+ it_behaves_like "a scope", :environment, :project
129
+ end
111
130
 
112
- describe "#server" do
113
- it_behaves_like "a scope", :server, :environment
131
+ describe "#server" do
132
+ it_behaves_like "a scope", :server, :environment
114
133
 
115
- it "should have name optional" do
116
- dsl(scopes[:environment], factory.create(:environment, :foo)) do |c|
117
- stub_find_or_create_scope_object(c, :server, :default)
118
- c.server do
119
- c.current_scope_object.name.should == :default
120
- end
121
- end
134
+ it "has name optional" do
135
+ dsl(scopes[:environment], factory.create(:environment, :foo)) do |c|
136
+ stub_find_or_create_scope_object(c, :server, :default)
137
+ c.server do
138
+ expect(c.current_scope_object.name).to eq(:default)
122
139
  end
140
+ end
141
+ end
123
142
 
124
- describe "#host" do
125
- it_behaves_like "a scoped method", :host, :server, :host=, "127.0.0.2"
126
- end
143
+ describe "#host" do
144
+ it_behaves_like "a scoped method", :host, :server, :host=, "127.0.0.2"
145
+ end
127
146
 
128
- describe "#port" do
129
- it_behaves_like "a scoped method", :port, :server, :port=, 4096
130
- end
147
+ describe "#port" do
148
+ it_behaves_like "a scoped method", :port, :server, :port=, 4096
149
+ end
131
150
 
132
- describe "#user" do
133
- it_behaves_like "a scoped method", :user, :server, :username=, "deployer"
134
- end
151
+ describe "#user" do
152
+ it_behaves_like "a scoped method", :user, :server, :username=, "deployer"
153
+ end
135
154
 
136
- describe "#location" do
137
- it_behaves_like "a scoped method", :location, :server, :default_location=, "/var/app/"
138
- end
155
+ describe "#location" do
156
+ it_behaves_like "a scoped method", :location, :server, :default_location=, "/var/app/"
157
+ end
139
158
 
140
- describe "#env" do
141
- it_behaves_like "a scoped method", :env, :server, :env, { :FOO => "bar" }
142
- end
159
+ describe "#env" do
160
+ it_behaves_like "a scoped method", :env, :server, :env, { :FOO => "bar" }
161
+ end
143
162
 
144
- describe "#global_alias" do
145
- it_behaves_like "a scoped method", :global_alias, :server, :global_alias=, "foobared"
146
- end
163
+ describe "#global_alias" do
164
+ it_behaves_like "a scoped method", :global_alias, :server, :global_alias=, "foobared"
165
+ end
147
166
 
148
- describe "#identity_file" do
149
- it_behaves_like "a scoped method", :identity_file, :server, :identity_file=, "/home/gor/.ssh/qqq"
150
- end
167
+ describe "#identity_file" do
168
+ it_behaves_like "a scoped method", :identity_file, :server, :identity_file=, "/home/gor/.ssh/qqq"
169
+ end
151
170
 
152
- describe "#command" do
153
- it_behaves_like "a scope", :command, :server
171
+ describe "#command" do
172
+ it_behaves_like "a scope", :command, :server
154
173
 
155
- describe "#execute" do
156
- it_behaves_like "a scoped method", :execute, :command, :command=, "rails c"
157
- end
174
+ describe "#execute" do
175
+ it_behaves_like "a scoped method", :execute, :command, :command=, "rails c"
176
+ end
158
177
 
159
- describe "#desc" do
160
- it_behaves_like "a scoped method", :desc, :command, :description=, "Run rails console"
161
- end
162
- end
178
+ describe "#desc" do
179
+ it_behaves_like "a scoped method", :desc, :command, :description=, "Run rails console"
163
180
  end
164
181
  end
165
182
  end
166
183
 
167
184
  describe "#current_scope_object" do
168
- it "should be config initially" do
185
+ it "is config initially" do
169
186
  dsl do |c|
170
- c.current_scope_object.should == factory.config
187
+ expect(c.current_scope_object).to eq(factory.config)
171
188
  end
172
189
  end
173
190
 
174
- it "should correspond to current scope" do
191
+ it "corresponds to current scope" do
175
192
  dsl(:project, factory.create_project(:foo)) do |c|
176
- c.current_scope_object.should == factory.project
193
+ expect(c.current_scope_object).to eq(factory.project)
177
194
  end
178
195
 
179
196
  dsl(:server, factory.create_server(:foo)) do |c|
180
- c.current_scope_object.should == factory.server
197
+ expect(c.current_scope_object).to eq(factory.server)
181
198
  end
182
199
  end
183
200
  end
184
201
 
185
202
  describe "#configure" do
186
- it "should read config from file if filename passed" do
203
+ it "reads config from file if filename passed" do
187
204
  File.stub(:read => "the config")
188
205
  dsl = Taketo::DSL.new(factory)
189
206
  dsl.should_receive(:instance_eval) do |config, *args|
190
- config.should == "the config"
207
+ expect(config).to eq("the config")
191
208
  end
192
209
  dsl.configure("path/to/config")
193
210
  end
194
211
 
195
- it "should be configured from block unless filename specified" do
212
+ it "is configured from block unless filename specified" do
196
213
  dsl = Taketo::DSL.new(factory)
197
214
  config = proc { }
198
215
  dsl.should_receive(:instance_eval).with(&config)
199
216
  dsl.configure &config
200
217
  end
201
218
 
202
- it "should raise an error if neither config filename nor block passed" do
219
+ it "raises an error if neither config filename nor block passed" do
203
220
  expect do
204
221
  Taketo::DSL.new(factory).configure
205
222
  end.to raise_error ArgumentError, /(config|block)/
206
223
  end
207
224
 
208
- it "should raise meaningful error if config parse failed"
225
+ it "raises meaningful error if config parse failed"
209
226
  end
210
227
 
211
228
  def stub_find_or_create_scope_object(scope_object, scope, name)
@@ -1,37 +1,65 @@
1
- require File.expand_path('../../../../spec_helper', __FILE__)
1
+ require 'spec_helper'
2
2
  require 'taketo/support/named_nodes_collection'
3
3
 
4
+ include Taketo::Support
5
+
4
6
  describe "NamedNodesCollection" do
5
- let(:collection) { Taketo::Support::NamedNodesCollection.new }
7
+ subject(:collection) { NamedNodesCollection.new }
6
8
  let(:node1) { stub(:name => :foo) }
7
9
  let(:node2) { stub(:name => :bar) }
8
10
 
9
- it "should be able to initialize with array" do
10
- Taketo::Support::NamedNodesCollection.new([1, 2, 3]).length.should == 3
11
+ it "can be initialized with array" do
12
+ expect(NamedNodesCollection.new([1, 2, 3]).length).to eq(3)
11
13
  end
12
14
 
13
- it "should mimic Array" do
14
- collection.should be_empty
15
- collection << node1
16
- collection.push node2
17
- collection[0].should == node1
18
- collection.map(&:name).should == [:foo, :bar]
19
- collection.length.should == 2
20
- collection.size.should == 2
21
- collection.first.should == node1
22
- collection.last.should == node2
15
+ [:empty?, :each, :length, :size, :first, :last].each do |delegated_method|
16
+ it { should respond_to(delegated_method) }
17
+ end
18
+
19
+ it "is Enumerable" do
20
+ expect(collection).to be_kind_of(Enumerable)
23
21
  end
24
22
 
25
- it "should raise error if element not found" do
26
- expect { collection[3] }.to raise_error KeyError, /#3/i
27
- expect { collection[:quux] }.to raise_error KeyError, /name/i
23
+ describe "#[]" do
24
+ subject(:collection) { NamedNodesCollection.new([node1]) }
25
+
26
+ it "retrieves node by index" do
27
+ expect(collection[0]).to eq(node1)
28
+ end
29
+
30
+ it "retrieves node by name" do
31
+ expect(collection[:foo]).to eq(node1)
32
+ end
33
+
34
+ it "raises error if node not found" do
35
+ expect { collection[3] }.to raise_error KeyError, /#3/i
36
+ expect { collection[:quux] }.to raise_error KeyError, /name/i
37
+ end
38
+ end
39
+
40
+ describe "#push, #<<" do
41
+ it "adds node to the collection" do
42
+ collection.push(node1)
43
+ expect(collection.length).to eq(1)
44
+ collection << node2
45
+ expect(collection.length).to eq(2)
46
+ end
47
+
48
+ it "does nothing if node with same name exists" do
49
+ collection.push(node1)
50
+ collection.push(node1)
51
+ expect(collection.length).to eq(1)
52
+ end
53
+
54
+ it "supports chaining" do
55
+ collection << node1 << node2
56
+ expect(collection.length).to eq(2)
57
+ end
28
58
  end
29
59
 
30
- it "should not add if node with same name exists" do
60
+ it "compares itself to array" do
31
61
  collection << node1
32
- collection.push node1
33
- collection.length.should == 1
34
- collection.first.should == node1
62
+ expect(collection).to eq([node1])
35
63
  end
36
64
  end
37
65
 
@@ -1,15 +1,15 @@
1
1
  shared_examples "a construct with nodes" do |name_plural, name_singular|
2
- specify "#append_#{name_singular} should add a #{name_singular} to " + # specify "#append_server should add a server to " +
3
- "#{subject.class.name}'s #{name_plural} collection" do # "environment's servers collection" do
2
+ specify "#append_#{name_singular} adds a #{name_singular} to " + # specify "#append_server adds a server to " +
3
+ "the #{name_plural} collection" do # "the servers collection" do
4
4
  node = mock(:name => :foo).as_null_object # server = mock(:name => :foo).as_null_object
5
5
  subject.send("append_#{name_singular}", node) # environment.append_server(server)
6
- subject.send(name_plural).should include(node) # environment.servers.should include(server)
6
+ expect(subject.send(name_plural)).to include(node) # expect(environment.servers).to include(server)
7
7
  end # end
8
8
 
9
- specify "#find_#{name_singular} should find #{name_singular} by name" do # specify "#find_server should find server by name" do
9
+ specify "#find_#{name_singular} finds #{name_singular} by name" do # specify "#find_server finds server by name" do
10
10
  subject.send(name_plural).should_receive(:find_by_name). # environment.servers.should_receive(:find_by_name).
11
11
  with(:foo).and_return(:bar) # with(:foo).and_return(:bar)
12
- subject.send("find_#{name_singular}", :foo).should == :bar # environment.find_server(:foo).should == :bar
12
+ expect(subject.send("find_#{name_singular}", :foo)).to eq(:bar) # expect(environment.find_server(:foo)).to eq(:bar)
13
13
  end # end
14
14
  end
15
15
 
@@ -5,6 +5,10 @@ RSpec::Matchers.define :be_appropriate_construct do |construct, *args|
5
5
  @enclosing_scope = enclosing_scope
6
6
  end
7
7
 
8
+ chain(:with_block) do |with_block|
9
+ @blk = Proc.new {} if with_block
10
+ end
11
+
8
12
  match do |actual|
9
13
  unless @enclosing_scope
10
14
  raise ArgumentError, "#under must be called to set enclosing scope"
@@ -13,7 +17,11 @@ RSpec::Matchers.define :be_appropriate_construct do |construct, *args|
13
17
  @result = true
14
18
  dsl(@enclosing_scope) do |c|
15
19
  begin
16
- c.send(construct, *args) {}
20
+ if @blk
21
+ c.send(construct, *args, &@blk)
22
+ else
23
+ c.send(construct, *args)
24
+ end
17
25
  rescue Taketo::DSL::ScopeError => e
18
26
  @result = false
19
27
  rescue
@@ -1,7 +1,10 @@
1
- RSpec::Matchers.define :have_accessor do |accessor|
1
+ RSpec::Matchers.define :have_accessor do |*args|
2
+ accessor = args.shift or raise ArgumentError, "No accessor name supplied"
3
+ value = args.shift || :foo
4
+
2
5
  match do |construct|
3
- construct.send("#{accessor}=", :foo)
4
- construct.send(accessor) == :foo
6
+ construct.send("#{accessor}=", value)
7
+ construct.send(accessor) == value
5
8
  end
6
9
  end
7
10