representative 0.2.5 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -53,6 +53,38 @@ describe Representative::Json do
53
53
  end
54
54
 
55
55
  end
56
+
57
+ describe "with attributes" do
58
+
59
+ describe "and a block" do
60
+
61
+ it "generates labelled fields for the attributes" do
62
+ @book = OpenStruct.new(:lang => "fr", :title => "En Edge")
63
+ r.element :book, @book, :lang => :lang do
64
+ r.element :title
65
+ end
66
+ resulting_json.should == undent(<<-JSON)
67
+ {
68
+ "@lang": "fr",
69
+ "title": "En Edge"
70
+ }
71
+ JSON
72
+ end
73
+
74
+ end
75
+
76
+ describe "and an explicit value" do
77
+
78
+ it "ignores the attributes" do
79
+ r.element :review, "Blah de blah", :lang => "fr"
80
+ resulting_json.should == undent(<<-JSON)
81
+ "Blah de blah"
82
+ JSON
83
+ end
84
+
85
+ end
86
+
87
+ end
56
88
 
57
89
  describe "without an explicit value" do
58
90
 
@@ -199,6 +231,23 @@ describe Representative::Json do
199
231
 
200
232
  end
201
233
 
234
+ describe "#attribute" do
235
+
236
+ it "generates labelled values, with a label prefix" do
237
+ r.element :author, Object.new do
238
+ r.attribute :href, "http://example.com/authors/1"
239
+ r.element :name, "Fred"
240
+ end
241
+ resulting_json.should == undent(<<-JSON)
242
+ {
243
+ "@href": "http://example.com/authors/1",
244
+ "name": "Fred"
245
+ }
246
+ JSON
247
+ end
248
+
249
+ end
250
+
202
251
  describe "#comment" do
203
252
 
204
253
  it "inserts a comment" do
