chemtrail 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/chemtrail +6 -0
- data/lib/chemtrail/class_name_inflector.rb +14 -0
- data/lib/chemtrail/cli.rb +34 -0
- data/lib/chemtrail/mapping.rb +1 -7
- data/lib/chemtrail/output.rb +3 -5
- data/lib/chemtrail/{declaration.rb → parameter.rb} +1 -1
- data/lib/chemtrail/section_presenter.rb +16 -0
- data/lib/chemtrail/template.rb +47 -14
- data/lib/chemtrail/version.rb +1 -1
- data/lib/chemtrail.rb +1 -1
- data/spec/lib/chemtrail/class_name_inflector_spec.rb +31 -0
- data/spec/lib/chemtrail/cli_spec.rb +25 -0
- data/spec/lib/chemtrail/{declaration_spec.rb → parameter_spec.rb} +6 -6
- data/spec/lib/chemtrail/section_presenter_spec.rb +22 -0
- data/spec/lib/chemtrail/template_spec.rb +44 -55
- data/spec/spec_helper.rb +3 -0
- data/spec/support/fixtures/fixture_template.rb +2 -0
- metadata +18 -8
- data/lib/chemtrail/section.rb +0 -5
- data/spec/lib/chemtrail/section_spec.rb +0 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e54ce07e90240967020fa7a8dc856b944338f78e
|
4
|
+
data.tar.gz: 132975f191f9df48d66606e27648852cb29a8608
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0cd2a647db49fb8ecef0863955670ea9dadbec2087e68a561376fbd2c4ca5ea3e55eb883fa404a8d17e2f1b180c5dfbc12d49e42b6d1f5d87e88bdf37f541c25
|
7
|
+
data.tar.gz: 22f400b9b20b389bec87ba1951f374cb37cd16a5c72359c8debe4913db6d7528cd3106477fb9ea659873cee5d270d06bd9a18d757a6e6155f2dbf57a73a078d0
|
data/bin/chemtrail
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
class Chemtrail::ClassNameInflector
|
2
|
+
attr_reader :class_name
|
3
|
+
|
4
|
+
def initialize(class_name)
|
5
|
+
@class_name = class_name.to_s.dup
|
6
|
+
end
|
7
|
+
|
8
|
+
def underscore
|
9
|
+
class_name.gsub(/([A-Z\d]+)([A-Z][a-z])/,'\1_\2')
|
10
|
+
.gsub(/([a-z\d])([A-Z])/,'\1_\2')
|
11
|
+
.gsub(/::/,':')
|
12
|
+
.downcase
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require "thor"
|
2
|
+
require "json"
|
3
|
+
|
4
|
+
class Chemtrail::Cli < Thor
|
5
|
+
default_task :list
|
6
|
+
|
7
|
+
desc "list", "Lists all available templates"
|
8
|
+
method_option :path, :default => File.expand_path("lib/templates")
|
9
|
+
def list
|
10
|
+
require_templates_from(options[:path])
|
11
|
+
Chemtrail::Template.subclass_map.keys.each { |k| Kernel.puts(k) }
|
12
|
+
end
|
13
|
+
|
14
|
+
desc "build TEMPLATE", "Builds the selected template"
|
15
|
+
method_option :path, :default => File.expand_path("lib/templates")
|
16
|
+
def build(template_name)
|
17
|
+
require_templates_from(options[:path])
|
18
|
+
template_class = fetch_template_class_named(template_name)
|
19
|
+
template_json = JSON.pretty_generate(template_class.new.to_hash)
|
20
|
+
Kernel.puts(template_json)
|
21
|
+
end
|
22
|
+
|
23
|
+
protected
|
24
|
+
|
25
|
+
def require_templates_from(path)
|
26
|
+
Dir.glob(File.expand_path("**/*_template.rb", path)).each { |t| require t }
|
27
|
+
end
|
28
|
+
|
29
|
+
def fetch_template_class_named(name)
|
30
|
+
template = Chemtrail::Template.subclass_map[name]
|
31
|
+
raise Thor::Error.new("Template #{name} does not exist") if template.nil?
|
32
|
+
template
|
33
|
+
end
|
34
|
+
end
|
data/lib/chemtrail/mapping.rb
CHANGED
@@ -12,13 +12,7 @@ class Chemtrail::Mapping
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def find(top_level, second_level)
|
15
|
-
|
16
|
-
"Fn::FindInMap" => [
|
17
|
-
id,
|
18
|
-
Chemtrail::ReferencePresenter.new(top_level).to_parameter,
|
19
|
-
Chemtrail::ReferencePresenter.new(second_level).to_parameter
|
20
|
-
]
|
21
|
-
}
|
15
|
+
Chemtrail::Function.new("Fn::FindInMap", id, top_level, second_level).to_hash
|
22
16
|
end
|
23
17
|
|
24
18
|
def to_hash
|
data/lib/chemtrail/output.rb
CHANGED
@@ -0,0 +1,16 @@
|
|
1
|
+
class Chemtrail::SectionPresenter
|
2
|
+
attr_reader :name, :entries
|
3
|
+
|
4
|
+
def initialize(name, entries)
|
5
|
+
@name = name
|
6
|
+
@entries = entries
|
7
|
+
end
|
8
|
+
|
9
|
+
def to_hash
|
10
|
+
if entries.empty?
|
11
|
+
{}
|
12
|
+
else
|
13
|
+
{name => entries.map(&:to_hash).reduce(Hash.new, :merge)}
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
data/lib/chemtrail/template.rb
CHANGED
@@ -1,36 +1,69 @@
|
|
1
|
-
require "chemtrail/
|
1
|
+
require "chemtrail/section_presenter"
|
2
|
+
require "chemtrail/class_name_inflector"
|
2
3
|
|
3
4
|
class Chemtrail::Template
|
5
|
+
class << self
|
6
|
+
def subclass_map
|
7
|
+
@subclass_map ||= {}
|
8
|
+
end
|
9
|
+
|
10
|
+
def inherited(subclass)
|
11
|
+
subclass_map[Chemtrail::ClassNameInflector.new(subclass).underscore] = subclass
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
4
15
|
attr_reader :description
|
5
16
|
|
6
|
-
def initialize(description)
|
17
|
+
def initialize(description = nil)
|
7
18
|
@description = description
|
8
19
|
end
|
9
20
|
|
10
21
|
def parameters
|
11
|
-
|
22
|
+
[]
|
12
23
|
end
|
13
24
|
|
14
25
|
def mappings
|
15
|
-
|
26
|
+
[]
|
16
27
|
end
|
17
28
|
|
18
29
|
def resources
|
19
|
-
|
30
|
+
[]
|
20
31
|
end
|
21
32
|
|
22
33
|
def outputs
|
23
|
-
|
34
|
+
[]
|
24
35
|
end
|
25
36
|
|
26
37
|
def to_hash
|
27
|
-
{
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
38
|
+
version_hash = {"AWSTemplateFormatVersion" => "2010-09-09"}
|
39
|
+
version_hash.merge(description_hash)
|
40
|
+
.merge(parameters_hash)
|
41
|
+
.merge(mappings_hash)
|
42
|
+
.merge(resources_hash)
|
43
|
+
.merge(outputs_hash)
|
44
|
+
end
|
45
|
+
|
46
|
+
protected
|
47
|
+
|
48
|
+
def description_hash
|
49
|
+
hash = {}
|
50
|
+
hash["Description"] = description unless description.nil?
|
51
|
+
hash
|
52
|
+
end
|
53
|
+
|
54
|
+
def parameters_hash
|
55
|
+
Chemtrail::SectionPresenter.new("Parameters", parameters).to_hash
|
56
|
+
end
|
57
|
+
|
58
|
+
def mappings_hash
|
59
|
+
Chemtrail::SectionPresenter.new("Mappings", mappings).to_hash
|
60
|
+
end
|
61
|
+
|
62
|
+
def resources_hash
|
63
|
+
Chemtrail::SectionPresenter.new("Resources", resources).to_hash
|
64
|
+
end
|
65
|
+
|
66
|
+
def outputs_hash
|
67
|
+
Chemtrail::SectionPresenter.new("Outputs", outputs).to_hash
|
35
68
|
end
|
36
69
|
end
|
data/lib/chemtrail/version.rb
CHANGED
data/lib/chemtrail.rb
CHANGED
@@ -0,0 +1,31 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Chemtrail::ClassNameInflector do
|
4
|
+
subject(:inflector) { Chemtrail::ClassNameInflector.new(class_name) }
|
5
|
+
|
6
|
+
describe "#underscore" do
|
7
|
+
context "with a normal name" do
|
8
|
+
let(:class_name) { "Tacos" }
|
9
|
+
|
10
|
+
its(:underscore) { should == "tacos" }
|
11
|
+
end
|
12
|
+
|
13
|
+
context "with a normal camelcase name" do
|
14
|
+
let(:class_name) { "ZapZap" }
|
15
|
+
|
16
|
+
its(:underscore) { should == "zap_zap" }
|
17
|
+
end
|
18
|
+
|
19
|
+
context "with a slightly abnormal camelcase name" do
|
20
|
+
let(:class_name) { "DSLAreGreat" }
|
21
|
+
|
22
|
+
its(:underscore) { should == "dsl_are_great" }
|
23
|
+
end
|
24
|
+
|
25
|
+
context "with a namespace" do
|
26
|
+
let(:class_name) { "Geese::Adorable" }
|
27
|
+
|
28
|
+
its(:underscore) { should == "geese:adorable" }
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Chemtrail::Cli do
|
4
|
+
subject(:cli) { Chemtrail::Cli.new }
|
5
|
+
|
6
|
+
describe "#list" do
|
7
|
+
it "lists available templates" do
|
8
|
+
Kernel.should_receive(:puts).with("tacos")
|
9
|
+
cli.list
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "#build" do
|
14
|
+
it "builds the specified template" do
|
15
|
+
Kernel.should_receive(:puts).with(JSON.pretty_generate(Tacos.new.to_hash))
|
16
|
+
cli.build("tacos")
|
17
|
+
end
|
18
|
+
|
19
|
+
context "when the template does not exist" do
|
20
|
+
it "blows up" do
|
21
|
+
expect { cli.build("house of cards") }.to raise_error(Thor::Error)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
|
-
describe Chemtrail::
|
4
|
-
subject(:
|
3
|
+
describe Chemtrail::Parameter do
|
4
|
+
subject(:parameter) { Chemtrail::Parameter.new("parmesan", "String") }
|
5
5
|
|
6
6
|
describe "#specifications" do
|
7
7
|
context "when there are no specifications" do
|
@@ -9,7 +9,7 @@ describe Chemtrail::Declaration do
|
|
9
9
|
end
|
10
10
|
|
11
11
|
context "when a specification has been passed into the initializer" do
|
12
|
-
subject(:
|
12
|
+
subject(:parameter) { Chemtrail::Parameter.new("parmesan", "String", ok: "great") }
|
13
13
|
|
14
14
|
its(:specifications) { should == {ok: "great"} }
|
15
15
|
end
|
@@ -21,12 +21,12 @@ describe Chemtrail::Declaration do
|
|
21
21
|
|
22
22
|
describe "#to_hash" do
|
23
23
|
its(:to_hash) { should have_key "parmesan" }
|
24
|
-
specify {
|
24
|
+
specify { parameter.to_hash["parmesan"].should include("Type" => "String") }
|
25
25
|
|
26
26
|
context "when there is a specification" do
|
27
|
-
before {
|
27
|
+
before { parameter.specifications[:ducks] = "amazing" }
|
28
28
|
|
29
|
-
specify {
|
29
|
+
specify { parameter.to_hash["parmesan"].should include(ducks: "amazing") }
|
30
30
|
end
|
31
31
|
end
|
32
32
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Chemtrail::SectionPresenter do
|
4
|
+
let(:entry) { double(:entry, to_hash: {tacos: "great"}) }
|
5
|
+
let(:entries) { [] }
|
6
|
+
|
7
|
+
subject(:section) { Chemtrail::SectionPresenter.new("Socks", entries) }
|
8
|
+
|
9
|
+
describe "#to_hash" do
|
10
|
+
context "when there are no entries" do
|
11
|
+
let(:entries) { [] }
|
12
|
+
|
13
|
+
its(:to_hash) { should == {} }
|
14
|
+
end
|
15
|
+
|
16
|
+
context "when there is an entry" do
|
17
|
+
let(:entries) { [entry] }
|
18
|
+
|
19
|
+
its(:to_hash) { should == {"Socks" => {tacos: "great"}} }
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -6,86 +6,75 @@ describe Chemtrail::Template do
|
|
6
6
|
let(:fake_parameter) { double(:parameter, to_hash: {"parameter" => "json"}) }
|
7
7
|
let(:fake_resource) { double(:resource, to_hash: {"resource" => "json"}) }
|
8
8
|
|
9
|
-
subject(:template) { Chemtrail::Template.new
|
9
|
+
subject(:template) { Chemtrail::Template.new }
|
10
10
|
|
11
|
-
describe "#
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
context "when the template does not have parameters" do
|
19
|
-
its(:parameters) { should be_empty }
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
describe "#mappings" do
|
24
|
-
context "when the template has mappings" do
|
25
|
-
before { template.mappings << fake_mapping }
|
26
|
-
|
27
|
-
its(:mappings) { should == [fake_mapping] }
|
28
|
-
end
|
29
|
-
|
30
|
-
context "when the template does not have mappings" do
|
31
|
-
its(:mappings) { should be_empty }
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
describe "#resources" do
|
36
|
-
context "when the template has resources" do
|
37
|
-
before { template.resources << fake_resource }
|
38
|
-
|
39
|
-
its(:resources) { should == [fake_resource] }
|
40
|
-
end
|
11
|
+
describe "#to_hash" do
|
12
|
+
its(:to_hash) { should include("AWSTemplateFormatVersion" => "2010-09-09") }
|
13
|
+
its(:to_hash) { should_not have_key "Parameters" }
|
14
|
+
its(:to_hash) { should_not have_key "Mappings" }
|
15
|
+
its(:to_hash) { should_not have_key "Resources" }
|
16
|
+
its(:to_hash) { should_not have_key "Outputs" }
|
41
17
|
|
42
|
-
context "when the
|
43
|
-
its(:
|
18
|
+
context "when the description is not set" do
|
19
|
+
its(:to_hash) { should_not have_key "Description" }
|
44
20
|
end
|
45
|
-
end
|
46
21
|
|
47
|
-
|
48
|
-
|
49
|
-
before { template.outputs << fake_output }
|
50
|
-
|
51
|
-
its(:outputs) { should == [fake_output] }
|
52
|
-
end
|
22
|
+
context "when the description is set" do
|
23
|
+
subject(:template) { Chemtrail::Template.new("super great") }
|
53
24
|
|
54
|
-
|
55
|
-
its(:outputs) { should be_empty }
|
25
|
+
its(:to_hash) { should include("Description" => "super great") }
|
56
26
|
end
|
57
|
-
end
|
58
|
-
|
59
|
-
describe "#to_hash" do
|
60
|
-
its(:to_hash) { should include("AWSTemplateFormatVersion" => "2010-09-09") }
|
61
|
-
its(:to_hash) { should include("Description" => "wat") }
|
62
|
-
its(:to_hash) { should have_key "Parameters" }
|
63
|
-
its(:to_hash) { should have_key "Mappings" }
|
64
|
-
its(:to_hash) { should have_key "Resources" }
|
65
|
-
its(:to_hash) { should have_key "Outputs" }
|
66
27
|
|
67
28
|
context "when the template has parameters" do
|
68
|
-
before { template.parameters
|
29
|
+
before { template.stub(parameters: [fake_parameter]) }
|
69
30
|
|
70
31
|
its(:to_hash) { should include("Parameters" => {"parameter" => "json"}) }
|
71
32
|
end
|
72
33
|
|
73
34
|
context "when the template has mappings" do
|
74
|
-
before { template.mappings
|
35
|
+
before { template.stub(mappings: [fake_mapping]) }
|
75
36
|
|
76
37
|
its(:to_hash) { should include("Mappings" => {"mapping" => "json"}) }
|
77
38
|
end
|
78
39
|
|
79
40
|
context "when the template has resources" do
|
80
|
-
before { template.resources
|
41
|
+
before { template.stub(resources: [fake_resource]) }
|
81
42
|
|
82
43
|
its(:to_hash) { should include("Resources" => {"resource" => "json"}) }
|
83
44
|
end
|
84
45
|
|
85
46
|
context "when the template has outputs" do
|
86
|
-
before { template.outputs
|
47
|
+
before { template.stub(outputs: [fake_output]) }
|
87
48
|
|
88
49
|
its(:to_hash) { should include("Outputs" => {"output" => "json"}) }
|
89
50
|
end
|
90
51
|
end
|
52
|
+
|
53
|
+
describe ".inherited" do
|
54
|
+
before { Chemtrail::Template.stub(subclass_map: {}) }
|
55
|
+
|
56
|
+
it "adds subclasses to the template map" do
|
57
|
+
expect {
|
58
|
+
Chemtrail::Template.send(:inherited, Object)
|
59
|
+
}.to change {
|
60
|
+
Chemtrail::Template.subclass_map
|
61
|
+
}.from({}).to("object" => Object)
|
62
|
+
end
|
63
|
+
|
64
|
+
it "adds namespaced subclasses to the template map" do
|
65
|
+
expect {
|
66
|
+
Chemtrail::Template.send(:inherited, Chemtrail::Template)
|
67
|
+
}.to change {
|
68
|
+
Chemtrail::Template.subclass_map
|
69
|
+
}.from({}).to("chemtrail:template" => Chemtrail::Template)
|
70
|
+
end
|
71
|
+
|
72
|
+
it "adds camelcased subclasses to the template map as snakecase" do
|
73
|
+
expect {
|
74
|
+
Chemtrail::Template.send(:inherited, Chemtrail::PropertyList)
|
75
|
+
}.to change {
|
76
|
+
Chemtrail::Template.subclass_map
|
77
|
+
}.from({}).to("chemtrail:property_list" => Chemtrail::PropertyList)
|
78
|
+
end
|
79
|
+
end
|
91
80
|
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: chemtrail
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Doc Ritezel
|
@@ -83,7 +83,8 @@ dependencies:
|
|
83
83
|
description: Seed your CloudFormation stack
|
84
84
|
email:
|
85
85
|
- pair+doc@ministryofvelocity.com
|
86
|
-
executables:
|
86
|
+
executables:
|
87
|
+
- chemtrail
|
87
88
|
extensions: []
|
88
89
|
extra_rdoc_files: []
|
89
90
|
files:
|
@@ -96,29 +97,35 @@ files:
|
|
96
97
|
- Guardfile
|
97
98
|
- LICENSE.txt
|
98
99
|
- README.md
|
100
|
+
- bin/chemtrail
|
99
101
|
- chemtrail.gemspec
|
100
102
|
- lib/chemtrail.rb
|
101
|
-
- lib/chemtrail/
|
103
|
+
- lib/chemtrail/class_name_inflector.rb
|
104
|
+
- lib/chemtrail/cli.rb
|
102
105
|
- lib/chemtrail/function.rb
|
103
106
|
- lib/chemtrail/mapping.rb
|
104
107
|
- lib/chemtrail/output.rb
|
108
|
+
- lib/chemtrail/parameter.rb
|
105
109
|
- lib/chemtrail/property_list.rb
|
106
110
|
- lib/chemtrail/reference_presenter.rb
|
107
111
|
- lib/chemtrail/resource.rb
|
108
|
-
- lib/chemtrail/
|
112
|
+
- lib/chemtrail/section_presenter.rb
|
109
113
|
- lib/chemtrail/template.rb
|
110
114
|
- lib/chemtrail/version.rb
|
111
115
|
- script/ci.sh
|
112
|
-
- spec/lib/chemtrail/
|
116
|
+
- spec/lib/chemtrail/class_name_inflector_spec.rb
|
117
|
+
- spec/lib/chemtrail/cli_spec.rb
|
113
118
|
- spec/lib/chemtrail/function_spec.rb
|
114
119
|
- spec/lib/chemtrail/mapping_spec.rb
|
115
120
|
- spec/lib/chemtrail/output_spec.rb
|
121
|
+
- spec/lib/chemtrail/parameter_spec.rb
|
116
122
|
- spec/lib/chemtrail/property_list_spec.rb
|
117
123
|
- spec/lib/chemtrail/reference_presenter_spec.rb
|
118
124
|
- spec/lib/chemtrail/resource_spec.rb
|
119
|
-
- spec/lib/chemtrail/
|
125
|
+
- spec/lib/chemtrail/section_presenter_spec.rb
|
120
126
|
- spec/lib/chemtrail/template_spec.rb
|
121
127
|
- spec/spec_helper.rb
|
128
|
+
- spec/support/fixtures/fixture_template.rb
|
122
129
|
homepage: https://github.com/minifast/chemtrail
|
123
130
|
licenses:
|
124
131
|
- MIT
|
@@ -144,13 +151,16 @@ signing_key:
|
|
144
151
|
specification_version: 4
|
145
152
|
summary: Build, create and maintain your CloudFormation stack
|
146
153
|
test_files:
|
147
|
-
- spec/lib/chemtrail/
|
154
|
+
- spec/lib/chemtrail/class_name_inflector_spec.rb
|
155
|
+
- spec/lib/chemtrail/cli_spec.rb
|
148
156
|
- spec/lib/chemtrail/function_spec.rb
|
149
157
|
- spec/lib/chemtrail/mapping_spec.rb
|
150
158
|
- spec/lib/chemtrail/output_spec.rb
|
159
|
+
- spec/lib/chemtrail/parameter_spec.rb
|
151
160
|
- spec/lib/chemtrail/property_list_spec.rb
|
152
161
|
- spec/lib/chemtrail/reference_presenter_spec.rb
|
153
162
|
- spec/lib/chemtrail/resource_spec.rb
|
154
|
-
- spec/lib/chemtrail/
|
163
|
+
- spec/lib/chemtrail/section_presenter_spec.rb
|
155
164
|
- spec/lib/chemtrail/template_spec.rb
|
156
165
|
- spec/spec_helper.rb
|
166
|
+
- spec/support/fixtures/fixture_template.rb
|
data/lib/chemtrail/section.rb
DELETED
@@ -1,13 +0,0 @@
|
|
1
|
-
require "spec_helper"
|
2
|
-
|
3
|
-
describe Chemtrail::Section do
|
4
|
-
let(:entry) { double(:entry, to_hash: {tacos: "great"}) }
|
5
|
-
|
6
|
-
subject(:section) { Chemtrail::Section.new }
|
7
|
-
|
8
|
-
describe "#to_hash" do
|
9
|
-
before { section << entry }
|
10
|
-
|
11
|
-
its(:to_hash) { should == {tacos: "great"} }
|
12
|
-
end
|
13
|
-
end
|