om 1.6.1 → 1.7.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
@@ -122,6 +122,7 @@ module OM::XML::TermValueOperators
122
122
  # @param [Array -- (OM term pointer array) OR String -- (like what you would pass into Nokogiri::XML::Builder.new)] template for building the new xml. Use the syntax that Nokogiri::XML::Builder uses.
123
123
  # @return [Nokogiri::XML::Node] the parent_node with new chldren inserted into it
124
124
  def insert_from_template(parent_node, new_values, template)
125
+ ng_xml_will_change!
125
126
  # If template is a string, use it as the template, otherwise use it as arguments to xml_builder_template
126
127
  unless template.instance_of?(String)
127
128
  template_args = Array(template)
@@ -202,20 +203,26 @@ module OM::XML::TermValueOperators
202
203
  end
203
204
 
204
205
  def term_value_update(node_select,node_index,new_value,opts={})
206
+ ng_xml_will_change!
205
207
  # template = opts.fetch(:template,nil)
206
208
 
207
209
  node = find_by_terms_and_value(*node_select)[node_index]
208
- if new_value == "" || new_value == :delete
210
+ if delete_on_update?(node, new_value)
209
211
  node.remove
210
212
  else
211
213
  node.content = new_value
212
214
  end
213
215
  end
216
+
217
+ def delete_on_update?(node, new_value)
218
+ new_value == "" || new_value == :delete
219
+ end
214
220
 
215
221
  # def term_value_set(term_ref, query_opts, node_index, new_value)
216
222
  # end
217
223
 
218
224
  def term_value_delete(opts={})
225
+ ng_xml_will_change!
219
226
  parent_select = Array( opts[:parent_select] )
220
227
  parent_index = opts[:parent_index]
221
228
  child_index = opts[:child_index]
@@ -1,4 +1,5 @@
1
1
  module OM::XML::Validation
2
+ extend ActiveSupport::Concern
2
3
 
3
4
  # Class Methods -- These methods will be available on classes that include this Module
4
5
 
@@ -52,12 +53,8 @@ module OM::XML::Validation
52
53
 
53
54
  # Instance Methods -- These methods will be available on instances of classes that include this module
54
55
 
55
- def self.included(klass)
56
- klass.extend(ClassMethods)
57
- end
58
-
59
56
  def validate
60
57
  self.class.validate(self)
61
58
  end
62
59
 
63
- end
60
+ end
data/om.gemspec CHANGED
@@ -12,10 +12,13 @@ Gem::Specification.new do |s|
12
12
  s.summary = %q{OM (Opinionated Metadata): A library to help you tame sprawling XML schemas like MODS.}
13
13
  s.description = %q{OM (Opinionated Metadata): A library to help you tame sprawling XML schemas like MODS. Wraps Nokogiri documents in objects with miscellaneous helper methods for doing things like retrieve generated xpath queries or look up properties based on a simplified DSL}
14
14
 
15
+ s.add_dependency 'activesupport'
16
+ s.add_dependency 'activemodel'
15
17
  s.add_dependency('nokogiri', ">= 1.4.2")
16
18
  s.add_dependency('mediashelf-loggable')
17
19
  s.add_development_dependency "rspec", "~> 2.0"
18
20
  s.add_development_dependency "rake"
21
+ s.add_development_dependency "awesome_print"
19
22
  s.add_development_dependency "mocha", ">= 0.9.8"
20
23
  s.add_development_dependency "equivalent-xml", ">= 0.2.4"
21
24
 
