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