resync 0.1.3 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7788451959096dfbc4797cbf223b4817f2058ed4
4
- data.tar.gz: e50c9e4839b2a595cb8cb1685f3bbd1b7a4a06c4
3
+ metadata.gz: aeaccafe9b78c6c1b73438dbc3615691e55acf37
4
+ data.tar.gz: 20ca197220dff4f8ac252d1fd3060446fad6e5e4
5
5
  SHA512:
6
- metadata.gz: f138fb16a10639f60575f198db8d320b8b17e411fb2d8dc5a78b9a75742cfcfd55991c6dee6367e3d13b7c3e7c090ccc9ac8cd85bca9049b0aa5330d65ce57ee
7
- data.tar.gz: 7b916f07c91848b65cfd3c390bdb321eec05a86dcd4e49745ca4f32d49a8913b1343242a635cb3dc75b69f4c6900ddde3dffde6f0e99ff322a9efbc94e97c032
6
+ metadata.gz: b82cd0986b56ea9aed5f12abc1532ead2bb942128938fed721b68fee918987acbc8fdb8683074d0669c5999cd9036d6b28c72b184ab39d44ed2f8928c48f2d85
7
+ data.tar.gz: eb88c946de862ab36cf3be1f9c01ff94f1f5ebe01d586ae6424bc729c004f0c6c80fd8b8a779415502c550faed3b350ee0f56b3e6c53e3d2e6273bd3934d10a9
data/CHANGES.md CHANGED
@@ -1,3 +1,9 @@
1
+ ## 0.2.0
2
+
3
+ - `BaseResourceList#resources` now returns an `IndexableLazy` instead of a plain array.
4
+ - Added `BaseResourcesList#resources_in` to filter resource lists by time.
5
+ - All `Augmented` objects now expose the complete set of time attribtues, so as to avoid having to fish around in the metadata.
6
+
1
7
  ## 0.1.3
2
8
 
3
9
  - Fix issue making it difficult to extend CapabilityList
@@ -10,6 +10,5 @@ module Resync
10
10
 
11
11
  # The capability provided by this type.
12
12
  CAPABILITY = 'resourcelist'
13
-
14
13
  end
15
14
  end
@@ -72,5 +72,22 @@ module Resync
72
72
  def link_for(rel:)
73
73
  links.find { |l| l.rel == rel }
74
74
  end
75
+
76
+ def at_time
77
+ metadata.at_time if metadata
78
+ end
79
+
80
+ def from_time
81
+ metadata.from_time if metadata
82
+ end
83
+
84
+ def until_time
85
+ metadata.until_time if metadata
86
+ end
87
+
88
+ def completed_time
89
+ metadata.completed_time if metadata
90
+ end
91
+
75
92
  end
76
93
  end
@@ -8,8 +8,8 @@ module Resync
8
8
  # must define a +CAPABILITY+ constant identifying the capability
9
9
  # they represent (e.g. +resourcelist+, +changelist+).
10
10
  #
11
- # @!attribute [rw] resources
12
- # @return [Array<Resource>] the +<url>+ or +<sitemap>+ elements contained in this list.
11
+ # @!attribute [r] resources
12
+ # @return [Util::IndexableLazy<Resource>] the +<url>+ or +<sitemap>+ elements contained in this list.
13
13
  class BaseResourceList < Augmented
14
14
  include ::XML::Mapping
15
15
 
@@ -40,7 +40,7 @@ module Resync
40
40
 
41
41
  # Sets the +resources+ list. +nil+ is treated as an empty list.
42
42
  def resources=(value)
43
- @resources = value || []
43
+ @resources = Util::IndexableLazy.new(value || [])
44
44
  end
45
45
 
46
46
  # Sets the metadata.
@@ -61,9 +61,9 @@ module Resync
61
61
 
62
62
  # Finds resources with the specified capability.
63
63
  # @param capability [String] the capability.
64
- # @return [Array<Resource>] those resources having that capability, or an empty array if none exist.
64
+ # @return [Enumerator::Lazy<Resource>] those resources having that capability, or an empty array if none exist.
65
65
  def resources_for(capability:)
66
- resources.select { |l| l.capability == capability }
66
+ resources.select { |r| r.capability == capability }
67
67
  end