@@ -0,0 +1,53 @@
1
+ require 'spec_helper'
2
+
3
+ describe "element values" do
4
+ before(:all) do
5
+ class ElementValueTerminology
6
+ include OM::XML::Document
7
+
8
+ set_terminology do |t|
9
+ t.root(:path => "outer", :xmlns => nil)
10
+ t.my_date(:type=>:date)
11
+ t.my_int(:type=>:integer)
12
+ end
13
+ end
14
+ end
15
+
16
+ subject do
17
+ ElementValueTerminology.from_xml <<-EOF
18
+ <outer outerId="hypatia:outer" type="outer type">
19
+ <my_date>2012-10-30</my_date>
20
+ <my_int>7</my_int>
21
+ </outer>
22
+ EOF
23
+ end
24
+
25
+ describe "Reading from xml" do
26
+ it "should handle date" do
27
+ subject.my_date.should == [Date.parse('2012-10-30')]
28
+ end
29
+ it "should handle ints" do
30
+ subject.my_int.should == [7]
31
+ end
32
+ end
33
+ describe "Writing to xml" do
34
+ it "should handle date" do
35
+ subject.my_date = [Date.parse('2012-09-22')]
36
+ subject.to_xml.should be_equivalent_to '<?xml version="1.0"?>
37
+ <outer outerId="hypatia:outer" type="outer type">
38
+ <my_date>2012-09-22</my_date>
39
+ <my_int>7</my_int>
40
+ </outer>'
41
+ end
42
+ it "should handle ints" do
43
+ subject.my_int = [9]
44
+ subject.to_xml.should be_equivalent_to '<?xml version="1.0"?>
45
+ <outer outerId="hypatia:outer" type="outer type">
46
+ <my_date>2012-10-30</my_date>
47
+ <my_int>9</my_int>
48
+ </outer>'
49
+ end
50
+ end
51
+
52
+ end
53
+
@@ -8,21 +8,25 @@ describe "OM::XML::Container" do
8
8
  end
9
9
  end
10
10
 
11
- before(:each) do
12
- @container = ContainerTest.from_xml("<foo><bar>1</bar></foo>")
13
- end
14
-
11
+ subject {
12
+ ContainerTest.from_xml("<foo><bar>1</bar></foo>")
13
+ }
14
+
15
15
  it "should add .ng_xml accessor" do
16
- @container.should respond_to(:ng_xml)
17
- @container.should respond_to(:ng_xml=)
16
+ subject.should respond_to(:ng_xml)
17
+ subject.should respond_to(:ng_xml=)
18
+ end
19
+
20
+ it "should initialize" do
21
+ ContainerTest.new.ng_xml.should be_a_kind_of Nokogiri::XML::Document
18
22
  end
19
23
 
20
24
  describe "new" do
21
25
  it "should populate ng_xml with an instance of Nokogiri::XML::Document" do
22
- @container.ng_xml.class.should == Nokogiri::XML::Document
26
+ subject.ng_xml.class.should == Nokogiri::XML::Document
23
27
  end
24
28
  end
25
-
29
+
26
30
  describe "#from_xml" do
27
31
  it "should accept a String, parse it and store it in .ng_xml" do
28
32
  Nokogiri::XML::Document.expects(:parse).returns("parsed xml")
@@ -44,20 +48,20 @@ describe "OM::XML::Container" do
44
48
 
45
49
  describe ".to_xml" do
46
50
  it "should call .ng_xml.to_xml" do
47
- @container.ng_xml.expects(:to_xml).returns("ng xml")
48
- @container.to_xml.should == "ng xml"
51
+ subject.ng_xml.expects(:to_xml).returns("ng xml")
52
+ subject.to_xml.should == "ng xml"
49
53
  end
50
54
 
51
55
  it 'should accept an optional Nokogiri::XML Document as an argument and insert its fields into that (mocked test)' do
52
56
  doc = Nokogiri::XML::Document.parse("<test_xml/>")
53
57
  mock_new_node = mock("new node")
54
- doc.root.expects(:add_child).with(@container.ng_xml.root).returns(mock_new_node)
55
- result = @container.to_xml(doc)
58
+ doc.root.expects(:add_child).with(subject.ng_xml.root).returns(mock_new_node)
59
+ result = subject.to_xml(doc)
56
60
  end
57
61
 
58
62
  it 'should accept an optional Nokogiri::XML Document as an argument and insert its fields into that (functional test)' do
59
63
  doc = Nokogiri::XML::Document.parse("<test_xml/>")
60
- @container.to_xml(doc).should == "<?xml version=\"1.0\"?>\n<test_xml>\n <foo>\n <bar>1</bar>\n </foo>\n</test_xml>\n"
64
+ subject.to_xml(doc).should == "<?xml version=\"1.0\"?>\n<test_xml>\n <foo>\n <bar>1</bar>\n </foo>\n</test_xml>\n"
61
65
  end
62
66
 
63
67
  it 'should add to root of Nokogiri::XML::Documents, but add directly to the elements if a Nokogiri::XML::Node is passed in' do
@@ -66,10 +70,10 @@ describe "OM::XML::Container" do
66
70
 
67
71
  doc = Nokogiri::XML::Document.parse("<test_document/>")
68
72
  el = Nokogiri::XML::Node.new("test_element", Nokogiri::XML::Document.new)
