representative 0.3.6 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.markdown CHANGED
@@ -11,23 +11,23 @@ Generating XML
11
11
  Given a Ruby data-structure:
12
12
 
13
13
  @books = [
14
- OpenStruct.new(
14
+ Book.new(
15
15
  :title => "Sailing for old dogs",
16
16
  :authors => ["Jim Watson"],
17
- :published => OpenStruct.new(
17
+ :published => Publication.new(
18
18
  :by => "Credulous Print",
19
19
  :year => 1994
20
20
  )
21
21
  ),
22
- OpenStruct.new(
22
+ Book.new(
23
23
  :title => "On the horizon",
24
24
  :authors => ["Zoe Primpton", "Stan Ford"],
25
- :published => OpenStruct.new(
25
+ :published => Publication.new(
26
26
  :by => "McGraw-Hill",
27
27
  :year => 2005
28
28
  )
29
29
  ),
30
- OpenStruct.new(
30
+ Book.new(
31
31
  :title => "The Little Blue Book of VHS Programming",
32
32
  :authors => ["Henry Nelson"],
33
33
  :rating => "****"
@@ -152,7 +152,35 @@ Representative is packaged as a Gem. Install with:
152
152
 
153
153
  gem install representative
154
154
 
155
+ Ruby on Rails integration
156
+ -------------------------
157
+
158
+ A separate gem, [RepresentativeView](https://github.com/mdub/representative_view), integrates Representative as an ActionPack template format.
159
+
160
+ Tilt integration
161
+ ----------------
162
+
163
+ Representative includes integration with [Tilt](https://github.com/rtomayko/tilt), which can be enabled with:
164
+
165
+ require "representative/tilt_integration"
166
+
167
+ This registers handlers for "`.xml.rep`" and "`.json.rep`" templates.
168
+
155
169
  Copyright
156
170
  ---------
157
171
 
158
172
  Copyright (c) 2009 Mike Williams. See LICENSE for details.
173
+
174
+ Similar projects
175
+ ----------------
176
+
177
+ If Representative is not your cup of tea, you may prefer:
178
+
179
+ * [Tokamak](https://github.com/abril/tokamak)
180
+ * [Builder](http://rubygems.org/gems/builder)
181
+ * [JSONify](https://github.com/bsiggelkow/jsonify)
182
+ * [Argonaut](https://github.com/jbr/argonaut)
183
+ * [JSON Builder](https://github.com/dewski/json_builder)
184
+ * [RABL](https://github.com/nesquena/rabl)
185
+
186
+ Just don't go back to using "`this_thing.to_xml`" and "`that_thing.to_json`", m'kay?
@@ -1,12 +1,10 @@
1
- $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
1
+ #! /usr/bin/env ruby
2
2
 
3
- require "rubygems"
4
- require "representative/nokogiri"
5
3
  require "ostruct"
6
4
 
7
5
  @books = [
8
6
  OpenStruct.new(
9
- :title => "Sailing for old dogs",
7
+ :title => "Sailing for old dogs",
10
8
  :authors => ["Jim Watson"],
11
9
  :published => OpenStruct.new(
12
10
  :by => "Credulous Print",
@@ -14,7 +12,7 @@ require "ostruct"
14
12
  )
15
13
  ),
16
14
  OpenStruct.new(
17
- :title => "On the horizon",
15
+ :title => "On the horizon",
18
16
  :authors => ["Zoe Primpton", "Stan Ford"],
19
17
  :published => OpenStruct.new(
20
18
  :by => "McGraw-Hill",
@@ -28,8 +26,10 @@ require "ostruct"
28
26
  )
29
27
  ]
30
28
 
31
- xml = Representative::Nokogiri.new do |r|
29
+ require "representative/json"
30
+ require "representative/nokogiri"
32
31
 
32
+ def represent_books(r)
33
33
  r.list_of :books, @books do
34
34
  r.element :title
35
35
  r.list_of :authors
@@ -38,7 +38,14 @@ xml = Representative::Nokogiri.new do |r|
38
38
  r.element :year
39
39
  end
40
40
  end
41
-
42
41
  end
43
42
 
44
- puts xml.to_s
43
+ puts "\n=== JSON ===\n\n"
44
+
45
+ json = Representative::Json.new.tap { |r| represent_books(r) }.to_s
46
+ puts json
47
+
48
+ puts "\n=== XML ===\n\n"
49
+
50
+ xml = Representative::Nokogiri.new.tap { |r| represent_books(r) }.to_s
51
+ puts xml
@@ -3,11 +3,11 @@ require "representative/base"
3
3
  require "multi_json"
4
4
 
5
5
  module Representative
6
-
6
+
7
7
  class Json < Base
8
8
 
9
9
  DEFAULT_ATTRIBUTE_PREFIX = "@".freeze
10
-
10
+
11
11
  def initialize(subject = nil, options = {})
12
12
  super(subject, options)
13
13
  @buffer = ""
@@ -16,19 +16,19 @@ module Representative
16
16
  now_at :beginning_of_buffer
17
17
  yield self if block_given?
18
18
  end
19
-
19
+
20
20
  attr_reader :attribute_prefix
21
-
21
+
22
22
  def element(name, *args, &block)
23
23
 
24
24
  metadata = @inspector.get_metadata(current_subject, name)
25
25
  attributes = args.extract_options!.merge(metadata)
26
26
 
27
- subject_of_element = if args.empty?
27
+ subject_of_element = if args.empty?
28
28
  lambda do |subject|
29
29
  @inspector.get_value(current_subject, name)
30
30
  end
31
- else
31
+ else
32
32
  args.shift
33
33
  end
34
34
 
@@ -36,13 +36,13 @@ module Representative
36
36
 
37
37
  label(name)
38
38
  value(subject_of_element, attributes, &block)
39
-
39
+
40
40
  end
41
41
 
42
42
  def attribute(name, value_generator = name)
43
43
  element(attribute_prefix + name.to_s, value_generator)
44
44
  end
45
-
45
+
46
46
  def list_of(name, *args, &block)
47
47
  options = args.extract_options!
48
48
  list_subject = args.empty? ? name : args.shift
@@ -60,7 +60,7 @@ module Representative
60
60
  end
61
61
  end
62
62
  end
63
-
63
+
64
64
  def value(subject, attributes = {})
65
65
  representing(subject) do
66
66
  if block_given? && !current_subject.nil?
@@ -76,23 +76,23 @@ module Representative
76
76
  end
77
77
  now_at :end_of_item
78
78
  end
79
-
79
+
80
80
  def comment(text)
81
81
  new_item
82
- emit("// #{text}")
82
+ emit("// " + text)
83
83
  now_at :end_of_comment
84
84
  end
85
85
 
86
86
  def to_json
87
87
  @buffer + "\n"
88
88
  end
89
-
89
+
90
90
  def to_s
91
91
  to_json
92
92
  end
93
93
 
94
94
  private
95
-
95
+
96
96
  def emit(s)
97
97
  @buffer << s
98
98
  end
@@ -100,7 +100,7 @@ module Representative
100
100
  def encode(data)
101
101
  MultiJson.encode(data)
102
102
  end
103
-
103
+
104
104
  def indentation
105
105
  (" " * @indent_level)
106
106
  end
@@ -108,7 +108,7 @@ module Representative
108
108
  def label(name)
109
109
  return false if @indent_level == 0
110
110
  new_item
111
- emit("#{encode(format_name(name))}: ")
111
+ emit(encode(format_name(name)) + ": ")
112
112
  end
113
113
 
114
114
  def new_item
@@ -117,14 +117,14 @@ module Representative
117
117
  emit(indentation)
118
118
  @pending_comma = ","
119
119
  end
120
-
120
+
121
121
  def inside(opening_char, closing_char)
122
122
  emit(opening_char)
123
123
  @indent_level += 1
124
124
  now_at :beginning_of_block
125
125
  yield
126
126
  @indent_level -= 1
127
- emit("\n#{indentation}") unless at? :beginning_of_block
127
+ emit("\n" + indentation) unless at? :beginning_of_block
128
128
  emit(closing_char)
129
129
  now_at :end_of_item
130
130
  end
@@ -136,9 +136,9 @@ module Representative
136
136
  def at?(state)
137
137
  @state == state
138
138
  end
139
-
139
+
140
140
  end
141
-
141
+
142
142
  JSON = Json
143
-
143
+
144
144
  end
@@ -1,3 +1,3 @@
1
1
  module Representative
2
- VERSION = "0.3.6".freeze
2
+ VERSION = "1.0.0".freeze
3
3
  end
@@ -8,15 +8,15 @@ shared_examples_for "an XML Representative" do
8
8
 
9
9
  before do
10
10
  @subject = OpenStruct.new(
11
- :name => "Fred",
12
- :full_name => "Fredrick",
13
- :width => 200,
11
+ :name => "Fred",
12
+ :full_name => "Fredrick",
13
+ :width => 200,
14
14
  :vehicle => OpenStruct.new(:year => "1959", :make => "Chevrolet")
15
15
  )
16
16
  end
17
17
 
18
18
  describe "#element" do
19
-
19
+
20
20
  it "generates an element with content extracted from the subject" do
21
21
  r.element :name
22
22
  resulting_xml.should == %(<name>Fred</name>)
@@ -77,7 +77,7 @@ shared_examples_for "an XML Representative" do
77
77
 
78
78
  end
79
79
 
80
- describe "with a Symbol argument" do
80
+ describe "with a Symbol value argument" do
81
81
 
82
82
  it "calls the named method to generate a value" do
83
83
  r.element :name, :width
@@ -103,7 +103,7 @@ shared_examples_for "an XML Representative" do
103
103
  end
104
104
  resulting_xml.should == %(<info><name>Fred</name></info>)
105
105
  end
106
-
106
+
107
107
  end
108
108
 
109
109
  describe "with value argument nil" do
@@ -169,7 +169,7 @@ shared_examples_for "an XML Representative" do
169
169
  end
170
170
 
171
171
  end
172
-
172
+
173
173
  describe "#list_of" do
174
174
 
175
175
  before do
@@ -181,8 +181,22 @@ shared_examples_for "an XML Representative" do
181
181
  resulting_xml.should == %(<nick-names type="array"><nick-name>Freddie</nick-name><nick-name>Knucklenose</nick-name></nick-names>)
182
182
  end
183
183
 
184
+ describe "with a Symbol value argument" do
185
+
186
+ it "calls the named method to generate a value" do
187
+ r.list_of(:foo_bars, :nick_names)
188
+ resulting_xml.should == %(<foo-bars type="array"><foo-bar>Freddie</foo-bar><foo-bar>Knucklenose</foo-bar></foo-bars>)
189
+ end
190
+
191
+ end
192
+
193
+ it "generates an array element" do
194
+ r.list_of(:nick_names)
195
+ resulting_xml.should == %(<nick-names type="array"><nick-name>Freddie</nick-name><nick-name>Knucklenose</nick-name></nick-names>)
196
+ end
197
+
184
198
  describe "with :list_attributes" do
185
-
199
+
186
200
  it "attaches attributes to the array element" do
187
201
  r.list_of(:nick_names, :list_attributes => {:color => "blue", :size => :size})
188
202
  array_element_attributes = REXML::Document.new(resulting_xml).root.attributes
@@ -191,7 +205,7 @@ shared_examples_for "an XML Representative" do
191
205
  array_element_attributes["size"].should == "2"
192
206
  array_element_attributes.size.should == 3
193
207
  end
194
-
208
+
195
209
  end
196
210
 
197
211
  describe "with :item_attributes" do
@@ -200,7 +214,7 @@ shared_examples_for "an XML Representative" do
200
214
  r.list_of(:nick_names, :item_attributes => {:length => :size})
201
215
  resulting_xml.should == %(<nick-names type="array"><nick-name length="7">Freddie</nick-name><nick-name length="11">Knucklenose</nick-name></nick-names>)
202
216
  end
203
-
217
+
204
218
  end
205
219
 
206
220
  describe "with an explicit :item_name" do
@@ -238,41 +252,41 @@ shared_examples_for "an XML Representative" do
238
252
  r.list_of(:nick_names, :item_attributes => {:value => :to_s}, &r.empty)
239
253
  resulting_xml.should == %(<nick-names type="array"><nick-name value="Freddie"/><nick-name value="Knucklenose"/></nick-names>)
240
254
  end
241
-
255
+
242
256
  end
243
-
257
+
244
258
  describe "with :item_attributes AND block" do
245
-
259
+
246
260
  it "generates attributes and nested elements" do
247
261
  r.list_of(:nick_names, :item_attributes => {:length => :size}) do
248
262
  r.element :reverse
249
263
  end
250
264
  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>)
251
265
  end
252
-
266
+
253
267
  end
254
268
 
255
269
  end
256
270
 
257
271
  describe "#representing" do
258
-
272
+
259
273
  it "selects a new subject without generating an element" do
260
274
  r.representing :vehicle do
261
275
  r.element :make
262
276
  end
263
277
  resulting_xml.should == %(<make>Chevrolet</make>)
264
278
  end
265
-
279
+
266
280
  end
267
281
 
268
282
  describe "#comment" do
269
-
283
+
270
284
  it "inserts a comment" do
271
285
  r.element :vehicle do
272
286
  r.comment "Year of manufacture"
273
287
  r.element :year
274
288
  end
275
- resulting_xml.should ==
289
+ resulting_xml.should ==
276
290
  %(<vehicle><!-- Year of manufacture --><year>1959</year></vehicle>)
277
291
  end
278
292
 
metadata CHANGED
@@ -1,125 +1,121 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: representative
3
- version: !ruby/object:Gem::Version
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
4
5
  prerelease:
5
- version: 0.3.6
6
6
  platform: ruby
7
- authors:
7
+ authors:
8
8
  - Mike Williams
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
-
13
- date: 2011-06-11 00:00:00 Z
14
- dependencies:
15
- - !ruby/object:Gem::Dependency
12
+ date: 2011-09-06 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
16
15
  name: activesupport
17
- requirement: &id001 !ruby/object:Gem::Requirement
16
+ requirement: &70241309663160 !ruby/object:Gem::Requirement
18
17
  none: false
19
- requirements:
20
- - - ">="
21
- - !ruby/object:Gem::Version
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
22
21
  version: 2.2.2
23
22
  type: :runtime
24
23
  prerelease: false
25
- version_requirements: *id001
26
- - !ruby/object:Gem::Dependency
24
+ version_requirements: *70241309663160
25
+ - !ruby/object:Gem::Dependency
27
26
  name: i18n
28
- requirement: &id002 !ruby/object:Gem::Requirement
27
+ requirement: &70241309662120 !ruby/object:Gem::Requirement
29
28
  none: false
30
- requirements:
31
- - - ">="
32
- - !ruby/object:Gem::Version
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
33
32
  version: 0.4.1
34
33
  type: :runtime
35
34
  prerelease: false
36
- version_requirements: *id002
37
- - !ruby/object:Gem::Dependency
35
+ version_requirements: *70241309662120
36
+ - !ruby/object:Gem::Dependency
38
37
  name: builder
39
- requirement: &id003 !ruby/object:Gem::Requirement
38
+ requirement: &70241309661380 !ruby/object:Gem::Requirement
40
39
  none: false
41
- requirements:
42
- - - ">="
43
- - !ruby/object:Gem::Version
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
44
43
  version: 2.1.2
45
44
  type: :runtime
46
45
  prerelease: false
47
- version_requirements: *id003
48
- - !ruby/object:Gem::Dependency
46
+ version_requirements: *70241309661380
47
+ - !ruby/object:Gem::Dependency
49
48
  name: multi_json
50
- requirement: &id004 !ruby/object:Gem::Requirement
49
+ requirement: &70241309660480 !ruby/object:Gem::Requirement
51
50
  none: false
52
- requirements:
53
- - - ">="
54
- - !ruby/object:Gem::Version
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
55
54
  version: 0.0.5
56
55
  type: :runtime
57
56
  prerelease: false
58
- version_requirements: *id004
59
- - !ruby/object:Gem::Dependency
57
+ version_requirements: *70241309660480
58
+ - !ruby/object:Gem::Dependency
60
59
  name: rake
61
- requirement: &id005 !ruby/object:Gem::Requirement
60
+ requirement: &70241309659680 !ruby/object:Gem::Requirement
62
61
  none: false
63
- requirements:
62
+ requirements:
64
63
  - - ~>
65
- - !ruby/object:Gem::Version
64
+ - !ruby/object:Gem::Version
66
65
  version: 0.8.7
67
66
  type: :development
68
67
  prerelease: false
69
- version_requirements: *id005
70
- - !ruby/object:Gem::Dependency
68
+ version_requirements: *70241309659680
69
+ - !ruby/object:Gem::Dependency
71
70
  name: rspec
72
- requirement: &id006 !ruby/object:Gem::Requirement
71
+ requirement: &70241309658960 !ruby/object:Gem::Requirement
73
72
  none: false
74
- requirements:
73
+ requirements:
75
74
  - - ~>
76
- - !ruby/object:Gem::Version
75
+ - !ruby/object:Gem::Version
77
76
  version: 2.5.0
78
77
  type: :development
79
78
  prerelease: false
80
- version_requirements: *id006
81
- - !ruby/object:Gem::Dependency
79
+ version_requirements: *70241309658960
80
+ - !ruby/object:Gem::Dependency
82
81
  name: tilt
83
- requirement: &id007 !ruby/object:Gem::Requirement
82
+ requirement: &70241309658220 !ruby/object:Gem::Requirement
84
83
  none: false
85
- requirements:
86
- - - ">="
87
- - !ruby/object:Gem::Version
88
- version: "0.9"
84
+ requirements:
85
+ - - ! '>='
86
+ - !ruby/object:Gem::Version
87
+ version: '0.9'
89
88
  type: :development
90
89
  prerelease: false
91
- version_requirements: *id007
92
- - !ruby/object:Gem::Dependency
90
+ version_requirements: *70241309658220
91
+ - !ruby/object:Gem::Dependency
93
92
  name: nokogiri
94
- requirement: &id008 !ruby/object:Gem::Requirement
93
+ requirement: &70241309657400 !ruby/object:Gem::Requirement
95
94
  none: false
96
- requirements:
95
+ requirements:
97
96
  - - ~>
98
- - !ruby/object:Gem::Version
97
+ - !ruby/object:Gem::Version
99
98
  version: 1.4.2
100
99
  type: :development
101
100
  prerelease: false
102
- version_requirements: *id008
103
- - !ruby/object:Gem::Dependency
101
+ version_requirements: *70241309657400
102
+ - !ruby/object:Gem::Dependency
104
103
  name: diff-lcs
105
- requirement: &id009 !ruby/object:Gem::Requirement
104
+ requirement: &70241309656760 !ruby/object:Gem::Requirement
106
105
  none: false
107
- requirements:
108
- - - ">="
109
- - !ruby/object:Gem::Version
110
- version: "0"
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
111
110
  type: :development
112
111
  prerelease: false
113
- version_requirements: *id009
112
+ version_requirements: *70241309656760
114
113
  description:
115
114
  email: mdub@dogbiscuit.org
116
115
  executables: []
117
-
118
116
  extensions: []
119
-
120
117
  extra_rdoc_files: []
121
-
122
- files:
118
+ files:
123
119
  - lib/representative/abstract_xml.rb
124
120
  - lib/representative/base.rb
125
121
  - lib/representative/empty.rb
@@ -130,8 +126,7 @@ files:
130
126
  - lib/representative/version.rb
131
127
  - lib/representative/xml.rb
132
128
  - lib/representative.rb
133
- - examples/json_demo.rb
134
- - examples/xml_demo.rb
129
+ - examples/books.rb
135
130
  - README.markdown
136
131
  - LICENSE
137
132
  - spec/representative/json_spec.rb
@@ -143,38 +138,35 @@ files:
143
138
  - Rakefile
144
139
  homepage: http://github.com/mdub/representative
145
140
  licenses: []
146
-
147
141
  post_install_message:
148
142
  rdoc_options: []
149
-
150
- require_paths:
143
+ require_paths:
151
144
  - lib
152
- required_ruby_version: !ruby/object:Gem::Requirement
145
+ required_ruby_version: !ruby/object:Gem::Requirement
153
146
  none: false
154
- requirements:
155
- - - ">="
156
- - !ruby/object:Gem::Version
157
- hash: 412267701560150101
158
- segments:
147
+ requirements:
148
+ - - ! '>='
149
+ - !ruby/object:Gem::Version
150
+ version: '0'
151
+ segments:
159
152
  - 0
160
- version: "0"
161
- required_rubygems_version: !ruby/object:Gem::Requirement
153
+ hash: -2883973472066778787
154
+ required_rubygems_version: !ruby/object:Gem::Requirement
162
155
  none: false
163
- requirements:
164
- - - ">="
165
- - !ruby/object:Gem::Version
166
- hash: 412267701560150101
167
- segments:
156
+ requirements:
157
+ - - ! '>='
158
+ - !ruby/object:Gem::Version
159
+ version: '0'
160
+ segments:
168
161
  - 0
169
- version: "0"
162
+ hash: -2883973472066778787
170
163
  requirements: []
171
-
172
164
  rubyforge_project:
173
- rubygems_version: 1.7.2
165
+ rubygems_version: 1.8.10
174
166
  signing_key:
175
167
  specification_version: 3
176
168
  summary: Builds XML and JSON representations of your Ruby objects
177
- test_files:
169
+ test_files:
178
170
  - spec/representative/json_spec.rb
179
171
  - spec/representative/nokogiri_spec.rb
180
172
  - spec/representative/tilt_integration_spec.rb
@@ -1,44 +0,0 @@
1
- $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
-
3
- require "rubygems"
4
- require "representative/json"
5
- require "ostruct"
6
-
7
- @books = [
8
- OpenStruct.new(
9
- :title => "Sailing for old dogs",
10
- :authors => ["Jim Watson"],
11
- :published => OpenStruct.new(
12
- :by => "Credulous Print",
13
- :year => 1994
14
- )
15
- ),
16
- OpenStruct.new(
17
- :title => "On the horizon",
18
- :authors => ["Zoe Primpton", "Stan Ford"],
19
- :published => OpenStruct.new(
20
- :by => "McGraw-Hill",
21
- :year => 2005
22
- )
23
- ),
24
- OpenStruct.new(
25
- :title => "The Little Blue Book of VHS Programming",
26
- :authors => ["Henry Nelson"],
27
- :rating => "****"
28
- )
29
- ]
30
-
31
- json = Representative::Json.new do |r|
32
-
33
- r.list_of :books, @books do
34
- r.element :title
35
- r.list_of :authors
36
- r.element :published do
37
- r.element :by
38
- r.element :year
39
- end
40
- end
41
-
42
- end
43
-
44
- puts json.to_s