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 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