om 1.8.1 → 1.9.0.pre1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. data/Rakefile +1 -1
  2. data/container_spec.rb +14 -14
  3. data/lib/om.rb +12 -9
  4. data/lib/om/samples/mods_article.rb +9 -9
  5. data/lib/om/tree_node.rb +6 -6
  6. data/lib/om/version.rb +1 -1
  7. data/lib/om/xml.rb +33 -31
  8. data/lib/om/xml/container.rb +12 -12
  9. data/lib/om/xml/document.rb +19 -18
  10. data/lib/om/xml/dynamic_node.rb +50 -45
  11. data/lib/om/xml/named_term_proxy.rb +13 -13
  12. data/lib/om/xml/node_generator.rb +3 -3
  13. data/lib/om/xml/template_registry.rb +26 -18
  14. data/lib/om/xml/term.rb +46 -30
  15. data/lib/om/xml/term_value_operators.rb +56 -52
  16. data/lib/om/xml/term_xpath_generator.rb +57 -51
  17. data/lib/om/xml/terminology.rb +10 -8
  18. data/lib/om/xml/terminology_based_solrizer.rb +90 -0
  19. data/lib/om/xml/validation.rb +19 -19
  20. data/lib/om/xml/vocabulary.rb +4 -4
  21. data/lib/tasks/om.rake +6 -4
  22. data/om.gemspec +2 -1
  23. data/spec/fixtures/mods_article.rb +90 -0
  24. data/spec/fixtures/mods_articles/hydrangea_article1.xml +2 -2
  25. data/spec/integration/differentiated_elements_spec.rb +2 -2
  26. data/spec/integration/element_value_spec.rb +13 -13
  27. data/spec/integration/proxies_and_ref_spec.rb +15 -15
  28. data/spec/integration/querying_documents_spec.rb +18 -24
  29. data/spec/integration/rights_metadata_integration_example_spec.rb +18 -18
  30. data/spec/integration/selective_querying_spec.rb +1 -1
  31. data/spec/integration/serialization_spec.rb +13 -13
  32. data/spec/integration/set_reentrant_terminology_spec.rb +10 -10
  33. data/spec/integration/xpathy_stuff_spec.rb +16 -16
  34. data/spec/spec_helper.rb +2 -2
  35. data/spec/unit/container_spec.rb +29 -28
  36. data/spec/unit/document_spec.rb +50 -49
  37. data/spec/unit/dynamic_node_spec.rb +45 -57
  38. data/spec/unit/named_term_proxy_spec.rb +16 -16
  39. data/spec/unit/node_generator_spec.rb +7 -7
  40. data/spec/unit/nokogiri_sanity_spec.rb +30 -30
  41. data/spec/unit/om_spec.rb +5 -5
  42. data/spec/unit/template_registry_spec.rb +69 -69
  43. data/spec/unit/term_builder_spec.rb +77 -77
  44. data/spec/unit/term_spec.rb +73 -79
  45. data/spec/unit/term_value_operators_spec.rb +191 -186
  46. data/spec/unit/term_xpath_generator_spec.rb +43 -37
  47. data/spec/unit/terminology_builder_spec.rb +85 -85
  48. data/spec/unit/terminology_spec.rb +98 -98
  49. data/spec/unit/validation_spec.rb +22 -22
  50. data/spec/unit/xml_serialization_spec.rb +22 -21
  51. data/spec/unit/xml_spec.rb +7 -7
  52. data/spec/unit/xml_terminology_based_solrizer_spec.rb +109 -0
  53. metadata +57 -17
  54. checksums.yaml +0 -7
  55. data/.rspec +0 -1
  56. data/.rubocop.yml +0 -1
  57. data/.rubocop_todo.yml +0 -382
  58. data/.travis.yml +0 -10
  59. data/gemfiles/gemfile.rails3 +0 -11
  60. data/gemfiles/gemfile.rails4 +0 -10
@@ -47,7 +47,9 @@ class OM::XML::Terminology
47
47
  @schema = opts.fetch(:schema,nil)
48
48
  opts.select {|k,v| k.to_s.include?("xmlns")}.each do |ns_pair|
49
49
  @namespaces[ns_pair.first.to_s] = ns_pair.last
50
- @namespaces["oxns"] = ns_pair.last if ns_pair.first.to_s == "xmlns"
50
+ if ns_pair.first.to_s == "xmlns"
51
+ @namespaces["oxns"] = ns_pair.last
52
+ end
51
53
  end
