om 3.0.4 → 3.0.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/om.rb +2 -0
- data/lib/om/version.rb +1 -1
- data/lib/om/xml/dynamic_node.rb +11 -1
- data/lib/om/xml/term.rb +242 -239
- data/spec/integration/serialization_spec.rb +37 -19
- data/spec/unit/dynamic_node_spec.rb +9 -0
- metadata +34 -34
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1de731732be29cdf0c460beebcb5b603deccb18c
|
4
|
+
data.tar.gz: 6fa913f9d7bcdd57e7d29555a266d265dd426ad0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e947f9c90119f8ac601105505d947a2ad78d4307ada79f3f7e609fd64ecb71c0330bbe668438e1d4ee71aac4dbcf112a9f5d2a0fe4a841d9a22125b81cd78e9d
|
7
|
+
data.tar.gz: 4db6a2f387c9630f6e9909966bc81e9939110ac92b6588745fb82766ec23d3249041ddbe70b5ddba6322b094622e51cdd09da26365bec6c6af7fcb12cc2a9f5a
|
data/lib/om.rb
CHANGED
data/lib/om/version.rb
CHANGED
data/lib/om/xml/dynamic_node.rb
CHANGED
@@ -44,7 +44,7 @@ module OM
|
|
44
44
|
elsif args.length > 1
|
45
45
|
new_update_node_with_index(name, args)
|
46
46
|
else
|
47
|
-
child =
|
47
|
+
child = term_child_by_name(term.nil? ? parent.term : term, name)
|
48
48
|
if child
|
49
49
|
OM::XML::DynamicNode.new(name, args.first, @document, child, self)
|
50
50
|
else
|
@@ -53,6 +53,10 @@ module OM
|
|
53
53
|
end
|
54
54
|
end
|
55
55
|
|
56
|
+
def respond_to?(method)
|
57
|
+
super || val.respond_to?(method)
|
58
|
+
end
|
59
|
+
|
56
60
|
def new_update_node(name, args)
|
57
61
|
modified_name = name.to_s.chop.to_sym
|
58
62
|
child = term.retrieve_term(modified_name)
|
@@ -97,6 +101,8 @@ module OM
|
|
97
101
|
end
|
98
102
|
end
|
99
103
|
|
104
|
+
# This resolves the target of this dynamic node into a reified Array
|
105
|
+
# @return [Array]
|
100
106
|
def val
|
101
107
|
query = xpath
|
102
108
|
trim_text = !query.index("text()").nil?
|
@@ -122,6 +128,10 @@ module OM
|
|
122
128
|
other == val
|
123
129
|
end
|
124
130
|
|
131
|
+
def !=(other)
|
132
|
+
val != other
|
133
|
+
end
|
134
|
+
|
125
135
|
def eql?(other)
|
126
136
|
self == other
|
127
137
|
end
|
data/lib/om/xml/term.rb
CHANGED
@@ -4,288 +4,291 @@ require 'om/xml/term_builder'
|
|
4
4
|
# type, index_as, attributes,
|
5
5
|
# is_root_term, required
|
6
6
|
#
|
7
|
-
|
7
|
+
module OM
|
8
|
+
class XML::Term
|
8
9
|
|
9
|
-
|
10
|
-
|
10
|
+
include TreeNode
|
11
|
+
include XML::TermBuilder
|
11
12
|
|
12
|
-
|
13
|
-
|
13
|
+
attr_accessor :name, :xpath, :xpath_constrained, :xpath_relative, :path, :index_as, :required, :type, :variant_of, :path, :default_content_path, :is_root_term
|
14
|
+
attr_accessor :children, :internal_xml, :terminology
|
14
15
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
16
|
+
# Any XML attributes that qualify the Term.
|
17
|
+
#
|
18
|
+
# @example Declare a Term that has a given attribute (ie. //title[@xml:lang='eng'])
|
19
|
+
# t.english_title(:path=>"title", :attributes=>{"xml:lang"=>"eng"}
|
20
|
+
# @example Use nil to point to nodes that do not have a given attribute (ie. //title[not(@xml:lang)])
|
21
|
+
# t.title_without_lang_attribute(:path=>"title", :attributes=>{"xml:lang"=>nil})
|
22
|
+
attr_accessor :attributes
|
22
23
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
24
|
+
# Namespace Prefix (xmlns) for the Term.
|
25
|
+
#
|
26
|
+
# By default, OM assumes that all terms in a Terminology have the namespace set in the root of the document. If you want to set a different namespace for a Term, pass :namespace_prefix into its initializer (or call .namespace_prefix= on its builder)
|
27
|
+
# If a node has _no_ namespace, you must explicitly set namespace_prefix to nil. Currently you have to do this on _each_ term, you can't set namespace_prefix to nil for an entire Terminology.
|
28
|
+
#
|
29
|
+
# @example
|
30
|
+
# # For xml like this
|
31
|
+
# <foo xmlns="http://foo.com/schemas/fooschema" xmlns:bar="http://bar.com/schemas/barschema">
|
32
|
+
# <address>1400 Pennsylvania Avenue</address>
|
33
|
+
# <bar:latitude>56</bar:latitude>
|
34
|
+
# </foo>
|
35
|
+
#
|
36
|
+
# # The Terminology would look like this
|
37
|
+
# OM::XML::Terminology::Builder.new do |t|
|
38
|
+
# t.root(:name=>:foo, :path=>"foo", :xmlns=>"http://foo.com/schemas/fooschema", "xmlns:bar"=>"http://bar.com/schemas/barschema")
|
39
|
+
# t.address
|
40
|
+
# t.latitude(:namespace_prefix=>"bar")
|
41
|
+
# end
|
42
|
+
#
|
43
|
+
attr_accessor :namespace_prefix
|
43
44
|
|
44
45
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
46
|
+
# h2. Namespaces
|
47
|
+
# By default, OM assumes you have no namespace defined unless it is explicitly defined at the root of your document.
|
48
|
+
#
|
49
|
+
# @param [Symbol] name the name to refer to this term by
|
50
|
+
# @param [Hash] opts
|
51
|
+
# @option opts [Array] :index_as a list of indexing hints provided to to_solr
|
52
|
+
# @option opts [String] :path partial xpath that points to the node.
|
53
|
+
# @option opts [Hash] :attributes xml attributes to match in the selector
|
54
|
+
# @option opts [String] :namespace_prefix xml namespace for this node. If not provided, the default namespace set in the terminology will be used.
|
55
|
+
# @option opts [Symbol] :type one of :string, :date, :time :integer. Defaults to :string
|
56
|
+
def initialize(name, opts={}, terminology=nil)
|
57
|
+
opts = {:ancestors=>[], :children=>{}}.merge(opts)
|
58
|
+
[:children, :ancestors,:path, :index_as, :required, :variant_of, :path, :attributes, :default_content_path, :namespace_prefix].each do |accessor_name|
|
59
|
+
instance_variable_set("@#{accessor_name}", opts.fetch(accessor_name, nil) )
|
60
|
+
end
|
60
61
|
|
61
|
-
|
62
|
+
self.type = opts[:type] || :string
|
62
63
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
64
|
+
unless terminology.nil?
|
65
|
+
if opts[:namespace_prefix].nil?
|
66
|
+
unless terminology.namespaces["xmlns"].nil?
|
67
|
+
@namespace_prefix = "oxns"
|
68
|
+
end
|
67
69
|
end
|
68
70
|
end
|
71
|
+
@name = name
|
72
|
+
if @path.nil? || @path.empty?
|
73
|
+
@path = name.to_s
|
74
|
+
end
|
69
75
|
end
|
70
|
-
@name = name
|
71
|
-
if @path.nil? || @path.empty?
|
72
|
-
@path = name.to_s
|
73
|
-
end
|
74
|
-
end
|
75
76
|
|
76
77
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
78
|
+
def sanitize_new_values(new_values)
|
79
|
+
# Sanitize new_values to always be a hash with indexes
|
80
|
+
case new_values
|
81
|
+
when Hash
|
82
|
+
sanitize_new_values(new_values.values)
|
83
|
+
when Array
|
84
|
+
new_values.map {|v| serialize(v)}
|
85
|
+
else
|
86
|
+
[serialize(new_values)]
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
# @param val [String,Date,Integer]
|
91
|
+
def serialize (val)
|
92
|
+
return if val.nil?
|
93
|
+
case type
|
94
|
+
when :date, :integer
|
95
|
+
val.to_s
|
96
|
+
when :time
|
97
|
+
time = val.to_time
|
98
|
+
raise TypeMismatch, "Can't convert `#{val}` to time" if time.nil?
|
99
|
+
time.utc.iso8601
|
100
|
+
when :boolean
|
101
|
+
val.to_s
|
84
102
|
else
|
85
|
-
|
103
|
+
val
|
86
104
|
end
|
87
|
-
end
|
88
|
-
|
89
|
-
# @param val [String,Date,Integer]
|
90
|
-
def serialize (val)
|
91
|
-
return if val.nil?
|
92
|
-
case type
|
93
|
-
when :date, :integer
|
94
|
-
val.to_s
|
95
|
-
when :time
|
96
|
-
val.to_time.utc.iso8601
|
97
|
-
when :boolean
|
98
|
-
val.to_s
|
99
|
-
else
|
100
|
-
val
|
101
105
|
end
|
102
|
-
end
|
103
106
|
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
107
|
+
# @param [String] val the value (from xml) to deserialize into the correct object type.
|
108
|
+
# @return [String,Date,Integer]
|
109
|
+
def deserialize(val)
|
110
|
+
case type
|
111
|
+
when :date
|
112
|
+
#TODO use present?
|
113
|
+
val.map { |v| !v.empty? ? Date.parse(v) : nil}
|
114
|
+
when :time
|
115
|
+
#TODO use present?
|
116
|
+
val.map { |v| !v.empty? ? DateTime.parse(v) : nil}
|
117
|
+
when :integer
|
118
|
+
#TODO use blank?
|
119
|
+
val.map { |v| v.empty? ? nil : v.to_i}
|
120
|
+
when :boolean
|
121
|
+
val.map { |v| v == 'true' }
|
122
|
+
else
|
123
|
+
val
|
124
|
+
end
|
121
125
|
end
|
122
|
-
end
|
123
126
|
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
end
|
130
|
-
new_mapper = self.new(name, :attributes=>attributes)
|
131
|
-
[:index_as, :required, :type, :variant_of, :path, :default_content_path, :namespace_prefix].each do |accessor_name|
|
132
|
-
attribute = mapper_xml.attribute(accessor_name.to_s)
|
133
|
-
unless attribute.nil?
|
134
|
-
new_mapper.instance_variable_set("@#{accessor_name}", attribute.text )
|
127
|
+
def self.from_node(mapper_xml)
|
128
|
+
name = mapper_xml.attribute("name").text.to_sym
|
129
|
+
attributes = {}
|
130
|
+
mapper_xml.xpath("./attribute").each do |a|
|
131
|
+
attributes[a.attribute("name").text.to_sym] = a.attribute("value").text
|
135
132
|
end
|
136
|
-
|
137
|
-
|
133
|
+
new_mapper = self.new(name, :attributes=>attributes)
|
134
|
+
[:index_as, :required, :type, :variant_of, :path, :default_content_path, :namespace_prefix].each do |accessor_name|
|
135
|
+
attribute = mapper_xml.attribute(accessor_name.to_s)
|
136
|
+
unless attribute.nil?
|
137
|
+
new_mapper.instance_variable_set("@#{accessor_name}", attribute.text )
|
138
|
+
end
|
139
|
+
end
|
140
|
+
new_mapper.internal_xml = mapper_xml
|
138
141
|
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
142
|
+
mapper_xml.xpath("./mapper").each do |child_node|
|
143
|
+
child = self.from_node(child_node)
|
144
|
+
new_mapper.add_child(child)
|
145
|
+
end
|
143
146
|
|
144
|
-
|
145
|
-
|
147
|
+
return new_mapper
|
148
|
+
end
|
146
149
|
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
150
|
+
##
|
151
|
+
# Always co-erce :index_as attributes into an Array
|
152
|
+
def index_as
|
153
|
+
Array(@index_as)
|
154
|
+
end
|
152
155
|
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
156
|
+
# crawl down into mapper's children hash to find the desired mapper
|
157
|
+
# ie. @test_mapper.retrieve_mapper(:conference, :role, :text)
|
158
|
+
def retrieve_term(*pointers)
|
159
|
+
children_hash = self.children
|
160
|
+
pointers.each do |p|
|
161
|
+
if children_hash.has_key?(p)
|
162
|
+
target = children_hash[p]
|
163
|
+
if pointers.index(p) == pointers.length-1
|
164
|
+
return target
|
165
|
+
else
|
166
|
+
children_hash = target.children
|
167
|
+
end
|
162
168
|
else
|
163
|
-
|
169
|
+
return nil
|
164
170
|
end
|
165
|
-
else
|
166
|
-
return nil
|
167
171
|
end
|
172
|
+
return target
|
168
173
|
end
|
169
|
-
return target
|
170
|
-
end
|
171
174
|
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
+
def is_root_term?
|
176
|
+
@is_root_term == true
|
177
|
+
end
|
175
178
|
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
+
def xpath_absolute
|
180
|
+
@xpath
|
181
|
+
end
|
179
182
|
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
183
|
+
# +term_pointers+ reference to the property you want to generate a builder template for
|
184
|
+
# @param [Hash] extra_opts
|
185
|
+
# @option extra_opts [Hash] :attributes
|
186
|
+
def xml_builder_template(extra_opts = {})
|
187
|
+
extra_attributes = extra_opts.fetch(:attributes, {})
|
185
188
|
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
189
|
+
node_options = []
|
190
|
+
node_child_template = ""
|
191
|
+
if !self.default_content_path.nil?
|
192
|
+
node_child_options = ["\':::builder_new_value:::\'"]
|
193
|
+
node_child_template = " { xml.#{self.default_content_path}( #{OM::XML.delimited_list(node_child_options)} ) }"
|
194
|
+
else
|
195
|
+
node_options = ["\':::builder_new_value:::\'"]
|
196
|
+
end
|
197
|
+
if !self.attributes.nil?
|
198
|
+
self.attributes.merge(extra_attributes).each_pair do |k,v|
|
199
|
+
node_options << "\'#{k}\'=>\'#{v}\'" unless v == :none
|
200
|
+
end
|
197
201
|
end
|
198
|
-
end
|
199
202
|
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
203
|
+
builder_ref = if self.path.include?(":")
|
204
|
+
"xml['#{self.path[0..path.index(":")-1]}']"
|
205
|
+
elsif !self.namespace_prefix.nil? and self.namespace_prefix != 'oxns'
|
206
|
+
"xml['#{self.namespace_prefix}']"
|
207
|
+
else
|
208
|
+
"xml"
|
209
|
+
end
|
207
210
|
|
208
|
-
|
211
|
+
attribute = OM::XML.delimited_list(node_options)
|
209
212
|
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
213
|
+
builder_method = if self.path.include?(":")
|
214
|
+
"#{self.path[path.index(":")+1..-1]}( #{attribute} )"
|
215
|
+
elsif self.path.include?(".")
|
216
|
+
"send(:\\\"#{self.path}\\\", #{attribute} )"
|
217
|
+
elsif self.path.kind_of?(Hash) && self.path[:attribute]
|
218
|
+
"@#{self.path[:attribute]}( #{OM::XML.delimited_list(node_options)} )"
|
219
|
+
elsif Nokogiri::XML::Builder.method_defined? self.path.to_sym
|
220
|
+
"#{self.path}_( #{OM::XML.delimited_list(node_options)} )"
|
221
|
+
else
|
222
|
+
"#{self.path}( #{OM::XML.delimited_list(node_options)} )"
|
223
|
+
end
|
224
|
+
template = "#{builder_ref}.#{builder_method}#{node_child_template}"
|
225
|
+
return template.gsub( /:::(.*?):::/ ) { '#{'+$1+'}' }
|
220
226
|
end
|
221
|
-
template = "#{builder_ref}.#{builder_method}#{node_child_template}"
|
222
|
-
return template.gsub( /:::(.*?):::/ ) { '#{'+$1+'}' }
|
223
|
-
end
|
224
227
|
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
228
|
+
# Generates absolute, relative, and constrained xpaths for the term, setting xpath, xpath_relative, and xpath_constrained accordingly.
|
229
|
+
# Also triggers update_xpath_values! on all child nodes, as their absolute paths rely on those of their parent nodes.
|
230
|
+
def generate_xpath_queries!
|
231
|
+
self.xpath = OM::XML::TermXpathGenerator.generate_absolute_xpath(self)
|
232
|
+
self.xpath_constrained = OM::XML::TermXpathGenerator.generate_constrained_xpath(self)
|
233
|
+
self.xpath_relative = OM::XML::TermXpathGenerator.generate_relative_xpath(self)
|
234
|
+
self.children.each_value {|child| child.generate_xpath_queries! }
|
235
|
+
return self
|
236
|
+
end
|
234
237
|
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
238
|
+
# Return an XML representation of the Term
|
239
|
+
# @param [Hash] options the term will be added to it. If :children=>false, skips rendering child Terms
|
240
|
+
# @param [Nokogiri::XML::Document] document (optional) document to insert the term xml into
|
241
|
+
# @return [Nokogiri::XML::Document]
|
242
|
+
# @example If :children=>false, skips rendering child Terms
|
243
|
+
# term.to_xml(:children=>false)
|
244
|
+
# @example You can provide your own Nokogiri document to insert the xml into
|
245
|
+
# doc = Nokogiri::XML::Document.new
|
246
|
+
# term.to_xml({}, document=doc)
|
247
|
+
def to_xml(options={}, document=Nokogiri::XML::Document.new)
|
248
|
+
builder = Nokogiri::XML::Builder.with(document) do |xml|
|
249
|
+
xml.term(:name=>name) {
|
250
|
+
if is_root_term?
|
251
|
+
xml.is_root_term("true")
|
252
|
+
end
|
253
|
+
xml.path path
|
254
|
+
xml.namespace_prefix namespace_prefix
|
255
|
+
unless attributes.nil? || attributes.empty?
|
256
|
+
xml.attributes {
|
257
|
+
attributes.each_pair do |attribute_name, attribute_value|
|
258
|
+
xml.send("#{attribute_name}_".to_sym, attribute_value)
|
259
|
+
end
|
260
|
+
}
|
261
|
+
end
|
262
|
+
xml.index_as {
|
263
|
+
unless index_as.nil?
|
264
|
+
index_as.each { |index_type| xml.index_type }
|
256
265
|
end
|
257
266
|
}
|
258
|
-
|
259
|
-
|
260
|
-
unless
|
261
|
-
|
267
|
+
xml.required required
|
268
|
+
xml.data_type type
|
269
|
+
unless variant_of.nil?
|
270
|
+
xml.variant_of variant_of
|
271
|
+
end
|
272
|
+
unless default_content_path.nil?
|
273
|
+
xml.default_content_path default_content_path
|
274
|
+
end
|
275
|
+
xml.xpath {
|
276
|
+
xml.relative xpath_relative
|
277
|
+
xml.absolute xpath
|
278
|
+
xml.constrained xpath_constrained
|
279
|
+
}
|
280
|
+
if options.fetch(:children, true)
|
281
|
+
xml.children
|
262
282
|
end
|
263
283
|
}
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
xml.default_content_path default_content_path
|
271
|
-
end
|
272
|
-
xml.xpath {
|
273
|
-
xml.relative xpath_relative
|
274
|
-
xml.absolute xpath
|
275
|
-
xml.constrained xpath_constrained
|
276
|
-
}
|
277
|
-
if options.fetch(:children, true)
|
278
|
-
xml.children
|
279
|
-
end
|
280
|
-
}
|
281
|
-
end
|
282
|
-
doc = builder.doc
|
283
|
-
if options.fetch(:children, true)
|
284
|
-
children.values.each {|child| child.to_xml(options, doc.xpath("//term[@name=\"#{name}\"]/children").first)}
|
284
|
+
end
|
285
|
+
doc = builder.doc
|
286
|
+
if options.fetch(:children, true)
|
287
|
+
children.values.each {|child| child.to_xml(options, doc.xpath("//term[@name=\"#{name}\"]/children").first)}
|
288
|
+
end
|
289
|
+
return doc
|
285
290
|
end
|
286
|
-
return doc
|
287
|
-
end
|
288
|
-
|
289
|
-
# private :update_xpath_values
|
290
291
|
|
292
|
+
# private :update_xpath_values
|
293
|
+
end
|
291
294
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
+
require 'active_support/core_ext/string/conversions' # for String#to_time conversion
|
2
3
|
|
3
4
|
describe "element values" do
|
4
5
|
before(:all) do
|
@@ -20,7 +21,7 @@ describe "element values" do
|
|
20
21
|
|
21
22
|
|
22
23
|
describe "when the xml template has existing values" do
|
23
|
-
|
24
|
+
let(:datastream) do
|
24
25
|
ElementValueTerminology.from_xml <<-EOF
|
25
26
|
<outer outerId="hypatia:outer" type="outer type">
|
26
27
|
<my_date>2012-10-30</my_date>
|
@@ -30,6 +31,7 @@ describe "element values" do
|
|
30
31
|
</outer>
|
31
32
|
EOF
|
32
33
|
end
|
34
|
+
subject { datastream }
|
33
35
|
describe "reading values" do
|
34
36
|
it "should deserialize date" do
|
35
37
|
subject.my_date.should == [Date.parse('2012-10-30')]
|
@@ -45,26 +47,42 @@ EOF
|
|
45
47
|
end
|
46
48
|
end
|
47
49
|
describe "Writing to xml" do
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
<
|
54
|
-
|
55
|
-
|
56
|
-
|
50
|
+
context "serializing time" do
|
51
|
+
context "with a valid time" do
|
52
|
+
subject { datastream.to_xml }
|
53
|
+
before { datastream.my_time = [DateTime.parse('2011-01-30T03:45:15Z')] }
|
54
|
+
it { should be_equivalent_to '<?xml version="1.0"?>
|
55
|
+
<outer outerId="hypatia:outer" type="outer type">
|
56
|
+
<my_date>2012-10-30</my_date>
|
57
|
+
<my_time>2011-01-30T03:45:15Z</my_time>
|
58
|
+
<my_int>7</my_int>
|
59
|
+
<active>true</active>
|
60
|
+
</outer>' }
|
61
|
+
end
|
62
|
+
|
63
|
+
context "setting an invalid time" do
|
64
|
+
it "raises a type mismatch error" do
|
65
|
+
expect { datastream.my_time = '' }.to raise_error OM::TypeMismatch
|
66
|
+
end
|
67
|
+
end
|
57
68
|
end
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
69
|
+
|
70
|
+
context "serializing dates" do
|
71
|
+
|
72
|
+
subject { datastream.to_xml }
|
73
|
+
context "with a valid date" do
|
74
|
+
|
75
|
+
before { datastream.my_date = [Date.parse('2012-09-22')] }
|
76
|
+
it { should be_equivalent_to '<?xml version="1.0"?>
|
77
|
+
<outer outerId="hypatia:outer" type="outer type">
|
78
|
+
<my_date>2012-09-22</my_date>
|
79
|
+
<my_time>2012-10-30T12:22:33Z</my_time>
|
80
|
+
<my_int>7</my_int>
|
81
|
+
<active>true</active>
|
82
|
+
</outer>' }
|
83
|
+
end
|
67
84
|
end
|
85
|
+
|
68
86
|
it "should serialize ints" do
|
69
87
|
subject.my_int = [9]
|
70
88
|
subject.to_xml.should be_equivalent_to '<?xml version="1.0"?>
|
@@ -47,6 +47,11 @@ describe "OM::XML::DynamicNode" do
|
|
47
47
|
@sample.date_created = ['A long time ago']
|
48
48
|
@sample.date_created.should == ['A long time ago']
|
49
49
|
end
|
50
|
+
|
51
|
+
it "checks inequality" do
|
52
|
+
@sample.foo = ['in a galaxy far far away']
|
53
|
+
expect(@sample.foo != ['nearby']).to be true
|
54
|
+
end
|
50
55
|
end
|
51
56
|
|
52
57
|
|
@@ -80,6 +85,10 @@ describe "OM::XML::DynamicNode" do
|
|
80
85
|
@article.person.last_name.first.should == "FAMILY NAME"
|
81
86
|
end
|
82
87
|
|
88
|
+
it "should respond_to? things an array can do" do
|
89
|
+
expect(@article.person.last_name).to respond_to(:map)
|
90
|
+
end
|
91
|
+
|
83
92
|
it "should delegate with blocks to the found array" do
|
84
93
|
arr = []
|
85
94
|
@article.person.last_name.each{|x| arr << x}
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: om
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.0.
|
4
|
+
version: 3.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matt Zumwalt
|
@@ -9,188 +9,188 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2014-06-05 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activesupport
|
16
16
|
requirement: !ruby/object:Gem::Requirement
|
17
17
|
requirements:
|
18
|
-
- -
|
18
|
+
- - ">="
|
19
19
|
- !ruby/object:Gem::Version
|
20
20
|
version: '0'
|
21
21
|
type: :runtime
|
22
22
|
prerelease: false
|
23
23
|
version_requirements: !ruby/object:Gem::Requirement
|
24
24
|
requirements:
|
25
|
-
- -
|
25
|
+
- - ">="
|
26
26
|
- !ruby/object:Gem::Version
|
27
27
|
version: '0'
|
28
28
|
- !ruby/object:Gem::Dependency
|
29
29
|
name: activemodel
|
30
30
|
requirement: !ruby/object:Gem::Requirement
|
31
31
|
requirements:
|
32
|
-
- -
|
32
|
+
- - ">="
|
33
33
|
- !ruby/object:Gem::Version
|
34
34
|
version: '0'
|
35
35
|
type: :runtime
|
36
36
|
prerelease: false
|
37
37
|
version_requirements: !ruby/object:Gem::Requirement
|
38
38
|
requirements:
|
39
|
-
- -
|
39
|
+
- - ">="
|
40
40
|
- !ruby/object:Gem::Version
|
41
41
|
version: '0'
|
42
42
|
- !ruby/object:Gem::Dependency
|
43
43
|
name: solrizer
|
44
44
|
requirement: !ruby/object:Gem::Requirement
|
45
45
|
requirements:
|
46
|
-
- - ~>
|
46
|
+
- - "~>"
|
47
47
|
- !ruby/object:Gem::Version
|
48
48
|
version: 3.1.0
|
49
49
|
type: :runtime
|
50
50
|
prerelease: false
|
51
51
|
version_requirements: !ruby/object:Gem::Requirement
|
52
52
|
requirements:
|
53
|
-
- - ~>
|
53
|
+
- - "~>"
|
54
54
|
- !ruby/object:Gem::Version
|
55
55
|
version: 3.1.0
|
56
56
|
- !ruby/object:Gem::Dependency
|
57
57
|
name: nokogiri
|
58
58
|
requirement: !ruby/object:Gem::Requirement
|
59
59
|
requirements:
|
60
|
-
- -
|
60
|
+
- - ">="
|
61
61
|
- !ruby/object:Gem::Version
|
62
62
|
version: 1.4.2
|
63
63
|
type: :runtime
|
64
64
|
prerelease: false
|
65
65
|
version_requirements: !ruby/object:Gem::Requirement
|
66
66
|
requirements:
|
67
|
-
- -
|
67
|
+
- - ">="
|
68
68
|
- !ruby/object:Gem::Version
|
69
69
|
version: 1.4.2
|
70
70
|
- !ruby/object:Gem::Dependency
|
71
71
|
name: mediashelf-loggable
|
72
72
|
requirement: !ruby/object:Gem::Requirement
|
73
73
|
requirements:
|
74
|
-
- -
|
74
|
+
- - ">="
|
75
75
|
- !ruby/object:Gem::Version
|
76
76
|
version: '0'
|
77
77
|
type: :runtime
|
78
78
|
prerelease: false
|
79
79
|
version_requirements: !ruby/object:Gem::Requirement
|
80
80
|
requirements:
|
81
|
-
- -
|
81
|
+
- - ">="
|
82
82
|
- !ruby/object:Gem::Version
|
83
83
|
version: '0'
|
84
84
|
- !ruby/object:Gem::Dependency
|
85
85
|
name: deprecation
|
86
86
|
requirement: !ruby/object:Gem::Requirement
|
87
87
|
requirements:
|
88
|
-
- -
|
88
|
+
- - ">="
|
89
89
|
- !ruby/object:Gem::Version
|
90
90
|
version: '0'
|
91
91
|
type: :runtime
|
92
92
|
prerelease: false
|
93
93
|
version_requirements: !ruby/object:Gem::Requirement
|
94
94
|
requirements:
|
95
|
-
- -
|
95
|
+
- - ">="
|
96
96
|
- !ruby/object:Gem::Version
|
97
97
|
version: '0'
|
98
98
|
- !ruby/object:Gem::Dependency
|
99
99
|
name: rspec
|
100
100
|
requirement: !ruby/object:Gem::Requirement
|
101
101
|
requirements:
|
102
|
-
- - ~>
|
102
|
+
- - "~>"
|
103
103
|
- !ruby/object:Gem::Version
|
104
104
|
version: '2.0'
|
105
105
|
type: :development
|
106
106
|
prerelease: false
|
107
107
|
version_requirements: !ruby/object:Gem::Requirement
|
108
108
|
requirements:
|
109
|
-
- - ~>
|
109
|
+
- - "~>"
|
110
110
|
- !ruby/object:Gem::Version
|
111
111
|
version: '2.0'
|
112
112
|
- !ruby/object:Gem::Dependency
|
113
113
|
name: rake
|
114
114
|
requirement: !ruby/object:Gem::Requirement
|
115
115
|
requirements:
|
116
|
-
- -
|
116
|
+
- - ">="
|
117
117
|
- !ruby/object:Gem::Version
|
118
118
|
version: '0'
|
119
119
|
type: :development
|
120
120
|
prerelease: false
|
121
121
|
version_requirements: !ruby/object:Gem::Requirement
|
122
122
|
requirements:
|
123
|
-
- -
|
123
|
+
- - ">="
|
124
124
|
- !ruby/object:Gem::Version
|
125
125
|
version: '0'
|
126
126
|
- !ruby/object:Gem::Dependency
|
127
127
|
name: yard
|
128
128
|
requirement: !ruby/object:Gem::Requirement
|
129
129
|
requirements:
|
130
|
-
- -
|
130
|
+
- - ">="
|
131
131
|
- !ruby/object:Gem::Version
|
132
132
|
version: '0'
|
133
133
|
type: :development
|
134
134
|
prerelease: false
|
135
135
|
version_requirements: !ruby/object:Gem::Requirement
|
136
136
|
requirements:
|
137
|
-
- -
|
137
|
+
- - ">="
|
138
138
|
- !ruby/object:Gem::Version
|
139
139
|
version: '0'
|
140
140
|
- !ruby/object:Gem::Dependency
|
141
141
|
name: rdoc
|
142
142
|
requirement: !ruby/object:Gem::Requirement
|
143
143
|
requirements:
|
144
|
-
- -
|
144
|
+
- - ">="
|
145
145
|
- !ruby/object:Gem::Version
|
146
146
|
version: '0'
|
147
147
|
type: :development
|
148
148
|
prerelease: false
|
149
149
|
version_requirements: !ruby/object:Gem::Requirement
|
150
150
|
requirements:
|
151
|
-
- -
|
151
|
+
- - ">="
|
152
152
|
- !ruby/object:Gem::Version
|
153
153
|
version: '0'
|
154
154
|
- !ruby/object:Gem::Dependency
|
155
155
|
name: RedCloth
|
156
156
|
requirement: !ruby/object:Gem::Requirement
|
157
157
|
requirements:
|
158
|
-
- -
|
158
|
+
- - ">="
|
159
159
|
- !ruby/object:Gem::Version
|
160
160
|
version: '0'
|
161
161
|
type: :development
|
162
162
|
prerelease: false
|
163
163
|
version_requirements: !ruby/object:Gem::Requirement
|
164
164
|
requirements:
|
165
|
-
- -
|
165
|
+
- - ">="
|
166
166
|
- !ruby/object:Gem::Version
|
167
167
|
version: '0'
|
168
168
|
- !ruby/object:Gem::Dependency
|
169
169
|
name: awesome_print
|
170
170
|
requirement: !ruby/object:Gem::Requirement
|
171
171
|
requirements:
|
172
|
-
- -
|
172
|
+
- - ">="
|
173
173
|
- !ruby/object:Gem::Version
|
174
174
|
version: '0'
|
175
175
|
type: :development
|
176
176
|
prerelease: false
|
177
177
|
version_requirements: !ruby/object:Gem::Requirement
|
178
178
|
requirements:
|
179
|
-
- -
|
179
|
+
- - ">="
|
180
180
|
- !ruby/object:Gem::Version
|
181
181
|
version: '0'
|
182
182
|
- !ruby/object:Gem::Dependency
|
183
183
|
name: equivalent-xml
|
184
184
|
requirement: !ruby/object:Gem::Requirement
|
185
185
|
requirements:
|
186
|
-
- -
|
186
|
+
- - ">="
|
187
187
|
- !ruby/object:Gem::Version
|
188
188
|
version: 0.2.4
|
189
189
|
type: :development
|
190
190
|
prerelease: false
|
191
191
|
version_requirements: !ruby/object:Gem::Requirement
|
192
192
|
requirements:
|
193
|
-
- -
|
193
|
+
- - ">="
|
194
194
|
- !ruby/object:Gem::Version
|
195
195
|
version: 0.2.4
|
196
196
|
description: 'OM (Opinionated Metadata): A library to help you tame sprawling XML
|
@@ -203,9 +203,9 @@ extensions: []
|
|
203
203
|
extra_rdoc_files:
|
204
204
|
- LICENSE
|
205
205
|
files:
|
206
|
-
- .document
|
207
|
-
- .gitignore
|
208
|
-
- .travis.yml
|
206
|
+
- ".document"
|
207
|
+
- ".gitignore"
|
208
|
+
- ".travis.yml"
|
209
209
|
- COMMON_OM_PATTERNS.textile
|
210
210
|
- CONTRIBUTING.md
|
211
211
|
- GETTING_FANCY.textile
|
@@ -289,17 +289,17 @@ require_paths:
|
|
289
289
|
- lib
|
290
290
|
required_ruby_version: !ruby/object:Gem::Requirement
|
291
291
|
requirements:
|
292
|
-
- -
|
292
|
+
- - ">="
|
293
293
|
- !ruby/object:Gem::Version
|
294
294
|
version: 1.9.3
|
295
295
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
296
296
|
requirements:
|
297
|
-
- -
|
297
|
+
- - ">="
|
298
298
|
- !ruby/object:Gem::Version
|
299
299
|
version: '0'
|
300
300
|
requirements: []
|
301
301
|
rubyforge_project:
|
302
|
-
rubygems_version: 2.
|
302
|
+
rubygems_version: 2.2.2
|
303
303
|
signing_key:
|
304
304
|
specification_version: 4
|
305
305
|
summary: 'OM (Opinionated Metadata): A library to help you tame sprawling XML schemas
|