68
68
 
69
69
  # Shortcut to find the first resource with the specified capability (in ResourceSync there often
@@ -71,7 +71,18 @@ module Resync
71
71
  # @param capability [String] the capability.
72
72
  # @return [Resource] the first resource having that capability, or nil if none exists.
73
73
  def resource_for(capability:)
74
- resources.find { |l| l.capability == capability }
74
+ resources.find { |r| r.capability == capability }
75
+ end
76
+
77
+ # Finds only those resources falling within the specified time range. Any of the time
78
+ # attributes (+:modified_time+, +:at_time+, +:completed_time+, +:from_time+, +:until_time+)
79
+ # can be used for filtering.
80
+ # @param time_range [Range[Time]] the range of acceptable times (inclusive or exclusive)
81
+ # @param time_attr [Symbol] the time type to filter on: +:modified_time+, +:at_time+,
82
+ # +:completed_time+, +:from_time+ or +:until_time+
83
+ # @return [Enumerator::Lazy<Resource>] a lazy enumeration of the resources within the specified range.
84
+ def resources_in(time_range:, time_attr:)
85
+ resources.select { |r| time_range.cover?(r.send(time_attr)) }
75
86
  end
76
87
 
77
88
  # ------------------------------------------------------------
@@ -109,7 +120,7 @@ module Resync
109
120
  capability = self.class::CAPABILITY
110
121
  fail ArgumentError, "Missing constant #{self.class}::CAPABILITY" unless capability
111
122
  return Metadata.new(capability: capability) unless metadata
112
- fail ArgumentError, "#{metadata} does not appear to be metadata" unless metadata.respond_to?('capability')
123
+ fail ArgumentError, ":metadata argument <#{metadata}> does not appear to be metadata" unless metadata.respond_to?(:capability)
113
124
  fail ArgumentError, "Wrong capability for #{self.class.name} metadata; expected '#{capability}', was '#{metadata.capability}'" unless metadata.capability == capability
114
125
  metadata
115
126
  end
@@ -48,12 +48,21 @@ module Resync
48
48
  def sorted(value)
49
49
  return [] unless value
50
50
  value.sort do |left, right|
51
- if left.modified_time && right.modified_time
52
- left.modified_time <=> right.modified_time
53
- else
54
- right.modified_time ? 1 : -1
51
+ compare(left, right)
52
+ end
53
+ end
54
+
55
+ def compare(left, right)
56
+ [:modified_time, :from_time, :at_time, :until_time, :completed_time].each do |time_reader|
57
+ left_time = left.send(time_reader)
58
+ right_time = right.send(time_reader)
59
+ if left_time && right_time
60
+ return left_time <=> right_time
61
+ elsif left_time || right_time
62
+ return left_time ? -1 : 1
55
63
  end
56
64
  end
65
+ 0
57
66
  end
58
67
 
59
68
  def by_uri(resources)
@@ -0,0 +1,18 @@
1
+ require 'delegate'
2
+
3
+ module Resync
4
+ module Util
5
+ class IndexableLazy < SimpleDelegator
6
+
7
+ def initialize(array)
8
+ super(array.lazy)
9
+ @array = array
10
+ end
11
+
12
+ def [](key)
13
+ @array[key]
14
+ end
15
+
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,6 @@
1
+ module Resync
2
+ # Miscellaneous utilities
3
+ module Types
4
+ Dir.glob(File.expand_path('../util/*.rb', __FILE__), &method(:require))
5
+ end
6
+ end
@@ -1,4 +1,4 @@
1
1
  module Resync
2
2
  # The version of this gem.
3
- VERSION = '0.1.3'
3
+ VERSION = '0.2.0'
4
4
  end
@@ -80,10 +80,10 @@ module Resync
80
80
  it 'maps resources by capability' do
81
81
  resources = valid_resources
82
82
  capability_list = CapabilityList.new(resources: resources, links: [Link.new(rel: 'up', uri: 'http://example.org/')])
