taketo 0.0.10 → 0.1.0

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 +14 -30
  3. data/README.md +4 -0
  4. data/Rakefile +4 -8
  5. data/VERSION +1 -1
  6. data/bin/taketo +5 -5
  7. data/lib/taketo/config_printer_visitor.rb +6 -22
  8. data/lib/taketo/config_traverser.rb +4 -33
  9. data/lib/taketo/config_validator.rb +1 -1
  10. data/lib/taketo/config_visitor.rb +15 -1
  11. data/lib/taketo/constructs/base_construct.rb +30 -6
  12. data/lib/taketo/constructs/config.rb +5 -0
  13. data/lib/taketo/constructs/environment.rb +6 -3
  14. data/lib/taketo/constructs/project.rb +3 -3
  15. data/lib/taketo/constructs/server.rb +3 -4
  16. data/lib/taketo/constructs.rb +6 -1
  17. data/lib/taketo/destination_resolver.rb +37 -52
  18. data/lib/taketo/dsl.rb +6 -3
  19. data/lib/taketo/printer.rb +29 -0
  20. data/lib/taketo/ssh_config_generator_visitor.rb +8 -22
  21. data/spec/acceptance/command_spec.rb +20 -0
  22. data/spec/acceptance/config_dsl_spec.rb +277 -0
  23. data/spec/acceptance/config_validation_spec.rb +109 -0
  24. data/spec/acceptance/connect_to_server_spec.rb +60 -0
  25. data/spec/acceptance/error_handling_spec.rb +31 -0
  26. data/spec/acceptance/generate_ssh_config_spec.rb +44 -0
  27. data/spec/acceptance/help_spec.rb +74 -0
  28. data/spec/acceptance/location_spec.rb +21 -0
  29. data/spec/acceptance_spec_helper.rb +71 -0
  30. data/spec/lib/taketo/config_traverser_spec.rb +20 -33
  31. data/spec/lib/taketo/config_validator_spec.rb +4 -4
  32. data/spec/lib/taketo/config_visitor_spec.rb +0 -4
  33. data/spec/lib/taketo/constructs/base_construct_spec.rb +37 -5
  34. data/spec/lib/taketo/constructs/environment_spec.rb +1 -1
  35. data/spec/lib/taketo/constructs/project_spec.rb +0 -6
  36. data/spec/lib/taketo/constructs/server_spec.rb +1 -3
  37. data/spec/lib/taketo/destination_resolver_spec.rb +21 -54
  38. data/spec/lib/taketo/dsl_spec.rb +46 -44
  39. data/spec/spec_helper.rb +1 -1
  40. data/spec/support/helpers/construct_spec_helper.rb +29 -0
  41. metadata +94 -82
  42. data/features/commands.feature +0 -36
  43. data/features/config.feature +0 -177
  44. data/features/config_validation.feature +0 -43
  45. data/features/connect_to_server.feature +0 -87
  46. data/features/default_server_config.feature +0 -41
  47. data/features/error_handling.feature +0 -29
  48. data/features/generate_ssh_config.feature +0 -44
  49. data/features/help.feature +0 -76
  50. data/features/step_definitions/main_steps.rb +0 -16
  51. data/features/support/env.rb +0 -14
@@ -1,62 +1,49 @@
1
1
  require 'spec_helper'
2
+ require 'support/helpers/construct_spec_helper'
2
3
  require 'taketo/config_traverser'
3
4
 
4
- # config 1
5
- # / \
6
- # project 1 2
5
+ # config 1--
6
+ # / \ \
7
+ # project 1 2 server_3
7
8
  # / \
8
9
  # environment 1 2
9
10
  # /|\
10
11
  # server 1 2 3
11
12
 
12
13
  describe Taketo::ConfigTraverser do
13
- let(:server_1) { stub(:Server1, :node_type => :server, :name => :server_1).as_null_object }
14
- let(:server_2) { stub(:Server2, :node_type => :server, :name => :server_2).as_null_object }
15
- let(:server_3) { stub(:Server3, :node_type => :server, :name => :server_3).as_null_object }
14
+ include ConstructsFixtures
16
15
 
17
- let(:environment_1) { stub(:Environment1, :node_type => :environment, :name => :environment_1) }
18
- let(:environment_2) { stub(:Environment2, :node_type => :environment, :name => :environment_2, :servers => [server_1, server_2, server_3]) }
16
+ let(:server_1) { server(:Server1) }
17
+ let(:server_2) { server(:Server2) }
18
+ let(:server_3) { server(:Server3) }
19
19
 
