om 3.0.4 → 3.0.5

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1506c83ba270fd799906372dec5dad78bf22e15b
4
- data.tar.gz: 52421f44573d4dd6dbccf317999992739b06a0d8
3
+ metadata.gz: 1de731732be29cdf0c460beebcb5b603deccb18c
4
+ data.tar.gz: 6fa913f9d7bcdd57e7d29555a266d265dd426ad0
5
5
  SHA512:
6
- metadata.gz: b6708395c67ab5aae28ff0f2019320869de2b6c528fbe83c6a62cef25342467eda7e2eca2917a828f4361448f68a16f917184397966eee55e9285154b41d13bc
7
- data.tar.gz: 8dc39146fa979e0acbab1915f73217868247629ff7a66c9b7200a85338969b89f8b683361afad740df704afc3896863725eea21da7650db999cc3c9450d16477
6
+ metadata.gz: e947f9c90119f8ac601105505d947a2ad78d4307ada79f3f7e609fd64ecb71c0330bbe668438e1d4ee71aac4dbcf112a9f5d2a0fe4a841d9a22125b81cd78e9d
7
+ data.tar.gz: 4db6a2f387c9630f6e9909966bc81e9939110ac92b6588745fb82766ec23d3249041ddbe70b5ddba6322b094622e51cdd09da26365bec6c6af7fcb12cc2a9f5a
data/lib/om.rb CHANGED
@@ -65,6 +65,8 @@ module OM
65
65
  def self.version
66
66
  Om::VERSION
67
67
  end
68
+
69
+ class TypeMismatch < StandardError; end
68
70
  end
69
71
 
70
72
  module OM::XML; end
@@ -1,3 +1,3 @@
1
1
  module Om
2
- VERSION = "3.0.4"
2
+ VERSION = "3.0.5"
3
3
  end
@@ -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 = term_child_by_name(term.nil? ? parent.term : term, name)
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
@@ -4,288 +4,291 @@ require 'om/xml/term_builder'
4
4
  # type, index_as, attributes,
5
5
  # is_root_term, required
6
6
  #
7
- class OM::XML::Term
7
+ module OM
8
+ class XML::Term
8
9
 
9
- include OM::TreeNode
10
- include OM::XML::TermBuilder
10
+ include TreeNode
11
+ include XML::TermBuilder
11
12
 
12
- attr_accessor :name, :xpath, :xpath_constrained, :xpath_relative, :path, :index_as, :required, :type, :variant_of, :path, :default_content_path, :is_root_term
13
- attr_accessor :children, :internal_xml, :terminology
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
- # Any XML attributes that qualify the Term.
16
- #
17
- # @example Declare a Term that has a given attribute (ie. //title[@xml:lang='eng'])
18
- # t.english_title(:path=>"title", :attributes=>{"xml:lang"=>"eng"}
19
- # @example Use nil to point to nodes that do not have a given attribute (ie. //title[not(@xml:lang)])
20
- # t.title_without_lang_attribute(:path=>"title", :attributes=>{"xml:lang"=>nil})
21
- attr_accessor :attributes
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
- # Namespace Prefix (xmlns) for the Term.
24
- #
25
- # 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)
26
- # 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.
27
- #
28
- # @example
29
- # # For xml like this
30
- # <foo xmlns="http://foo.com/schemas/fooschema" xmlns:bar="http://bar.com/schemas/barschema">
31
- # <address>1400 Pennsylvania Avenue</address>
32
- # <bar:latitude>56</bar:latitude>
33
- # </foo>
34
- #
35
- # # The Terminology would look like this
36
- # OM::XML::Terminology::Builder.new do |t|
37
- # t.root(:name=>:foo, :path=>"foo", :xmlns=>"http://foo.com/schemas/fooschema", "xmlns:bar"=>"http://bar.com/schemas/barschema")
38
- # t.address
39
- # t.latitude(:namespace_prefix=>"bar")
40
- # end
41
- #
42
- attr_accessor :namespace_prefix
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
- # h2. Namespaces
46
- # By default, OM assumes you have no namespace defined unless it is explicitly defined at the root of your document.
47
- #
48
- # @param [Symbol] name the name to refer to this term by
49
- # @param [Hash] opts
50
- # @option opts [Array] :index_as a list of indexing hints provided to to_solr
51
- # @option opts [String] :path partial xpath that points to the node.
52
- # @option opts [Hash] :attributes xml attributes to match in the selector
53
- # @option opts [String] :namespace_prefix xml namespace for this node. If not provided, the default namespace set in the terminology will be used.
54
- # @option opts [Symbol] :type one of :string, :date, :time :integer. Defaults to :string
55
- def initialize(name, opts={}, terminology=nil)
56
- opts = {:ancestors=>[], :children=>{}}.merge(opts)
57
- [:children, :ancestors,:path, :index_as, :required, :variant_of, :path, :attributes, :default_content_path, :namespace_prefix].each do |accessor_name|
58
- instance_variable_set("@#{accessor_name}", opts.fetch(accessor_name, nil) )
59
- end
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
- self.type = opts[:type] || :string
62
+ self.type = opts[:type] || :string
62
63
 