83
- expect(capability_list.resources_for(capability: 'resourcelist')).to eq([resources[0]])
84
- expect(capability_list.resources_for(capability: 'resourcedump')).to eq([resources[1]])
85
- expect(capability_list.resources_for(capability: 'changelist')).to eq([resources[2]])
86
- expect(capability_list.resources_for(capability: 'changedump')).to eq([resources[3]])
83
+ expect(capability_list.resources_for(capability: 'resourcelist').to_a).to eq([resources[0]])
84
+ expect(capability_list.resources_for(capability: 'resourcedump').to_a).to eq([resources[1]])
85
+ expect(capability_list.resources_for(capability: 'changelist').to_a).to eq([resources[2]])
86
+ expect(capability_list.resources_for(capability: 'changedump').to_a).to eq([resources[3]])
87
87
  end
88
88
  end
89
89
 
@@ -3,10 +3,7 @@ require_relative 'shared/base_resource_list_examples'
3
3
  module Resync
4
4
  describe ResourceListIndex do
5
5
  it_behaves_like BaseResourceList
6
-
7
- describe 'links' do
8
- it_behaves_like Augmented
9
- end
6
+ it_behaves_like Augmented
10
7
 
11
8
  describe 'XML conversion' do
12
9
  describe '#from_xml' do
@@ -3,10 +3,7 @@ require_relative 'shared/base_resource_list_examples'
3
3
  module Resync
4
4
  describe ResourceDumpManifest do
5
5
  it_behaves_like BaseResourceList
6
-
7
- describe 'links' do
8
- it_behaves_like Augmented
9
- end
6
+ it_behaves_like Augmented
10
7
 
11
8
  describe 'XML conversion' do
12
9
  describe '#from_xml' do
@@ -3,10 +3,7 @@ require_relative 'shared/base_resource_list_examples'
3
3
  module Resync
4
4
  describe ResourceDump do
5
5
  it_behaves_like BaseResourceList
6
-
7
- describe 'links' do
8
- it_behaves_like Augmented
9
- end
6
+ it_behaves_like Augmented
10
7
 
11
8
  describe 'XML conversion' do
12
9
  describe '#from_xml' do
@@ -3,10 +3,7 @@ require_relative 'shared/base_resource_list_examples'
3
3
  module Resync
4
4
  describe ResourceListIndex do
5
5
  it_behaves_like BaseResourceList
6
-
7
- describe 'links' do
8
- it_behaves_like Augmented
9
- end
6
+ it_behaves_like Augmented
10
7
 
11
8
  describe 'XML conversion' do
12
9
  describe '#from_xml' do
@@ -3,10 +3,7 @@ require_relative 'shared/base_resource_list_examples'
3
3
  module Resync
4
4
  describe ResourceList do
5
5
  it_behaves_like BaseResourceList
6
-
7
- describe 'links' do
8
- it_behaves_like Augmented
9
- end
6
+ it_behaves_like Augmented
10
7
 
11
8
  describe 'XML conversion' do
12
9
  describe '#from_xml' do
@@ -4,6 +4,13 @@ require_relative 'shared/augmented_examples'
4
4
 
5
5
  module Resync
6
6
  describe Resource do
7
+
8
+ def required_arguments
9
+ { uri: 'http://example.org' }
10
+ end
11
+
12
+ it_behaves_like Augmented
13
+
7
14
  describe '#new' do
8
15
 
9
16
  describe 'uri' do
@@ -23,13 +30,6 @@ module Resync
23
30
  end
24
31
  end
25
32
 
26
- describe 'links' do
27
- def required_arguments
28
- { uri: 'http://example.org' }
29
- end
30
- it_behaves_like Augmented
31
- end
32
-
33
33
  describe 'metadata' do
34
34
  it 'accepts metadata' do
35
35
  md = Metadata.new
@@ -13,15 +13,14 @@ module Resync
13
13
  describe 'links' do
14
14
  it 'accepts a list of links' do
15
15
  links = [Link.new(rel: 'describedby', uri: 'http://example.org/'), Link.new(rel: 'duplicate', uri: 'http://example.com/')]
16
- list = new_instance(links: links)
17
- expect(list.links).to eq(links)
16
+ augmented = new_instance(links: links)
17
+ expect(augmented.links).to eq(links)
18
18
  end
19
19
 
20
- it 'defaults to an empty list if no links are specified' do
21
- list = new_instance
22
- expect(list.links).to eq([])
20
+ it 'defaults to an empty augmented if no links are specified' do
21
+ augmented = new_instance
22
+ expect(augmented.links).to eq([])
23
23
  end