52
54
  root_term_builder = OM::XML::Term::Builder.new(opts.fetch(:path,:root).to_s.sub(/[_!]$/, '')).is_root_term(true)
53
55
  term_opts = opts.dup
@@ -55,7 +57,7 @@ class OM::XML::Terminology
55
57
  root_term_builder.settings.merge!(term_opts)
56
58
  @term_builders[root_term_builder.name] = root_term_builder
57
59
 
58
- root_term_builder
60
+ return root_term_builder
59
61
  end
60
62
 
61
63
  # Returns an array of Terms that have been marked as "root" terms
@@ -97,7 +99,7 @@ class OM::XML::Terminology
97
99
  raise OM::XML::Terminology::BadPointerError, "You attempted to retrieve a TermBuilder using this pointer: #{args.inspect} but no TermBuilder exists at that location. Everything is fine until \"#{arg.inspect}\", which doesn't exist."
98
100
  end
99
101
  end
100
- current_term
102
+ return current_term
101
103
  end
102
104
 
103
105
  # Add additional terms into this terminology
@@ -135,12 +137,12 @@ class OM::XML::Terminology
135
137
 
136
138
  # Returns true if the current terminology has a term defined at the location indicated by +pointers+ array
137
139
  def has_term?(*pointers)
138
-
140
+ begin
139
141
  retrieve_term(*OM.pointers_to_flat_array(pointers, false))
140
142
  return true
141
143
  rescue
142
144
  return false
143
-
145
+ end
144
146
  end
145
147
 
146
148
  # Returns the Term corresponding to the given _pointer_.
@@ -158,7 +160,7 @@ class OM::XML::Terminology
158
160
  end
159
161
  end
160
162
  end
161
- current_term
163
+ return current_term
162
164
  end
163
165
 
164
166
  def retrieve_node_subsequent(args, context)
@@ -238,7 +240,7 @@ class OM::XML::Terminology
238
240
  end
239
241
 
240
242
  term = retrieve_term(*term_pointers)
241
- term.xml_builder_template(extra_opts)
243
+ return term.xml_builder_template(extra_opts)
242
244
  end
243
245
 
244
246
  # Returns an array of Terms that have been marked as "root" terms
@@ -272,7 +274,7 @@ class OM::XML::Terminology
272
274
  end
273
275
  document = builder.doc
274
276
  terms.values.each {|term| term.to_xml(options,document.xpath("//terms").first)}
275
- document
277
+ return document
276
278
  end
277
279
 
278
280
  def self.term_generic_name(*pointers)
