resync 0.3.0 → 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +0 -3
- data/CHANGES.md +4 -0
- data/lib/resync/version.rb +1 -1
- data/lib/resync/xml.rb +11 -122
- data/resync.gemspec +2 -1
- data/spec/.rubocop.yml +7 -0
- data/spec/rspec_custom_matchers.rb +3 -0
- data/spec/spec_helper.rb +1 -1
- data/spec/unit/resync/xml/xml_spec.rb +7 -0
- data/spec/unit/resync/xml_parser_spec.rb +6 -0
- metadata +21 -7
- data/spec/unit/resync/xml/timenode_spec.rb +0 -48
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 406859fe6a51bf6ff5b90b58ef0ec0f1b6ed1867
|
4
|
+
data.tar.gz: ce626f5a9adabe17fa4af8c21e2aa70da299a3f2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8f6728c7ccb7d6b2d96cb37e58dc0a8bcfcff95ba0edcc018bf3fc440d7a8befb9889e0fcf40122954a85830404d5125a08030b29f61cddd2b7a799586033137
|
7
|
+
data.tar.gz: 4f42a290b7f90f94825255d8cdd1af737eb18a076e15b8724223df14b1e4d9aad8f647e30f6262c635cd919e4fb0ab56adfb0506e18a8271d609f6b40d5392dc
|
data/.rubocop.yml
CHANGED
data/CHANGES.md
CHANGED
data/lib/resync/version.rb
CHANGED
data/lib/resync/xml.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
require 'uri'
|
2
2
|
require 'time'
|
3
3
|
require 'xml/mapping'
|
4
|
+
require 'xml/mapping_extensions'
|
5
|
+
|
4
6
|
require_relative 'types'
|
5
7
|
|
6
8
|
module Resync
|
@@ -56,83 +58,11 @@ module Resync
|
|
56
58
|
end
|
57
59
|
private_class_method :can_parse
|
58
60
|
|
59
|
-
# ------------------------------------------------------------
|
60
|
-
# Time
|
61
|
-
|
62
|
-
# Maps +Time+ objects.
|
63
|
-
class TimeNode < ::XML::Mapping::SingleAttributeNode
|
64
|
-
def initialize(*args)
|
65
|
-
path, *args = super(*args)
|
66
|
-
@path = ::XML::XXPath.new(path)
|
67
|
-
args
|
68
|
-
end
|
69
|
-
|
70
|
-
# Implements +::XML::Mapping::SingleAttributeNode#extract_attr_value+.
|
71
|
-
def extract_attr_value(xml)
|
72
|
-
value = default_when_xpath_err { @path.first(xml).text }
|
73
|
-
value ? Time.iso8601(value).utc : nil
|
74
|
-
end
|
75
|
-
|
76
|
-
# Implements +::XML::Mapping::SingleAttributeNode#set_attr_value+.
|
77
|
-
def set_attr_value(xml, value)
|
78
|
-
@path.first(xml, ensure_created: true).text = value.iso8601
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
::XML::Mapping.add_node_class TimeNode
|
83
|
-
|
84
|
-
# ------------------------------------------------------------
|
85
|
-
# URI
|
86
|
-
|
87
|
-
# Maps +URI+ objects.
|
88
|
-
class UriNode < ::XML::Mapping::SingleAttributeNode
|
89
|
-
def initialize(*args)
|
90
|
-
path, *args = super(*args)
|
91
|
-
@path = ::XML::XXPath.new(path)
|
92
|
-
args
|
93
|
-
end
|
94
|
-
|
95
|
-
# Implements +::XML::Mapping::SingleAttributeNode#extract_attr_value+.
|
96
|
-
def extract_attr_value(xml)
|
97
|
-
val = default_when_xpath_err { @path.first(xml).text }
|
98
|
-
URI(val.strip)
|
99
|
-
end
|
100
|
-
|
101
|
-
# Implements +::XML::Mapping::SingleAttributeNode#set_attr_value+.
|
102
|
-
def set_attr_value(xml, value)
|
103
|
-
@path.first(xml, ensure_created: true).text = value.to_s
|
104
|
-
end
|
105
|
-
end
|
106
|
-
|
107
|
-
::XML::Mapping.add_node_class UriNode
|
108
|
-
|
109
|
-
# ------------------------------------------------------------
|
110
|
-
# Resync::Types
|
111
|
-
|
112
|
-
class EnumNode < ::XML::Mapping::SingleAttributeNode
|
113
|
-
def initialize(*args)
|
114
|
-
path, *args = super(*args)
|
115
|
-
@path = ::XML::XXPath.new(path)
|
116
|
-
args
|
117
|
-
end
|
118
|
-
|
119
|
-
# Implements +::XML::Mapping::SingleAttributeNode#extract_attr_value+.
|
120
|
-
def extract_attr_value(xml)
|
121
|
-
enum_class = self.class::ENUM_CLASS
|
122
|
-
enum_class.parse(default_when_xpath_err { @path.first(xml).text })
|
123
|
-
end
|
124
|
-
|
125
|
-
# Implements +::XML::Mapping::SingleAttributeNode#set_attr_value+.
|
126
|
-
def set_attr_value(xml, value)
|
127
|
-
@path.first(xml, ensure_created: true).text = value.to_s
|
128
|
-
end
|
129
|
-
end
|
130
|
-
|
131
61
|
# ------------------------------------------------------------
|
132
62
|
# Resync::Types::Change
|
133
63
|
|
134
64
|
# Maps +Resync::Types::Change+ values.
|
135
|
-
class ChangeNode <
|
65
|
+
class ChangeNode < ::XML::MappingExtensions::EnumNodeBase
|
136
66
|
ENUM_CLASS = Resync::Types::Change
|
137
67
|
end
|
138
68
|
|
@@ -142,69 +72,28 @@ module Resync
|
|
142
72
|
# Resync::Types::Changefreq
|
143
73
|
|
144
74
|
# Maps +Resync::Types::ChangeFrequency+ values.
|
145
|
-
class ChangefreqNode <
|
75
|
+
class ChangefreqNode < ::XML::MappingExtensions::EnumNodeBase
|
146
76
|
ENUM_CLASS = Resync::Types::ChangeFrequency
|
147
77
|
end
|
148
78
|
|
149
79
|
::XML::Mapping.add_node_class ChangefreqNode
|
150
80
|
|
151
|
-
# ------------------------------------------------------------
|
152
|
-
# MIME::Type
|
153
|
-
|
154
|
-
# Maps +MIME::Type+ values.
|
155
|
-
class MimeTypeNode < ::XML::Mapping::SingleAttributeNode
|
156
|
-
def initialize(*args)
|
157
|
-
path, *args = super(*args)
|
158
|
-
@path = ::XML::XXPath.new(path)
|
159
|
-
args
|
160
|
-
end
|
161
|
-
|
162
|
-
# Implements +::XML::Mapping::SingleAttributeNode#extract_attr_value+.
|
163
|
-
def extract_attr_value(xml)
|
164
|
-
mime_type = default_when_xpath_err { @path.first(xml).text }
|
165
|
-
return nil unless mime_type
|
166
|
-
return mime_type if mime_type.is_a?(MIME::Type)
|
167
|
-
|
168
|
-
mt = MIME::Types[mime_type].first
|
169
|
-
return mt if mt
|
170
|
-
|
171
|
-
MIME::Type.new(mime_type)
|
172
|
-
end
|
173
|
-
|
174
|
-
# Implements +::XML::Mapping::SingleAttributeNode#set_attr_value+.
|
175
|
-
def set_attr_value(xml, value)
|
176
|
-
@path.first(xml, ensure_created: true).text = value.to_s
|
177
|
-
end
|
178
|
-
end
|
179
|
-
|
180
|
-
::XML::Mapping.add_node_class MimeTypeNode
|
181
|
-
|
182
81
|
# ------------------------------------------------------------
|
183
82
|
# Whitespace-separated hashcode list
|
184
83
|
|
185
84
|
# Maps the whitespace-separated list of hash codes in a +<rs:ln>+
|
186
85
|
# or +<rs:md>+ tag to a hash of digest values keyed by hash algorithm.
|
187
86
|
# (See {Resync::Descriptor#hashes}.)
|
188
|
-
class HashCodesNode < ::XML::
|
189
|
-
def initialize(*args)
|
190
|
-
path, *args = super(*args)
|
191
|
-
@path = ::XML::XXPath.new(path)
|
192
|
-
args
|
193
|
-
end
|
87
|
+
class HashCodesNode < ::XML::MappingExtensions::NodeBase
|
194
88
|
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
return hashes if hashes.is_a?(Hash)
|
200
|
-
hashes.split(/[[:space:]]+/).map { |hash| hash.split(':') }.to_h
|
89
|
+
def to_value(xml_text)
|
90
|
+
return {} unless xml_text
|
91
|
+
return xml_text if xml_text.is_a?(Hash)
|
92
|
+
xml_text.split(/[[:space:]]+/).map { |hash| hash.split(':') }.to_h
|
201
93
|
end
|
202
94
|
|
203
|
-
|
204
|
-
|
205
|
-
return if value.empty?
|
206
|
-
hash_str = value.map { |k, v| "#{k}:#{v}" }.join(' ')
|
207
|
-
@path.first(xml, ensure_created: true).text = hash_str
|
95
|
+
def to_xml_text(value)
|
96
|
+
value.map { |k, v| "#{k}:#{v}" }.join(' ') if value && !value.empty?
|
208
97
|
end
|
209
98
|
end
|
210
99
|
|
data/resync.gemspec
CHANGED
@@ -25,11 +25,12 @@ Gem::Specification.new do |spec|
|
|
25
25
|
spec.add_dependency 'mime-types', '~> 2.5'
|
26
26
|
spec.add_dependency 'ruby-enum', '~> 0.4'
|
27
27
|
spec.add_dependency 'xml-mapping', '~> 0.10'
|
28
|
+
spec.add_dependency 'xml-mapping_extensions', '~> 0.1.0'
|
28
29
|
|
29
30
|
spec.add_development_dependency 'equivalent-xml', '~> 0.6.0'
|
30
31
|
spec.add_development_dependency 'rake', '~> 10.4'
|
31
32
|
spec.add_development_dependency 'rspec', '~> 3.2'
|
32
|
-
spec.add_development_dependency 'rubocop', '~> 0.
|
33
|
+
spec.add_development_dependency 'rubocop', '~> 0.32'
|
33
34
|
spec.add_development_dependency 'simplecov', '~> 0.9.2'
|
34
35
|
spec.add_development_dependency 'simplecov-console', '~> 0.2.0'
|
35
36
|
spec.add_development_dependency 'yard', '~> 0.8'
|
data/spec/.rubocop.yml
ADDED
@@ -4,6 +4,7 @@ require 'equivalent-xml'
|
|
4
4
|
RSpec::Matchers.define :be_xml do |expected|
|
5
5
|
|
6
6
|
def to_nokogiri(xml)
|
7
|
+
return nil unless xml
|
7
8
|
case xml
|
8
9
|
when Nokogiri::XML::Element
|
9
10
|
xml
|
@@ -13,6 +14,8 @@ RSpec::Matchers.define :be_xml do |expected|
|
|
13
14
|
to_nokogiri(Nokogiri::XML(xml))
|
14
15
|
when REXML::Element
|
15
16
|
to_nokogiri(xml.to_s)
|
17
|
+
else
|
18
|
+
fail "be_xml() expected XML, got #{xml.class}"
|
16
19
|
end
|
17
20
|
end
|
18
21
|
|
data/spec/spec_helper.rb
CHANGED
@@ -30,6 +30,13 @@ module Resync
|
|
30
30
|
expect(elem).to be_xml(xml_str)
|
31
31
|
end
|
32
32
|
|
33
|
+
it 'parses a file as an XML document' do
|
34
|
+
file = File.new('spec/data/examples/example-1.xml')
|
35
|
+
elem = XML.element(file)
|
36
|
+
expect(elem).to be_a(REXML::Element)
|
37
|
+
expect(elem.name).to eq('urlset')
|
38
|
+
end
|
39
|
+
|
33
40
|
it 'fails when it gets something other than XML' do
|
34
41
|
data = 12_345
|
35
42
|
expect { XML.element(data) }.to raise_exception
|
@@ -31,6 +31,12 @@ module Resync
|
|
31
31
|
expect(urlset).to be_a(ResourceList)
|
32
32
|
end
|
33
33
|
|
34
|
+
it 'parses a file' do
|
35
|
+
file = File.new('spec/data/examples/example-1.xml')
|
36
|
+
urlset = XMLParser.parse(file)
|
37
|
+
expect(urlset).to be_a(ResourceList)
|
38
|
+
end
|
39
|
+
|
34
40
|
it 'parses an XML fragment' do
|
35
41
|
data = '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:rs="http://www.openarchives.org/rs/terms/">
|
36
42
|
<rs:md capability="resourcelist" at="2013-01-03T09:00:00Z"/>
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: resync
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Moles
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-09-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: mime-types
|
@@ -52,6 +52,20 @@ dependencies:
|
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0.10'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: xml-mapping_extensions
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 0.1.0
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 0.1.0
|
55
69
|
- !ruby/object:Gem::Dependency
|
56
70
|
name: equivalent-xml
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -100,14 +114,14 @@ dependencies:
|
|
100
114
|
requirements:
|
101
115
|
- - "~>"
|
102
116
|
- !ruby/object:Gem::Version
|
103
|
-
version: 0.
|
117
|
+
version: '0.32'
|
104
118
|
type: :development
|
105
119
|
prerelease: false
|
106
120
|
version_requirements: !ruby/object:Gem::Requirement
|
107
121
|
requirements:
|
108
122
|
- - "~>"
|
109
123
|
- !ruby/object:Gem::Version
|
110
|
-
version: 0.
|
124
|
+
version: '0.32'
|
111
125
|
- !ruby/object:Gem::Dependency
|
112
126
|
name: simplecov
|
113
127
|
requirement: !ruby/object:Gem::Requirement
|
@@ -212,6 +226,7 @@ files:
|
|
212
226
|
- lib/resync/xml.rb
|
213
227
|
- lib/resync/xml_parser.rb
|
214
228
|
- resync.gemspec
|
229
|
+
- spec/.rubocop.yml
|
215
230
|
- spec/acceptance/xml_parser_spec.rb
|
216
231
|
- spec/data/changedump-index.xml
|
217
232
|
- spec/data/examples/README.md
|
@@ -275,7 +290,6 @@ files:
|
|
275
290
|
- spec/unit/resync/shared/sorted_list_examples.rb
|
276
291
|
- spec/unit/resync/shared/uri_field_examples.rb
|
277
292
|
- spec/unit/resync/source_description_spec.rb
|
278
|
-
- spec/unit/resync/xml/timenode_spec.rb
|
279
293
|
- spec/unit/resync/xml/xml_spec.rb
|
280
294
|
- spec/unit/resync/xml_parser_spec.rb
|
281
295
|
homepage: http://github.com/dmolesUC3/resync
|
@@ -298,11 +312,12 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
298
312
|
version: '0'
|
299
313
|
requirements: []
|
300
314
|
rubyforge_project:
|
301
|
-
rubygems_version: 2.4.
|
315
|
+
rubygems_version: 2.4.6
|
302
316
|
signing_key:
|
303
317
|
specification_version: 4
|
304
318
|
summary: Utility library for ResourceSync
|
305
319
|
test_files:
|
320
|
+
- spec/.rubocop.yml
|
306
321
|
- spec/acceptance/xml_parser_spec.rb
|
307
322
|
- spec/data/changedump-index.xml
|
308
323
|
- spec/data/examples/README.md
|
@@ -366,7 +381,6 @@ test_files:
|
|
366
381
|
- spec/unit/resync/shared/sorted_list_examples.rb
|
367
382
|
- spec/unit/resync/shared/uri_field_examples.rb
|
368
383
|
- spec/unit/resync/source_description_spec.rb
|
369
|
-
- spec/unit/resync/xml/timenode_spec.rb
|
370
384
|
- spec/unit/resync/xml/xml_spec.rb
|
371
385
|
- spec/unit/resync/xml_parser_spec.rb
|
372
386
|
has_rdoc:
|
@@ -1,48 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
module Resync
|
4
|
-
module XML
|
5
|
-
|
6
|
-
class Elem
|
7
|
-
include ::XML::Mapping
|
8
|
-
time_node :time, '@time', default_value: nil
|
9
|
-
|
10
|
-
def self.from_str(time_str)
|
11
|
-
xml_string = "<elem time='#{time_str}'/>"
|
12
|
-
doc = REXML::Document.new(xml_string)
|
13
|
-
load_from_xml(doc.root)
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
describe TimeNode do
|
18
|
-
|
19
|
-
def time(str)
|
20
|
-
Elem.from_str(str).time
|
21
|
-
end
|
22
|
-
|
23
|
-
it 'parses a date with hours, minutes, and seconds' do
|
24
|
-
actual = time('1997-07-16T19:20:30')
|
25
|
-
expected = Time.new(1997, 7, 16, 19, 20, 30)
|
26
|
-
expect(actual).to be_time(expected)
|
27
|
-
end
|
28
|
-
|
29
|
-
it 'parses a date with hours, minutes, seconds, and fractional seconds' do
|
30
|
-
actual = time('1997-07-16T19:20:30.45')
|
31
|
-
expected = Time.new(1997, 7, 16, 19, 20, 30.45)
|
32
|
-
expect(actual).to be_time(expected)
|
33
|
-
end
|
34
|
-
|
35
|
-
it 'parses a UTC "zulu" time (time zone designator "Z")' do
|
36
|
-
actual = time('1997-07-16T19:20:30.45Z')
|
37
|
-
expected = Time.new(1997, 7, 16, 19, 20, 30.45, '+00:00')
|
38
|
-
expect(actual).to be_time(expected)
|
39
|
-
end
|
40
|
-
|
41
|
-
it 'parses a time with a numeric timezone offset' do
|
42
|
-
actual = time('1997-07-16T19:20:30.45+01:30')
|
43
|
-
expected = Time.new(1997, 7, 16, 19, 20, 30.45, '+01:30')
|
44
|
-
expect(actual).to be_time(expected)
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|