20
- let(:project_1) { stub(:Project1, :node_type => :project, :name => :project_1, :environments => [environment_1, environment_2]) }
21
- let(:project_2) { stub(:Project2, :node_type => :project, :name => :project_2) }
20
+ let(:environment_1) { environment(:Environment1) }
21
+ let(:environment_2) { environment(:Environment2, :servers => [server_1, server_2]) }
22
22
 
23
- let(:config) { stub(:Config, :node_type => :config, :projects => [project_1, project_2], :name => :config) }
23
+ let(:project_1) { project(:Project1, :environments => [environment_1, environment_2]) }
24
+ let(:project_2) { project(:Project2) }
24
25
 
25
- let(:traverser) { described_class.new(config) }
26
-
27
- before do
28
- config.stub(:has_nodes?).with(:projects).and_return(true)
29
- config.stub(:nodes).with(:projects).and_return([project_1, project_2])
30
-
31
- project_1.stub(:has_nodes?).with(:environments).and_return(true)
32
- project_1.stub(:nodes).with(:environments).and_return([environment_1, environment_2])
33
-
34
- project_2.stub(:has_nodes?).with(:environments).and_return(false)
35
- project_2.should_not_receive(:nodes)
26
+ let(:config) { create_config(:projects => [project_1, project_2], :servers => server_3) }
36
27
 
37
- environment_1.stub(:has_nodes?).with(:servers).and_return(false)
38
- environment_1.should_not_receive(:nodes)
39
-
40
- environment_2.stub(:has_nodes?).with(:servers).and_return(true)
41
- environment_2.stub(:nodes).and_return([server_1, server_2, server_3])
42
- end
28
+ let(:traverser) { described_class.new(config) }
43
29
 
44
30
  class PrintingVisitor
31
+ attr_reader :result
32
+
45
33
  def initialize
46
34
  @result = []
47
35
  end
48
36
 
49
- def visit(type)
37
+ def visit(node)
38
+ @result << node.name
50
39
  end
51
40
  end
52
41
 
53
42
  describe "#visit_depth_first" do
54
43
  it "traverses in depth with visitor" do
55
- visitor = stub(:Visitor)
56
- [config, project_1, environment_1, environment_2, server_1, server_2, server_3, project_2].each do |node|
57
- visitor.should_receive(:visit).with(node).ordered
58
- end
44
+ visitor = PrintingVisitor.new
59
45
  traverser.visit_depth_first(visitor)
46
+ visitor.result.should == [config, server_3, project_1, environment_1, environment_2, server_1, server_2, project_2].map(&:name)
60
47
  end
61
48
  end
62
49
  end
@@ -18,12 +18,12 @@ end
18
18
  describe "ConfigValidator::ConfigValidatorVisitor" do
19
19
  subject(:visitor) { ConfigValidator::ConfigValidatorVisitor.new }
20
20
 
21
- it "requires config to have projects" do
22
- config = stub(:Config, :has_projects? => false)
23
- error_message = /no projects/
21
+ it "requires config to have servers" do
22
+ config = stub(:Config, :has_servers? => false)
23
+ error_message = /no servers/
24
24
  expect { visitor.visit_config(config) }.to raise_error ConfigError, error_message
25
25
 
26
- config.stub(:has_projects? => true)
26
+ config.stub(:has_servers? => true)
27
27
  expect { visitor.visit_config(config) }.not_to raise_error ConfigError, error_message
28
28
  end
29
29
 
@@ -43,9 +43,5 @@ describe "ConfigVisitor" do
43
43
  end
44
44
  expect(visitor.visit(c.new)).to eq("captured as Numeric")
45
45
  end
46
-
47
- it "raises if doesn't know how to visit" do
48
- expect { visitor.visit([]) }.to raise_error /Array/
49
- end
50
46
  end
51
47
 
@@ -16,15 +16,47 @@ describe "BaseConstruct" do
16
16
  expect(construct.qualified_name).to eq('test_base_construct my_node')
17
17
  end
18
18
 
