muffins 0.0.5 → 0.0.6

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.
@@ -0,0 +1,46 @@
1
+ require 'spec_helper'
2
+
3
+ describe Muffins::Document do
4
+
5
+ subject { described_class.new(:body => body) }
6
+
7
+ context "HTML" do
8
+
9
+ let(:body) { fixture_file("books.html") }
10
+ let(:path) { ".book" }
11
+
12
+ describe "#all" do
13
+ it "returns 2 objects" do
14
+ subject.all(path).size.should eql(2)
15
+ end
16
+ end
17
+
18
+ describe "#first" do
19
+ it "returns a string" do
20
+ subject.first(path).should be_a(String)
21
+ end
22
+ end
23
+
24
+ end
25
+
26
+ context "XML" do
27
+
28
+ let(:body) { fixture_file("books.xml") }
29
+ let(:path) { "book" }
30
+
31
+ describe "#all" do
32
+ it "returns 2 objects" do
33
+ subject.all(path).size.should eql(2)
34
+ end
35
+ end
36
+
37
+ describe "#first" do
38
+ it "returns an element" do
39
+ subject.first(path).should be_a(String)
40
+ end
41
+ end
42
+
43
+ end
44
+
45
+
46
+ end
@@ -0,0 +1,33 @@
1
+ require "spec_helper"
2
+
3
+ describe Muffins::MappingParent do
4
+
5
+ class Book
6
+ include Muffins
7
+ end
8
+
9
+ subject { Muffins::MappingParent.new(options) }
10
+
11
+ let(:options) do
12
+ { :path => path,
13
+ :klass => klass }
14
+ end
15
+
16
+ let(:klass) { Book }
17
+ let(:path) { "#book" }
18
+
19
+ let(:name) { :foo }
20
+ let(:type) { String }
21
+ let(:opts) { {} }
22
+
23
+ its(:klass) { should eql(klass) }
24
+ its(:path) { should eql(path) }
25
+
26
+ describe "#map" do
27
+ it "initializes a namespaced mapping" do
28
+ subject.map(name, type, opts)
29
+ klass.send(:mappings).first.within.should == path
30
+ end
31
+ end
32
+
33
+ end
@@ -1,280 +1,43 @@
1
1
  require 'spec_helper'
2
2
 
3
- module Muffins
4
- class Book
5
- include Muffins
6
- end
7
-
8
- describe Mapping do
9
-
10
- let(:name) { :foo }
11
- let(:options) { {} }
12
-
13
- let(:document) { mock(Nokogiri::XML::Document) }
14
-
15
- let(:node) { mock(Nokogiri::XML::Node) }
16
- let(:nodes) { [node] }
17
-
18
- let(:value) { 'bar' }
19
- let(:values) { [value] }
20
-
21
- subject { Mapping.new(name, options) }
22
-
23
- describe "#map" do
24
- before(:each) do
25
- subject.stub(:typecast).with(node).and_return(value)
26
- end
27
-
28
- context "#collection? returns true" do
29
- before(:each) do
30
- subject.stub(:collection?).and_return(true)
31
-
32
- document.stub(:css).and_return(nodes)
33
- end
34
-
35
- it "typecasts the parsed values" do
36
- subject.should_receive(:typecast).with(node).and_return(value)
37
- subject.map(document)
38
- end
39
-
40
- it "returns an array of typecasted values" do
41
- subject.map(document).should == values
42
- end
43
- end
44
-
45
- context "#collection? returns false" do
46
- before(:each) do
47
- subject.stub(:collection?).and_return(false)
48
-
49
- document.stub(:at_css).and_return(node)
50
- end
51
-
52
- it "typecasts the parsed value" do
53
- subject.should_receive(:typecast).with(node).and_return(value)
54
- subject.map(document)
55
- end
56
-
57
- it "returns the typecasted value" do
58
- subject.map(document).should == value
59
- end
60
- end
61
- end
62
-
63
- describe "#path" do
64
- context "no options are passed" do
65
- it "returns the mapping name" do
66
- subject.path.should == name
67
- end
68
- end
3
+ describe Muffins::Mapping do
69
4
 