@@ -0,0 +1,74 @@
1
+ require 'spec_helper'
2
+
3
+ require "nokogiri"
4
+ require "representative/nokogiri"
5
+ require "representative/xml_behaviour"
6
+
7
+ describe Representative::Nokogiri do
8
+
9
+ def r
10
+ @representative ||= Representative::Nokogiri.new(@subject)
11
+ end
12
+
13
+ def resulting_xml
14
+ r.to_xml(:save_with => Nokogiri::XML::Node::SaveOptions::NO_DECLARATION).rstrip
15
+ end
16
+
17
+ it_should_behave_like "an XML Representative"
18
+
19
+ describe "for some 'subject'" do
20
+
21
+ before do
22
+ @subject = OpenStruct.new(:name => "Fred", :width => 200, :vehicle => OpenStruct.new(:year => "1959", :make => "Chevrolet"))
23
+ end
24
+
25
+ describe "#attribute" do
26
+
27
+ describe "without a value argument" do
28
+ it "extracts the named field of the subject" do
29
+ r.element :person, @subject do
30
+ r.attribute :name
31
+ end
32
+ resulting_xml.should == %(<person name="Fred"/>)
33
+ end
34
+ end
35
+
36
+ describe "with an explicit value" do
37
+ it "attaches an attribute to the current element" do
38
+ r.element :person, @subject do
39
+ r.attribute :lang, "fr"
40
+ end
41
+ resulting_xml.should == %(<person lang="fr"/>)
42
+ end
43
+ end
44
+
45
+ describe "with a value that supports #to_proc" do
46
+ it "calls the Proc on the subject to generate attribute value" do
47
+ r.element :person, @subject do
48
+ r.attribute :name, lambda { |person| person.name.reverse }
49
+ end
50
+ resulting_xml.should == %(<person name="derF"/>)
51
+ end
52
+ end
53
+
54
+ it "dasherizes the attribute name" do
55
+ r.element :name do
56
+ r.attribute :sourced_from, "phonebook"
57
+ end
58
+ resulting_xml.should == %(<name sourced-from="phonebook"/>)
59
+ end
60
+
61
+ describe "with value nil" do
62
+ it "omits the attribute" do
63
+ r.element :person, @subject do
64
+ r.attribute :name, nil
65
+ end
66
+ resulting_xml.should == %(<person/>)
67
+ end
68
+ end
69
+
70
+ end
71
+
72
+ end
73
+
74
+ end
@@ -0,0 +1,136 @@
1
+ require 'spec_helper'
2
+
3
+ require "ostruct"
4
+ require "representative/tilt_integration"
5
+
6
+ describe Representative::Tilt do
7
+
8
+ def with_template(file_name, content)
9
+ @template = Tilt.new(file_name, 1) { content }
10
+ end
11
+
12
+ def render(*args, &block)
13
+ @output = @template.render(*args, &block)
14
+ end
15
+
16
+ describe "XML template" do
17
+
18
+ def resulting_xml
19
+ @output.sub(/^<\?xml.*\n/, '')
20
+ end
21
+
22
+ describe "#render" do
23
+
24
+ it "generates XML" do
25
+ with_template("whatever.xml.rep", <<-RUBY)
26
+ r.element :foo, "bar"
27
+ RUBY
28
+ render
29
+ resulting_xml.should == %{<foo>bar</foo>\n}
30
+ end
31
+
32
+ it "provides access to scope" do
33
+
34
+ with_template("whatever.xml.rep", <<-RUBY)
35
+ r.element :author, @mike do
36
+ r.element :name
37
+ end
38
+ RUBY
39
+
40
+ scope = Object.new
41
+ scope.instance_eval do
42
+ @mike = OpenStruct.new(:name => "Mike")
43
+ end
44
+ render(scope)
45
+
46
+ resulting_xml.should == undent(<<-XML)
47
+ <author>
48
+ <name>Mike</name>
49
+ </author>
50
+ XML
51
+
52
+ end
53
+
54
+ it "provides access to local variables" do
55
+
56
+ with_template("whatever.xml.rep", <<-RUBY)
57
+ r.element :author, author do
58
+ r.element :name
59
+ end
60
+ RUBY
61
+
62
+ render(Object.new, {:author => OpenStruct.new(:name => "Mike")})
63
+
64
+ resulting_xml.should == undent(<<-XML)
65
+ <author>
66
+ <name>Mike</name>
67
+ </author>
68
+ XML
69
+
70
+ end
71
+
72
+ end
73
+
74
+ end
75
+
76
+ describe "JSON template" do
77
+
78
+ def resulting_json
79
+ @output.sub(/^<\?xml.*\n/, '')
80
+ end
81
+
82
+ describe "#render" do
83
+
84
+ it "generates JSON" do
85
+ with_template("whatever.json.rep", <<-RUBY)
86
+ r.element :foo, "bar"
87
+ RUBY
88
+ render
89
+ resulting_json.should == %{"bar"\n}
90
+ end
91
+
92
+ it "provides access to scope" do
93
+
94
+ with_template("whatever.json.rep", <<-RUBY)
95
+ r.element :author, @mike do
96
+ r.element :name
97
+ end
98
+ RUBY
99
+
100
+ scope = Object.new
101
+ scope.instance_eval do
102
+ @mike = OpenStruct.new(:name => "Mike")
103
+ end
104
+ render(scope)
105
+
106
+ resulting_json.should == undent(<<-JSON)
107
+ {
108
+ "name": "Mike"
109
+ }
110
+ JSON
111
+
112
+ end
113
+
114
+ it "provides access to local variables" do
115
+
116
+ with_template("whatever.json.rep", <<-RUBY)
117
+ r.element :author, author do
118
+ r.element :name
119
+ end
120
+ RUBY
121
+
122
+ render(Object.new, {:author => OpenStruct.new(:name => "Mike")})
123
+
124
+ resulting_json.should == undent(<<-JSON)
125
+ {
126
+ "name": "Mike"
127
+ }
128
+ JSON
129
+
130
+ end
131
+
132
+ end
133
+
134
+ end
135
+
136
+ end
@@ -0,0 +1,270 @@
1
+ require 'spec_helper'
2
+
3
+ require "rexml/document"
4
+
5
+ shared_examples_for "an XML Representative" do
6
+
7
+ describe "for some 'subject'" do
8
+
9
+ before do
10
+ @subject = OpenStruct.new(:name => "Fred", :width => 200, :vehicle => OpenStruct.new(:year => "1959", :make => "Chevrolet"))
11
+ end
12
+
13
+ describe "#element" do
14
+
15
+ it "generates an element with content extracted from the subject" do
16
+ r.element :name
17
+ resulting_xml.should == %(<name>Fred</name>)
18
+ end
19
+
20
+ it "dasherizes the property name" do
21
+ @subject.full_name = "Fredrick"
22
+ r.element :full_name
23
+ resulting_xml.should == %(<full-name>Fredrick</full-name>)
24
+ end
25
+
26
+ describe "with attributes" do
27
+
28
+ it "generates attributes on the element" do
29
+ r.element :name, :lang => "fr"
30
+ resulting_xml.should == %(<name lang="fr">Fred</name>)
31
+ end
32
+
33
+ it "dasherizes the attribute name" do
34
+ r.element :name, :sourced_from => "phonebook"
35
+ resulting_xml.should == %(<name sourced-from="phonebook">Fred</name>)
36
+ end
37
+
38
+ describe "whose value supports #to_proc" do
39
+
40
+ it "calls the Proc on the subject to generate a value" do
41
+ r.element :name, :rev => :reverse
42
+ resulting_xml.should == %(<name rev="derF">Fred</name>)
43
+ end
44
+
45
+ end
46
+
47
+ describe "with value nil" do
48
+
49
+ it "omits the attribute" do
50
+ r.element :name, :lang => nil
51
+ resulting_xml.should == %(<name>Fred</name>)
52
+ end
53
+
54
+ end
55
+
56
+ end
57
+
58
+ describe "with an explicit value" do
59
+
60
+ it "generates an element with explicitly provided content" do
61
+ r.element :name, "Bloggs"
62
+ resulting_xml.should == %(<name>Bloggs</name>)
63
+ end
64
+
65
+ describe "AND attributes" do
66
+
67
+ it "generates attributes on the element" do
68
+ r.element :name, "Bloggs", :lang => "fr"
69
+ resulting_xml.should == %(<name lang="fr">Bloggs</name>)
70
+ end
71
+
72
+ end
73
+
74
+ end
75
+
76
+ describe "with a value argument that supports #to_proc" do
77
+
78
+ it "calls the Proc on the subject to generate a value" do
79
+ r.element :name, :width
80
+ resulting_xml.should == %(<name>200</name>)
81
+ end
82
+
83
+ end
84
+
85
+ describe "with value argument :self" do
86
+
87
+ it "doesn't alter the subject" do
88
+ r.element :info, :self do
89
+ r.element :name
90
+ end
91
+ resulting_xml.should == %(<info><name>Fred</name></info>)
92
+ end
93
+
94
+ end
95
+
96
+ describe "with value argument nil" do
97
+
98
+ it "builds an empty element" do
99
+ r.element :name, nil
100
+ resulting_xml.should == %(<name/>)
101
+ end
102
+
103
+ describe "and attributes" do
104
+
105
+ it "omits attributes derived from the subject" do
106
+ r.element :name, nil, :size => :size
107
+ resulting_xml.should == %(<name/>)
108
+ end
109
+
110
+ it "retains attributes with explicit values" do
111
+ r.element :name, nil, :lang => "en"
112
+ resulting_xml.should == %(<name lang="en"/>)
113
+ end
114
+
115
+ end
116
+
117
+ describe "and a block" do
118
+
119
+ it "doesn't call the block" do
120
+ r.element :name, nil do
121
+ raise "hell"
122
+ end
123
+ resulting_xml.should == %(<name/>)
124
+ end
125
+
126
+ end
127
+
128
+ end
129
+
130
+ describe "with a block" do
131
+
132
+ it "generates nested elements" do
133
+ r.element :vehicle do
134
+ r.element :year
135
+ r.element :make
136
+ end
137
+ resulting_xml.should == %(<vehicle><year>1959</year><make>Chevrolet</make></vehicle>)
138
+ end
139
+
140
+ it "yields each new subject" do
141
+ r.element :vehicle do |vehicle|
142
+ r.element :year, vehicle.year
143
+ end
144
+ resulting_xml.should == %(<vehicle><year>1959</year></vehicle>)
145
+ end
146
+
147
+ end
148
+
149
+ describe "with an EMPTY block" do
150
+
151
+ it "generates an empty element" do
152
+ r.element :vehicle, :year => :year, &r.empty
153
+ resulting_xml.should == %(<vehicle year="1959"/>)
154
+ end
155
+
156
+ end
157
+
158
+ end
159
+
160
+ describe "#list_of" do
161
+
162
+ before do
163
+ @subject.nick_names = ["Freddie", "Knucklenose"]
164
+ end
165
+
166
+ it "generates an array element" do
167
+ r.list_of(:nick_names)
168
+ resulting_xml.should == %(<nick-names type="array"><nick-name>Freddie</nick-name><nick-name>Knucklenose</nick-name></nick-names>)
169
+ end
170
+
171
+ describe "with :list_attributes" do
172
+
173
+ it "attaches attributes to the array element" do
174
+ r.list_of(:nick_names, :list_attributes => {:color => "blue", :size => :size})
175
+ array_element_attributes = REXML::Document.new(resulting_xml).root.attributes
176
+ array_element_attributes["type"].should == "array"
177
+ array_element_attributes["color"].should == "blue"
178
+ array_element_attributes["size"].should == "2"
179
+ array_element_attributes.size.should == 3
180
+ end
181
+
182
+ end
183
+
184
+ describe "with :item_attributes" do
185
+
186
+ it "attaches attributes to each item element" do
187
+ r.list_of(:nick_names, :item_attributes => {:length => :size})
188
+ resulting_xml.should == %(<nick-names type="array"><nick-name length="7">Freddie</nick-name><nick-name length="11">Knucklenose</nick-name></nick-names>)
189
+ end
190
+
191
+ end
192
+
193
+ describe "with an explicit :item_name" do
194
+ it "uses the name provided" do
195
+ r.list_of(:nick_names, :item_name => :nick)
196
+ resulting_xml.should == %(<nick-names type="array"><nick>Freddie</nick><nick>Knucklenose</nick></nick-names>)
197
+ end
198
+ end
199
+
200
+ describe "with an argument that resolves to nil" do
201
+
202
+ it "omits the attribute" do
203
+ r.list_of(:services) do
204
+ r.date
205
+ end
206
+ resulting_xml.should == %(<services/>)
207
+ end
208
+
209
+ end
210
+
211
+ describe "with a block" do
212
+
213
+ it "generates a nested element for each list element" do
214
+ r.list_of(:nick_names) do
215
+ r.element :length
216
+ end
217
+ resulting_xml.should == %(<nick-names type="array"><nick-name><length>7</length></nick-name><nick-name><length>11</length></nick-name></nick-names>)
218
+ end
219
+
220
+ end
221
+
222
+ describe "with an EMPTY block" do
223
+
224
+ it "generates empty elements for each list element" do
225
+ r.list_of(:nick_names, :item_attributes => {:value => :to_s}, &r.empty)
226
+ resulting_xml.should == %(<nick-names type="array"><nick-name value="Freddie"/><nick-name value="Knucklenose"/></nick-names>)
227
+ end
228
+
229
+ end
230
+
231
+ describe "with :item_attributes AND block" do
232
+
233
+ it "generates attributes and nested elements" do
234
+ r.list_of(:nick_names, :item_attributes => {:length => :size}) do
235
+ r.element :reverse
236
+ end
237
+ resulting_xml.should == %(<nick-names type="array"><nick-name length="7"><reverse>eidderF</reverse></nick-name><nick-name length="11"><reverse>esonelkcunK</reverse></nick-name></nick-names>)
238
+ end
239
+
240
+ end
241
+
242
+ end
243
+
244
+ describe "#representing" do
245
+
246
+ it "selects a new subject without generating an element" do
247
+ r.representing :vehicle do
248
+ r.element :make
249
+ end
250
+ resulting_xml.should == %(<make>Chevrolet</make>)
251
+ end
252
+
253
+ end
254
+
255
+ describe "#comment" do
256
+
257
+ it "inserts a comment" do
258
+ r.element :vehicle do
259
+ r.comment "Year of manufacture"
260
+ r.element :year
261
+ end
262
+ resulting_xml.should ==
263
+ %(<vehicle><!-- Year of manufacture --><year>1959</year></vehicle>)
264
+ end
265
+
266
+ end
267
+
268
+ end
269
+
270
+ end