resync-client 0.3.1 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGES.md +5 -0
- data/lib/resync/client/mixins/capability_list_extensions.rb +55 -0
- data/lib/resync/client/mixins/change_index.rb +9 -4
- data/lib/resync/client/mixins/list_index.rb +0 -12
- data/lib/resync/client/mixins/plain_list.rb +25 -0
- data/lib/resync/client/version.rb +1 -1
- data/spec/unit/resync/client/capability_list_extensions_spec.rb +61 -0
- data/spec/unit/resync/client/list_index_spec.rb +10 -0
- data/spec/unit/resync/client/mixins_spec.rb +35 -14
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bd8d1fac9a7feece07634eca0cb2b9b4e9d2ce93
|
4
|
+
data.tar.gz: 27e94c732902e0f9b42be6ce9ec9df74f16d641a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 188aab78224fc2e642aa7759a3c9c5a4a97d156c332ef66df771d6a305758126b64352ff9651d6c68ccff3bb3da226d1f47d7f83b22ff0abc5576ed1bc13d0f9
|
7
|
+
data.tar.gz: 4eebbc3ba5cb6ecb5115eec09015d22fca5155a4da3fb79e6b4c99ac99c935fbda05cc93d4b444483f4a0273483306560df4d0e2bf5859a879106049e4c10b89
|
data/CHANGES.md
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
# 0.3.2
|
2
|
+
|
3
|
+
- Added utility methods to `CapabilityList` to simplify downloading and parsing ResourceSync documents by capability
|
4
|
+
- Make `ChangeList#all_changes`, and `#all_resources` on both `ResourceList` and `ChangeList`, return `Enumerator::Lazy` to improve interoperation with the corresponding methods on `ResourceIndex/ChangeIndex`
|
5
|
+
|
1
6
|
# 0.3.1
|
2
7
|
|
3
8
|
- Make `#get` and `#get_and_parse` in `Downloadable` (i.e., `Resource` and `Link`) cache the downloaded content
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'resync'
|
2
|
+
|
3
|
+
module Resync
|
4
|
+
class CapabilityList
|
5
|
+
|
6
|
+
# Downloads and parses the document for the specified capability.
|
7
|
+
# Subsequent calls will return the same parsed object.
|
8
|
+
# @return [ResourceList, ResourceListIndex, ChangeList, ChangeListIndex, ResourceDump, ResourceDumpIndex, ChangeDump, ChangeDumpIndex, nil]
|
9
|
+
# the document, or +nil+ if this capability list does not provide that capability
|
10
|
+
def document_for(capability)
|
11
|
+
@documents ||= {}
|
12
|
+
@documents[capability] ||= get_and_parse_resource_for(capability)
|
13
|
+
end
|
14
|
+
|
15
|
+
# Downloads and parses the resource list or resource list index.
|
16
|
+
# Subsequent calls will return the same parsed object.
|
17
|
+
# @return [ResourceList, ResourceListIndex, nil] the resource list, or +nil+ if this capability list does not
|
18
|
+
# provide one
|
19
|
+
def resource_list
|
20
|
+
document_for(ResourceList::CAPABILITY)
|
21
|
+
end
|
22
|
+
|
23
|
+
# Downloads and parses the change list or change list index.
|
24
|
+
# Subsequent calls will return the same parsed object.
|
25
|
+
# @return [ChangeList, ChangeListIndex, nil] the change list, or +nil+ if this capability list does not
|
26
|
+
# provide one
|
27
|
+
def change_list
|
28
|
+
document_for(ChangeList::CAPABILITY)
|
29
|
+
end
|
30
|
+
|
31
|
+
# Downloads and parses the resource dump or resource dump index.
|
32
|
+
# Subsequent calls will return the same parsed object.
|
33
|
+
# @return [ResourceDump, ResourceDumpIndex, nil] the resource dump, or +nil+ if this capability dump does not
|
34
|
+
# provide one
|
35
|
+
def resource_dump
|
36
|
+
document_for(ResourceDump::CAPABILITY)
|
37
|
+
end
|
38
|
+
|
39
|
+
# Downloads and parses the change dump or change dump index.
|
40
|
+
# Subsequent calls will return the same parsed object.
|
41
|
+
# @return [ChangeDump, ChangeDumpIndex, nil] the change dump, or +nil+ if this capability dump does not
|
42
|
+
# provide one
|
43
|
+
def change_dump
|
44
|
+
document_for(ChangeDump::CAPABILITY)
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def get_and_parse_resource_for(capability)
|
50
|
+
resource = resource_for(capability: capability)
|
51
|
+
resource.get_and_parse if resource
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
end
|
@@ -22,7 +22,7 @@ module Resync
|
|
22
22
|
def all_changes(of_type: nil, in_range: nil)
|
23
23
|
@change_lists ||= {}
|
24
24
|
lists = in_range ? change_lists(in_range: in_range, strict: false) : resources
|
25
|
-
lists.flat_map do |cl|
|
25
|
+
lists.lazy.flat_map do |cl|
|
26
26
|
@change_lists[cl] ||= cl.get_and_parse
|
27
27
|
@change_lists[cl].changes(of_type: of_type, in_range: in_range)
|
28
28
|
end
|
@@ -36,8 +36,13 @@ module Resync
|
|
36
36
|
end
|
37
37
|
|
38
38
|
class ChangeList
|
39
|
-
#
|
40
|
-
#
|
41
|
-
|
39
|
+
# Delegates to {ChangeList#changes} for interoperation with {ChangeList#all_changes}.
|
40
|
+
# @param of_type [Types::Change] the change type
|
41
|
+
# @param in_range [Range<Time>] the range of modification times
|
42
|
+
# @return [Enumerator::Lazy<Resource>] a lazy enumeration of the matching changes, or all
|
43
|
+
# changes if neither +of_type+ nor +in_range+ is specified.
|
44
|
+
def all_changes(of_type: nil, in_range: nil)
|
45
|
+
changes(of_type: of_type, in_range: in_range).lazy
|
46
|
+
end
|
42
47
|
end
|
43
48
|
end
|
@@ -27,19 +27,7 @@ module Resync
|
|
27
27
|
prepend Client::Mixins::ListIndex
|
28
28
|
end
|
29
29
|
|
30
|
-
class ChangeList
|
31
|
-
# Aliases +:resources+ as +:all_resources+ for transparent
|
32
|
-
# interoperability with +ChangeListIndex+
|
33
|
-
alias_method :all_resources, :resources
|
34
|
-
end
|
35
|
-
|
36
30
|
class ResourceListIndex
|
37
31
|
prepend Client::Mixins::ListIndex
|
38
32
|
end
|
39
|
-
|
40
|
-
class ResourceList
|
41
|
-
# Aliases +:resources+ as +:all_resources+ for transparent
|
42
|
-
# interoperability with +ResourceListIndex+
|
43
|
-
alias_method :all_resources, :resources
|
44
|
-
end
|
45
33
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'resync'
|
2
|
+
require_relative 'resource_client_delegate'
|
3
|
+
|
4
|
+
module Resync
|
5
|
+
class Client
|
6
|
+
module Mixins
|
7
|
+
# A resource container whose resources are not, themselves, resource containers
|
8
|
+
module PlainList
|
9
|
+
# Delegates to {BaseResourceList#resources} for interoperation with {ListIndex#all_resources}.
|
10
|
+
# @return [Enumerator::Lazy<Resync::Resource>] a lazy enumeration of the resources in this document
|
11
|
+
def all_resources
|
12
|
+
resources.lazy
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
class ChangeList
|
19
|
+
prepend Client::Mixins::PlainList
|
20
|
+
end
|
21
|
+
|
22
|
+
class ResourceList
|
23
|
+
prepend Client::Mixins::PlainList
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Resync
|
4
|
+
describe CapabilityList do
|
5
|
+
doc_types = [ResourceList, ResourceDump, ChangeList, ChangeDump]
|
6
|
+
|
7
|
+
before(:each) do
|
8
|
+
@client = instance_double(Resync::Client)
|
9
|
+
allow(@client).to receive(:client) { @client }
|
10
|
+
@cap_list = XMLParser.parse(File.read('spec/data/examples/capability-list.xml'))
|
11
|
+
@cap_list.client_delegate = @client
|
12
|
+
end
|
13
|
+
|
14
|
+
describe '#document_for' do
|
15
|
+
it 'downloads and parses documents by capability' do
|
16
|
+
doc_types.each do |doc_type|
|
17
|
+
capability = doc_type::CAPABILITY
|
18
|
+
class_name = doc_type.name.split('::').last
|
19
|
+
uri = URI("http://example.com/dataset1/#{class_name.downcase}.xml")
|
20
|
+
doc = instance_double(doc_type)
|
21
|
+
expect(@client).to receive(:get_and_parse).once.with(uri) { doc }
|
22
|
+
expect(@cap_list.document_for(capability)).to be(doc)
|
23
|
+
expect(@cap_list.document_for(capability)).to be(@cap_list.document_for(capability))
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'caches downloaded resources' do
|
28
|
+
doc_types.each do |doc_type|
|
29
|
+
capability = doc_type::CAPABILITY
|
30
|
+
class_name = doc_type.name.split('::').last
|
31
|
+
uri = URI("http://example.com/dataset1/#{class_name.downcase}.xml")
|
32
|
+
doc = instance_double(doc_type)
|
33
|
+
expect(@client).to receive(:get_and_parse).once.with(uri) { doc }
|
34
|
+
expect(@cap_list.document_for(capability)).to be(@cap_list.document_for(capability))
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
doc_types.each do |doc_type|
|
40
|
+
class_name = doc_type.name.split('::').last
|
41
|
+
method_name = class_name.gsub(/(.)([A-Z])/, '\1_\2').downcase
|
42
|
+
|
43
|
+
describe "##{method_name}" do
|
44
|
+
it "downloads and parses the #{class_name}" do
|
45
|
+
uri = URI("http://example.com/dataset1/#{class_name.downcase}.xml")
|
46
|
+
doc = instance_double(doc_type)
|
47
|
+
expect(@client).to receive(:get_and_parse).once.with(uri) { doc }
|
48
|
+
expect(@cap_list.send(method_name.to_sym)).to be(doc)
|
49
|
+
end
|
50
|
+
|
51
|
+
it "caches the downloaded/parsed #{class_name}" do
|
52
|
+
uri = URI("http://example.com/dataset1/#{class_name.downcase}.xml")
|
53
|
+
doc = instance_double(doc_type)
|
54
|
+
expect(@client).to receive(:get_and_parse).once.with(uri) { doc }
|
55
|
+
expect(@cap_list.send(method_name.to_sym)).to be(@cap_list.send(method_name.to_sym))
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
end
|
@@ -36,6 +36,16 @@ module Resync
|
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
39
|
+
it 'is lazy' do
|
40
|
+
index_uri = URI('http://example.com/resource-list-index.xml')
|
41
|
+
index_data = File.read('spec/data/examples/resource-list-index.xml')
|
42
|
+
expect(@helper).to receive(:fetch).with(uri: index_uri).and_return(index_data)
|
43
|
+
|
44
|
+
index = @client.get_and_parse(index_uri)
|
45
|
+
all_resources = index.all_resources
|
46
|
+
expect(all_resources).to be_a(Enumerator::Lazy)
|
47
|
+
end
|
48
|
+
|
39
49
|
it 'is lazy enough not to download anything till it \'s iterated ' do
|
40
50
|
index_uri = URI('http://example.com/resource-list-index.xml')
|
41
51
|
index_data = File.read('spec/data/examples/resource-list-index.xml')
|
@@ -44,33 +44,37 @@ module Resync
|
|
44
44
|
|
45
45
|
describe ResourceList do
|
46
46
|
describe '#all_resources' do
|
47
|
-
it '
|
47
|
+
it 'delegates to #resources, but lazily' do
|
48
48
|
resources = Array.new(3) do
|
49
49
|
resource = instance_double(Resource)
|
50
50
|
allow(resource).to receive(:client_delegate=)
|
51
51
|
resource
|
52
52
|
end
|
53
53
|
list = ResourceList.new(resources: resources)
|
54
|
-
|
54
|
+
all_resources = list.all_resources
|
55
|
+
expect(all_resources.to_a).to eq(list.resources)
|
56
|
+
expect(all_resources).to be_a(Enumerator::Lazy)
|
55
57
|
end
|
56
58
|
end
|
57
59
|
end
|
58
60
|
|
59
61
|
describe ChangeList do
|
60
|
-
describe '#
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
62
|
+
describe '#all_resources' do
|
63
|
+
it 'delegates to #resources, but lazily' do
|
64
|
+
resources = []
|
65
|
+
resources[0] = Resource.new(uri: 'http://example.org/', modified_time: Time.utc(1999, 1, 1))
|
66
|
+
resources[1] = Resource.new(uri: 'http://example.org/', modified_time: Time.utc(2000, 1, 1))
|
67
|
+
resources[2] = Resource.new(uri: 'http://example.org/', modified_time: Time.utc(2001, 3, 1))
|
68
|
+
|
69
|
+
list = ChangeList.new(resources: resources)
|
70
|
+
all_resources = list.all_resources
|
71
|
+
expect(all_resources.to_a).to eq(list.resources)
|
72
|
+
expect(all_resources).to be_a(Enumerator::Lazy)
|
71
73
|
end
|
74
|
+
end
|
72
75
|
|
73
|
-
|
76
|
+
describe '#all_changes' do
|
77
|
+
it 'delegates to #changes, lazily' do
|
74
78
|
resources = []
|
75
79
|
resources[0] = Resource.new(uri: 'http://example.org/', modified_time: Time.utc(1999, 1, 1), metadata: Metadata.new(change: Types::Change::CREATED))
|
76
80
|
resources[1] = Resource.new(uri: 'http://example.org/', modified_time: Time.utc(2000, 1, 1), metadata: Metadata.new(change: Types::Change::CREATED))
|
@@ -82,6 +86,7 @@ module Resync
|
|
82
86
|
resources[7] = Resource.new(uri: 'http://example.org/', modified_time: Time.utc(2000, 9, 1), metadata: Metadata.new(change: Types::Change::DELETED))
|
83
87
|
list = ChangeList.new(resources: resources)
|
84
88
|
all_changes = list.all_changes(of_type: Types::Change::UPDATED, in_range: Time.utc(1999, 4, 1)..Time.utc(2000, 4, 1))
|
89
|
+
expect(all_changes).to be_a(Enumerator::Lazy)
|
85
90
|
expect(all_changes.to_a).to eq([resources[3], resources[4]])
|
86
91
|
end
|
87
92
|
end
|
@@ -152,6 +157,22 @@ module Resync
|
|
152
157
|
end
|
153
158
|
expect(count).to eq(1)
|
154
159
|
end
|
160
|
+
|
161
|
+
it 'is lazy when unfiltered' do
|
162
|
+
change_index_uri = URI('http://example.com/dataset1/changelist.xml')
|
163
|
+
change_index_data = File.read('spec/data/examples/change-list-index.xml')
|
164
|
+
expect(@helper).to receive(:fetch).with(uri: change_index_uri).and_return(change_index_data)
|
165
|
+
|
166
|
+
list2_uri = URI('http://example.com/20130102-changelist.xml')
|
167
|
+
expect(@helper).not_to receive(:fetch).with(uri: list2_uri)
|
168
|
+
|
169
|
+
list3_uri = URI('http://example.com/20130103-changelist.xml')
|
170
|
+
expect(@helper).not_to receive(:fetch).with(uri: list3_uri)
|
171
|
+
|
172
|
+
change_index = @client.get_and_parse(change_index_uri)
|
173
|
+
all_changes = change_index.all_changes
|
174
|
+
expect(all_changes).to be_a(Enumerator::Lazy)
|
175
|
+
end
|
155
176
|
end
|
156
177
|
end
|
157
178
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: resync-client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.2
|
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-06-
|
11
|
+
date: 2015-06-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: lazy
|
@@ -197,6 +197,7 @@ files:
|
|
197
197
|
- lib/resync/client/http_helper.rb
|
198
198
|
- lib/resync/client/mixins.rb
|
199
199
|
- lib/resync/client/mixins/bitstream_resource.rb
|
200
|
+
- lib/resync/client/mixins/capability_list_extensions.rb
|
200
201
|
- lib/resync/client/mixins/change_index.rb
|
201
202
|
- lib/resync/client/mixins/client_delegator.rb
|
202
203
|
- lib/resync/client/mixins/downloadable.rb
|
@@ -205,6 +206,7 @@ files:
|
|
205
206
|
- lib/resync/client/mixins/dump_manifest.rb
|
206
207
|
- lib/resync/client/mixins/link_client_delegate.rb
|
207
208
|
- lib/resync/client/mixins/list_index.rb
|
209
|
+
- lib/resync/client/mixins/plain_list.rb
|
208
210
|
- lib/resync/client/mixins/resource_client_delegate.rb
|
209
211
|
- lib/resync/client/mixins/zipped_resource.rb
|
210
212
|
- lib/resync/client/version.rb
|
@@ -243,6 +245,7 @@ files:
|
|
243
245
|
- spec/spec_helper.rb
|
244
246
|
- spec/todo.rb
|
245
247
|
- spec/unit/resync/client/bitstream_spec.rb
|
248
|
+
- spec/unit/resync/client/capability_list_extensions_spec.rb
|
246
249
|
- spec/unit/resync/client/change_dump_index_spec.rb
|
247
250
|
- spec/unit/resync/client/change_dump_spec.rb
|
248
251
|
- spec/unit/resync/client/client_spec.rb
|
@@ -308,6 +311,7 @@ test_files:
|
|
308
311
|
- spec/spec_helper.rb
|
309
312
|
- spec/todo.rb
|
310
313
|
- spec/unit/resync/client/bitstream_spec.rb
|
314
|
+
- spec/unit/resync/client/capability_list_extensions_spec.rb
|
311
315
|
- spec/unit/resync/client/change_dump_index_spec.rb
|
312
316
|
- spec/unit/resync/client/change_dump_spec.rb
|
313
317
|
- spec/unit/resync/client/client_spec.rb
|