19
- specify "#parent= sets default server config to parent's default server config" do
20
- parent_default_server_config = proc {}
21
- construct.parent = stub(:default_server_config => parent_default_server_config)
22
- expect(construct.default_server_config).to eq(parent_default_server_config)
19
+ describe "#parent=" do
20
+ it "stores parent" do
21
+ parent = stub
22
+ construct.parent = parent
23
+ construct.parent.should == parent
24
+ end
25
+ end
26
+
27
+ shared_context "parents" do
28
+ let(:grand_parent) { TestBaseConstruct.new(:grand_parent) }
29
+ let(:parent) { TestBaseConstruct.new(:parent) }
30
+
31
+ before(:each) do
32
+ parent.parent = grand_parent
33
+ construct.parent = parent
34
+ end
35
+ end
36
+
37
+ describe "#parents" do
38
+ include_context "parents"
39
+
40
+ it "returns parent nodes up until NullConstruct" do
41
+ expect(construct.parents).to eq([parent, grand_parent])
42
+ end
43
+ end
44
+
45
+ specify "#parents returns an empty array if there are no parents" do
46
+ expect(construct.parents).to eq([])
47
+ end
48
+
49
+ describe "#path" do
50
+ include_context "parents"
51
+
52
+ it "returns names of parents separated by :" do
53
+ expect(construct.path).to eq("grand_parent:parent:my_node")
54
+ end
23
55
  end
24
56
 
25
57
  describe "#default_server_config=" do
26
58
  let(:default_server_config) { proc { call_from_self } }
27
- let(:context) { stub }
59
+ let(:context) { stub(:Context) }
28
60
 
29
61
  it "sets default server config" do
30
62
  construct.default_server_config = default_server_config
@@ -14,7 +14,7 @@ describe "Environment" do
14
14
  it_behaves_like "a construct with nodes", :servers, :server
15
15
 
16
16
  specify "#project_name returns project name" do
17
- environment.project = stub(:Project, :name => "TheProject")
17
+ environment.parent = Taketo::Constructs::Project.new("TheProject")
18
18
  expect(environment.project_name).to eq("TheProject")
19
19
  end
20
20
  end
@@ -11,12 +11,6 @@ describe "Project" do
11
11
  expect(project.name).to eq(:foo)
12
12
  end
13
13
 
14
- specify "#append_environment sets project attribute on an environment to self" do
15
- environment = mock(:Environment, :name => :bar)
16
- environment.should_receive(:project=).with(project)
17
- project.append_environment(environment)
18
- end
19
-
20
14
  it_behaves_like "a construct with nodes", :environments, :environment
21
15
  end
22
16
 
@@ -48,9 +48,7 @@ describe "Server" do
48
48
  end
49
49
 
50
50
  describe "#parent=" do
51
- let(:environment) { environment = stub(:Environment, :name => :the_environment, :default_server_config => proc {}) }
52
-
53
- it { should have_accessor(:environment, environment) }
51
+ let(:environment) { environment = Taketo::Constructs::Environment.new(:the_environment) }
54
52
 
55
53
  it "sets RAILS_ENV environment variable" do
56
54
  server.environment_variables.should == {}
@@ -1,53 +1,31 @@
1
1
  require 'spec_helper'
2
+ require 'support/helpers/construct_spec_helper'
2
3
  require 'taketo/destination_resolver'
3
4
  require 'taketo/support/named_nodes_collection'
4
5
 
5
6
  include Taketo
6
7
 
7
8
  describe "DestinationResolver" do
8
- class TestNode
9
- attr_reader :name, :node_type
10
- def initialize(node_type, name, *nodes)
11
- @node_type, @name, @nodes = node_type, name, nodes
12
- end
13
-
14
- def find(type, name)
15
- @nodes.detect { |s| s.name == name } or raise KeyError, name.to_s
16
- end
17
-
18
- def nodes(type)
19
- @nodes
20
- end
21
-
22
- def global_alias
23
- :the_alias if name == :s1 && node_type == :server
24
- end
25
- end
26
-
27
- [:project, :environment, :server].each do |node_type|
28
- define_method node_type do |name, *nodes|
29
- TestNode.new(node_type, name, *nodes)
30
- end
31
- end
9
+ include ConstructsFixtures
32
10
 
33
- let(:server1) { server(:s1) }
34
- let(:environment1) { environment(:bar, server1) }
35
- let(:project1) { project(:foo, environment1) }
11
+ let(:server1) { s = server(:s1); s.global_alias = :the_alias; s }
12
+ let(:environment1) { environment(:bar, :servers => server1) }
13
+ let(:project1) { project(:foo, :environments => environment1) }
36
14
 
37
15
  let(:server2) { server(:s2) }
