taketo 0.0.6 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
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