24
-
25
24
  end
26
25
 
27
26
  describe '#links_for' do
@@ -32,10 +31,10 @@ module Resync
32
31
  Link.new(rel: 'describedby', uri: 'http://example.org/desc2'),
33
32
  Link.new(rel: 'duplicate', uri: 'http://example.com/dup2')
34
33
  ]
35
- list = new_instance(links: links)
36
- expect(list.links_for(rel: 'describedby')).to eq([links[0], links[2]])
37
- expect(list.links_for(rel: 'duplicate')).to eq([links[1], links[3]])
38
- expect(list.links_for(rel: 'elvis')).to eq([])
34
+ augmented = new_instance(links: links)
35
+ expect(augmented.links_for(rel: 'describedby')).to eq([links[0], links[2]])
36
+ expect(augmented.links_for(rel: 'duplicate')).to eq([links[1], links[3]])
37
+ expect(augmented.links_for(rel: 'elvis')).to eq([])
39
38
  end
40
39
  end
41
40
 
@@ -47,10 +46,27 @@ module Resync
47
46
  Link.new(rel: 'describedby', uri: 'http://example.org/desc2'),
48
47
  Link.new(rel: 'duplicate', uri: 'http://example.com/dup2')
49
48
  ]
50
- list = new_instance(links: links)
51
- expect(list.link_for(rel: 'describedby')).to eq(links[0])
52
- expect(list.link_for(rel: 'duplicate')).to eq(links[1])
53
- expect(list.link_for(rel: 'elvis')).to eq(nil)
49
+ augmented = new_instance(links: links)
50
+ expect(augmented.link_for(rel: 'describedby')).to eq(links[0])
51
+ expect(augmented.link_for(rel: 'duplicate')).to eq(links[1])
52
+ expect(augmented.link_for(rel: 'elvis')).to eq(nil)
53
+ end
54
+ end
55
+
56
+ describe 'additional time attributes' do
57
+ it 'extracts the at_time, from_time, until_time, and completed_time from the metadata' do
58
+ capability = described_class::CAPABILITY if defined?(described_class::CAPABILITY)
59
+ md = Metadata.new(
60
+ at_time: Time.utc(1999, 1, 1),
61
+ from_time: Time.utc(2001, 1, 1),
62
+ until_time: Time.utc(2003, 1, 1),
63
+ completed_time: Time.utc(2005, 1, 1),
64
+ capability: capability
65
+ )
66
+ augmented = new_instance(metadata: md)
67
+ [:at_time, :from_time, :until_time, :completed_time].each do |t|
68
+ expect(augmented.send(t)).to be_time(md.send(t))
69
+ end
54
70
  end
55
71
  end
56
72
 
@@ -9,7 +9,12 @@ module Resync
9
9
 
10
10
  # TODO: Find a better way to express this
11
11
  def resource_list
12
- (defined? valid_resources) ? valid_resources : [Resource.new(uri: 'http://example.org/'), Resource.new(uri: 'http://example.com/')]
12
+ (defined? valid_resources) ? valid_resources : [
13
+ Resource.new(uri: 'http://example.com/res1'),
14
+ Resource.new(uri: 'http://example.com/res2'),
15
+ Resource.new(uri: 'http://example.com/res3'),
16
+ Resource.new(uri: 'http://example.com/res4')
17
+ ]
13
18
  end
14
19
 
15
20
  # TODO: Find a better way to express this
@@ -25,15 +30,34 @@ module Resync
25
30
  describe '#new' do
26
31
  describe 'resources' do
27
32
  it 'accepts a list of resources' do
28
- puts defined? valid_resources
29
33
  resources = resource_list
30
34
  list = new_instance(resources: resources)
31
- expect(list.resources).to eq(resources)
35
+ expect(list.resources.to_a).to eq(resources)
36
+ end
37
+
38
+ it 'is lazy' do
39
+ resources = resource_list
40
+ list = new_instance(resources: resources)
41
+
42
+ half = resources.size / 2
43
+ (0...resources.size).each do |i|
44
+ if i < half
45
+ expect(resources[i]).to receive(:priority).and_return(i)
46
+ else
47
+ expect(resources[i]).not_to receive(:priority)
48
+ end
49
+ end
50
+
51
+ count = 0
52
+ list.resources.take(half).each do |r|
53
+ expect(r.priority).to eq(count)
54
+ count += 1
55
+ end
32
56
  end