@@ -0,0 +1,90 @@
1
+ require 'solrizer'
2
+ # This module is only suitable to mix into Classes that use the OM::XML::Document Module
3
+ module OM::XML::TerminologyBasedSolrizer
4
+ def self.included(klass)
5
+ klass.send(:include, ::Solrizer::Common)
6
+ klass.send(:extend, ClassMethods)
7
+ end
8
+
9
+ # Module Methods
10
+ module ClassMethods
11
+
12
+ # Build a solr document from +doc+ based on its terminology
13
+ # @param [OM::XML::Document] doc
14
+ # @param [Hash] (optional) solr_doc (values hash) to populate
15
+ def solrize(doc, solr_doc=Hash.new, field_mapper = nil)
16
+ unless doc.class.terminology.nil?
17
+ doc.class.terminology.terms.each_pair do |term_name,term|
18
+ doc.solrize_term(term, solr_doc, field_mapper)
19
+ end
20
+ end
21
+
22
+ return solr_doc
23
+ end
24
+
25
+ # Populate a solr document with fields based on nodes in +xml+
26
+ # Values for a term are gathered by to +term_pointer+ using OM::XML::TermValueOperators.term_values
27
+ # and are deserialized by OM according to :type, as determined in its terminology.
28
+ # The content of the actual field in solr is each +node+ of the +nodeset+ returned by OM,
29
+ # rendered to a string.
30
+ # @param [OM::XML::Document] doc xml document to extract values from
31
+ # @param [OM::XML::Term] term corresponding to desired xml values
32
+ # @param [Hash] (optional) solr_doc (values hash) to populate
33
+ def solrize_term(doc, term, solr_doc = Hash.new, field_mapper = nil, opts={})
34
+ parents = opts.fetch(:parents, [])
35
+ term_pointer = parents+[term.name]
36
+ nodeset = doc.term_values(*term_pointer)
37
+
38
+ nodeset.each do |n|
39
+ doc.solrize_node(n, term_pointer, term, solr_doc, field_mapper)
40
+ unless term.kind_of? OM::XML::NamedTermProxy
41
+ term.children.each_pair do |child_term_name, child_term|
42
+ doc.solrize_term(child_term, solr_doc, field_mapper, opts={:parents=>parents+[{term.name=>nodeset.index(n)}]})
43
+ end
44
+ end
45
+ end
46
+ solr_doc
47
+ end
48
+
49
+ # Populate a solr document with solr fields corresponding to the given xml node
50
+ # Field names are generated using settings from the term in the +doc+'s terminology corresponding to +term_pointer+
51
+ # If the supplied term does not have an index_as attribute, no indexing will be performed.
52
+ # @param [Nokogiri::XML::Node] node to solrize
53
+ # @param [OM::XML::Document] doc document the node came from
54
+ # @param [Array] term_pointer Array pointing to the term that should be used for solrization settings
55
+ # @param [Term] term the term to be solrized
56
+ # @param [Hash] (optional) solr_doc (values hash) to populate
57
+ # @return [Hash] the solr doc
58
+ def solrize_node(node_value, doc, term_pointer, term, solr_doc = Hash.new, field_mapper = nil, opts = {})
59
+ return solr_doc unless term.index_as && !term.index_as.empty?
60
+
61
+ generic_field_name_base = OM::XML::Terminology.term_generic_name(*term_pointer)
62
+ create_and_insert_terms(generic_field_name_base, node_value, term.index_as, solr_doc)
63
+
64
+ if term_pointer.length > 1
65
+ hierarchical_field_name_base = OM::XML::Terminology.term_hierarchical_name(*term_pointer)
66
+ create_and_insert_terms(hierarchical_field_name_base, node_value, term.index_as, solr_doc)
67
+ end
68
+ solr_doc
69
+ end
70
+
71
+ end
72
+
73
+
74
+ # Instance Methods
75
+
76
+ attr_accessor :field_mapper
77
+
78
+ def to_solr(solr_doc = Hash.new, field_mapper = self.field_mapper) # :nodoc:
79
+ self.class.solrize(self, solr_doc, field_mapper)
80
+ end
81
+
82
+ def solrize_term(term, solr_doc = Hash.new, field_mapper = self.field_mapper, opts={})
83
+ self.class.solrize_term(self, term, solr_doc, field_mapper, opts)
84
+ end
85
+
86
+ def solrize_node(node, term_pointer, term, solr_doc = Hash.new, field_mapper = self.field_mapper, opts={})
87
+ self.class.solrize_node(node, self, term_pointer, term, solr_doc, field_mapper, opts)
88
+ end
89
+
90
+ end
@@ -1,60 +1,60 @@
1
1
  module OM::XML::Validation
2
2
  extend ActiveSupport::Concern
3
-
4
- # Class Methods -- These methods will be available on classes that include this Module
5
-
3
+
4
+ # Class Methods -- These methods will be available on classes that include this Module
5
+
6
6
  module ClassMethods
7
7
  attr_accessor :schema_url
8
8
  attr_writer :schema_file
9
-
9
+
10
10
  ##
11
11
  # Validation Support
12
12
  ##
13
-
13
+
14
14
  # Validate the given document against the Schema provided by the root_property for this class
15
15
  def validate(doc)
16
16
  schema.validate(doc).each do |error|
17
17
  puts error.message
18
18
  end
19
19
  end
20
-
20
+
21
21
  # Retrieve the Nokogiri Schema for this class
22
22
  def schema
23
23
  @schema ||= Nokogiri::XML::Schema(schema_file.read)
24
24
  end
25
-
25
+
26
26
  # Retrieve the schema file for this class
27
27
  # If the schema file is not already set, it will be loaded from the schema url provided in the root_property configuration for the class
28
28
  def schema_file
29
29
  @schema_file ||= file_from_url(schema_url)
30
30
  end
31
-
31
+
32
32
  # Retrieve file from a url (used by schema_file method to retrieve schema file from the schema url)
33
33
  def file_from_url( url )
34
34
  # parsed_url = URI.parse( url )
35
- #
36
- # if parsed_url.class != URI::HTTP
35
+ #
36
+ # if parsed_url.class != URI::HTTP
37
37
  # raise "Invalid URL. Could not parse #{url} as a HTTP url."
