om 1.1.1 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile CHANGED
@@ -8,4 +8,5 @@ group :development, :test do
8
8
  gem "rspec", "<2.0.0"
9
9
  gem "mocha", ">= 0.9.8"
10
10
  gem "ruby-debug"
11
+ gem "equivalent-xml", ">= 0.1.6"
11
12
  end
data/Gemfile.lock CHANGED
@@ -2,6 +2,8 @@ GEM
2
2
  remote: http://rubygems.org/
3
3
  specs:
4
4
  columnize (0.3.2)
5
+ equivalent-xml (0.1.6)
6
+ nokogiri
5
7
  facets (2.9.1)
6
8
  git (1.2.5)
7
9
  jeweler (1.5.2)
@@ -23,6 +25,7 @@ PLATFORMS
23
25
  ruby
24
26
 
25
27
  DEPENDENCIES
28
+ equivalent-xml (>= 0.1.6)
26
29
  facets
27
30
  jeweler
28
31
  mocha (>= 0.9.8)
data/History.textile CHANGED
@@ -1,4 +1,8 @@
1
- 1.0.1
1
+ 1.2.0
2
+
3
+ added OM::XML::TemplateRegistry for built-in templating and creation of new XML nodes
4
+
5
+ 1.1.1
2
6
 
3
7
  "HYDRA-395":https://jira.duraspace.org/browse/HYDRA-395: Fixed bug that prevented you from appending term values with apostrophes in them
4
8
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.1.1
1
+ 1.2.0
data/lib/om/xml.rb CHANGED
@@ -9,6 +9,7 @@ require "om/xml/term_value_operators"
9
9
  require "om/xml/named_term_proxy"
10
10
  require "om/xml/document"
11
11
 
12
+ require "om/xml/template_registry"
12
13
 
13
14
  module OM::XML
14
15
 
@@ -5,7 +5,7 @@ module OM::XML::Document
5
5
 
6
6
  module ClassMethods
7
7
 
8
- attr_accessor :terminology
8
+ attr_accessor :terminology, :template_registry
9
9
 
10
10
  # Sets the OM::XML::Terminology for the Document
11
11
  # Expects +&block+ that will be passed into OM::XML::Terminology::Builder.new
@@ -13,6 +13,15 @@ module OM::XML::Document
13
13
  @terminology = OM::XML::Terminology::Builder.new( &block ).build
14
14
  end
15
15
 
16
+ # Define a new node template with the OM::XML::TemplateRegistry.
17
+ # * +name+ is a Symbol indicating the name of the new template.
18
+ # * The +block+ does the work of creating the new node, and will receive
19
+ # a Nokogiri::XML::Builder and any other args passed to one of the node instantiation methods.
20
+ def define_template name, &block
21
+ @template_registry ||= OM::XML::TemplateRegistry.new
22
+ @template_registry.define name, &block
23
+ end
24
+
16
25
  # Returns any namespaces defined by the Class' Terminology
17
26
  def ox_namespaces
18
27
  if @terminology.nil?
@@ -58,11 +67,70 @@ module OM::XML::Document
58
67
  return ng_xml.xpath(xpath, ox_namespaces)
59
68
  end
60
69
  end