33
57
 
34
58
  it 'defaults to an empty list if no resources are specified' do
35
59
  list = new_instance
36
- expect(list.resources).to eq([])
60
+ expect(list.resources.to_a).to eq([])
37
61
  end
38
62
  end
39
63
 
@@ -67,9 +91,9 @@ module Resync
67
91
  Resource.new(uri: 'http://example.com/dataset1/changelist2.xml', metadata: Metadata.new(capability: 'changelist'))
68
92
  ]
69
93
  list = new_instance(resources: resources)
70
- expect(list.resources_for(capability: 'resourcedump')).to eq([resources[0], resources[2]])
71
- expect(list.resources_for(capability: 'changelist')).to eq([resources[1], resources[3]])
72
- expect(list.resources_for(capability: 'changedump')).to eq([])
94
+ expect(list.resources_for(capability: 'resourcedump').to_a).to eq([resources[0], resources[2]])
95
+ expect(list.resources_for(capability: 'changelist').to_a).to eq([resources[1], resources[3]])
96
+ expect(list.resources_for(capability: 'changedump').to_a).to eq([])
73
97
  end
74
98
  end
75
99
  end
@@ -91,7 +115,7 @@ module Resync
91
115
  end
92
116
  end
93
117
 
94
- describe 'capability' do
118
+ describe '#capability' do
95
119
  it 'extracts the capability' do
96
120
  metadata = Metadata.new(capability: described_class::CAPABILITY)
97
121
  list = new_instance(metadata: metadata)
@@ -99,5 +123,48 @@ module Resync
99
123
  end
100
124
  end
101
125
 
126
+ describe '#resources_in' do
127
+ [:at_time, :completed_time, :from_time, :until_time, :modified_time].each do |reader|
128
+ it "allows filtering by #{reader}" do
129
+ before_time = Time.utc(1969, 1, 1)
130
+ start_time = Time.utc(1970, 1, 1)
131
+ end_time = Time.utc(1980, 1, 1)
132
+ after_time = Time.utc(1981, 1, 1)
133
+ times = [before_time, start_time, end_time, after_time]
134
+
135
+ writer = "#{reader}=".to_sym
136
+ resources = resource_list
137
+ resources.each_with_index do |r, i|
138
+ if writer == :modified_time=
139
+ r.send(writer, times[i])
140
+ else
141
+ md = r.metadata || (r.metadata = Metadata.new)
142
+ md.send(writer, times[i])
143
+ end
144
+ expect(r.send(reader)).to be_time(times[i]) # just to be sure
145
+ end
146
+
147
+ list = new_instance(resources: resources, metadata: Metadata.new(capability: described_class::CAPABILITY))
148
+
149
+ range_inclusive = start_time..end_time
150
+
151
+ filtered = list.resources_in(time_range: range_inclusive, time_attr: reader).to_a
152
+ expect(filtered.size).to eq(2)
153
+ expect(filtered).not_to include(resources[0])
154
+ expect(filtered).to include(resources[1])
155
+ expect(filtered).to include(resources[2])
156
+ expect(filtered).not_to include(resources[3])
157
+
158
+ range_exclusive = start_time...end_time
159
+ filtered = list.resources_in(time_range: range_exclusive, time_attr: reader).to_a
160
+ expect(filtered.size).to eq(1)
161
+ expect(filtered).not_to include(resources[0])
162
+ expect(filtered).to include(resources[1])
163
+ expect(filtered).not_to include(resources[2])
164
+ expect(filtered).not_to include(resources[3])
165
+ end
166
+ end
167
+ end
168
+
102
169
  end
103
170
  end
@@ -24,7 +24,20 @@ module Resync
24
24
  resource0 = Resource.new(uri: 'http://example.org', modified_time: Time.utc(1997, 7, 16, 19, 20, 30.45))
25
25
  resource1 = Resource.new(uri: 'http://example.org', modified_time: Time.utc(1998, 7, 16, 19, 20, 30.45))
