muffins 0.0.5 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -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