38
- let(:environment2) { environment(:qux, server2) }
39
- let(:project2) { project(:baz, environment2) }
16
+ let(:environment2) { environment(:qux, :servers => server2) }
17
+ let(:project2) { project(:baz, :environments => environment2) }
40
18
 
41
19
  let(:server3) { server(:s3) }
42
20
  let(:server4) { server(:s4) }
43
- let(:environment3) { environment(:corge, server3, server4) }
44
- let(:project3) { environment(:quux, environment3) }
21
+ let(:environment3) { environment(:corge, :servers => [server3, server4]) }
22
+ let(:project3) { project(:quux, :environments => environment3) }
45
23
 
46
- let(:environment4) { environment(:garply, server(:s5), server(:s6)) }
47
- let(:environment5) { environment(:waldo, server(:s7)) }
48
- let(:project4) { project(:grault, environment4, environment5) }
24
+ let(:environment4) { environment(:garply, :servers => [server(:s5), server(:s6)]) }
25
+ let(:environment5) { environment(:waldo, :servers => server(:s7)) }
26
+ let(:project4) { project(:grault, :environments => [environment4, environment5]) }
49
27
 
50
- let(:config) { TestNode.new(:config, nil, project1, project2, project3, project4) }
28
+ let(:config) { create_config(:projects => [project1, project2, project3, project4]) }
51
29
 
52
30
  context "when project, environment and server specified" do
53
31
  it "returns server if it exists" do
@@ -114,43 +92,38 @@ describe "DestinationResolver" do
114
92
  context "when there's one environment" do
115
93
  context "when there's one server" do
116
94
  it "executes command without asking project/environment/server" do
117
- config = TestNode.new(:config, nil, project1)
118
- config.stub(:default_destination => nil)
95
+ config = create_config(:projects => project1)
119
96
  expect(resolver(config, "").resolve).to eq(server1)
120
97
  end
121
98
  end
122
99
 
123
100
  context "when there are multiple servers" do
124
101
  it "asks for server" do
125
- config = TestNode.new(:config, nil, project3)
126
- config.stub(:default_destination => nil)
127
- expect { resolver(config, "").resolve }.to raise_error AmbiguousDestinationError, /server/i
102
+ config = create_config(:projects => project3)
103
+ expect { resolver(config, "").resolve }.to raise_error AmbiguousDestinationError, /s3.*s4/i
128
104
  end
129
105
  end
130
106
  end
131
107
 
132
108
  context "when there are multiple environments" do
133
109
  it "asks for environment" do
134
- config = TestNode.new(:config, nil, project4)
135
- config.stub(:default_destination => nil)
136
- expect { resolver(config, "").resolve }.to raise_error AmbiguousDestinationError, /environment/i
110
+ config = create_config(:projects => project4)
111
+ expect { resolver(config, "").resolve }.to raise_error AmbiguousDestinationError, /garply:s5.*garply:s6.*waldo:s7/i
137
112
  end
138
113
  end
139
114
  end
140
115
 
141
116
  context "when there are multiple projects" do
142
117
  it "asks for project" do
143
- config = TestNode.new(:config, nil, project3, project4)
144
- config.stub(:default_destination => nil)
145
-
146
- expect { resolver(config, "").resolve }.to raise_error AmbiguousDestinationError, /projects/i
118
+ config = create_config(:projects => [project3, project4])
119
+ expect { resolver(config, "").resolve }.to raise_error AmbiguousDestinationError, /corge:s3.*corge:s4.*garply:s5.*garply:s6.*waldo:s7/i
147
120
  end
148
121
  end
149
122
  end
150
123
 
151
124
  context "when there is default destination" do
152
125
  it "resolves by default destination" do
153
- config.stub(:default_destination => "foo:bar:s1")
126
+ config.default_destination = "foo:bar:s1"
154
127
  expect(resolver(config, "").resolve).to eq(server1)
155
128
  end
156
129
  end
@@ -176,12 +149,10 @@ describe "DestinationResolver" do
176
149
  end
177
150
 
178
151
  it "returns the config if path has is empty and there's no default destination" do
179
- config.stub(:default_destination => nil)
180
152
  expect(resolver(config, "").get_node).to eq(config)
181
153
  end
182
154
 
183
155
  it "raises NonExistentDestinationError when path is not correct" do
184
- config.should_receive(:find).with(:project, :i).and_raise(KeyError)
185
156
  expect { resolver(config, "i").get_node }.to raise_error(NonExistentDestinationError)
186
157
  end
187
158
  end