26
26
  list = new_instance(resources: [resource1, resource0])
27
- expect(list.resources).to eq([resource0, resource1])
27
+ expect(list.resources.to_a).to eq([resource0, resource1])
28
+ end
29
+
30
+ it 'is non-destructive when sorting resources with identical times' do
31
+ resource0 = Resource.new(uri: 'http://example.org', modified_time: Time.utc(1997, 7, 16, 19, 20, 30.45))
32
+ resource1 = Resource.new(uri: 'http://example.org', modified_time: Time.utc(1998, 7, 16, 19, 20, 30.45))
33
+ resource2 = Resource.new(uri: 'http://example.org', modified_time: Time.utc(1998, 7, 16, 19, 20, 30.45))
34
+ resource4 = Resource.new(uri: 'http://example.org', modified_time: Time.utc(1998, 1, 16, 19, 20, 30.45))
35
+ list = new_instance(resources: [resource1, resource4, resource2, resource0])
36
+ resources = list.resources.to_a
37
+ expect(resources[0]).to be(resource0)
38
+ expect(resources[1]).to be(resource4)
39
+ expect(resources).to include(resource1)
40
+ expect(resources).to include(resource2)
28
41
  end
29
42
 
30
43
  it 'sorts resources with modified_time before resources without' do
@@ -32,7 +45,44 @@ module Resync
32
45
  resource1 = Resource.new(uri: 'http://example.org', modified_time: Time.utc(1998, 7, 16, 19, 20, 30.45))
33
46
  resource2 = Resource.new(uri: 'http://example.com')
34
47
  list = new_instance(resources: [resource1, resource2, resource0])
35
- expect(list.resources).to eq([resource0, resource1, resource2])
48
+ expect(list.resources.to_a).to eq([resource0, resource1, resource2])
49
+ end
50
+
51
+ it 'sorts resources by from_time' do
52
+ resource0 = Resource.new(uri: 'http://example.org', metadata: Metadata.new(from_time: Time.utc(1997, 7, 16, 19, 20, 30.45)))
53
+ resource1 = Resource.new(uri: 'http://example.org', metadata: Metadata.new(from_time: Time.utc(1998, 7, 16, 19, 20, 30.45)))
54
+ list = new_instance(resources: [resource1, resource0])
55
+ expect(list.resources.to_a).to eq([resource0, resource1])
56
+ end
57
+
58
+ it 'sorts resources by at_time' do
59
+ resource0 = Resource.new(uri: 'http://example.org', metadata: Metadata.new(at_time: Time.utc(1997, 7, 16, 19, 20, 30.45)))
60
+ resource1 = Resource.new(uri: 'http://example.org', metadata: Metadata.new(at_time: Time.utc(1998, 7, 16, 19, 20, 30.45)))
61
+ list = new_instance(resources: [resource1, resource0])
62
+ expect(list.resources.to_a).to eq([resource0, resource1])
63
+ end
64
+
65
+ it 'sorts resources by until_time' do
66
+ resource0 = Resource.new(uri: 'http://example.org', metadata: Metadata.new(until_time: Time.utc(1997, 7, 16, 19, 20, 30.45)))
67
+ resource1 = Resource.new(uri: 'http://example.org', metadata: Metadata.new(until_time: Time.utc(1998, 7, 16, 19, 20, 30.45)))
68
+ list = new_instance(resources: [resource1, resource0])
69
+ expect(list.resources.to_a).to eq([resource0, resource1])
70
+ end
71
+
72
+ it 'sorts resources by completed_time' do
73
+ resource0 = Resource.new(uri: 'http://example.org', metadata: Metadata.new(completed_time: Time.utc(1997, 7, 16, 19, 20, 30.45)))
74
+ resource1 = Resource.new(uri: 'http://example.org', metadata: Metadata.new(completed_time: Time.utc(1998, 7, 16, 19, 20, 30.45)))
75
+ list = new_instance(resources: [resource1, resource0])
76
+ expect(list.resources.to_a).to eq([resource0, resource1])
77
+ end
78
+
79
+ it 'preferentially sorts by modified_time' do
80
+ resource0 = Resource.new(uri: 'http://example.org', metadata: Metadata.new(at_time: Time.utc(1998, 7, 16, 19, 20, 30.45)))
81
+ resource1 = Resource.new(uri: 'http://example.org', metadata: Metadata.new(at_time: Time.utc(1997, 7, 16, 19, 20, 30.45)))
82
+ resource2 = Resource.new(uri: 'http://example.org', modified_time: Time.utc(2001, 7, 16, 19, 20, 30.45), metadata: Metadata.new(at_time: Time.utc(2003, 7, 16, 19, 20, 30.45)))
83
+ resource3 = Resource.new(uri: 'http://example.org', modified_time: Time.utc(2000, 1, 16, 19, 20, 30.45), metadata: Metadata.new(at_time: Time.utc(2005, 7, 16, 19, 20, 30.45)))
84
+ list = new_instance(resources: [resource0, resource1, resource2, resource3])
85
+ expect(list.resources.to_a).to eq([resource3, resource2, resource1, resource0])
36
86
  end
