taketo 0.1.3 → 0.2.0.alpha
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/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)
|