63
- unless terminology.nil?
64
- if opts[:namespace_prefix].nil?
65
- unless terminology.namespaces["xmlns"].nil?
66
- @namespace_prefix = "oxns"
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
- def sanitize_new_values(new_values)
78
- # Sanitize new_values to always be a hash with indexes
79
- case new_values
80
- when Hash
81
- sanitize_new_values(new_values.values)
82
- when Array
83
- new_values.map {|v| serialize(v)}
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
- [serialize(new_values)]
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
- # @param [String] val the value (from xml) to deserialize into the correct object type.
105
- # @return [String,Date,Integer]
106
- def deserialize(val)
107
- case type
108
- when :date
109
- #TODO use present?
110
- val.map { |v| !v.empty? ? Date.parse(v) : nil}
111
- when :time
112
- #TODO use present?
113
- val.map { |v| !v.empty? ? DateTime.parse(v) : nil}
114
- when :integer
115
- #TODO use blank?
116
- val.map { |v| v.empty? ? nil : v.to_i}
117
- when :boolean
118
- val.map { |v| v == 'true' }
119
- else
120
- val
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
- def self.from_node(mapper_xml)
125
- name = mapper_xml.attribute("name").text.to_sym
126
- attributes = {}
127
- mapper_xml.xpath("./attribute").each do |a|
128
- attributes[a.attribute("name").text.to_sym] = a.attribute("value").text
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
- end
137
- new_mapper.internal_xml = mapper_xml
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
- mapper_xml.xpath("./mapper").each do |child_node|
140
- child = self.from_node(child_node)
141
- new_mapper.add_child(child)
142
- end
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
- return new_mapper
145
- end
147
+ return new_mapper
148
+ end
146
149
 
147
- ##
148
- # Always co-erce :index_as attributes into an Array
149
- def index_as
150
- Array(@index_as)
151
- end
150
+ ##
151
+ # Always co-erce :index_as attributes into an Array
152
+ def index_as
153
+ Array(@index_as)
154
+ end
152
155
 
153
- # crawl down into mapper's children hash to find the desired mapper
154
- # ie. @test_mapper.retrieve_mapper(:conference, :role, :text)
155
- def retrieve_term(*pointers)
156
- children_hash = self.children
157
- pointers.each do |p|
158
- if children_hash.has_key?(p)
159
- target = children_hash[p]
160
- if pointers.index(p) == pointers.length-1
161
- return target
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
- children_hash = target.children
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
- def is_root_term?
173
- @is_root_term == true
174
- end
175
+ def is_root_term?
176
+ @is_root_term == true
177
+ end
175
178
 
176
- def xpath_absolute
177
- @xpath
178
- end
179
+ def xpath_absolute
180
+ @xpath
181
+ end
179
182
 
180
- # +term_pointers+ reference to the property you want to generate a builder template for
181
- # @param [Hash] extra_opts
182
- # @option extra_opts [Hash] :attributes
183
- def xml_builder_template(extra_opts = {})
184
- extra_attributes = extra_opts.fetch(:attributes, {})
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
- node_options = []
187
- node_child_template = ""
188
- if !self.default_content_path.nil?
189
- node_child_options = ["\':::builder_new_value:::\'"]
190
- node_child_template = " { xml.#{self.default_content_path}( #{OM::XML.delimited_list(node_child_options)} ) }"
191
- else
192
- node_options = ["\':::builder_new_value:::\'"]
193
- end
194
- if !self.attributes.nil?
195
- self.attributes.merge(extra_attributes).each_pair do |k,v|
196
- node_options << "\'#{k}\'=>\'#{v}\'" unless v == :none
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
- builder_ref = if self.path.include?(":")
201
- "xml['#{self.path[0..path.index(":")-1]}']"
202
- elsif !self.namespace_prefix.nil? and self.namespace_prefix != 'oxns'
203
- "xml['#{self.namespace_prefix}']"
204
- else
205
- "xml"
206
- end
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
- attribute = OM::XML.delimited_list(node_options)
211
+ attribute = OM::XML.delimited_list(node_options)
209
212
 