70
- context "options[:to] is passed" do
71
- let(:to) { 'bar' }
72
- let(:options) { {:to => to} }
5
+ subject { described_class.new(options) }
73
6
 
74
- before(:each) do
75
- subject.stub(:options).and_return(options)
76
- end
7
+ let(:name) { :foo }
8
+ let(:type) { String }
9
+ let(:to) { ".book > .title" }
10
+ let(:within) { "#books" }
11
+ let(:collection) { false }
77
12
 
78
- it "returns the passed path name" do
79
- subject.path.should == to
80
- end
81
- end
13
+ let(:document) { fixture_file("books.html") }
82
14
 
83
- context "options[:within] is passed" do
84
- let(:within) { 'parent' }
85
- let(:to) { 'child' }
86
-
87
- let(:options) { {:within => within, :to => to} }
15
+ let(:options) do
16
+ { :name => name,
17
+ :type => type,
18
+ :to => to,
19
+ :within => within,
20
+ :collection => collection }
21
+ end
88
22
 
89
- before(:each) do
90
- subject.stub(:options).and_return(options)
91
- end
23
+ its(:absolute_path) { should eql("#books > .book > .title") }
24
+ its(:relative_path) { should eql(".book > .title") }
92
25
 
93
- it "returns the css selector with parent and child" do
94
- subject.path.should == "#{within} > #{to}"
95
- end
96
- end
26
+ describe "#coerce" do
27
+ it "coerces to the set type" do
28
+ subject.coerce(1).should be_a(String)
97
29
  end
30
+ end
98
31
 
99
- describe "#collection?" do
100
- context "options[:collection] is nil" do
101
- it "returns false" do
102
- subject.collection?.should be_false
103
- end
104
- end
105
-
106
- context "options[:collection] is false" do
107
-
108
- let(:options) { {:collection => false} }
109
-
110
- before(:each) do
111
- subject.stub(:options).and_return(options)
112
- end
113
-
114
- it "returns false" do
115
- subject.collection?.should be_false
116
- end
117
- end
118
-
119
- context "options[:collection] is true" do
120
-
121
- let(:options) { {:collection => true} }
122
-
123
- before(:each) do
124
- subject.stub(:options).and_return(options)
125
- end
126
-
127
- it "returns true" do
128
- subject.collection?.should be_true
129
- end
130
- end
32
+ describe "#parse" do
33
+ context "when collection is false" do
34
+ it { subject.parse(document).should eql("War and Peace (Vintage Classics)") }
131
35
  end
132
36
 