69
- doc.root.expects(:add_child).with(@container.ng_xml.root).returns(mock_new_node)
70
- el.expects(:add_child).with(@container.ng_xml.root).returns(mock_new_node)
71
- @container.to_xml(doc).should
72
- @container.to_xml(el)
73
+ doc.root.expects(:add_child).with(subject.ng_xml.root).returns(mock_new_node)
74
+ el.expects(:add_child).with(subject.ng_xml.root).returns(mock_new_node)
75
+ subject.to_xml(doc).should
76
+ subject.to_xml(el)
73
77
  end
74
78
  end
75
79
 
@@ -132,11 +132,14 @@ describe "OM::XML::DynamicNode" do
132
132
  end
133
133
 
134
134
  it "should append nodes at the specified index if possible, setting dirty to true if the object responds to dirty" do
135
+ # backwards-compatible stuff..
135
136
  @article.stubs(:respond_to?).with(:dirty=).returns(true)
136
- @article.expects(:dirty=).with(true).twice
137
+ @article.expects(:dirty=).with(true).at_least(2)
138
+
137
139
  @article.journal.title_info = ["all", "for", "the"]
138
140
  @article.journal.title_info(3, 'glory')
139
141
  @article.term_values(:journal, :title_info).should == ["all", "for", "the", "glory"]
142
+ @article.should be_changed
140
143
  end
141
144
 
142
145
  end
@@ -28,6 +28,7 @@ describe "OM::XML::TermValueOperators" do
28
28
  test_args = {[{:person=>0}, :first_name]=>{"0"=>"Replacement FirstName"}}
29
29
  @article.update_values(test_args)
30
30
  @article.term_values({:person=>0}, :first_name).should == ["Replacement FirstName"]
31
+ @article.should be_changed
31
32
  end
32
33
 
33
34
  it "should update the xml according to the find_by_terms_and_values in the given hash" do
@@ -39,6 +40,7 @@ describe "OM::XML::TermValueOperators" do
39
40
  terms_update_hash = {[{":person"=>"0"}, "affiliation"]=>{"0"=>"affiliation1", "1"=>"affiliation2", "2"=>"affiliation3"}, [{:person=>1}, :last_name]=>"Andronicus", [{"person"=>"1"},:first_name]=>["Titus"],[{:person=>1},:role]=>["otherrole1","otherrole2"] }
40
41
  result = @article.update_values(terms_update_hash)
41
42
  result.should == {"person_0_affiliation"=>{"0"=>"affiliation1", "1"=>"affiliation2", "2"=>"affiliation3"}, "person_1_last_name"=>{"0"=>"Andronicus"},"person_1_first_name"=>{"0"=>"Titus"}, "person_1_role"=>{"0"=>"otherrole1","1"=>"otherrole2"}}
43
+ @article.should be_changed
42
44
  end
43
45
 
44
46
  it "should work when you re-run the command" do
@@ -66,6 +68,7 @@ describe "OM::XML::TermValueOperators" do
66
68
  terms_update_hash = {[{":person"=>"0"}, "affiliation"]=>{"0"=>"affiliation1", "1"=>"affiliation2", "2"=>"affiliation3"}, [{:person=>1}, :last_name]=>"Andronicus", [{"person"=>"1"},:first_name]=>["Titus"],[{:person=>1},:role]=>["otherrole1","otherrole2"] }
67
69
  result = @article.update_values(terms_update_hash)
68
70
  result.should == {"person_0_affiliation"=>{"0"=>"affiliation1", "1"=>"affiliation2", "2"=>"affiliation3"}, "person_1_last_name"=>{"0"=>"Andronicus"},"person_1_first_name"=>{"0"=>"Titus"}, "person_1_role"=>{"0"=>"otherrole1","1"=>"otherrole2"}}
71
+ @article.should be_changed
69
72
  end
70
73
  end
71
74
 
