representative 0.2.3 → 0.2.4
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.
- data/README.markdown +63 -10
- data/Rakefile +2 -0
- data/examples/json_demo.rb +44 -0
- data/examples/xml_demo.rb +5 -2
- data/lib/representative/base.rb +62 -0
- data/lib/representative/json.rb +122 -0
- data/lib/representative/version.rb +1 -1
- data/lib/representative/xml.rb +3 -52
- data/spec/representative/json_spec.rb +224 -0
- data/spec/representative/xml_spec.rb +1 -1
- data/spec/spec_helper.rb +9 -0
- metadata +6 -2
data/README.markdown
CHANGED
@@ -1,16 +1,16 @@
|
|
1
1
|
Representative
|
2
2
|
==============
|
3
3
|
|
4
|
-
"Representative" makes it easier to create XML representations of your Ruby objects.
|
5
|
-
It works best when you want the XML to roughly follow the object structure,
|
6
|
-
but still have complete control of the result.
|
4
|
+
"Representative" makes it easier to create XML or JSON representations of your Ruby objects.
|
7
5
|
|
8
|
-
|
9
|
-
|
6
|
+
It works best when you want the output to roughly follow the object structure, but still want complete control of the result.
|
7
|
+
|
8
|
+
Generating XML
|
9
|
+
--------------
|
10
10
|
|
11
11
|
Given a Ruby data-structure:
|
12
12
|
|
13
|
-
books = [
|
13
|
+
@books = [
|
14
14
|
OpenStruct.new(
|
15
15
|
:title => "Sailing for old dogs",
|
16
16
|
:authors => ["Jim Watson"],
|
@@ -34,13 +34,13 @@ Given a Ruby data-structure:
|
|
34
34
|
)
|
35
35
|
]
|
36
36
|
|
37
|
-
Representative::Xml can be used to generate XML
|
37
|
+
Representative::Xml can be used to generate XML:
|
38
38
|
|
39
39
|
xml = Builder::XmlMarkup.new(:indent => 2)
|
40
40
|
|
41
41
|
Representative::Xml.new(xml) do |r|
|
42
42
|
|
43
|
-
r.list_of :books, books do
|
43
|
+
r.list_of :books, @books do
|
44
44
|
r.element :title
|
45
45
|
r.list_of :authors
|
46
46
|
r.element :published do
|
@@ -53,7 +53,7 @@ Representative::Xml can be used to generate XML, in a declarative style:
|
|
53
53
|
|
54
54
|
puts xml.target!
|
55
55
|
|
56
|
-
|
56
|
+
which produces:
|
57
57
|
|
58
58
|
<books type="array">
|
59
59
|
<book>
|
@@ -88,12 +88,65 @@ The resulting XML looks like this:
|
|
88
88
|
|
89
89
|
Notice that:
|
90
90
|
|
91
|
-
- The structure of the
|
91
|
+
- The structure of the output mirrors the structure described by the nested Ruby blocks.
|
92
92
|
- Representative walks the object-graph for you.
|
93
93
|
- Using `list_of` for a collection attribute generates an "array" element, which plays nicely
|
94
94
|
with most Ruby XML-to-hash converters.
|
95
95
|
- Where a named object-attribute is nil, you get an empty element.
|
96
96
|
|
97
|
+
Generating JSON
|
98
|
+
---------------
|
99
|
+
|
100
|
+
Representative::Json can be used to generate JSON, using exactly the same DSL:
|
101
|
+
|
102
|
+
json = Representative::Json.new do |r|
|
103
|
+
|
104
|
+
r.list_of :books, @books do
|
105
|
+
r.element :title
|
106
|
+
r.list_of :authors
|
107
|
+
r.element :published do
|
108
|
+
r.element :by
|
109
|
+
r.element :year
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|
114
|
+
|
115
|
+
puts json.to_s
|
116
|
+
|
117
|
+
producing:
|
118
|
+
|
119
|
+
[
|
120
|
+
{
|
121
|
+
"title": "Sailing for old dogs",
|
122
|
+
"authors": [
|
123
|
+
"Jim Watson"
|
124
|
+
],
|
125
|
+
"published": {
|
126
|
+
"by": "Credulous Print",
|
127
|
+
"year": 1994
|
128
|
+
}
|
129
|
+
},
|
130
|
+
{
|
131
|
+
"title": "On the horizon",
|
132
|
+
"authors": [
|
133
|
+
"Zoe Primpton",
|
134
|
+
"Stan Ford"
|
135
|
+
],
|
136
|
+
"published": {
|
137
|
+
"by": "McGraw-Hill",
|
138
|
+
"year": 2005
|
139
|
+
}
|
140
|
+
},
|
141
|
+
{
|
142
|
+
"title": "The Little Blue Book of VHS Programming",
|
143
|
+
"authors": [
|
144
|
+
"Henry Nelson"
|
145
|
+
],
|
146
|
+
"published": null
|
147
|
+
}
|
148
|
+
]
|
149
|
+
|
97
150
|
Installation
|
98
151
|
------------
|
99
152
|
|
data/Rakefile
CHANGED
@@ -0,0 +1,44 @@
|
|
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
|
data/examples/xml_demo.rb
CHANGED
@@ -4,7 +4,7 @@ require "rubygems"
|
|
4
4
|
require "representative/xml"
|
5
5
|
require "ostruct"
|
6
6
|
|
7
|
-
books = [
|
7
|
+
@books = [
|
8
8
|
OpenStruct.new(
|
9
9
|
:title => "Sailing for old dogs",
|
10
10
|
:authors => ["Jim Watson"],
|
@@ -29,8 +29,10 @@ books = [
|
|
29
29
|
]
|
30
30
|
|
31
31
|
xml = Builder::XmlMarkup.new(:indent => 2)
|
32
|
+
|
32
33
|
Representative::Xml.new(xml) do |r|
|
33
|
-
|
34
|
+
|
35
|
+
r.list_of :books, @books do
|
34
36
|
r.element :title
|
35
37
|
r.list_of :authors
|
36
38
|
r.element :published do
|
@@ -38,6 +40,7 @@ Representative::Xml.new(xml) do |r|
|
|
38
40
|
r.element :year
|
39
41
|
end
|
40
42
|
end
|
43
|
+
|
41
44
|
end
|
42
45
|
|
43
46
|
puts xml.target!
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require "representative/object_inspector"
|
2
|
+
|
3
|
+
module Representative
|
4
|
+
|
5
|
+
class Base
|
6
|
+
|
7
|
+
def initialize(subject = nil, options = {})
|
8
|
+
@subjects = [subject]
|
9
|
+
@inspector = options[:inspector] || ObjectInspector.new
|
10
|
+
end
|
11
|
+
|
12
|
+
# Return the current "subject" of representation.
|
13
|
+
#
|
14
|
+
# This object will provide element values where they haven't been
|
15
|
+
# explicitly provided.
|
16
|
+
#
|
17
|
+
def current_subject
|
18
|
+
@subjects.last
|
19
|
+
end
|
20
|
+
|
21
|
+
alias :subject :current_subject
|
22
|
+
|
23
|
+
# Evaluate a block with a specified object as #subject.
|
24
|
+
#
|
25
|
+
def representing(new_subject, &block)
|
26
|
+
with_subject(resolve_value(new_subject), &block)
|
27
|
+
end
|
28
|
+
|
29
|
+
protected
|
30
|
+
|
31
|
+
def with_subject(subject)
|
32
|
+
@subjects.push(subject)
|
33
|
+
begin
|
34
|
+
yield subject
|
35
|
+
ensure
|
36
|
+
@subjects.pop
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def resolve_value(value_generator)
|
41
|
+
if value_generator == :self
|
42
|
+
current_subject
|
43
|
+
elsif value_generator.respond_to?(:to_proc)
|
44
|
+
value_generator.to_proc.call(current_subject) unless current_subject.nil?
|
45
|
+
else
|
46
|
+
value_generator
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def resolve_attributes(attributes)
|
51
|
+
if attributes
|
52
|
+
attributes.inject({}) do |resolved, (name, value_generator)|
|
53
|
+
resolved_value = resolve_value(value_generator)
|
54
|
+
resolved[name.to_s.dasherize] = resolved_value unless resolved_value.nil?
|
55
|
+
resolved
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
@@ -0,0 +1,122 @@
|
|
1
|
+
require "active_support/core_ext/array"
|
2
|
+
require "representative/base"
|
3
|
+
require "json"
|
4
|
+
|
5
|
+
module Representative
|
6
|
+
|
7
|
+
class Json < Base
|
8
|
+
|
9
|
+
def initialize(subject = nil, options = {})
|
10
|
+
super(subject, options)
|
11
|
+
@buffer = ""
|
12
|
+
@indent_level = 0
|
13
|
+
now_at :beginning_of_buffer
|
14
|
+
yield self if block_given?
|
15
|
+
end
|
16
|
+
|
17
|
+
def element(name, *args, &block)
|
18
|
+
|
19
|
+
metadata = @inspector.get_metadata(current_subject, name)
|
20
|
+
attributes = args.extract_options!.merge(metadata)
|
21
|
+
|
22
|
+
subject_of_element = if args.empty?
|
23
|
+
lambda do |subject|
|
24
|
+
@inspector.get_value(current_subject, name)
|
25
|
+
end
|
26
|
+
else
|
27
|
+
args.shift
|
28
|
+
end
|
29
|
+
|
30
|
+
raise ArgumentError, "too many arguments" unless args.empty?
|
31
|
+
|
32
|
+
label(name)
|
33
|
+
value(subject_of_element, &block)
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
def list_of(name, *args, &block)
|
38
|
+
list_subject = args.empty? ? name : args.shift
|
39
|
+
items = resolve_value(list_subject)
|
40
|
+
label(name)
|
41
|
+
inside "[", "]" do
|
42
|
+
items.each do |item|
|
43
|
+
new_item
|
44
|
+
value(item, &block)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def value(subject)
|
50
|
+
representing(subject) do
|
51
|
+
if block_given? && !current_subject.nil?
|
52
|
+
inside "{", "}" do
|
53
|
+
yield current_subject
|
54
|
+
end
|
55
|
+
else
|
56
|
+
emit(current_subject.to_json)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
now_at :end_of_item
|
60
|
+
end
|
61
|
+
|
62
|
+
def comment(text)
|
63
|
+
new_item
|
64
|
+
emit("// #{text}")
|
65
|
+
now_at :end_of_comment
|
66
|
+
end
|
67
|
+
|
68
|
+
def to_json
|
69
|
+
@buffer + "\n"
|
70
|
+
end
|
71
|
+
|
72
|
+
def to_s
|
73
|
+
to_json
|
74
|
+
end
|
75
|
+
|
76
|
+
private
|
77
|
+
|
78
|
+
def emit(s)
|
79
|
+
@buffer << s
|
80
|
+
end
|
81
|
+
|
82
|
+
def indentation
|
83
|
+
(" " * @indent_level)
|
84
|
+
end
|
85
|
+
|
86
|
+
def label(name)
|
87
|
+
return false if @indent_level == 0
|
88
|
+
new_item
|
89
|
+
emit("#{name.to_s.to_json}: ")
|
90
|
+
end
|
91
|
+
|
92
|
+
def new_item
|
93
|
+
emit(",") if at? :end_of_item
|
94
|
+
emit("\n") unless at? :beginning_of_buffer
|
95
|
+
emit(indentation)
|
96
|
+
@pending_comma = ","
|
97
|
+
end
|
98
|
+
|
99
|
+
def inside(opening_char, closing_char)
|
100
|
+
emit(opening_char)
|
101
|
+
@indent_level += 1
|
102
|
+
now_at :beginning_of_block
|
103
|
+
yield
|
104
|
+
@indent_level -= 1
|
105
|
+
emit("\n#{indentation}") unless at? :beginning_of_block
|
106
|
+
emit(closing_char)
|
107
|
+
now_at :end_of_item
|
108
|
+
end
|
109
|
+
|
110
|
+
def now_at(state)
|
111
|
+
@state = state
|
112
|
+
end
|
113
|
+
|
114
|
+
def at?(state)
|
115
|
+
@state == state
|
116
|
+
end
|
117
|
+
|
118
|
+
end
|
119
|
+
|
120
|
+
JSON = Json
|
121
|
+
|
122
|
+
end
|
data/lib/representative/xml.rb
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
require "active_support/core_ext/array"
|
2
2
|
require "active_support/core_ext/string"
|
3
3
|
require "builder"
|
4
|
+
require "representative/base"
|
4
5
|
require "representative/empty"
|
5
|
-
require "representative/object_inspector"
|
6
6
|
|
7
7
|
module Representative
|
8
8
|
|
9
9
|
# Easily generate XML while traversing an object-graph.
|
10
10
|
#
|
11
|
-
class Xml
|
11
|
+
class Xml < Base
|
12
12
|
|
13
13
|
# Create an XML-generating Representative. The first argument should be an instance of
|
14
14
|
# Builder::XmlMarkup (or something that implements it's interface). The second argument
|
@@ -16,28 +16,10 @@ module Representative
|
|
16
16
|
#
|
17
17
|
def initialize(xml_builder, subject = nil, options = {})
|
18
18
|
@xml = xml_builder
|
19
|
-
|
20
|
-
@inspector = options[:inspector] || ObjectInspector.new
|
19
|
+
super(subject, options)
|
21
20
|
yield self if block_given?
|
22
21
|
end
|
23
22
|
|
24
|
-
# Return the current "subject" of representation.
|
25
|
-
#
|
26
|
-
# This object will provide element values where they haven't been
|
27
|
-
# explicitly provided.
|
28
|
-
#
|
29
|
-
def current_subject
|
30
|
-
@subjects.last
|
31
|
-
end
|
32
|
-
|
33
|
-
alias :subject :current_subject
|
34
|
-
|
35
|
-
# Evaluate a block with a specified object as #subject.
|
36
|
-
#
|
37
|
-
def representing(new_subject, &block)
|
38
|
-
with_subject(resolve_value(new_subject), &block)
|
39
|
-
end
|
40
|
-
|
41
23
|
# Generate an element.
|
42
24
|
#
|
43
25
|
# With two arguments, it generates an element with the specified text content.
|
@@ -156,37 +138,6 @@ module Representative
|
|
156
138
|
@xml.comment!(text)
|
157
139
|
end
|
158
140
|
|
159
|
-
private
|
160
|
-
|
161
|
-
def with_subject(subject)
|
162
|
-
@subjects.push(subject)
|
163
|
-
begin
|
164
|
-
yield subject
|
165
|
-
ensure
|
166
|
-
@subjects.pop
|
167
|
-
end
|
168
|
-
end
|
169
|
-
|
170
|
-
def resolve_value(value_generator)
|
171
|
-
if value_generator == :self
|
172
|
-
current_subject
|
173
|
-
elsif value_generator.respond_to?(:to_proc)
|
174
|
-
value_generator.to_proc.call(current_subject) unless current_subject.nil?
|
175
|
-
else
|
176
|
-
value_generator
|
177
|
-
end
|
178
|
-
end
|
179
|
-
|
180
|
-
def resolve_attributes(attributes)
|
181
|
-
if attributes
|
182
|
-
attributes.inject({}) do |resolved, (name, value_generator)|
|
183
|
-
resolved_value = resolve_value(value_generator)
|
184
|
-
resolved[name.to_s.dasherize] = resolved_value unless resolved_value.nil?
|
185
|
-
resolved
|
186
|
-
end
|
187
|
-
end
|
188
|
-
end
|
189
|
-
|
190
141
|
end
|
191
142
|
|
192
143
|
end
|
@@ -0,0 +1,224 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require "representative/json"
|
4
|
+
|
5
|
+
describe Representative::Json do
|
6
|
+
|
7
|
+
def r
|
8
|
+
@representative ||= Representative::Json.new(@subject)
|
9
|
+
end
|
10
|
+
|
11
|
+
def resulting_json
|
12
|
+
r.to_json
|
13
|
+
end
|
14
|
+
|
15
|
+
describe "at the top level" do
|
16
|
+
|
17
|
+
describe "#element" do
|
18
|
+
|
19
|
+
describe "with an explicit String value" do
|
20
|
+
|
21
|
+
it "outputs the value as JSON" do
|
22
|
+
r.element :name, "Fred"
|
23
|
+
resulting_json.should == %{"Fred"\n}
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "with an explicit integer value" do
|
29
|
+
|
30
|
+
it "outputs the value as JSON" do
|
31
|
+
r.element :age, 36
|
32
|
+
resulting_json.should == "36\n"
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
describe "with a nil value" do
|
38
|
+
|
39
|
+
it "generates null" do
|
40
|
+
r.element :flavour, nil
|
41
|
+
resulting_json.should == "null\n"
|
42
|
+
end
|
43
|
+
|
44
|
+
describe "and a block" do
|
45
|
+
|
46
|
+
it "generates null" do
|
47
|
+
r.element :book, nil do
|
48
|
+
r.element :author
|
49
|
+
end
|
50
|
+
resulting_json.should == "null\n"
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
describe "without an explicit value" do
|
58
|
+
|
59
|
+
it "extracts the value from the current subject" do
|
60
|
+
@author = OpenStruct.new(:name => "Fred", :age => 36)
|
61
|
+
r.representing(@author) do
|
62
|
+
r.element :name
|
63
|
+
end
|
64
|
+
resulting_json.should == %{"Fred"\n}
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
|
69
|
+
describe "with a block" do
|
70
|
+
|
71
|
+
it "outputs an object" do
|
72
|
+
r.element :something, Object.new do
|
73
|
+
end
|
74
|
+
resulting_json.should == "{}\n"
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
|
81
|
+
describe "#list_of" do
|
82
|
+
|
83
|
+
describe "with an explicit array value" do
|
84
|
+
|
85
|
+
it "outputs the array as JSON" do
|
86
|
+
r.list_of :names, %w(Hewey Dewey Louie)
|
87
|
+
resulting_json.should == undent(<<-JSON)
|
88
|
+
[
|
89
|
+
"Hewey",
|
90
|
+
"Dewey",
|
91
|
+
"Louie"
|
92
|
+
]
|
93
|
+
JSON
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
97
|
+
|
98
|
+
describe "without an explicit value" do
|
99
|
+
|
100
|
+
it "extracts the value from the current subject" do
|
101
|
+
@donald = OpenStruct.new(:nephews => %w(Hewey Dewey Louie))
|
102
|
+
r.element(:duck, @donald) do
|
103
|
+
r.list_of :nephews
|
104
|
+
end
|
105
|
+
resulting_json.should == undent(<<-JSON)
|
106
|
+
{
|
107
|
+
"nephews": [
|
108
|
+
"Hewey",
|
109
|
+
"Dewey",
|
110
|
+
"Louie"
|
111
|
+
]
|
112
|
+
}
|
113
|
+
JSON
|
114
|
+
end
|
115
|
+
|
116
|
+
end
|
117
|
+
|
118
|
+
describe "with a block" do
|
119
|
+
|
120
|
+
it "generates an object for each array element" do
|
121
|
+
@authors = [
|
122
|
+
OpenStruct.new(:name => "Hewey", :age => 3),
|
123
|
+
OpenStruct.new(:name => "Dewey", :age => 4),
|
124
|
+
OpenStruct.new(:name => "Louie", :age => 5)
|
125
|
+
]
|
126
|
+
r.list_of :authors, @authors do
|
127
|
+
r.element :name
|
128
|
+
r.element :age
|
129
|
+
end
|
130
|
+
resulting_json.should == undent(<<-JSON)
|
131
|
+
[
|
132
|
+
{
|
133
|
+
"name": "Hewey",
|
134
|
+
"age": 3
|
135
|
+
},
|
136
|
+
{
|
137
|
+
"name": "Dewey",
|
138
|
+
"age": 4
|
139
|
+
},
|
140
|
+
{
|
141
|
+
"name": "Louie",
|
142
|
+
"age": 5
|
143
|
+
}
|
144
|
+
]
|
145
|
+
JSON
|
146
|
+
end
|
147
|
+
|
148
|
+
end
|
149
|
+
|
150
|
+
end
|
151
|
+
|
152
|
+
describe "#comment" do
|
153
|
+
|
154
|
+
it "inserts a comment" do
|
155
|
+
r.comment "now pay attention"
|
156
|
+
resulting_json.should == undent(<<-JSON)
|
157
|
+
// now pay attention
|
158
|
+
JSON
|
159
|
+
end
|
160
|
+
|
161
|
+
end
|
162
|
+
|
163
|
+
end
|
164
|
+
|
165
|
+
describe "within an element block" do
|
166
|
+
|
167
|
+
describe "#element" do
|
168
|
+
|
169
|
+
it "generates labelled values" do
|
170
|
+
r.element :author, Object.new do
|
171
|
+
r.element :name, "Fred"
|
172
|
+
r.element :age, 36
|
173
|
+
end
|
174
|
+
resulting_json.should == undent(<<-JSON)
|
175
|
+
{
|
176
|
+
"name": "Fred",
|
177
|
+
"age": 36
|
178
|
+
}
|
179
|
+
JSON
|
180
|
+
end
|
181
|
+
|
182
|
+
describe "without an explicit value" do
|
183
|
+
|
184
|
+
it "extracts the value from the current subject" do
|
185
|
+
@author = OpenStruct.new(:name => "Fred", :age => 36)
|
186
|
+
r.element :author, @author do
|
187
|
+
r.element :name
|
188
|
+
r.element :age
|
189
|
+
end
|
190
|
+
resulting_json.should == undent(<<-JSON)
|
191
|
+
{
|
192
|
+
"name": "Fred",
|
193
|
+
"age": 36
|
194
|
+
}
|
195
|
+
JSON
|
196
|
+
end
|
197
|
+
|
198
|
+
end
|
199
|
+
|
200
|
+
end
|
201
|
+
|
202
|
+
describe "#comment" do
|
203
|
+
|
204
|
+
it "inserts a comment" do
|
205
|
+
@author = OpenStruct.new(:name => "Fred", :age => 36)
|
206
|
+
r.element :author, @author do
|
207
|
+
r.element :name
|
208
|
+
r.comment "age is irrelevant"
|
209
|
+
r.element :age
|
210
|
+
end
|
211
|
+
resulting_json.should == undent(<<-JSON)
|
212
|
+
{
|
213
|
+
"name": "Fred",
|
214
|
+
// age is irrelevant
|
215
|
+
"age": 36
|
216
|
+
}
|
217
|
+
JSON
|
218
|
+
end
|
219
|
+
|
220
|
+
end
|
221
|
+
|
222
|
+
end
|
223
|
+
|
224
|
+
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 2
|
8
|
-
-
|
9
|
-
version: 0.2.
|
8
|
+
- 4
|
9
|
+
version: 0.2.4
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Mike Williams
|
@@ -40,11 +40,14 @@ extensions: []
|
|
40
40
|
extra_rdoc_files: []
|
41
41
|
|
42
42
|
files:
|
43
|
+
- lib/representative/base.rb
|
43
44
|
- lib/representative/empty.rb
|
45
|
+
- lib/representative/json.rb
|
44
46
|
- lib/representative/object_inspector.rb
|
45
47
|
- lib/representative/version.rb
|
46
48
|
- lib/representative/xml.rb
|
47
49
|
- lib/representative.rb
|
50
|
+
- examples/json_demo.rb
|
48
51
|
- examples/xml_demo.rb
|
49
52
|
- README.markdown
|
50
53
|
- LICENSE
|
@@ -79,6 +82,7 @@ signing_key:
|
|
79
82
|
specification_version: 3
|
80
83
|
summary: Builds XML representations of your Ruby objects
|
81
84
|
test_files:
|
85
|
+
- spec/representative/json_spec.rb
|
82
86
|
- spec/representative/xml_spec.rb
|
83
87
|
- spec/spec_helper.rb
|
84
88
|
- Rakefile
|