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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c72554545a2d19f93f85eb0b021de5516041024f
4
- data.tar.gz: a285cc547f7c90a4bc6d1ca5ef27ae8e75b2c9fb
3
+ metadata.gz: bd8d1fac9a7feece07634eca0cb2b9b4e9d2ce93
4
+ data.tar.gz: 27e94c732902e0f9b42be6ce9ec9df74f16d641a
5
5
  SHA512:
6
- metadata.gz: 8e4600dffb2cbe106fb2454c402e84085743ccbaed5d3195564bdc79ddb96d26b1c746876aedabbc599ac1d262e6a7f16b37c4bc412b782854f65679fd15bbf4
7
- data.tar.gz: ff4b5427c5a8fdbb88d9a56688cb908ccf3bdaae73e0aba580c202a8b30ba7f07e74dd37765e0985499802bc7c57f686672f96dfd07eaf7a499c6ccc08e2c6f9
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
- # Aliases +:changes+ as +:all_changes+ for transparent
40
- # interoperability with +ChangeListIndex+
41
- alias_method :all_changes, :changes
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
@@ -1,6 +1,6 @@
1
1
  module Resync
2
2
  class Client
3
3
  # The version of this gem.
4
- VERSION = '0.3.1'
4
+ VERSION = '0.3.2'
5
5
  end
6
6
  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 'is an alias for #resources' do
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
- expect(list.all_resources).to be(list.resources)
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 '#all_changes' do
61
- describe '#all_resources' do
62
- it 'is an alias for #resources' do
63
- resources = []
64
- resources[0] = Resource.new(uri: 'http://example.org/', modified_time: Time.utc(1999, 1, 1))
65
- resources[1] = Resource.new(uri: 'http://example.org/', modified_time: Time.utc(2000, 1, 1))
66
- resources[2] = Resource.new(uri: 'http://example.org/', modified_time: Time.utc(2001, 3, 1))
67
-
68
- all_resources = ResourceList.new(resources: resources).all_resources
69
- expect(all_resources.to_a).to eq(resources)
70
- end
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
- it 'is a proxy for #changes' do
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.1
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-24 00:00:00.000000000 Z
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