210
- builder_method = if self.path.include?(":")
211
- "#{self.path[path.index(":")+1..-1]}( #{attribute} )"
212
- elsif self.path.include?(".")
213
- "send(:\\\"#{self.path}\\\", #{attribute} )"
214
- elsif self.path.kind_of?(Hash) && self.path[:attribute]
215
- "@#{self.path[:attribute]}( #{OM::XML.delimited_list(node_options)} )"
216
- elsif Nokogiri::XML::Builder.method_defined? self.path.to_sym
217
- "#{self.path}_( #{OM::XML.delimited_list(node_options)} )"
218
- else
219
- "#{self.path}( #{OM::XML.delimited_list(node_options)} )"
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
- # Generates absolute, relative, and constrained xpaths for the term, setting xpath, xpath_relative, and xpath_constrained accordingly.
226
- # Also triggers update_xpath_values! on all child nodes, as their absolute paths rely on those of their parent nodes.
227
- def generate_xpath_queries!
228
- self.xpath = OM::XML::TermXpathGenerator.generate_absolute_xpath(self)
229
- self.xpath_constrained = OM::XML::TermXpathGenerator.generate_constrained_xpath(self)
230
- self.xpath_relative = OM::XML::TermXpathGenerator.generate_relative_xpath(self)
231
- self.children.each_value {|child| child.generate_xpath_queries! }
232
- return self
233
- end
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
- # Return an XML representation of the Term
236
- # @param [Hash] options the term will be added to it. If :children=>false, skips rendering child Terms
237
- # @param [Nokogiri::XML::Document] document (optional) document to insert the term xml into
238
- # @return [Nokogiri::XML::Document]
239
- # @example If :children=>false, skips rendering child Terms
240
- # term.to_xml(:children=>false)
241
- # @example You can provide your own Nokogiri document to insert the xml into
242
- # doc = Nokogiri::XML::Document.new
243
- # term.to_xml({}, document=doc)
244
- def to_xml(options={}, document=Nokogiri::XML::Document.new)
245
- builder = Nokogiri::XML::Builder.with(document) do |xml|
246
- xml.term(:name=>name) {
247
- if is_root_term?
248
- xml.is_root_term("true")
249
- end
250
- xml.path path
251
- xml.namespace_prefix namespace_prefix
252
- unless attributes.nil? || attributes.empty?
253
- xml.attributes {
254
- attributes.each_pair do |attribute_name, attribute_value|
255
- xml.send("#{attribute_name}_".to_sym, attribute_value)
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
- end
259
- xml.index_as {
260
- unless index_as.nil?
261
- index_as.each { |index_type| xml.index_type }
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
- xml.required required
265
- xml.data_type type
266
- unless variant_of.nil?
267
- xml.variant_of variant_of
268
- end
269
- unless default_content_path.nil?
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
- subject do
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
- it "should serialize time" do
49
- subject.my_time = [DateTime.parse('2011-01-30T03:45:15Z')]
50
- subject.to_xml.should be_equivalent_to '<?xml version="1.0"?>
51
- <outer outerId="hypatia:outer" type="outer type">
52
- <my_date>2012-10-30</my_date>
53
- <my_time>2011-01-30T03:45:15Z</my_time>
54
- <my_int>7</my_int>
55
- <active>true</active>
56
- </outer>'
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
- it "should serialize date" do
59
- subject.my_date = [Date.parse('2012-09-22')]
60
- subject.to_xml.should be_equivalent_to '<?xml version="1.0"?>
61
- <outer outerId="hypatia:outer" type="outer type">
62
- <my_date>2012-09-22</my_date>
63
- <my_time>2012-10-30T12:22:33Z</my_time>
64
- <my_int>7</my_int>
65
- <active>true</active>
66
- </outer>'
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
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: 2013-10-10 00:00:00.000000000 Z
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.0.3
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