@@ -1,204 +1,243 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe "OM::XML::Term" do
4
-
5
- before(:each) do
6
- @test_name_part = OM::XML::Term.new(:namePart, {}).generate_xpath_queries!
7
- @test_volume = OM::XML::Term.new(:volume, :path=>"detail", :attributes=>{:type=>"volume"}, :default_content_path=>"number")
8
- @test_date = OM::XML::Term.new(:namePart, :attributes=>{:type=> "date"})
9
- @test_person = OM::XML::Term.new(:namePart, :attributes=>{:type=> :none})
10
- @test_affiliation = OM::XML::Term.new(:affiliation)
11
- @test_role_code = OM::XML::Term.new(:roleTerm, :attributes=>{:type=>"code"})
12
- @test_type = OM::XML::Term.new(:class)
13
- end
14
-
15
- describe '#new' do
16
- it "should set path from mapper name if no path is provided" do
17
- @test_name_part.path.should == "namePart"
18
- end
19
- it "should populate the xpath values if no options are provided" do
20
- local_mapping = OM::XML::Term.new(:namePart)
21
- local_mapping.xpath_relative.should be_nil
22
- local_mapping.xpath.should be_nil
23
- local_mapping.xpath_constrained.should be_nil
3
+ describe OM::XML::Term do
4
+ describe "without a type" do
5
+ subject { OM::XML::Term.new(:test_term) }
6
+ its (:type) { should == :string }
7
+ end
8
+ describe "when type is specified" do
9
+ subject { OM::XML::Term.new(:test_term, :type=>:date)}
10
+ its (:type) { should == :date }
11
+ end
12
+
13
+ describe "a big test" do
14
+ before(:each) do
15
+ @test_name_part = OM::XML::Term.new(:namePart, {}).generate_xpath_queries!
16
+ @test_volume = OM::XML::Term.new(:volume, :path=>"detail", :attributes=>{:type=>"volume"}, :default_content_path=>"number")
17
+ @test_date = OM::XML::Term.new(:namePart, :attributes=>{:type=> "date"})
18
+ @test_person = OM::XML::Term.new(:namePart, :attributes=>{:type=> :none})
19
+ @test_affiliation = OM::XML::Term.new(:affiliation)
20
+ @test_role_code = OM::XML::Term.new(:roleTerm, :attributes=>{:type=>"code"})
21
+ @test_type = OM::XML::Term.new(:class)
22
+ end
23
+
24
+ describe '#new' do
25
+ it "should set path from mapper name if no path is provided" do
26
+ @test_name_part.path.should == "namePart"
27
+ end
28
+ it "should populate the xpath values if no options are provided" do
29
+ local_mapping = OM::XML::Term.new(:namePart)
30
+ local_mapping.xpath_relative.should be_nil
31
+ local_mapping.xpath.should be_nil
32
+ local_mapping.xpath_constrained.should be_nil
33
+ end
24
34
  end
25
- end
26
35
 
27
- describe 'inner_xml' do
28
- it "should be a kind of Nokogiri::XML::Node" do
29
- pending
30
- @test_mapping.inner_xml.should be_kind_of(Nokogiri::XML::Node)
36
+ describe 'inner_xml' do
37
+ it "should be a kind of Nokogiri::XML::Node" do
38
+ pending
39
+ @test_mapping.inner_xml.should be_kind_of(Nokogiri::XML::Node)
40
+ end
31
41
  end
32
- end
33
42
 