70
+
71
+ # Access the class's template registry
72
+ def template_registry
73
+ self.class.template_registry
74
+ end
75
+
76
+ # Instantiate a +node_type+ template and add it as a child of +target_node+, where +target_node+ is one of:
77
+ # * a Nokogiri::XML::Node
78
+ # * a single-element Nokogiri::XML::NodeSet
79
+ # * a +term_pointer+ array resolving to a single-element Nokogiri::XML::NodeSet
80
+ # Additional arguments will be passed to the template unaltered.
81
+ #
82
+ # Returns the new Nokogiri::XML::Node.
83
+ def add_child_node(target_node, node_type, *args)
84
+ manipulate_node(:add_child, target_node, node_type, *args)
85
+ end
86
+
87
+ # Instantiate a +node_type+ template and insert it as the following sibling of +target_node+.
88
+ # Returns the new Nokogiri::XML::Node.
89
+ def add_next_sibling_node(target_node, node_type, *args)
90
+ manipulate_node(:add_next_sibling, target_node, node_type, *args)
91
+ end
92
+
93
+ # Instantiate a +node_type+ template and insert it as the preceding sibling of +target_node+.
94
+ # Returns the new Nokogiri::XML::Node.
95
+ def add_previous_sibling_node(target_node, node_type, *args)
96
+ manipulate_node(:add_previous_sibling, target_node, node_type, *args)
97
+ end
98
+
99
+ # Instantiate a +node_type+ template and insert it as the following sibling of +target_node+.
100
+ # Returns +target_node+.
101
+ def after_node(target_node, node_type, *args)
102
+ manipulate_node(:after, target_node, node_type, *args)
103
+ end
104
+
105
+ # Instantiate a +node_type+ template and insert it as the preceding sibling of +target_node+.
106
+ # Returns +target_node+.
107
+ def before_node(target_node, node_type, *args)
108
+ manipulate_node(:before, target_node, node_type, *args)
109
+ end
110
+
111
+ # Instantiate a +node_type+ template and replace +target_node+ with it.
112
+ # Returns the new Nokogiri::XML::Node.
113
+ def replace_node(target_node, node_type, *args)
114
+ manipulate_node(:replace, target_node, node_type, *args)
115
+ end
116
+
117
+ # Instantiate a +node_type+ template and replace +target_node+ with it.
118
+ # Returns +target_node+.
119
+ def swap_node(target_node, node_type, *args)
120
+ manipulate_node(:swap, target_node, node_type, *args)
121
+ end
61
122
 
62
123
  # Returns a hash combining the current documents namespaces (provided by nokogiri) and any namespaces that have been set up by your Terminology.
63
124
  # Most importantly, this matches the 'oxns' namespace to the namespace you provided in your Terminology's root term config
64
125
  def ox_namespaces
65
126
  @ox_namespaces ||= ng_xml.namespaces.merge(self.class.ox_namespaces)
66
127
  end
67
-
128
+
129
+ private
130
+ def manipulate_node(method, target, *args)
131
+ if target.is_a?(Array)
132
+ target = self.find_by_terms(*target)
133
+ end
134
+ template_registry.send(method, target, *args)
135
+ end
68
136
  end