38
38
  # end
39
-
40
-
39
+
40
+ begin
41
41
  file = open( url )
42
42
  return file
43
43
  rescue OpenURI::HTTPError => e
44
44
  raise "Could not retrieve file from #{url}. Error: #{e}"
45
- rescue Exception => e
45
+ rescue Exception => e
46
46
  raise "Could not retrieve file from #{url}. Error: #{e}"
47
-
47
+ end
48
48
  end
49
-
49
+
50
50
  private :file_from_url
51
-
51
+
52
52
  end
53
-
53
+
54
54
  # Instance Methods -- These methods will be available on instances of classes that include this module
55
-
55
+
56
56
  def validate
57
57
  self.class.validate(self)
58
58
  end
59
-
59
+
60
60
  end
@@ -1,15 +1,15 @@
1
1
  class OM::XML::Vocabulary
2
-
2
+
3
3
  attr_accessor :builder
4
- # Vocabularies are not editable once they've been created because inserting/removing/rearranging mappers in a vocabulary
4
+ # Vocabularies are not editable once they've been created because inserting/removing/rearranging mappers in a vocabulary
5
5
  # will invalidate the xpath queries for an entire branch of the Vocabulary's tree of mappers.
6
6
  # If you want to change a vocabulary's structure, retrieve it's +builder+, make your changes, and re-generate the vocabulary.
7
- #
7
+ #
8
8
  # Ex:
9
9
  # builder = vocabulary.builder
10
10
  # builder.insert_mapper(:name_, :namePart)
11
11
  # vocabulary = builder.build
12
-
12
+
13
13
  # Mappers can be retrieved by their mapper name
14
14
  # Ex.
15
15
  # vocabulary.retrieve_mapper(:name_, :namePart)
data/lib/tasks/om.rake CHANGED
@@ -6,18 +6,20 @@ end
6
6
 
7
7
 
8
8
  desc "Execute specs with coverage"
9
- task :coverage do
9
+ task :coverage do
10
10
  # Put spec opts in a file named .rspec in root
11
11
  ruby_engine = defined?(RUBY_ENGINE) ? RUBY_ENGINE : "ruby"
12
12
  ENV['COVERAGE'] = 'true' unless ruby_engine == 'jruby'
13
+
14
+
13
15
  Rake::Task['om:rspec'].invoke
14
16
  end
15
17
 
16
- namespace :om do
18
+ namespace :om do
17
19
 
18
20
  require 'rspec/core/rake_task'
19
21
  RSpec::Core::RakeTask.new(:rspec) do |spec|
20
- if ENV['COVERAGE'] && RUBY_VERSION =~ /^1.8/
22
+ if ENV['COVERAGE'] and RUBY_VERSION =~ /^1.8/
21
23
  spec.rcov = true