34
- describe '#from_node' do
35
- it "should create a mapper from a nokogiri node" do
36
- pending "probably should do this in the Builder"
37
- ng_builder = Nokogiri::XML::Builder.new do |xml|
38
- xml.mapper(:name=>"person", :path=>"name") {
39
- xml.attribute(:name=>"type", :value=>"personal")
40
- xml.mapper(:name=>"first_name", :path=>"namePart") {
41
- xml.attribute(:name=>"type", :value=>"given")
42
- xml.attribute(:name=>"another_attribute", :value=>"myval")
43
+ describe '#from_node' do
44
+ it "should create a mapper from a nokogiri node" do
45
+ pending "probably should do this in the Builder"
46
+ ng_builder = Nokogiri::XML::Builder.new do |xml|
47
+ xml.mapper(:name=>"person", :path=>"name") {
48
+ xml.attribute(:name=>"type", :value=>"personal")
49
+ xml.mapper(:name=>"first_name", :path=>"namePart") {
50
+ xml.attribute(:name=>"type", :value=>"given")
51
+ xml.attribute(:name=>"another_attribute", :value=>"myval")
52
+ }
43
53
  }
44
- }
54
+ end
55
+ # node = Nokogiri::XML::Document.parse( '<mapper name="first_name" path="namePart"><attribute name="type" value="given"/><attribute name="another_attribute" value="myval"/></mapper>' ).root
56
+ node = ng_builder.doc.root
57
+ mapper = OM::XML::Term.from_node(node)
58
+ mapper.name.should == :person
59
+ mapper.path.should == "name"
60
+ mapper.attributes.should == {:type=>"personal"}
61
+ mapper.internal_xml.should == node
62
+
63
+ child = mapper.children[:first_name]
64
+
65
+ child.name.should == :first_name
66
+ child.path.should == "namePart"
67
+ child.attributes.should == {:type=>"given", :another_attribute=>"myval"}
68
+ child.internal_xml.should == node.xpath("./mapper").first
45
69
  end
46
- # node = Nokogiri::XML::Document.parse( '<mapper name="first_name" path="namePart"><attribute name="type" value="given"/><attribute name="another_attribute" value="myval"/></mapper>' ).root
47
- node = ng_builder.doc.root
48
- mapper = OM::XML::Term.from_node(node)
49
- mapper.name.should == :person
50
- mapper.path.should == "name"
51
- mapper.attributes.should == {:type=>"personal"}
52
- mapper.internal_xml.should == node
53
-
54
- child = mapper.children[:first_name]
55
-
56
- child.name.should == :first_name
57
- child.path.should == "namePart"
58
- child.attributes.should == {:type=>"given", :another_attribute=>"myval"}
59
- child.internal_xml.should == node.xpath("./mapper").first
60
70
  end
61
- end
62
71
 
63
- describe ".label" do
64
- it "should default to the mapper name with underscores converted to spaces"
65
- end
72
+ describe ".label" do
73
+ it "should default to the mapper name with underscores converted to spaces"
74
+ end
66
75
 
67
- describe ".retrieve_term" do
68
- it "should crawl down into mapper children to find the desired term" do
69
- mock_role = mock("mapper", :children =>{:text=>"the target"})
70
- mock_conference = mock("mapper", :children =>{:role=>mock_role})
71
- @test_name_part.expects(:children).returns({:conference=>mock_conference})
72
- @test_name_part.retrieve_term(:conference, :role, :text).should == "the target"
76
+ describe ".retrieve_term" do
77
+ it "should crawl down into mapper children to find the desired term" do
78
+ mock_role = mock("mapper", :children =>{:text=>"the target"})
79
+ mock_conference = mock("mapper", :children =>{:role=>mock_role})
80
+ @test_name_part.expects(:children).returns({:conference=>mock_conference})
81
+ @test_name_part.retrieve_term(:conference, :role, :text).should == "the target"
82
+ end
83
+ it "should return an empty hash if no term can be found" do
84
+ @test_name_part.retrieve_term(:journal, :issue, :end_page).should == nil
85
+ end
73
86
  end
74
- it "should return an empty hash if no term can be found" do
75
- @test_name_part.retrieve_term(:journal, :issue, :end_page).should == nil
87
+
88
+ describe 'inner_xml' do
89
+ it "should be a kind of Nokogiri::XML::Node" do
90
+ pending
91
+ @test_name_part.inner_xml.should be_kind_of(Nokogiri::XML::Node)
92
+ end
76
93
  end
77
- end
78
94
 
79
- describe 'inner_xml' do
80
- it "should be a kind of Nokogiri::XML::Node" do
81
- pending
82
- @test_name_part.inner_xml.should be_kind_of(Nokogiri::XML::Node)
95
+ describe "getters/setters" do
96
+ it "should set the corresponding .settings value and return the current value" do
97
+ # :index_as is a special case
98
+ [:path, :required, :data_type, :variant_of, :path, :attributes, :default_content_path, :namespace_prefix].each do |method_name|
99
+ @test_name_part.send(method_name.to_s+"=", "#{method_name.to_s}foo").should == "#{method_name.to_s}foo"
100
+ @test_name_part.send(method_name).should == "#{method_name.to_s}foo"
101
+ end
102
+ end
83
103
  end
84
- end
85
104
 
86
- describe "getters/setters" do
87
- it "should set the corresponding .settings value and return the current value" do
88
- [:path, :index_as, :required, :data_type, :variant_of, :path, :attributes, :default_content_path, :namespace_prefix].each do |method_name|
89
- @test_name_part.send(method_name.to_s+"=", "#{method_name.to_s}foo").should == "#{method_name.to_s}foo"
90
- @test_name_part.send(method_name).should == "#{method_name.to_s}foo"
105
+ describe "OM terminology should accept a symbol as a value to :index_as" do
106
+ subject {
107
+ class TestTerminology
108
+ include OM::XML::Document
109
+
110
+ set_terminology do |t|
111
+ t.as_array :index_as => [:not_searchable]
112
+ t.as_symbol :index_as => :not_searchable
113
+ end
114
+ end
115
+
116
+ TestTerminology
117
+ }
118
+
119
+ it "should accept an array as an :index_as value" do
120
+ subject.terminology.terms[:as_array].index_as.should be_a_kind_of(Array)
121
+ subject.terminology.terms[:as_array].index_as.should == [:not_searchable]
122
+ end
123
+ it "should accept a plain symbol as a value to :index_as" do
124
+ subject.terminology.terms[:as_symbol].index_as.should be_a_kind_of(Array)
125
+ subject.terminology.terms[:as_symbol].index_as.should == [:not_searchable]
91
126
  end
92
127
  end
93
- end
94
- it "should have a .terminology attribute accessor" do
95
- @test_volume.should respond_to :terminology
96
- @test_volume.should respond_to :terminology=
97
- end
98
- describe ".ancestors" do
99
- it "should return an array of Terms that are the ancestors of the current object, ordered from the top/root of the hierarchy" do
100
- @test_volume.set_parent(@test_name_part)
101
- @test_volume.ancestors.should == [@test_name_part]
128
+ it "should have a .terminology attribute accessor" do
129
+ @test_volume.should respond_to :terminology
130
+ @test_volume.should respond_to :terminology=
102
131
  end
103
- end
104
- describe ".parent" do
105
- it "should retrieve the immediate parent of the given object from the ancestors array" do
106
- # @test_name_part.expects(:ancestors).returns(["ancestor1","ancestor2","ancestor3"])
107
- @test_name_part.ancestors = ["ancestor1","ancestor2","ancestor3"]
108
- @test_name_part.parent.should == "ancestor3"
132
+ describe ".ancestors" do
133
+ it "should return an array of Terms that are the ancestors of the current object, ordered from the top/root of the hierarchy" do
134
+ @test_volume.set_parent(@test_name_part)
135
+ @test_volume.ancestors.should == [@test_name_part]
136
+ end
109
137
  end
110
- end
111
- describe ".children" do
112
- it "should return a hash of Terms that are the children of the current object, indexed by name" do
113
- @test_volume.add_child(@test_name_part)
114
- @test_volume.children[@test_name_part.name].should == @test_name_part
138
+ describe ".parent" do
139
+ it "should retrieve the immediate parent of the given object from the ancestors array" do
140
+ # @test_name_part.expects(:ancestors).returns(["ancestor1","ancestor2","ancestor3"])
141
+ @test_name_part.ancestors = ["ancestor1","ancestor2","ancestor3"]
142
+ @test_name_part.parent.should == "ancestor3"
143
+ end
115
144
  end
116
- end
117
- describe ".retrieve_child" do
118
- it "should fetch the child identified by the given name" do
119
- @test_volume.add_child(@test_name_part)
120
- @test_volume.retrieve_child(@test_name_part.name).should == @test_volume.children[@test_name_part.name]
145
+ describe ".children" do
146
+ it "should return a hash of Terms that are the children of the current object, indexed by name" do
147
+ @test_volume.add_child(@test_name_part)
148
+ @test_volume.children[@test_name_part.name].should == @test_name_part
149
+ end
121
150
  end
122
- end
123
- describe ".set_parent" do
124
- it "should insert the mapper into the given parent" do
125
- @test_name_part.set_parent(@test_volume)
126
- @test_name_part.ancestors.should include(@test_volume)
127
- @test_volume.children[@test_name_part.name].should == @test_name_part
151
+ describe ".retrieve_child" do
152
+ it "should fetch the child identified by the given name" do
153
+ @test_volume.add_child(@test_name_part)
154
+ @test_volume.retrieve_child(@test_name_part.name).should == @test_volume.children[@test_name_part.name]
155
+ end
128
156
  end
129
- end
130
- describe ".add_child" do
131
- it "should insert the given mapper into the current mappers children" do
132
- @test_volume.add_child(@test_name_part)
133
- @test_volume.children[@test_name_part.name].should == @test_name_part
134
- @test_name_part.ancestors.should include(@test_volume)
157
+ describe ".set_parent" do
158
+ it "should insert the mapper into the given parent" do
159
+ @test_name_part.set_parent(@test_volume)
160
+ @test_name_part.ancestors.should include(@test_volume)
161
+ @test_volume.children[@test_name_part.name].should == @test_name_part
162
+ end
135
163
  end
136
- end
137
-
138
- describe "generate_xpath_queries!" do
139
- it "should return the current object" do
140
- @test_name_part.generate_xpath_queries!.should == @test_name_part
164
+ describe ".add_child" do
165
+ it "should insert the given mapper into the current mappers children" do
166
+ @test_volume.add_child(@test_name_part)
167
+ @test_volume.children[@test_name_part.name].should == @test_name_part
168
+ @test_name_part.ancestors.should include(@test_volume)
169
+ end
141
170
  end
142
- it "should regenerate the xpath values" do
143
- @test_volume.xpath_relative.should be_nil
144
- @test_volume.xpath.should be_nil
145
- @test_volume.xpath_constrained.should be_nil
146
171
 
147
- @test_volume.generate_xpath_queries!.should == @test_volume
172
+ describe "generate_xpath_queries!" do
173
+ it "should return the current object" do
174
+ @test_name_part.generate_xpath_queries!.should == @test_name_part
175
+ end
176
+ it "should regenerate the xpath values" do
177
+ @test_volume.xpath_relative.should be_nil
178
+ @test_volume.xpath.should be_nil
179
+ @test_volume.xpath_constrained.should be_nil
148
180
 
149
- @test_volume.xpath_relative.should == 'detail[@type="volume"]'
150
- @test_volume.xpath.should == '//detail[@type="volume"]'
151
- @test_volume.xpath_constrained.should == '//detail[@type="volume" and contains(number, "#{constraint_value}")]'.gsub('"', '\"')
152
- end
153
- it "should trigger update on any child objects" do
154
- mock_child = mock("child term")
155
- mock_child.expects(:generate_xpath_queries!).times(3)
156
- @test_name_part.expects(:children).returns({1=>mock_child, 2=>mock_child, 3=>mock_child})
157
- @test_name_part.generate_xpath_queries!
181
+ @test_volume.generate_xpath_queries!.should == @test_volume
182
+
183
+ @test_volume.xpath_relative.should == 'detail[@type="volume"]'
184
+ @test_volume.xpath.should == '//detail[@type="volume"]'
185
+ @test_volume.xpath_constrained.should == '//detail[@type="volume" and contains(number, "#{constraint_value}")]'.gsub('"', '\"')
186
+ end
187
+ it "should trigger update on any child objects" do
188
+ mock_child = mock("child term")
189
+ mock_child.expects(:generate_xpath_queries!).times(3)
190
+ @test_name_part.expects(:children).returns({1=>mock_child, 2=>mock_child, 3=>mock_child})
191
+ @test_name_part.generate_xpath_queries!
192
+ end
158
193
  end
159
- end
160
194
 
161
- describe "#xml_builder_template" do
195
+ describe "#xml_builder_template" do
162
196
 
163
- it "should generate a template call for passing into the builder block (assumes 'xml' as the argument for the block)" do
164
- @test_date.xml_builder_template.should == 'xml.namePart( \'#{builder_new_value}\', \'type\'=>\'date\' )'
165
- @test_person.xml_builder_template.should == 'xml.namePart( \'#{builder_new_value}\' )'
166
- @test_affiliation.xml_builder_template.should == 'xml.affiliation( \'#{builder_new_value}\' )'
167
- end
168
- it "should accept extra options" do
169
- marcrelator_role_xml_builder_template = 'xml.roleTerm( \'#{builder_new_value}\', \'type\'=>\'code\', \'authority\'=>\'marcrelator\' )'
170
- @test_role_code.xml_builder_template(:attributes=>{"authority"=>"marcrelator"}).should == marcrelator_role_xml_builder_template
171
- end
197
+ it "should generate a template call for passing into the builder block (assumes 'xml' as the argument for the block)" do
198
+ @test_date.xml_builder_template.should == 'xml.namePart( \'#{builder_new_value}\', \'type\'=>\'date\' )'
199
+ @test_person.xml_builder_template.should == 'xml.namePart( \'#{builder_new_value}\' )'
200
+ @test_affiliation.xml_builder_template.should == 'xml.affiliation( \'#{builder_new_value}\' )'
201
+ end
172
202
 
173
- it "should work for namespaced nodes" do
174
- @ical_date = OM::XML::Term.new(:ical_date, :path=>"ical:date")
175
- @ical_date.xml_builder_template.should == "xml[\'ical\'].date( '\#{builder_new_value}' )"
176
- @ical_date = OM::XML::Term.new(:ical_date, :path=>"date", :namespace_prefix=>"ical")
177
- @ical_date.xml_builder_template.should == "xml[\'ical\'].date( '\#{builder_new_value}' )"
178
- end
203
+ it "should accept extra options" do
204
+ # Expected marcrelator_role_xml_builder_template.
205
+ # Include both version to handle either ordering of the hash -- a band-aid hack to fix failing test.
206
+ e1 = %q{xml.roleTerm( '#{builder_new_value}', 'type'=>'code', 'authority'=>'marcrelator' )}
207
+ e2 = %q{xml.roleTerm( '#{builder_new_value}', 'authority'=>'marcrelator', 'type'=>'code' )}
208
+ got = @test_role_code.xml_builder_template(:attributes=>{"authority"=>"marcrelator"})
209
+ [e1, e2].should include(got)
210
+ end
179
211
 
180
- it "should work for nodes with default_content_path" do
181
- @test_volume.xml_builder_template.should == "xml.detail( \'type\'=>'volume' ) { xml.number( '\#{builder_new_value}' ) }"
182
- end
212
+ it "should work for namespaced nodes" do
213
+ @ical_date = OM::XML::Term.new(:ical_date, :path=>"ical:date")
214
+ @ical_date.xml_builder_template.should == "xml[\'ical\'].date( '\#{builder_new_value}' )"
215
+ @ical_date = OM::XML::Term.new(:ical_date, :path=>"date", :namespace_prefix=>"ical")
216
+ @ical_date.xml_builder_template.should == "xml[\'ical\'].date( '\#{builder_new_value}' )"
217
+ end
183
218
 
184
- it "should support terms that are attributes" do
185
- @type_attribute_term = OM::XML::Term.new(:type_attribute, :path=>{:attribute=>:type})
186
- @type_attribute_term.xml_builder_template.should == "xml.@type( '\#{builder_new_value}' )"
187
- end
219
+ it "should work for nodes with default_content_path" do
220
+ @test_volume.xml_builder_template.should == "xml.detail( \'type\'=>'volume' ) { xml.number( '\#{builder_new_value}' ) }"
221
+ end
188
222
 
189
- it "should support terms with namespaced attributes" do
190
- @french_title = OM::XML::Term.new(:french_title, :path=>"title", :attributes=>{"xml:lang"=>"fre"})
191
- @french_title.xml_builder_template.should == "xml.title( '\#{builder_new_value}', 'xml:lang'=>'fre' )"
192
- end
223
+ it "should support terms that are attributes" do
224
+ @type_attribute_term = OM::XML::Term.new(:type_attribute, :path=>{:attribute=>:type})
225
+ @type_attribute_term.xml_builder_template.should == "xml.@type( '\#{builder_new_value}' )"
226
+ end
193
227
 
194
- it "should support terms that are namespaced attributes" do
195
- @xml_lang_attribute_term = OM::XML::Term.new(:xml_lang_attribute, :path=>{:attribute=>"xml:lang"})
196
- @xml_lang_attribute_term.xml_builder_template.should == "xml.@xml:lang( '\#{builder_new_value}' )"
197
- end
198
-
199
- it "should generate a template call for passing into the builder block (assumes 'xml' as the argument for the block) for terms that share a name with an existing method on the builder" do
200
- @test_type.xml_builder_template.should == 'xml.class_( \'#{builder_new_value}\' )'
228
+ it "should support terms with namespaced attributes" do
229
+ @french_title = OM::XML::Term.new(:french_title, :path=>"title", :attributes=>{"xml:lang"=>"fre"})
230
+ @french_title.xml_builder_template.should == "xml.title( '\#{builder_new_value}', 'xml:lang'=>'fre' )"
231
+ end
232
+
233
+ it "should support terms that are namespaced attributes" do
234
+ @xml_lang_attribute_term = OM::XML::Term.new(:xml_lang_attribute, :path=>{:attribute=>"xml:lang"})
235
+ @xml_lang_attribute_term.xml_builder_template.should == "xml.@xml:lang( '\#{builder_new_value}' )"
236
+ end
237
+
238
+ it "should generate a template call for passing into the builder block (assumes 'xml' as the argument for the block) for terms that share a name with an existing method on the builder" do
239
+ @test_type.xml_builder_template.should == 'xml.class_( \'#{builder_new_value}\' )'
240
+ end
201
241
  end
202
242
  end
203
-
204
243
  end