@@ -0,0 +1,146 @@
1
+ class OM::XML::TemplateRegistry
2
+
3
+ def initialize
4
+ @templates = {}
5
+ end
6
+
7
+ # Define an XML template
8
+ # @param [Symbol] a node_type key to associate with this template
9
+ # @param [Block] a block that will receive a [Nokogiri::XML::Builder] object and any arbitrary parameters passed to +instantiate+
10
+ # @return the +node_type+ Symbol
11
+ def define(node_type, &block)
12
+ unless node_type.is_a?(Symbol)
13
+ raise TypeError, "Registered node type must be a Symbol (e.g., :person)"
14
+ end
15
+
16
+ @templates[node_type] = block
17
+ node_type
18
+ end
19
+
20
+ # Undefine an XML template
21
+ # @param [Symbol] the node_type key of the template to undefine
22
+ # @return the +node_type+ Symbol
23
+ def undefine(node_type)
24
+ @templates.delete(node_type)
25
+ node_type
26
+ end
27
+
28
+ # Check whether a particular node_type is defined
29
+ # @param [Symbol] the node_type key to check
30
+ # @return [True] or [False]
31
+ def has_node_type?(node_type)
32
+ @templates.has_key?(node_type)
33
+ end
34
+
35
+ # List defined node_types
36
+ # @return [Array] of node_type symbols.
37
+ def node_types
38
+ @templates.keys
39
+ end
40
+
41
+ # Instantiate a detached, standalone node
42
+ # @param [Symbol] the node_type to instantiate
43
+ # @param additional arguments to pass to the template
44
+ def instantiate(node_type, *args)
45
+ result = create_detached_node(nil, node_type, *args)
46
+ # Strip namespaces from text and CDATA nodes. Stupid Nokogiri.
47
+ result.traverse { |node|
48
+ if node.is_a?(Nokogiri::XML::CharacterData)
49
+ node.namespace = nil
50
+ end
51
+ }
52
+ return result
53
+ end
54
+
55
+ # +instantiate+ a node and add it as a child of the [Nokogiri::XML::Node] specified by +target_node+
56
+ # @return the new [Nokogiri::XML::Node]
57
+ def add_child(target_node, node_type, *args)
58
+ attach_node(:add_child, target_node, :self, node_type, *args)
59
+ end
60
+
61
+ # +instantiate+ a node and add it as a following sibling of the [Nokogiri::XML::Node] specified by +target_node+
62
+ # @return the new [Nokogiri::XML::Node]
63
+ def add_next_sibling(target_node, node_type, *args)
64
+ attach_node(:add_next_sibling, target_node, :parent, node_type, *args)
65
+ end
66
+
67
+ # +instantiate+ a node and add it as a preceding sibling of the [Nokogiri::XML::Node] specified by +target_node+
68
+ # @return the new [Nokogiri::XML::Node]
69
+ def add_previous_sibling(target_node, node_type, *args)
70
+ attach_node(:add_previous_sibling, target_node, :parent, node_type, *args)
71
+ end
72
+
73
+ # +instantiate+ a node and add it as a following sibling of the [Nokogiri::XML::Node] specified by +target_node+
74
+ # @return +target_node+
75
+ def after(target_node, node_type, *args)
76
+ attach_node(:after, target_node, :parent, node_type, *args)
77
+ end
78
+
79
+ # +instantiate+ a node and add it as a preceding sibling of the [Nokogiri::XML::Node] specified by +target_node+
80
+ # @return +target_node+
81
+ def before(target_node, node_type, *args)
82
+ attach_node(:before, target_node, :parent, node_type, *args)
83
+ end
84
+
85
+ # +instantiate+ a node replace the [Nokogiri::XML::Node] specified by +target_node+ with it
86
+ # @return the new [Nokogiri::XML::Node]
87
+ def replace(target_node, node_type, *args)
88
+ attach_node(:replace, target_node, :parent, node_type, *args)
89
+ end
90
+
91
+ # +instantiate+ a node replace the [Nokogiri::XML::Node] specified by +target_node+ with it
92
+ # @return +target_node+
93
+ def swap(target_node, node_type, *args)
94
+ attach_node(:swap, target_node, :parent, node_type, *args)
95
+ end
96
+
97
+ def methods
98
+ super + @templates.keys.collect { |k| k.to_s }
99
+ end
100
+
101
+ def method_missing(sym,*args)
102
+ sym = sym.to_s.sub(/_$/,'').to_sym
103
+ if @templates.has_key?(sym)
104
+ instantiate(sym,*args)
105
+ else
106
+ super(sym,*args)
107
+ end
108
+ end
109
+
110
+ private
111
+ def create_detached_node(builder_node, node_type, *args)
112
+ proc = @templates[node_type]
113
+ if proc.nil?
114
+ raise NameError, "Unknown node type: #{node_type.to_s}"
115
+ end
116
+ if builder_node.nil?
117
+ builder_node = empty_root_node
118
+ end
119
+
120
+ builder = Nokogiri::XML::Builder.with(builder_node) do |xml|
121
+ proc.call(xml,*args)
122
+ end
123
+ builder_node.elements.last.remove
124
+ end
125
+
126
+ def attach_node(method, target_node, builder_node_offset, node_type, *args)
127
+ if target_node.is_a?(Nokogiri::XML::NodeSet) and target_node.length == 1
128
+ target_node = target_node.first
129
+ end
130
+ builder_node = builder_node_offset == :parent ? target_node.parent : target_node
131
+ new_node = create_detached_node(builder_node, node_type, *args)
132
+ result = target_node.send(method, new_node)
133
+ # Strip namespaces from text and CDATA nodes. Stupid Nokogiri.
134
+ new_node.traverse { |node|
135
+ if node.is_a?(Nokogiri::XML::CharacterData)
136
+ node.namespace = nil
137
+ end
138
+ }
139
+ return result
140
+ end
141
+
142
+ def empty_root_node
143
+ Nokogiri::XML('<root/>').root
144
+ end
145
+
146
+ end
data/om.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{om}
8
- s.version = "1.1.1"
8
+ s.version = "1.2.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Matt Zumwalt"]
12
- s.date = %q{2011-03-08}
12
+ s.date = %q{2011-03-22}
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
  s.email = %q{matt.zumwalt@yourmediashelf.com}