22
24
  spec.rcov_opts = %w{-I../../app -I../../lib --exclude spec\/*,gems\/*,ruby\/* --aggregate coverage.data}
23
25
  end
@@ -33,7 +35,7 @@ namespace :om do
33
35
  YARD::Rake::YardocTask.new(:doc) do |yt|
34
36
  readme_filename = 'README.textile'
35
37
  textile_docs = []
36
- Dir[File.join(project_root, "*.textile")].each_with_index do |f, index|
38
+ Dir[File.join(project_root, "*.textile")].each_with_index do |f, index|
37
39
  unless f.include?("/#{readme_filename}") # Skip readme, which is already built by the --readme option
38
40
  textile_docs << '-'
39
41
  textile_docs << f
data/om.gemspec CHANGED
@@ -14,10 +14,11 @@ Gem::Specification.new do |s|
14
14
 
15
15
  s.add_dependency 'activesupport'
16
16
  s.add_dependency 'activemodel'
17
+ s.add_dependency 'solrizer', '~> 3.0.0.pre8'
17
18
  s.add_dependency('nokogiri', ">= 1.4.2")
18
19
  s.add_dependency('mediashelf-loggable')
19
20
  s.add_dependency('deprecation')
20
- s.add_development_dependency "rspec", "~> 2.99"
21
+ s.add_development_dependency "rspec", "~> 2.0"
21
22
  s.add_development_dependency "rake"
22
23
  s.add_development_dependency "rdoc"
23
24
  s.add_development_dependency "awesome_print"
@@ -0,0 +1,90 @@
1
+ module Samples
2
+ class ModsArticle
3
+
4
+ include OM::XML::Document
5
+
6
+ set_terminology do |t|
7
+ t.root(:path=>"mods", :xmlns=>"http://www.loc.gov/mods/v3", :schema=>"http://www.loc.gov/standards/mods/v3/mods-3-2.xsd", "xmlns:foo"=>"http://my.custom.namespace")
8
+
9
+
10
+ t.title_info(:path=>"titleInfo") {
11
+ t.main_title(:index_as=>[:facetable],:path=>"title", :label=>"title") {
12
+ t.main_title_lang(:path=>{:attribute=> "xml:lang"})
13
+ }
14
+ t.french_title(:ref=>[:title_info,:main_title], :attributes=>{"xml:lang"=>"fre"})
15
+
16
+ t.language(:index_as=>[:facetable, :stored_searchable],:path=>{:attribute=>"lang"})
17
+ }
18
+ t.language{
19
+ t.lang_code(:index_as=>[:facetable], :path=>"languageTerm", :attributes=>{:type=>"code"})
20
+ }
21
+ t.abstract(:index_as=>[:stored_searchable])
22
+ t.subject {
23
+ t.topic(:index_as=>[:facetable])
24
+ }
25
+ t.topic_tag(:proxy=>[:subject, :topic], :index_as=>[:stored_searchable])
26
+ # t.topic_tag(:index_as=>[:facetable],:path=>"subject", :default_content_path=>"topic")
27
+ # This is a mods:name. The underscore is purely to avoid namespace conflicts.
28
+ t.name_ {
29
+ # this is a namepart
30
+ t.namePart(:type=>:string, :label=>"generic name")
31
+ # affiliations are great
32
+ t.affiliation
33
+ t.institution(:path=>"affiliation", :index_as=>[:facetable], :label=>"organization")
34
+ t.displayForm
35
+ t.role(:ref=>[:role])
36
+ t.description(:index_as=>[:facetable])
37
+ t.date(:path=>"namePart", :attributes=>{:type=>"date"})
38
+ t.last_name(:path=>"namePart", :attributes=>{:type=>"family"}, :index_as=>[:stored_searchable])
39
+ t.first_name(:path=>"namePart", :attributes=>{:type=>"given"}, :label=>"first name")
40
+ t.terms_of_address(:path=>"namePart", :attributes=>{:type=>"termsOfAddress"})
41
+ t.computing_id
42
+ t.name_content(:path=>"text()")
43
+ }
44
+ # lookup :person, :first_name
45
+ t.person(:ref=>:name, :attributes=>{:type=>"personal"}, :index_as=>[:facetable])
46
+ t.department(:proxy=>[:person,:description],:index_as=>[:facetable])
47
+ t.organization(:ref=>:name, :attributes=>{:type=>"corporate"}, :index_as=>[:facetable])
48
+ t.conference(:ref=>:name, :attributes=>{:type=>"conference"}, :index_as=>[:facetable])
49
+ t.role {
50
+ t.text(:path=>"roleTerm",:attributes=>{:type=>"text"}, :index_as=>[:stored_searchable])
51
+ t.code(:path=>"roleTerm",:attributes=>{:type=>"code"})
52
+ }
53
+ t.journal(:path=>'relatedItem', :attributes=>{:type=>"host"}) {
54
+ t.title_info(:index_as=>[:facetable],:ref=>[:title_info])
55
+ t.origin_info(:path=>"originInfo") {
56
+ t.publisher
57
+ t.date_issued(:path=>"dateIssued", :type => :date, :index_as => [:stored_searchable])
58
+ t.issuance(:index_as=>[:facetable])
59
+ }
60
+ t.issn(:path=>"identifier", :attributes=>{:type=>"issn"})
61
+ t.issue(:path=>"part") {
62
+ t.volume(:path=>"detail", :attributes=>{:type=>"volume"}, :default_content_path=>"number")
63
+ t.level(:path=>"detail", :attributes=>{:type=>"number"}, :default_content_path=>"number")
64
+ t.extent
65
+ t.pages(:path=>"extent", :attributes=>{:unit=>"pages"}) {
66
+ t.start
67
+ t.end
68
+ }
69
+ t.start_page(:proxy=>[:pages, :start])
70
+ t.end_page(:proxy=>[:pages, :end])
71
+ t.publication_date(:path=>"date", :type => :date, :index_as => [:stored_searchable])
72
+ }
73
+ }
74
+ t.note
75
+ t.location(:path=>"location") {
76
+ t.url(:path=>"url")
77
+ }
78
+ t.publication_url(:proxy=>[:location,:url])
79
+ t.title(:proxy=>[:title_info, :main_title])
80
+ t.journal_title(:proxy=>[:journal, :title_info, :main_title])
81
+ t.pub_date(:proxy=>[:journal, :issue, :publication_date])
82
+ t.issue_date(:ref=>[:journal, :origin_info, :date_issued], :type=> :date)
83
+ end
84
+
85
+ # Changes from OM::Properties implementation
86
+ # renamed family_name => last_name
87
+ # start_page & end_page now accessible as [:journal, :issue, :pages, :start] (etc.)
88
+
89
+ end
90
+ end
@@ -71,7 +71,7 @@
71
71
  </titleInfo>
72
72
  <originInfo>
73
73
  <publisher>PUBLISHER</publisher>
74
- <dateIssued>DATE</dateIssued>
74
+ <dateIssued>2007-02-15</dateIssued>
75
75
  </originInfo>
76
76
  <identifier type="issn">0013-8908</identifier>
77
77
  <part>
@@ -84,7 +84,7 @@
84
84
  <extent unit="pages">
85
85
  <start>195</start>
86
86
  </extent>
87
- <date>FEB. 2007</date>
87
+ <date>2007-02-01</date>
88
88
  </part>
89
89
  </relatedItem>
90
90
 
@@ -30,10 +30,10 @@ describe "use the root element as a member of the proxy address" do
30
30
  end
31
31
 
32
32
  it "should pull out all occurences of the_thing_we_want in the relevant_container" do
33
- expect(subject.relevant_container.the_thing_we_want).to eq(["1", "2"])
33
+ subject.relevant_container.the_thing_we_want.should == ["1", "2"]
34
34
  end
35
35
 
36
36
  it "should only pull out the_thing_we_want at the root level" do
37
- expect(subject.the_thing_we_want).to eq(["2"])
37
+ subject.the_thing_we_want.should == ["2"]
38
38
  end
39
39
  end
@@ -53,39 +53,39 @@ EOF
53
53
  end
54
54
 
55
55
  it "should handle single-element terms correctly" do
56
- expect(subject.elementA).to eq(["valA"])
56
+ subject.elementA.should == ["valA"]
57
57
  end
58
58
 
59
59
  it "should handle term paths" do
60
- expect(subject.elC).to eq(["valC"])
60
+ subject.elC.should == ["valC"]
61
61
  end
62
62
 
63
63
  it "should handle multiple-element, terms with paths correctly" do
64
- expect(subject.elB).to eq(["valB1", "valB2"])
64
+ subject.elB.should == ["valB1", "valB2"]
65
65
  end
66
66
 
67
67
  it "should handle terms that require specific attributes" do
68
- expect(subject.elementC).to eq(["valC"])
68
+ subject.elementC.should == ["valC"]
69
69
  end
70
70
 
71
71
  it "should handle" do
72
- expect(subject.here.length).to eq(1)
73
- expect(subject.here.first.split(/\W/)).to include('123', '456')
72
+ subject.here.length.should == 1
73
+ subject.here.first.split(/\W/).should include('123', '456')
74
74
  end
75
75
 
76
76
  it "should handle missing terms" do
77
- expect(subject.there).to be_empty
77
+ subject.there.should be_empty
78
78
  end
79
79
 
80
80
  it "should handle element value given the absence of a specific attribute" do
81
- expect(subject.elementD).to eq(["valD1"])
82
- expect(subject.no_attrib).to eq(["valB1"])
81
+ subject.elementD.should == ["valD1"]
82
+ subject.no_attrib.should == ["valB1"]
83
83
  end
84
84
 
85
85
  it "should handle OM terms for an attribute value" do
86
- expect(subject.elementB.my_attr).to eq(["vole"])
87
- expect(subject.alternate).to eq(["vole"])
88
- expect(subject.another).to eq(["vole"])
89
- expect(subject.animal_attrib).to include("vole", "seagull")
86
+ subject.elementB.my_attr.should == ["vole"]
87
+ subject.alternate.should == ["vole"]
88
+ subject.another.should == ["vole"]
89
+ subject.animal_attrib.should include("vole", "seagull")
90
90
  end
91
91
  end