133
- describe "#primitive?" do
134
- end
135
-
136
- describe "#typecast" do
137
-
138
- before(:each) do
139
- node.stub(:try).with(:text).and_return(value)
140
-
141
- subject.stub(:options).and_return(options)
142
- end
143
-
144
- context "#primitive? returns true" do
145
-
146
- before(:each) do
147
- subject.stub(:primitive?).and_return(true)
148
- end
149
-
150
- context "options[:type] = String" do
151
- let(:options) { {:type => String} }
152
-
153
- it "returns an instance of String" do
154
- subject.typecast(node).should be_a(String)
155
- end
156
- end
157
-
158
- context "options[:type] = Float" do
159
- let(:options) { {:type => Float} }
160
- let(:value) { '10.01' }
161
-
162
- it "returns an instance of Float" do
163
- subject.typecast(node).should be_a(Float)
164
- end
165
- end
166
-
167
- context "options[:type] = Time" do
168
- let(:options) { {:type => Time} }
169
-
170
- let(:value) { '00:00:00 -0700' }
171
-
172
- it "returns an instance of Time" do
173
- subject.typecast(node).should be_a(Time)
174
- end
175
- end
176
-
177
- context "options[:type] = Date" do
178
- let(:options) { {:type => Date} }
179
-
180
- let(:value) { '2011-01-01' }
181
-
182
- it "returns an instance of Date" do
183
- subject.typecast(node).should be_a(Date)
184
- end
185
- end
186
-
187
- context "options[:type] = DateTime" do
188
- let(:options) { {:type => DateTime} }
189
-
190
- let(:value) { '2011-01-01 00:00:00 -0700' }
191
-
192
- it "returns an instance of DateTime" do
193
- subject.typecast(node).should be_a(DateTime)
194
- end
195
- end
196
-
197
- context "options[:type] = Integer" do
198
- let(:options) { {:type => Integer} }
199
-
200
- let(:value) { '12908234' }
201
-
202
- it "returns an instance of Integer" do
203
- subject.typecast(node).should be_a(Integer)
204
- end
205
- end
206
-
207
- context "options[:type] = Boolean" do
208
- let(:options) { {:type => Boolean} }
209
-
210
- context "value = 't'" do
211
-
212
- let(:value) { 't' }
213
-
214
- it "returns true" do
215
- subject.typecast(node).should be_true
216
- end
217
- end
218
-
219
- context "value = 'true'" do
220
-
221
- let(:value) { 'true' }
222
-
223
- it "returns true" do
224
- subject.typecast(node).should be_true
225
- end
226
- end
227
-
228
- context "value = '1'" do
229
-
230
- let(:value) { '1' }
231
-
232
- it "returns true" do
233
- subject.typecast(node).should be_true
234
- end
235
- end
236
-
237
- context "value = '0'" do
238
-
239
- let(:value) { '0' }
240
-
241
- it "returns false" do
242
- subject.typecast(node).should be_false
243
- end
244
- end
245
-
246
- context "value = 'false'" do
247
-
248
- let(:value) { 'false' }
249
-
250
- it "returns false" do
251
- subject.typecast(node).should be_false
252
- end
253
- end
254
-
255
- context "value = 'f'" do
256
-
257
- let(:value) { 'f' }
258
-
259
- it "returns false" do
260
- subject.typecast(node).should be_false
261
- end
262
- end
263
- end
264
- end
265
-
266
- context "#primitive? returns false" do
267
- let(:options) { {:type => Book} }
268
-
269
- before(:each) do
270
- subject.stub(:primitive?).and_return(false)
271
- end
272
-
273
- it "attempts to parse the nested set" do
274
- Book.should_receive(:parse).with(node)
275
- subject.typecast(node)
276
- end
277
- end
37
+ context "when collection is true" do
38
+ let(:collection) { true }
39
+ it { subject.parse(document).should eql([ "War and Peace (Vintage Classics)", "Anna Karenina (Oprah's Book Club)" ])}
278
40
  end
279
41
  end
280
- end
42
+
43
+ end
data/spec/muffins_spec.rb CHANGED
@@ -2,127 +2,67 @@ require 'spec_helper'
2
2
 
3
3
  describe Muffins do
4
4
 
5
- context "when included in a class" do
5
+ class Book
6
+ include Muffins
6
7
 
7
- subject do
8
- class Book
9
- include Muffins
10
- end
11
- end
12
-
13
- let(:book) { mock(Book) }
14
-
15
- let(:mapping) { mock(Muffins::Mapping) }
16
- let(:mapping_name) { :foo }
17
- let(:mapping_options) { {} }
18
-
19
-
20
- describe ".mappings" do
21
- it "returns an array" do
22
- subject.mappings.should be_an(Array)
23
- end
24
- end
25
-
26
- describe ".base_path" do
27
- context "value is passed" do
28
- it "sets @base_path to the passed value" do
29
- subject.base_path('book')
30
- subject.instance_variable_get(:@base_path).should == 'book'
31
- end
32
- end
8
+ path ".book"
9
+ end
33
10
 
34
- context "no value is passed" do
35
- it "returns the value of @base_path" do
36
- subject.instance_variable_set(:@base_path, 'book')
37
- subject.base_path.should == 'book'
38
- end
39
- end
40
- end
11
+ subject { Book }
41
12
 
42
- describe ".parse" do
43
- let(:document) { mock(Nokogiri::XML::Document) }
44
- let(:node) { mock(Nokogiri::XML::Node) }
13
+ let(:book) { Book.new }
45
14
 
46
- let(:nodes) { [node] }
15
+ let(:name) { :foo }
16
+ let(:type) { String }
47
17
 