@@ -190,9 +161,5 @@ describe "DestinationResolver" do
190
161
  DestinationResolver.new(*args)
191
162
  end
192
163
 
193
- def list(*items)
194
- Taketo::Support::NamedNodesCollection.new(items)
195
- end
196
-
197
164
  end
198
165
 
@@ -21,49 +21,51 @@ describe "DSL" do
21
21
  end
22
22
  end
23
23
 
24
- shared_examples "a scope" do |scope_name, parent_scope_name|
25
- parent_scope = scopes[parent_scope_name]
26
-
27
- it_behaves_like "a scoped construct", scope_name, parent_scope_name, true
28
-
29
- it { should enclose_scope(scope_name).under(parent_scope) }
30
-
31
- it "creates a #{scope_name} and set it as current scope object" do # it "creates project and set it as current scope object"
32
- dsl(parent_scope, factory.create(parent_scope_name)) do |c| # dsl([:config], factory.create(:config)) do |c|
33
- stub_find_or_create_scope_object(c, scope_name, :bar) # stub_find_or_create_scope_object(c, :project, :bar)
34
- c.send(scope_name, :bar) do # c.project(:bar) do
35
- expect(c.current_scope_object).not_to be_nil # expect(c.current_scope_object).not_to be_nil
36
- expect(c.current_scope_object).to eq(factory.send(scope_name)) # expect(c.current_scope_object).to eq(factory.project)
37
- end # end
38
- end # end
39
- end # end
40
-
41
- it "does not leak #{scope_name} as current scope object" do # it "does not leak project as current scope object"
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.send(scope_name, :bar) do # c.project(:bar) do
45
- expect(c.current_scope_object).to eq(factory.send(scope_name)) # expect(c.current_scope_object).to eq(factory.project)
46
- end # end
47
- expect(c.current_scope_object).not_to eq(factory.send(scope_name)) # expect(c.current_scope_object).not_to eq(factory.project)
48
- end # end
49
- end # end
50
-
51
- 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
52
- dsl(parent_scope, factory.create(parent_scope_name)) do |c| # dsl([:config], factory.create(:config)) do |c|
53
- stub_find_or_create_scope_object(c, scope_name, :bar) # stub_find_or_create_scope_object(c, :project, :bar)
54
- c.current_scope_object.should_receive("append_#{scope_name}"). # c.current_scope_object.should_receive(:append_project).
55
- with(factory.send(scope_name)) # with(factory.project)
56
- c.send(scope_name, :bar) {} # c.project(:bar) {}
57
- end # end
58
- end # end
59
-
60
- it "sets #{scope_name}'s parent to the #{parent_scope_name} scope object" do # it "sets project's parent to the config scope object" do
61
- dsl(parent_scope, factory.create(parent_scope_name)) do |c| # dsl([:config], factory.create(:config)) do |c|
62
- stub_find_or_create_scope_object(c, scope_name, :bar) # stub_find_or_create_scope_object(c, :project, :bar)
63
- factory.send(scope_name).should_receive(:parent=).with(c.current_scope_object) # factory.project.should_receive(:parent=).with(c.current_scope_object)
64
- c.send(scope_name, :bar) {} # c.project(:bar) {}
65
- end # end
66
- end #
24
+ shared_examples "a scope" do |scope_name, parent_scope_names|
25
+ it_behaves_like "a scoped construct", scope_name, Array(parent_scope_names), true
26
+
27
+ Array(parent_scope_names).each do |parent_scope_name|
28
+ parent_scope = scopes[parent_scope_name]
29
+
30
+ it { should enclose_scope(scope_name).under(parent_scope) }
31
+
32
+ it "creates a #{scope_name} and set it as current scope object" do # it "creates project and set it as current scope object"
33
+ dsl(parent_scope, factory.create(parent_scope_name)) do |c| # dsl([:config], factory.create(:config)) do |c|
34
+ stub_find_or_create_scope_object(c, scope_name, :bar) # stub_find_or_create_scope_object(c, :project, :bar)
35
+ c.send(scope_name, :bar) do # c.project(:bar) do
36
+ expect(c.current_scope_object).not_to be_nil # expect(c.current_scope_object).not_to be_nil
37
+ expect(c.current_scope_object).to eq(factory.send(scope_name)) # expect(c.current_scope_object).to eq(factory.project)
38
+ end # end
39
+ end # end
40
+ end # end
41
+
42
+ it "does not leak #{scope_name} as current scope object" do # it "does not leak project as current scope object"
43
+ dsl(parent_scope, factory.create(parent_scope_name)) do |c| # dsl([:config], factory.create(:config)) do |c|
44
+ stub_find_or_create_scope_object(c, scope_name, :bar) # stub_find_or_create_scope_object(c, :project, :bar)
45
+ c.send(scope_name, :bar) do # c.project(:bar) do
46
+ expect(c.current_scope_object).to eq(factory.send(scope_name)) # expect(c.current_scope_object).to eq(factory.project)
47
+ end # end
48
+ expect(c.current_scope_object).not_to eq(factory.send(scope_name)) # expect(c.current_scope_object).not_to eq(factory.project)
49
+ end # end
50
+ end # end
51
+
52
+ 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
53
+ dsl(parent_scope, factory.create(parent_scope_name)) do |c| # dsl([:config], factory.create(:config)) do |c|
54
+ stub_find_or_create_scope_object(c, scope_name, :bar) # stub_find_or_create_scope_object(c, :project, :bar)
55
+ c.current_scope_object.should_receive("append_#{scope_name}"). # c.current_scope_object.should_receive(:append_project).
56
+ with(factory.send(scope_name)) # with(factory.project)
57
+ c.send(scope_name, :bar) {} # c.project(:bar) {}
58
+ end # end
59
+ end # end
60
+
61
+ it "sets #{scope_name}'s parent to the #{parent_scope_name} scope object" do # it "sets project's parent to the config scope object" do
62
+ dsl(parent_scope, factory.create(parent_scope_name)) do |c| # dsl([:config], factory.create(:config)) do |c|
63
+ stub_find_or_create_scope_object(c, scope_name, :bar) # stub_find_or_create_scope_object(c, :project, :bar)
64
+ factory.send(scope_name).should_receive(:parent=).with(c.current_scope_object) # factory.project.should_receive(:parent=).with(c.current_scope_object)
65
+ c.send(scope_name, :bar) {} # c.project(:bar) {}
66
+ end # end
67
+ end #
68
+ end
67
69
  end