15
15
  s.extra_rdoc_files = [
@@ -37,6 +37,7 @@ Gem::Specification.new do |s|
37
37
  "lib/om/xml/document.rb",
38
38
  "lib/om/xml/named_term_proxy.rb",
39
39
  "lib/om/xml/node_generator.rb",
40
+ "lib/om/xml/template_registry.rb",
40
41
  "lib/om/xml/term.rb",
41
42
  "lib/om/xml/term_value_operators.rb",
42
43
  "lib/om/xml/term_xpath_generator.rb",
@@ -57,6 +58,7 @@ Gem::Specification.new do |s|
57
58
  "spec/unit/named_term_proxy_spec.rb",
58
59
  "spec/unit/node_generator_spec.rb",
59
60
  "spec/unit/om_spec.rb",
61
+ "spec/unit/template_registry_spec.rb",
60
62
  "spec/unit/term_builder_spec.rb",
61
63
  "spec/unit/term_spec.rb",
62
64
  "spec/unit/term_value_operators_spec.rb",
@@ -78,6 +80,7 @@ Gem::Specification.new do |s|
78
80
  "spec/unit/named_term_proxy_spec.rb",
79
81
  "spec/unit/node_generator_spec.rb",
80
82
  "spec/unit/om_spec.rb",
83
+ "spec/unit/template_registry_spec.rb",
81
84
  "spec/unit/term_builder_spec.rb",
82
85
  "spec/unit/term_spec.rb",
83
86
  "spec/unit/term_value_operators_spec.rb",
@@ -99,6 +102,7 @@ Gem::Specification.new do |s|
99
102
  s.add_development_dependency(%q<rspec>, ["< 2.0.0"])
100
103
  s.add_development_dependency(%q<mocha>, [">= 0.9.8"])
101
104
  s.add_development_dependency(%q<ruby-debug>, [">= 0"])
105
+ s.add_development_dependency(%q<equivalent-xml>, [">= 0.1.6"])
102
106
  s.add_runtime_dependency(%q<nokogiri>, [">= 1.4.2"])
103
107
  s.add_runtime_dependency(%q<facets>, [">= 0"])
104
108
  s.add_development_dependency(%q<rspec>, [">= 1.2.9"])
@@ -111,6 +115,7 @@ Gem::Specification.new do |s|
111
115
  s.add_dependency(%q<rspec>, ["< 2.0.0"])
112
116
  s.add_dependency(%q<mocha>, [">= 0.9.8"])
113
117
  s.add_dependency(%q<ruby-debug>, [">= 0"])
118
+ s.add_dependency(%q<equivalent-xml>, [">= 0.1.6"])
114
119
  s.add_dependency(%q<nokogiri>, [">= 1.4.2"])
115
120
  s.add_dependency(%q<facets>, [">= 0"])
116
121
  s.add_dependency(%q<rspec>, [">= 1.2.9"])
@@ -124,6 +129,7 @@ Gem::Specification.new do |s|
124
129
  s.add_dependency(%q<rspec>, ["< 2.0.0"])
125
130
  s.add_dependency(%q<mocha>, [">= 0.9.8"])
126
131
  s.add_dependency(%q<ruby-debug>, [">= 0"])
132
+ s.add_dependency(%q<equivalent-xml>, [">= 0.1.6"])
127
133
  s.add_dependency(%q<nokogiri>, [">= 1.4.2"])
128
134
  s.add_dependency(%q<facets>, [">= 0"])
129
135
  s.add_dependency(%q<rspec>, [">= 1.2.9"])
@@ -0,0 +1,214 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+ require "om"
3
+ require 'equivalent-xml'
4
+
5
+ describe "OM::XML::TemplateRegistry" do
6
+
7
+ before(:all) do
8
+ class RegistryTest
9
+
10
+ include OM::XML::Document
11
+
12
+ set_terminology do |t|
13
+ t.root(:path => "people", :xmlns => 'urn:registry-test')
14
+ t.person {
15
+ t.title(:path => "@title")
16
+ }
17
+ end
18
+
19
+ define_template :person do |xml,name,title|
20
+ xml.person(:title => title) do
21
+ xml.text(name)
22
+ end
23
+ end
24
+
25
+ end
26
+ end
27
+
28
+ after(:all) do
29
+ Object.send(:remove_const, :RegistryTest)
30
+ end
31
+
32
+ before(:each) do
33
+ @test_document = RegistryTest.from_xml('<people xmlns="urn:registry-test"><person title="Actor">Alice</person></people>')
34
+ @expectations = {
35
+ :before => %{<people xmlns="urn:registry-test"><person title="Builder">Bob</person><person title="Actor">Alice</person></people>},
36
+ :after => %{<people xmlns="urn:registry-test"><person title="Actor">Alice</person><person title="Builder">Bob</person></people>},
37
+ :instead => %{<people xmlns="urn:registry-test"><person title="Builder">Bob</person></people>}
38
+ }
39
+ end
40
+
41
+ describe "template definitions" do
42
+ it "should contain predefined templates" do
43
+ RegistryTest.template_registry.node_types.should include(:person)
44
+ RegistryTest.template_registry.node_types.should_not include(:zombie)
45
+ end
46
+
47
+ it "should define new templates" do
48
+ RegistryTest.template_registry.node_types.should_not include(:zombie)
49
+ RegistryTest.define_template :zombie do |xml,name|
50
+ xml.monster(:wants => 'braaaaainz') do
51
+ xml.text(name)
52
+ end
53
+ end
54
+ RegistryTest.template_registry.node_types.should include(:zombie)
55
+ end
56
+
57
+ it "should instantiate a detached node from a template" do
58
+ node = RegistryTest.template_registry.instantiate(:zombie, 'Zeke')
59
+ expectation = Nokogiri::XML('<monster wants="braaaaainz">Zeke</monster>').root
60
+ EquivalentXml.equivalent?(node, expectation).should == true
61
+ end
62
+
63
+ it "should raise an error when trying to instantiate an unknown node_type" do
64
+ lambda { RegistryTest.template_registry.instantiate(:demigod, 'Hercules') }.should raise_error(NameError)
65
+ end
66
+
67
+ it "should instantiate a detached node from a template using the template name as a method" do
68
+ node = RegistryTest.template_registry.zombie('Zeke')
69
+ expectation = Nokogiri::XML('<monster wants="braaaaainz">Zeke</monster>').root
70
+ EquivalentXml.equivalent?(node, expectation).should == true
71
+ end
72
+
73
+ it "should raise an exception if a missing method name doesn't match a node_type" do
74
+ lambda { RegistryTest.template_registry.demigod('Hercules') }.should raise_error(NameError)
75
+ end
76
+
77
+ it "should undefine existing templates" do
78
+ RegistryTest.template_registry.node_types.should include(:zombie)
79
+ RegistryTest.template_registry.undefine :zombie
80
+ RegistryTest.template_registry.node_types.should_not include(:zombie)
81
+ end
82
+
83
+ it "should complain if the template name isn't a symbol" do
84
+ lambda { RegistryTest.template_registry.define("die!") { |xml| xml.this_never_happened } }.should raise_error(TypeError)
85
+ end
86
+
87
+ it "should report on whether a given template is defined" do
88
+ RegistryTest.template_registry.has_node_type?(:person).should == true
89
+ RegistryTest.template_registry.has_node_type?(:zombie).should == false
90
+ end
91
+
92
+ it "should include defined node_types as method names for introspection" do
93
+ RegistryTest.template_registry.methods.should include('person')
94
+ end
95
+ end
96
+
97
+ describe "template-based document manipulations" do
98
+ it "should accept a Nokogiri::XML::Node as target" do
99
+ @test_document.template_registry.after(@test_document.ng_xml.root.elements.first, :person, 'Bob', 'Builder')
100
+ @test_document.ng_xml.root.elements.length.should == 2
101
+ end
102
+
103
+ it "should accept a Nokogiri::XML::NodeSet as target" do
104
+ @test_document.template_registry.after(@test_document.find_by_terms(:person => 0), :person, 'Bob', 'Builder')
105
+ @test_document.ng_xml.root.elements.length.should == 2
106
+ end
107
+
108
+ it "should add_child" do
109
+ return_value = @test_document.template_registry.add_child(@test_document.ng_xml.root, :person, 'Bob', 'Builder')
110
+ return_value.should == @test_document.find_by_terms(:person => 1).first
111
+ EquivalentXml.equivalent?(@test_document.ng_xml, @expectations[:after], :element_order => true).should == true
112
+ end
113
+
114
+ it "should add_next_sibling" do
115
+ return_value = @test_document.template_registry.add_next_sibling(@test_document.find_by_terms(:person => 0), :person, 'Bob', 'Builder')
116
+ return_value.should == @test_document.find_by_terms(:person => 1).first
117
+ EquivalentXml.equivalent?(@test_document.ng_xml, @expectations[:after], :element_order => true).should == true
118
+ end
119
+
120
+ it "should add_previous_sibling" do
121
+ return_value = @test_document.template_registry.add_previous_sibling(@test_document.find_by_terms(:person => 0), :person, 'Bob', 'Builder')
122
+ return_value.should == @test_document.find_by_terms(:person => 0).first
123
+ EquivalentXml.equivalent?(@test_document.ng_xml, @expectations[:before], :element_order => true).should == true
124
+ end
125
+
126
+ it "should after" do
127
+ return_value = @test_document.template_registry.after(@test_document.find_by_terms(:person => 0), :person, 'Bob', 'Builder')
128
+ return_value.should == @test_document.find_by_terms(:person => 0).first
129
+ EquivalentXml.equivalent?(@test_document.ng_xml, @expectations[:after], :element_order => true).should == true
130
+ end
131
+
132
+ it "should before" do
133
+ return_value = @test_document.template_registry.before(@test_document.find_by_terms(:person => 0), :person, 'Bob', 'Builder')
134
+ return_value.should == @test_document.find_by_terms(:person => 1).first
135
+ EquivalentXml.equivalent?(@test_document.ng_xml, @expectations[:before], :element_order => true).should == true
136
+ end
137
+
138
+ it "should replace" do
139
+ target_node = @test_document.find_by_terms(:person => 0).first
140
+ return_value = @test_document.template_registry.replace(target_node, :person, 'Bob', 'Builder')
141
+ return_value.should == @test_document.find_by_terms(:person => 0).first
142
+ EquivalentXml.equivalent?(@test_document.ng_xml, @expectations[:instead], :element_order => true).should == true
143
+ end
144
+
145
+ it "should swap" do
146
+ target_node = @test_document.find_by_terms(:person => 0).first
147
+ return_value = @test_document.template_registry.swap(target_node, :person, 'Bob', 'Builder')
148
+ return_value.should == target_node
149
+ EquivalentXml.equivalent?(@test_document.ng_xml, @expectations[:instead], :element_order => true).should == true
150
+ end
151
+ end
152
+
153
+ describe "document-based document manipulations" do
154
+ it "should accept a Nokogiri::XML::Node as target" do
155
+ @test_document.after_node(@test_document.ng_xml.root.elements.first, :person, 'Bob', 'Builder')
156
+ @test_document.ng_xml.root.elements.length.should == 2
157
+ end
158
+
159
+ it "should accept a Nokogiri::XML::NodeSet as target" do
160
+ @test_document.after_node(@test_document.find_by_terms(:person => 0), :person, 'Bob', 'Builder')
161
+ @test_document.ng_xml.root.elements.length.should == 2
162
+ end
163
+
164
+ it "should accept a term-pointer array as target" do
165
+ @test_document.after_node([:person => 0], :person, 'Bob', 'Builder')
166
+ @test_document.ng_xml.root.elements.length.should == 2
167
+ end
168
+
169
+ it "should add_child_node" do
170
+ return_value = @test_document.add_child_node(@test_document.ng_xml.root, :person, 'Bob', 'Builder')
171
+ return_value.should == @test_document.find_by_terms(:person => 1).first
172
+ EquivalentXml.equivalent?(@test_document.ng_xml, @expectations[:after], :element_order => true).should == true
173
+ end
174
+
175
+ it "should add_next_sibling_node" do
176
+ return_value = @test_document.add_next_sibling_node([:person => 0], :person, 'Bob', 'Builder')
177
+ return_value.should == @test_document.find_by_terms(:person => 1).first
178
+ EquivalentXml.equivalent?(@test_document.ng_xml, @expectations[:after], :element_order => true).should == true
179
+ end
180
+
181
+ it "should add_previous_sibling_node" do
182
+ return_value = @test_document.add_previous_sibling_node([:person => 0], :person, 'Bob', 'Builder')
183
+ return_value.should == @test_document.find_by_terms(:person => 0).first
184
+ EquivalentXml.equivalent?(@test_document.ng_xml, @expectations[:before], :element_order => true).should == true
185
+ end
186
+
187
+ it "should after_node" do
188
+ return_value = @test_document.after_node([:person => 0], :person, 'Bob', 'Builder')
189
+ return_value.should == @test_document.find_by_terms(:person => 0).first
190
+ EquivalentXml.equivalent?(@test_document.ng_xml, @expectations[:after], :element_order => true).should == true
191
+ end
192
+
193
+ it "should before_node" do
194
+ return_value = @test_document.before_node([:person => 0], :person, 'Bob', 'Builder')
195
+ return_value.should == @test_document.find_by_terms(:person => 1).first
196
+ EquivalentXml.equivalent?(@test_document.ng_xml, @expectations[:before], :element_order => true).should == true
197
+ end
198
+
199
+ it "should replace_node" do
200
+ target_node = @test_document.find_by_terms(:person => 0).first
201
+ return_value = @test_document.replace_node(target_node, :person, 'Bob', 'Builder')
202
+ return_value.should == @test_document.find_by_terms(:person => 0).first
203
+ EquivalentXml.equivalent?(@test_document.ng_xml, @expectations[:instead], :element_order => true).should == true
204
+ end
205
+
206
+ it "should swap_node" do
207
+ target_node = @test_document.find_by_terms(:person => 0).first
208
+ return_value = @test_document.swap_node(target_node, :person, 'Bob', 'Builder')
209
+ return_value.should == target_node
210
+ EquivalentXml.equivalent?(@test_document.ng_xml, @expectations[:instead], :element_order => true).should == true
211
+ end
212
+ end
213
+
214
+ end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: om
3
3
  version: !ruby/object:Gem::Version
4
- hash: 17
4
+ hash: 31
5
5
  prerelease: false
6
6
  segments:
7
7
  - 1
8
- - 1
9
- - 1
10
- version: 1.1.1
8
+ - 2
9
+ - 0
10
+ version: 1.2.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Matt Zumwalt
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-03-08 00:00:00 -06:00
18
+ date: 2011-03-22 00:00:00 -07:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -106,11 +106,27 @@ dependencies:
106
106
  - 0
107
107
  version: "0"
108
108
  requirement: *id006
109
+ - !ruby/object:Gem::Dependency
110
+ type: :development
111
+ prerelease: false
112
+ name: equivalent-xml
113
+ version_requirements: &id007 !ruby/object:Gem::Requirement
114
+ none: false
115
+ requirements:
116
+ - - ">="
117
+ - !ruby/object:Gem::Version
118
+ hash: 23
119
+ segments:
120
+ - 0
121
+ - 1
122
+ - 6
123
+ version: 0.1.6
124
+ requirement: *id007
109
125
  - !ruby/object:Gem::Dependency
110
126
  type: :runtime
111
127
  prerelease: false
112
128
  name: nokogiri
113
- version_requirements: &id007 !ruby/object:Gem::Requirement
129
+ version_requirements: &id008 !ruby/object:Gem::Requirement
114
130
  none: false
115
131
  requirements:
116
132
  - - ">="
@@ -121,12 +137,12 @@ dependencies:
121
137
  - 4
122
138
  - 2
123
139
  version: 1.4.2
124
- requirement: *id007
140
+ requirement: *id008
125
141
  - !ruby/object:Gem::Dependency
126
142
  type: :runtime
127
143
  prerelease: false
128
144
  name: facets
129
- version_requirements: &id008 !ruby/object:Gem::Requirement
145
+ version_requirements: &id009 !ruby/object:Gem::Requirement
130
146
  none: false
131
147
  requirements:
132
148
  - - ">="
@@ -135,12 +151,12 @@ dependencies:
135
151
  segments:
136
152
  - 0
137
153
  version: "0"
138
- requirement: *id008
154
+ requirement: *id009
139
155
  - !ruby/object:Gem::Dependency
140
156
  type: :development
141
157
  prerelease: false
142
158
  name: rspec
143
- version_requirements: &id009 !ruby/object:Gem::Requirement
159
+ version_requirements: &id010 !ruby/object:Gem::Requirement
144
160
  none: false
145
161
  requirements:
146
162
  - - ">="
@@ -151,12 +167,12 @@ dependencies:
151
167
  - 2
152
168
  - 9
153
169
  version: 1.2.9
154
- requirement: *id009
170
+ requirement: *id010
155
171
  - !ruby/object:Gem::Dependency
156
172
  type: :development
157
173
  prerelease: false
158
174
  name: mocha
159
- version_requirements: &id010 !ruby/object:Gem::Requirement
175
+ version_requirements: &id011 !ruby/object:Gem::Requirement
160
176
  none: false
161
177
  requirements:
162
178
  - - ">="
@@ -167,12 +183,12 @@ dependencies:
167
183
  - 9
168
184
  - 8
169
185
  version: 0.9.8
170
- requirement: *id010
186
+ requirement: *id011
171
187
  - !ruby/object:Gem::Dependency
172
188
  type: :development
173
189
  prerelease: false
174
190
  name: ruby-debug
175
- version_requirements: &id011 !ruby/object:Gem::Requirement
191
+ version_requirements: &id012 !ruby/object:Gem::Requirement
176
192
  none: false
177
193
  requirements:
178
194
  - - ">="
@@ -181,7 +197,7 @@ dependencies:
181
197
  segments:
182
198
  - 0
183
199
  version: "0"
184
- requirement: *id011
200
+ requirement: *id012
185
201
  description: "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"
186
202
  email: matt.zumwalt@yourmediashelf.com
187
203
  executables: []
@@ -212,6 +228,7 @@ files:
212
228
  - lib/om/xml/document.rb
213
229
  - lib/om/xml/named_term_proxy.rb
214
230
  - lib/om/xml/node_generator.rb
231
+ - lib/om/xml/template_registry.rb
215
232
  - lib/om/xml/term.rb
216
233
  - lib/om/xml/term_value_operators.rb
217
234
  - lib/om/xml/term_xpath_generator.rb
@@ -232,6 +249,7 @@ files:
232
249
  - spec/unit/named_term_proxy_spec.rb
233
250
  - spec/unit/node_generator_spec.rb
234
251
  - spec/unit/om_spec.rb
252
+ - spec/unit/template_registry_spec.rb
235
253
  - spec/unit/term_builder_spec.rb
236
254
  - spec/unit/term_spec.rb
237
255
  - spec/unit/term_value_operators_spec.rb
@@ -282,6 +300,7 @@ test_files:
282
300
  - spec/unit/named_term_proxy_spec.rb
283
301
  - spec/unit/node_generator_spec.rb
284
302
  - spec/unit/om_spec.rb
303
+ - spec/unit/template_registry_spec.rb
285
304
  - spec/unit/term_builder_spec.rb
286
305
  - spec/unit/term_spec.rb
287
306
  - spec/unit/term_value_operators_spec.rb