taketo 0.1.3 → 0.2.0.alpha
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +1 -0
- data/Gemfile.lock +8 -0
- data/README.md +16 -1
- data/Rakefile +1 -0
- data/VERSION +1 -1
- data/bin/taketo +17 -89
- data/lib/taketo/actions/base_action.rb +29 -0
- data/lib/taketo/actions/generate_ssh_config.rb +22 -0
- data/lib/taketo/actions/group_action.rb +15 -0
- data/lib/taketo/actions/list.rb +22 -0
- data/lib/taketo/actions/login.rb +40 -0
- data/lib/taketo/actions/matches.rb +28 -0
- data/lib/taketo/actions/node_action.rb +15 -0
- data/lib/taketo/actions/server_action.rb +14 -0
- data/lib/taketo/actions/view.rb +24 -0
- data/lib/taketo/actions.rb +21 -0
- data/lib/taketo/associated_nodes.rb +4 -0
- data/lib/taketo/commands.rb +2 -1
- data/lib/taketo/config_validator.rb +4 -0
- data/lib/taketo/config_visitor.rb +3 -1
- data/lib/taketo/constructs/config.rb +2 -1
- data/lib/taketo/constructs/environment.rb +9 -0
- data/lib/taketo/constructs/group.rb +20 -0
- data/lib/taketo/constructs/project.rb +2 -1
- data/lib/taketo/constructs/server.rb +1 -1
- data/lib/taketo/constructs.rb +1 -0
- data/lib/taketo/constructs_factory.rb +4 -0
- data/lib/taketo/destination_matcher.rb +4 -4
- data/lib/taketo/dsl.rb +18 -17
- data/lib/taketo/group_list_visitor.rb +11 -0
- data/lib/taketo/group_resolver.rb +12 -0
- data/lib/taketo/{destination_resolver.rb → node_resolver.rb} +5 -27
- data/lib/taketo/server_resolver.rb +29 -0
- data/spec/acceptance/command_spec.rb +2 -1
- data/spec/acceptance/completion_spec.rb +26 -9
- data/spec/acceptance/config_dsl_spec.rb +74 -13
- data/spec/acceptance/config_validation_spec.rb +20 -5
- data/spec/acceptance/connect_to_server_spec.rb +6 -3
- data/spec/acceptance/error_handling_spec.rb +2 -2
- data/spec/acceptance/generate_ssh_config_spec.rb +1 -1
- data/spec/acceptance/help_spec.rb +4 -2
- data/spec/acceptance/location_spec.rb +2 -1
- data/spec/acceptance_spec_helper.rb +1 -1
- data/spec/lib/taketo/actions_spec.rb +17 -0
- data/spec/lib/taketo/associated_nodes_spec.rb +34 -0
- data/spec/lib/taketo/config_validator_spec.rb +1 -1
- data/spec/lib/taketo/constructs/config_spec.rb +4 -1
- data/spec/lib/taketo/constructs/environment_spec.rb +6 -1
- data/spec/lib/taketo/constructs/group_spec.rb +30 -0
- data/spec/lib/taketo/constructs/project_spec.rb +2 -0
- data/spec/lib/taketo/constructs/server_spec.rb +6 -2
- data/spec/lib/taketo/constructs_factory_spec.rb +5 -0
- data/spec/lib/taketo/dsl_spec.rb +86 -74
- data/spec/lib/taketo/group_list_visitor_spec.rb +20 -0
- data/spec/lib/taketo/group_resolver_spec.rb +59 -0
- data/spec/lib/taketo/{destination_resolver_spec.rb → server_resolver_spec.rb} +3 -29
- data/spec/support/helpers/construct_spec_helper.rb +9 -0
- data/spec/support/helpers/dsl_spec_helper.rb +31 -9
- data/spec/support/matchers/enclose_scope_matcher.rb +15 -7
- metadata +41 -20
@@ -97,5 +97,39 @@ describe "AssociatedNodes" do
|
|
97
97
|
expect { construct.has_nodes?(:quack) }.to raise_error NodesNotDefinedError
|
98
98
|
end
|
99
99
|
end
|
100
|
+
|
101
|
+
describe "#has_deeply_nested_nodes?" do
|
102
|
+
class TestNestedNodes
|
103
|
+
include AssociatedNodes
|
104
|
+
|
105
|
+
def name; :foo; end
|
106
|
+
|
107
|
+
has_nodes :foos, :foo
|
108
|
+
has_nodes :bars, :bar
|
109
|
+
end
|
110
|
+
|
111
|
+
subject(:construct) { TestNestedNodes.new }
|
112
|
+
let(:foo) { TestNestedNodes.new }
|
113
|
+
|
114
|
+
context "directly nested nodes" do
|
115
|
+
it "returns true when present" do
|
116
|
+
construct.nodes(:foos) << foo
|
117
|
+
expect(construct).to have_deeply_nested_nodes(:foos)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
context "indirectly nested nodes" do
|
122
|
+
before(:each) { construct.nodes(:foos) << foo }
|
123
|
+
|
124
|
+
it "returns true when present" do
|
125
|
+
foo.nodes(:bars) << stub(:Bar, :name => :bar)
|
126
|
+
expect(construct).to have_deeply_nested_nodes(:bars)
|
127
|
+
end
|
128
|
+
|
129
|
+
it "returns false when not present" do
|
130
|
+
expect(construct).not_to have_deeply_nested_nodes(:bars)
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
100
134
|
end
|
101
135
|
|
@@ -18,7 +18,7 @@ end
|
|
18
18
|
describe "ConfigValidator::ConfigValidatorVisitor" do
|
19
19
|
subject(:visitor) { ConfigValidator::ConfigValidatorVisitor.new }
|
20
20
|
|
21
|
-
{ :Config => nil, :Project => "my_project" }.each do |node_type, path|
|
21
|
+
{ :Config => nil, :Project => "my_project", :Group => "my_group" }.each do |node_type, path|
|
22
22
|
it "requires #{node_type} to have servers" do
|
23
23
|
node = stub(node_type, :has_servers? => false, :path => path)
|
24
24
|
error_message = /#{path ? path + ": " : ""}no servers/
|
@@ -5,10 +5,13 @@ require 'taketo/constructs/config'
|
|
5
5
|
include Taketo
|
6
6
|
|
7
7
|
describe "Config" do
|
8
|
-
subject { Taketo::Constructs::Config.new }
|
8
|
+
subject(:config) { Taketo::Constructs::Config.new }
|
9
9
|
|
10
|
+
it_behaves_like "a construct with nodes", :groups, :group
|
10
11
|
it_behaves_like "a construct with nodes", :projects, :project
|
11
12
|
|
12
13
|
it { should have_accessor(:default_destination) }
|
14
|
+
|
15
|
+
it_behaves_like "a node with servers", :servers, :server
|
13
16
|
end
|
14
17
|
|
@@ -11,12 +11,17 @@ describe "Environment" do
|
|
11
11
|
expect(environment.name).to eq(:foo)
|
12
12
|
end
|
13
13
|
|
14
|
-
it_behaves_like "a construct with nodes", :
|
14
|
+
it_behaves_like "a construct with nodes", :groups, :group
|
15
|
+
it_behaves_like "a node with servers"
|
15
16
|
|
16
17
|
specify "#project_name returns project name" do
|
17
18
|
environment.parent = Taketo::Constructs::Project.new("TheProject")
|
18
19
|
expect(environment.project_name).to eq("TheProject")
|
19
20
|
end
|
21
|
+
|
22
|
+
specify "#rails_env returns name as string" do
|
23
|
+
environment.rails_env.should == "foo"
|
24
|
+
end
|
20
25
|
end
|
21
26
|
|
22
27
|
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'support/helpers/construct_spec_helper'
|
3
|
+
require 'taketo/constructs/group'
|
4
|
+
|
5
|
+
include Taketo
|
6
|
+
|
7
|
+
describe "Group" do
|
8
|
+
subject(:group) { Taketo::Constructs::Group.new(:foo) }
|
9
|
+
|
10
|
+
it "has name" do
|
11
|
+
expect(group.name).to eq(:foo)
|
12
|
+
end
|
13
|
+
|
14
|
+
describe "#rails_env" do
|
15
|
+
it "returns parent's #rails_env" do
|
16
|
+
group.parent = stub(:Environment, :rails_env => "bar")
|
17
|
+
expect(group.rails_env).to eq("bar")
|
18
|
+
end
|
19
|
+
|
20
|
+
it "does not fail if parent does not provide #rails_env" do
|
21
|
+
group.parent = 1
|
22
|
+
expect(group.rails_env).to eq(nil)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
it_behaves_like "a node with servers"
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
|
@@ -48,12 +48,16 @@ describe "Server" do
|
|
48
48
|
end
|
49
49
|
|
50
50
|
describe "#parent=" do
|
51
|
-
let(:environment) {
|
51
|
+
let(:environment) { stub(:Environment, :rails_env => 'the_env') }
|
52
52
|
|
53
53
|
it "sets RAILS_ENV environment variable" do
|
54
54
|
server.environment_variables.should == {}
|
55
55
|
server.parent = environment
|
56
|
-
expect(server.environment_variables[:RAILS_ENV]).to eq(environment.
|
56
|
+
expect(server.environment_variables[:RAILS_ENV]).to eq(environment.rails_env)
|
57
|
+
end
|
58
|
+
|
59
|
+
it "does not fail if parent doesn't provide #rails_env" do
|
60
|
+
expect { server.parent = 1 }.not_to raise_error
|
57
61
|
end
|
58
62
|
end
|
59
63
|
|
@@ -33,6 +33,11 @@ describe "ConstructsFactory" do
|
|
33
33
|
expect(server).to be_an_instance_of(Taketo::Constructs::Server)
|
34
34
|
end
|
35
35
|
|
36
|
+
specify "#create_group creates a group object" do
|
37
|
+
group = factory.create_group(:foo)
|
38
|
+
expect(group).to be_an_instance_of(Taketo::Constructs::Group)
|
39
|
+
end
|
40
|
+
|
36
41
|
specify "#create_command creates a command object" do
|
37
42
|
command = factory.create_command(:foo)
|
38
43
|
expect(command).to be_an_instance_of(Taketo::Constructs::Command)
|
data/spec/lib/taketo/dsl_spec.rb
CHANGED
@@ -8,63 +8,67 @@ describe "DSL" do
|
|
8
8
|
extend DSLSpec
|
9
9
|
include DSLSpec
|
10
10
|
|
11
|
-
|
11
|
+
shared_examples_for "a scoped construct" do |name, parents, with_block|
|
12
12
|
parents = Array(parents)
|
13
13
|
|
14
14
|
parents.each do |parent_scope_name|
|
15
|
-
|
16
|
-
|
15
|
+
scopes[parent_scope_name].each do |parent_scope_variant|
|
16
|
+
it { should be_appropriate_construct(name, :foo).with_block(with_block).under(parent_scope_variant) }
|
17
|
+
end
|
17
18
|
end
|
18
19
|
|
19
|
-
scopes.except(*parents).each do |
|
20
|
-
|
20
|
+
scopes.except(*parents).each do |inappropriate_scopes|
|
21
|
+
inappropriate_scopes.each do |inappropriate_scope_variant|
|
22
|
+
it { should_not be_appropriate_construct(name, :foo).with_block(with_block).under(inappropriate_scope_variant) }
|
23
|
+
end
|
21
24
|
end
|
22
25
|
end
|
23
26
|
|
24
|
-
|
27
|
+
shared_examples_for "a scope" do |scope_name, parent_scope_names|
|
25
28
|
it_behaves_like "a scoped construct", scope_name, Array(parent_scope_names), true
|
26
29
|
|
27
30
|
Array(parent_scope_names).each do |parent_scope_name|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
31
|
+
parent_scope_variants = scopes[parent_scope_name]
|
32
|
+
|
33
|
+
context "under #{parent_scope_name} #{parent_scope_variants.inspect}" do
|
34
|
+
it { should enclose_scope(scope_name).under(parent_scope_variants) }
|
35
|
+
|
36
|
+
it "creates a #{scope_name} under #{parent_scope_name} and set it as current scope object" do
|
37
|
+
within_parent_dsl(parent_scope_name) do |c|
|
38
|
+
stub_find_or_create_scope_object(c, scope_name, :bar)
|
39
|
+
c.send(scope_name, :bar) do
|
40
|
+
expect(c.current_scope_object).to eq(factory.send(scope_name))
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
it "does not leak #{scope_name} as current scope object" do
|
46
|
+
within_parent_dsl(parent_scope_name) do |c|
|
47
|
+
stub_find_or_create_scope_object(c, scope_name, :bar)
|
48
|
+
c.send(scope_name, :bar) do
|
49
|
+
expect(c.current_scope_object).to eq(factory.send(scope_name))
|
50
|
+
end
|
51
|
+
expect(c.current_scope_object).not_to eq(factory.send(scope_name))
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
it "adds a #{scope_name} to the #{parent_scope_name}'s #{scope_name}s collection" do
|
56
|
+
within_parent_dsl(parent_scope_name) do |c|
|
57
|
+
stub_find_or_create_scope_object(c, scope_name, :bar)
|
58
|
+
c.current_scope_object.should_receive("append_#{scope_name}").
|
59
|
+
with(factory.send(scope_name))
|
60
|
+
c.send(scope_name, :bar) {}
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
it "sets #{scope_name}'s parent to the #{parent_scope_name} scope object" do
|
65
|
+
within_parent_dsl(parent_scope_name) do |c|
|
66
|
+
stub_find_or_create_scope_object(c, scope_name, :bar)
|
67
|
+
factory.send(scope_name).should_receive(:parent=).with(c.current_scope_object)
|
68
|
+
c.send(scope_name, :bar) {}
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
68
72
|
end
|
69
73
|
end
|
70
74
|
|
@@ -72,11 +76,11 @@ describe "DSL" do
|
|
72
76
|
it_behaves_like "a scoped construct", attribute_name, parent_scope_names, false
|
73
77
|
|
74
78
|
Array(parent_scope_names).each do |parent_scope_name|
|
75
|
-
it "calls #{parent_scope_method} on current #{parent_scope_name}" do
|
76
|
-
|
77
|
-
factory.send(parent_scope_name).should_receive(parent_scope_method).with(example_value)
|
78
|
-
c.send(attribute_name, example_value)
|
79
|
-
end
|
79
|
+
it "calls #{parent_scope_method} on current #{parent_scope_name}" do
|
80
|
+
within_parent_dsl(parent_scope_name) do |c|
|
81
|
+
factory.send(parent_scope_name).should_receive(parent_scope_method).with(example_value)
|
82
|
+
c.send(attribute_name, example_value)
|
83
|
+
end
|
80
84
|
end
|
81
85
|
end
|
82
86
|
end
|
@@ -86,10 +90,10 @@ describe "DSL" do
|
|
86
90
|
end
|
87
91
|
|
88
92
|
describe "#default_server_config" do
|
89
|
-
it_behaves_like "a scoped construct", :default_server_config, [:config, :project, :environment]
|
93
|
+
it_behaves_like "a scoped construct", :default_server_config, [:config, :project, :environment, :group]
|
90
94
|
|
91
95
|
it "stores a block" do
|
92
|
-
|
96
|
+
within_parent_dsl(:config) do |c|
|
93
97
|
cfg = proc { any_method_call_here }
|
94
98
|
factory.config.should_receive(:default_server_config=).with(cfg)
|
95
99
|
c.default_server_config(&cfg)
|
@@ -101,7 +105,7 @@ describe "DSL" do
|
|
101
105
|
it_behaves_like "a scoped construct", :shared_server_config, :config
|
102
106
|
|
103
107
|
it "stores a block" do
|
104
|
-
|
108
|
+
within_parent_dsl(:config) do |c|
|
105
109
|
cfg = proc { any_method_call_here }
|
106
110
|
c.shared_server_config(:foo, &cfg)
|
107
111
|
expect(c.shared_server_configs[:foo]).to eq(cfg)
|
@@ -111,10 +115,10 @@ describe "DSL" do
|
|
111
115
|
|
112
116
|
describe "#include_shared_server_config" do
|
113
117
|
it "executes the block on dsl object in server scope for given shared config names" do
|
114
|
-
|
118
|
+
within_parent_dsl(:server) do |c|
|
115
119
|
c.stub(:shared_server_configs => { :foo => proc { call_from_foo }, :bar => proc { call_from_bar } })
|
116
|
-
c.should_receive(:call_from_foo)
|
117
|
-
c.should_receive(:call_from_bar)
|
120
|
+
c.should_receive(:call_from_foo).once
|
121
|
+
c.should_receive(:call_from_bar).once
|
118
122
|
c.include_shared_server_config(:foo, :bar)
|
119
123
|
end
|
120
124
|
end
|
@@ -122,7 +126,7 @@ describe "DSL" do
|
|
122
126
|
context "when the argument is hash where shared config names are keys" do
|
123
127
|
context "when hash values are arrays" do
|
124
128
|
it "includes config corresponding to hash key and passes exploded arguments" do
|
125
|
-
|
129
|
+
within_parent_dsl(:server) do |c|
|
126
130
|
c.stub(:shared_server_configs => { :foo => proc { |a, b| any_method_call_here(a, b) } })
|
127
131
|
c.should_receive(:any_method_call_here).with(321, 322)
|
128
132
|
c.include_shared_server_config(:foo => [321, 322])
|
@@ -132,7 +136,7 @@ describe "DSL" do
|
|
132
136
|
|
133
137
|
context "when hash values are single values" do
|
134
138
|
it "includes config corresponding to hash key and passes the argument" do
|
135
|
-
|
139
|
+
within_parent_dsl(:server) do |c|
|
136
140
|
c.stub(:shared_server_configs => { :foo => proc { |qux| any_method_call_here(qux) } })
|
137
141
|
c.should_receive(:any_method_call_here).with(321)
|
138
142
|
c.include_shared_server_config(:foo => 321)
|
@@ -143,7 +147,7 @@ describe "DSL" do
|
|
143
147
|
|
144
148
|
context "whne there are symbol arguments (names of shared configs) and a hash" do
|
145
149
|
it "includes config corresponding to symbol arguments and hash keys" do
|
146
|
-
|
150
|
+
within_parent_dsl(:server) do |c|
|
147
151
|
c.stub(:shared_server_configs => { :foo => proc { call_from_foo }, :bar => proc { |qux| call_from_bar(qux) } })
|
148
152
|
c.should_receive(:call_from_foo)
|
149
153
|
c.should_receive(:call_from_bar).with(123)
|
@@ -153,7 +157,7 @@ describe "DSL" do
|
|
153
157
|
end
|
154
158
|
|
155
159
|
it "raises ConfigError if non-existent config included" do
|
156
|
-
|
160
|
+
within_parent_dsl(:server) do |c|
|
157
161
|
expect { c.include_shared_server_config(:foo) }.to raise_error(Taketo::DSL::ConfigError, "Shared server config 'foo' is not defined!")
|
158
162
|
end
|
159
163
|
end
|
@@ -167,25 +171,25 @@ describe "DSL" do
|
|
167
171
|
it_behaves_like "a scope", :environment, :project
|
168
172
|
end
|
169
173
|
|
174
|
+
describe "#group" do
|
175
|
+
it_behaves_like "a scope", :group, [:project, :environment, :config]
|
176
|
+
end
|
177
|
+
|
170
178
|
describe "#server" do
|
171
|
-
it_behaves_like "a scope", :server, [:environment, :config, :project]
|
179
|
+
it_behaves_like "a scope", :server, [:environment, :config, :project, :group]
|
172
180
|
|
173
181
|
it "evaluates default_server_config" do
|
174
|
-
|
182
|
+
within_parent_dsl(:environment) do |c|
|
175
183
|
stub_find_or_create_scope_object(c, :server, :bar)
|
176
|
-
|
177
184
|
default_server_config = proc { some_setup }
|
178
185
|
factory.server.stub(:default_server_config => default_server_config)
|
179
|
-
|
180
186
|
c.should_receive(:some_setup)
|
181
|
-
|
182
|
-
c.server(:bar) do
|
183
|
-
end
|
187
|
+
c.server(:bar) {}
|
184
188
|
end
|
185
189
|
end
|
186
190
|
|
187
191
|
it "has name optional" do
|
188
|
-
|
192
|
+
within_parent_dsl(:environment) do |c|
|
189
193
|
stub_find_or_create_scope_object(c, :server, :default)
|
190
194
|
c.server do
|
191
195
|
expect(c.current_scope_object.name).to eq(:default)
|
@@ -246,11 +250,11 @@ describe "DSL" do
|
|
246
250
|
end
|
247
251
|
|
248
252
|
it "corresponds to current scope" do
|
249
|
-
|
253
|
+
within_parent_dsl(:project) do |c|
|
250
254
|
expect(c.current_scope_object).to eq(factory.project)
|
251
255
|
end
|
252
256
|
|
253
|
-
|
257
|
+
within_parent_dsl(:server) do |c|
|
254
258
|
expect(c.current_scope_object).to eq(factory.server)
|
255
259
|
end
|
256
260
|
end
|
@@ -282,9 +286,17 @@ describe "DSL" do
|
|
282
286
|
it "raises meaningful error if config parse failed"
|
283
287
|
end
|
284
288
|
|
285
|
-
def stub_find_or_create_scope_object(
|
286
|
-
|
287
|
-
factory.should_receive(:create).with(scope, name)
|
289
|
+
def stub_find_or_create_scope_object(dsl_object, scope, name)
|
290
|
+
dsl_object.current_scope_object.stub(:find).with(scope, name).and_yield.and_return(factory.create(scope, name))
|
288
291
|
end
|
292
|
+
|
293
|
+
def within_parent_dsl(parent_scope, &block)
|
294
|
+
scopes[parent_scope].each do |parent_scope_variant|
|
295
|
+
dsl(parent_scope_variant, factory.create(parent_scope)) do |c|
|
296
|
+
block.call(c)
|
297
|
+
end
|
298
|
+
end
|
299
|
+
end
|
300
|
+
|
289
301
|
end
|
290
302
|
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'taketo/group_list_visitor'
|
3
|
+
|
4
|
+
include Taketo
|
5
|
+
|
6
|
+
describe "GroupListVisitor" do
|
7
|
+
subject(:group_list) { GroupListVisitor.new }
|
8
|
+
|
9
|
+
describe "#result" do
|
10
|
+
it "outputs list of qualified server names" do
|
11
|
+
server1 = stub(:Server, :path => "foo")
|
12
|
+
server2 = stub(:Server, :path => "bar")
|
13
|
+
group_list.visit_server(server1)
|
14
|
+
group_list.visit_server(server2)
|
15
|
+
group_list.result.should == "foo\nbar"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'support/helpers/construct_spec_helper'
|
3
|
+
require 'taketo/group_resolver'
|
4
|
+
|
5
|
+
include Taketo
|
6
|
+
|
7
|
+
describe "GroupResolver" do
|
8
|
+
include ConstructsFixtures
|
9
|
+
|
10
|
+
let(:server1) { s = server(:s1); s.global_alias = :the_alias; s }
|
11
|
+
let(:environment1) { environment(:bar, :servers => server1) }
|
12
|
+
let(:project1) { project(:foo, :environments => environment1) }
|
13
|
+
|
14
|
+
let(:server2) { server(:s2) }
|
15
|
+
let(:environment2) { environment(:qux, :servers => server2) }
|
16
|
+
let(:project2) { project(:baz, :environments => environment2) }
|
17
|
+
|
18
|
+
let(:server3) { server(:s3) }
|
19
|
+
let(:server4) { server(:s4) }
|
20
|
+
let(:environment3) { environment(:corge, :servers => [server3, server4]) }
|
21
|
+
let(:project3) { project(:quux, :environments => environment3) }
|
22
|
+
|
23
|
+
let(:server5) { server(:s5) }
|
24
|
+
let(:server6) { server(:s6) }
|
25
|
+
let(:environment4) { environment(:garply, :servers => [server5, server6]) }
|
26
|
+
let(:environment5) { environment(:waldo, :servers => server(:s7)) }
|
27
|
+
let(:project4) { project(:grault, :environments => [environment4, environment5]) }
|
28
|
+
|
29
|
+
let(:config) { create_config(:projects => [project1, project2, project3, project4]) }
|
30
|
+
|
31
|
+
describe "#resolve" do
|
32
|
+
it "does not resolve to server" do
|
33
|
+
expect{ resolver(config, "foo:bar:s1").resolve }.to raise_error(Taketo::NonExistentDestinationError)
|
34
|
+
end
|
35
|
+
|
36
|
+
it "returns environment when path has 2 segments and is correct" do
|
37
|
+
expect(resolver(config, "foo:bar").resolve).to eq(environment1)
|
38
|
+
end
|
39
|
+
|
40
|
+
it "returns project when path has 1 segment and is correct" do
|
41
|
+
expect(resolver(config, "foo").resolve).to eq(project1)
|
42
|
+
end
|
43
|
+
|
44
|
+
it "returns the config if path has is empty and there's no default destination" do
|
45
|
+
expect(resolver(config, "").resolve).to eq(config)
|
46
|
+
end
|
47
|
+
|
48
|
+
it "raises NonExistentDestinationError when path is not correct" do
|
49
|
+
expect { resolver(config, "i").resolve }.to raise_error(NonExistentDestinationError)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def resolver(*args)
|
54
|
+
GroupResolver.new(*args)
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
|
@@ -1,10 +1,10 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
require 'support/helpers/construct_spec_helper'
|
3
|
-
require 'taketo/
|
3
|
+
require 'taketo/server_resolver'
|
4
4
|
|
5
5
|
include Taketo
|
6
6
|
|
7
|
-
describe "
|
7
|
+
describe "ServerResolver" do
|
8
8
|
include ConstructsFixtures
|
9
9
|
|
10
10
|
let(:server1) { s = server(:s1); s.global_alias = :the_alias; s }
|
@@ -145,34 +145,8 @@ describe "DestinationResolver" do
|
|
145
145
|
end
|
146
146
|
end
|
147
147
|
|
148
|
-
describe "#get_node" do
|
149
|
-
it "returns server when path has 3 segments and is correct" do
|
150
|
-
expect(resolver(config, "foo:bar:s1").get_node).to eq(server1)
|
151
|
-
end
|
152
|
-
|
153
|
-
it "returns environment when path has 2 segments and is correct" do
|
154
|
-
expect(resolver(config, "foo:bar").get_node).to eq(environment1)
|
155
|
-
end
|
156
|
-
|
157
|
-
it "returns project when path has 1 segment and is correct" do
|
158
|
-
expect(resolver(config, "foo").get_node).to eq(project1)
|
159
|
-
end
|
160
|
-
|
161
|
-
it "returns the config if path has is empty and there's no default destination" do
|
162
|
-
expect(resolver(config, "").get_node).to eq(config)
|
163
|
-
end
|
164
|
-
|
165
|
-
it "resolves to server by global server alias" do
|
166
|
-
expect(resolver(config, "the_alias").get_node).to eq(server1)
|
167
|
-
end
|
168
|
-
|
169
|
-
it "raises NonExistentDestinationError when path is not correct" do
|
170
|
-
expect { resolver(config, "i").get_node }.to raise_error(NonExistentDestinationError)
|
171
|
-
end
|
172
|
-
end
|
173
|
-
|
174
148
|
def resolver(*args)
|
175
|
-
|
149
|
+
ServerResolver.new(*args)
|
176
150
|
end
|
177
151
|
|
178
152
|
end
|
@@ -15,6 +15,15 @@ shared_examples "a construct with nodes" do |name_plural, name_singular|
|
|
15
15
|
end # end
|
16
16
|
end
|
17
17
|
|
18
|
+
shared_examples "a node with servers" do
|
19
|
+
it_behaves_like "a construct with nodes", :servers, :server
|
20
|
+
|
21
|
+
specify "#has_servers? should perform deep search on child nodes" do
|
22
|
+
subject.should_receive(:has_deeply_nested_nodes?).with(:servers)
|
23
|
+
subject.has_servers?
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
18
27
|
module ConstructsFixtures
|
19
28
|
include Taketo::Constructs
|
20
29
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module DSLSpec
|
2
2
|
class TestConstructsFactory
|
3
|
-
attr_reader :config, :project, :environment, :server, :command
|
3
|
+
attr_reader :config, :project, :environment, :server, :group, :command
|
4
4
|
|
5
5
|
def create(type, *args)
|
6
6
|
send("create_#{type}", *args)
|
@@ -22,6 +22,10 @@ module DSLSpec
|
|
22
22
|
@server ||= RSpec::Mocks::Mock.new(:Server, :name => name, :default_server_config => proc {}).as_null_object
|
23
23
|
end
|
24
24
|
|
25
|
+
def create_group(name = :foo)
|
26
|
+
@group ||= RSpec::Mocks::Mock.new(:Group, :name => name, :default_server_config => proc {}).as_null_object
|
27
|
+
end
|
28
|
+
|
25
29
|
def create_command(name = :the_cmd)
|
26
30
|
@command ||= RSpec::Mocks::Mock.new(:Command, :name => name, :default_server_config => proc {}).as_null_object
|
27
31
|
end
|
@@ -37,7 +41,7 @@ module DSLSpec
|
|
37
41
|
end
|
38
42
|
end
|
39
43
|
|
40
|
-
def dsl(scope = [:config], scope_object = nil)
|
44
|
+
def dsl(scope = scopes[:config], scope_object = nil, &block)
|
41
45
|
context = DSL.new(factory)
|
42
46
|
|
43
47
|
def context.set_scope(s, obj)
|
@@ -46,17 +50,35 @@ module DSLSpec
|
|
46
50
|
end
|
47
51
|
|
48
52
|
context.set_scope(scope, scope_object || factory.create_config)
|
49
|
-
|
50
|
-
yield context
|
53
|
+
block.call(context)
|
51
54
|
end
|
52
55
|
|
53
56
|
def scopes
|
54
57
|
scopes_hash = {
|
55
|
-
:config => [:config],
|
56
|
-
:project => [:config, :project],
|
57
|
-
:environment => [:config, :project, :environment],
|
58
|
-
:
|
59
|
-
|
58
|
+
:config => [[:config]],
|
59
|
+
:project => [[:config, :project]],
|
60
|
+
:environment => [[:config, :project, :environment]],
|
61
|
+
:group => [
|
62
|
+
[:config, :group],
|
63
|
+
[:config, :project, :group],
|
64
|
+
[:config, :project, :environment, :group]
|
65
|
+
],
|
66
|
+
:server => [
|
67
|
+
# [:config, :server],
|
68
|
+
# [:config, :group, :server],
|
69
|
+
# [:config, :project, :server],
|
70
|
+
# [:config, :project, :group, :server],
|
71
|
+
# [:config, :project, :environment, :server],
|
72
|
+
[:config, :project, :environment, :group, :server]
|
73
|
+
],
|
74
|
+
:command => [
|
75
|
+
[:config, :server, :command],
|
76
|
+
[:config, :group, :server, :command],
|
77
|
+
[:config, :project, :server, :command],
|
78
|
+
[:config, :project, :group, :server, :command],
|
79
|
+
[:config, :project, :environment, :server, :command],
|
80
|
+
[:config, :project, :environment, :group, :server, :command]
|
81
|
+
]
|
60
82
|
}
|
61
83
|
|
62
84
|
def scopes_hash.except(*keys)
|