48
- let(:base_path) { 'book' }
49
- let(:mappings) { [mapping] }
18
+ let(:mapping) { mock(Muffins::Mapping) }
19
+ let(:mappings) { [] }
50
20
 
51
- let(:mapping_value) { 'bar' }
21
+ describe ".parse" do
52
22
 
53
- before(:each) do
54
- subject.stub(:base_path).and_return(base_path)
55
- subject.stub(:new).and_return(book)
56
- subject.stub(:mappings).and_return(mappings)
23
+ let(:document) { fixture_file("books.html") }
57
24
 
58
- book.stub("#{mapping_name}=")
25
+ it "parses a document based on the path" do
26
+ subject.parse(document).count.should == 2
27
+ end
59
28
 
60
- document.stub(:css).with(base_path).and_return(nodes)
29
+ end
61
30
 
62
- mapping.stub(:name).and_return(mapping_name)
63
- mapping.stub(:map).with(node).and_return(mapping_value)
31
+ describe ".within" do
32
+ it "yields an instance of MappingParent" do
33
+ subject.within(name) do |parent|
34
+ parent.should be_a(Muffins::MappingParent)
64
35
  end
36
+ end
37
+ end
65
38
 
66
- it "sets klass#method_name to the mapped node value" do
67
- book.should_receive("#{mapping_name}=").with(mapping_value)
68
- subject.parse(document)
69
- end
39
+ describe ".map" do
70
40
 
71
- it "returns an array of klasses" do
72
- subject.parse(document).should == [book]
73
- end
41
+ before do
42
+ Muffins::Mapping.stub(:new).and_return(mapping)
43
+ subject.stub(:mappings).and_return(mappings)
74
44
  end
75
45
 
76
- describe ".within" do
77
- it "yields an instance of Muffins::MappingDecorator" do
78
- subject.within :foo do |foo|
79
- foo.should be_a(Muffins::MappingDecorator)
80
- end
81
- end
46
+ it "initializes a new Mapping" do
47
+ Muffins::Mapping.should_receive(:new).with(:name => name, :type => type)
48
+ subject.map(name, type)
82
49
  end
83
50
 
84
- describe ".map" do
85
-
86
- let(:mappings) { [] }
87
-
88
- before(:each) do
89
- Muffins::Mapping.stub(:new)
90
- .with(mapping_name, mapping_options)
91
- .and_return(mapping)
92
-
93
-
94
- book.stub(:respond_to?).with(mapping_name)
95
- subject.stub(:new).and_return(book)
96
-
97
- subject.stub(:mappings).and_return(mappings)
98
- end
99
-
100
- it "adds a new instance of Muffins::Mapping to .mappings" do
101
- mappings.should_receive(:<<).with(mapping)
102
- subject.map mapping_name, mapping_options
103
- end
104
-
105
- context "the mapping name is not a defined method" do
106
- before(:each) do
107
- book.stub(:respond_to?).with(mapping_name).and_return(false)
108
- end
109
-
110
- it "defines an attr_accessor for the mapping name" do
111
- subject.should_receive(:attr_accessor).with(mapping_name)
112
- subject.map mapping_name
113
- end
114
- end
51
+ it "adds a mapping to the list of mappings" do
52
+ mappings.should_receive(:<<).with(mapping)
53
+ subject.map(name, type)
54
+ end
115
55
 
116
- context "the mapping name is already a defined method" do
117
- before(:each) do
118
- book.stub(:respond_to?).with(mapping_name).and_return(true)
119
- end
56
+ it "creates a getter method for :foo" do
57
+ subject.map(name, type)
58
+ book.should respond_to(name)
59
+ end
120
60
 
121
- it "does not overwrite the existing method" do
122
- subject.should_not_receive(:attr_accessor).with(mapping_name)
123
- subject.map mapping_name
124
- end
125
- end
61
+ it "creates a setter method for :foo" do
62
+ subject.map(name, type)
63
+ book.should respond_to("#{name}=")
126
64
  end
65
+
127
66
  end
128
- end
67
+
68
+ end