37
87
  end
38
88
  end
@@ -5,10 +5,7 @@ require_relative 'shared/augmented_examples'
5
5
  module Resync
6
6
  describe SourceDescription do
7
7
  it_behaves_like BaseResourceList
8
-
9
- describe 'links' do
10
- it_behaves_like Augmented
11
- end
8
+ it_behaves_like Augmented
12
9
 
13
10
  describe 'XML conversion' do
14
11
  describe '#from_xml' do
@@ -0,0 +1,133 @@
1
+ require 'spec_helper'
2
+
3
+ module Resync
4
+ module Util
5
+ describe IndexableLazy do
6
+
7
+ before(:each) do
8
+ @size = 3
9
+ @array = Array.new(@size) { instance_double(Object) }
10
+ @lazy = IndexableLazy.new(@array)
11
+ end
12
+
13
+ describe '#size' do
14
+ it 'returns the size of the underlying array' do
15
+ expect(@lazy.size).to eq(@size)
16
+ end
17
+ end
18
+
19
+ describe '#[]' do
20
+ it 'is lazy' do
21
+ expect(@array[0]).to receive(:to_s).and_return('0')
22
+ expect(@array[1]).to receive(:to_s).and_return('1')
23
+ expect(@array[2]).not_to receive(:to_s)
24
+
25
+ (0...@lazy.size).each do |i|
26
+ expect(@lazy[i]).to eq(@array[i])
27
+ break if @lazy[i].to_s == '1'
28
+ end
29
+ end
30
+ end
31
+
32
+ describe '#each' do
33
+ it 'is lazy' do
34
+ expect(@array[0]).to receive(:to_s).and_return('0')
35
+ expect(@array[1]).to receive(:to_s).and_return('1')
36
+ expect(@array[2]).not_to receive(:to_s)
37
+
38
+ @lazy.each do |v|
39
+ break if v.to_s == '1'
40
+ end
41
+ end
42
+ end
43
+
44
+ describe '#each_with_index' do
45
+ it 'is lazy' do
46
+ expect(@array[0]).to receive(:to_s).and_return('0')
47
+ expect(@array[1]).to receive(:to_s).and_return('1')
48
+ expect(@array[2]).not_to receive(:to_s)
49
+
50
+ @lazy.each_with_index do |v, i|
51
+ break if v.to_s == '1' || i > 1
52
+ end
53
+ end
54
+ end
55
+
56
+ describe '#each_with_object' do
57
+ it 'is lazy' do
58
+ expect(@array[0]).to receive(:to_s).and_return('0')
59
+ expect(@array[1]).to receive(:to_s).and_return('1')
60
+ expect(@array[2]).not_to receive(:to_s)
61
+
62
+ acc = []
63
+ @lazy.each_with_object(acc) do |v, obj|
64
+ obj << v.to_s
65
+ break if obj[-1] == '1'
66
+ end
67
+ expect(acc).to eq(%w(0 1))
68
+ end
69
+ end
70
+
71
+ describe '#find' do
72
+ it 'is lazy' do
73
+ expect(@array[0]).to receive(:to_s).and_return('0')
74
+ expect(@array[1]).to receive(:to_s).and_return('1')
75
+ expect(@array[2]).not_to receive(:to_s)
76
+
77
+ expect(@lazy.find { |v| v.to_s == '1' }).to be(@array[1])
78
+ end
79
+ end
80
+
81
+ describe '#find_index' do
82
+ it 'is lazy' do
83
+ expect(@array[0]).to receive(:to_s).and_return('0')
84
+ expect(@array[1]).to receive(:to_s).and_return('1')
85
+ expect(@array[2]).not_to receive(:to_s)
86
+
87
+ expect(@lazy.find_index { |v| v.to_s == '1' }).to eq(1)
88
+ end
89
+ end
90
+
91
+ describe '#take_while' do
92
+ it 'is lazy' do
93
+ expect(@array[0]).to receive(:to_s).and_return('0')
94
+ expect(@array[1]).to receive(:to_s).and_return('1')
95
+ expect(@array[2]).not_to receive(:to_s)
96
+
97
+ expect(@lazy.take_while { |v| v.to_s == '0' }.to_a).to eq([@array[0]])
98
+ end
99
+ end
100
+
101
+ describe '#map' do
102
+ it 'is lazy' do
103
+ expect(@array[0]).to receive(:to_s).and_return('0')
104
+ expect(@array[1]).to receive(:to_s).and_return('1')
105
+ expect(@array[2]).not_to receive(:to_s)
106
+
107
+ mapped = @lazy.map(&:to_s)
108
+ expect(mapped.take(2).to_a).to eq(%w(0 1))
109
+ end
110
+ end
111
+
112
+ describe '#take' do
113
+ it 'is lazy' do
114
+ expect(@array[0]).to receive(:to_s).and_return('0')
115
+ expect(@array[1]).to receive(:to_s).and_return('1')
116
+ expect(@array[2]).not_to receive(:to_s)
117
+
118
+ expect(@lazy.take(2).map(&:to_s).to_a).to eq(%w(0 1))
119
+ end
120
+ end
121
+
122
+ describe '#select' do
123
+ it 'is lazy' do
124
+ expect(@array[0]).not_to receive(:to_s)
125
+ expect(@array[1]).not_to receive(:to_s)
126
+ expect(@array[2]).not_to receive(:to_s)
127
+
128
+ @lazy.select(&:to_s)
129
+ end
130
+ end
131
+ end
132
+ end
133
+ end
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.1.3
4
+ version: 0.2.0
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-05 00:00:00.000000000 Z
11
+ date: 2015-06-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: mime-types
@@ -191,6 +191,8 @@ files:
191
191
  - lib/resync/types.rb
