representative 0.2.5 → 0.3.0

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.
@@ -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