68
70
 
69
71
  shared_examples "a scoped method" do |attribute_name, parent_scope_names, parent_scope_method, example_value|
@@ -166,7 +168,7 @@ describe "DSL" do
166
168
  end
167
169
 
168
170
  describe "#server" do
169
- it_behaves_like "a scope", :server, :environment
171
+ it_behaves_like "a scope", :server, [:environment, :config, :project]
170
172
 
171
173
  it "evaluates default_server_config" do
172
174
  dsl(scopes[:environment], factory.create(:environment, :foo)) do |c|
data/spec/spec_helper.rb CHANGED
@@ -17,5 +17,5 @@ require 'rspec/autorun'
17
17
 
18
18
  $:.unshift File.expand_path('../../lib', __FILE__)
19
19
 
20
- Dir[File.dirname(__FILE__) + "/support/matchers/*.rb"].each {|f| require f}
20
+ Dir[File.dirname(__FILE__) + "/support/matchers/*.rb"].each { |f| require f }
21
21
 
@@ -1,3 +1,5 @@
1
+ require 'taketo/constructs'
2
+
1
3
  shared_examples "a construct with nodes" do |name_plural, name_singular|
2
4
  specify "#append_#{name_singular} adds a #{name_singular} to " + # specify "#append_server adds a server to " +
3
5
  "the #{name_plural} collection" do # "the servers collection" do
@@ -13,3 +15,30 @@ shared_examples "a construct with nodes" do |name_plural, name_singular|
13
15
  end # end
14
16
  end
15
17
 
18
+ module ConstructsFixtures
19
+ include Taketo::Constructs
20
+
21
+ [Project, Environment, Server].each do |node_type|
22
+ define_method node_type.name.downcase.gsub(/\w*::/, '') do |name, *args|
23
+ n = node_type.new(name)
24
+ add_nodes(n, args.first || {})
25
+ n
26
+ end
27
+ end
28
+
29
+ def create_config(nodes_by_types = {})
30
+ c = Taketo::Constructs::Config.new
31
+ add_nodes(c, nodes_by_types)
32
+ c
33
+ end
34
+
35
+ def add_nodes(node, nodes_by_types)
36
+ nodes_by_types.each do |child_type, children_of_type|
37
+ Array(children_of_type).each do |c|
38
+ node.nodes(child_type) << c
39
+ c.parent = node
40
+ end
41
+ end
42
+ end
43
+ end
44
+