192
192
  - lib/resync/types/change.rb
193
193
  - lib/resync/types/change_frequency.rb
194
+ - lib/resync/util.rb
195
+ - lib/resync/util/indexable_lazy.rb
194
196
  - lib/resync/version.rb
195
197
  - lib/resync/xml.rb
196
198
  - lib/resync/xml_parser.rb
@@ -256,6 +258,7 @@ files:
256
258
  - spec/unit/resync/shared/sorted_list_examples.rb
257
259
  - spec/unit/resync/shared/uri_field_examples.rb
258
260
  - spec/unit/resync/source_description_spec.rb
261
+ - spec/unit/resync/util/indexable_lazy_spec.rb
259
262
  - spec/unit/resync/xml/timenode_spec.rb
260
263
  - spec/unit/resync/xml/xml_spec.rb
261
264
  - spec/unit/resync/xml_parser_spec.rb
@@ -279,7 +282,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
279
282
  version: '0'
280
283
  requirements: []
281
284
  rubyforge_project:
282
- rubygems_version: 2.4.6
285
+ rubygems_version: 2.4.7
283
286
  signing_key:
284
287
  specification_version: 4
285
288
  summary: Utility library for ResourceSync
@@ -345,6 +348,7 @@ test_files:
345
348
  - spec/unit/resync/shared/sorted_list_examples.rb
346
349
  - spec/unit/resync/shared/uri_field_examples.rb
347
350
  - spec/unit/resync/source_description_spec.rb
351
+ - spec/unit/resync/util/indexable_lazy_spec.rb
348
352
  - spec/unit/resync/xml/timenode_spec.rb
349
353
  - spec/unit/resync/xml/xml_spec.rb
350
354
  - spec/unit/resync/xml_parser_spec.rb