Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bound recursive checksumming #518

Merged
merged 1 commit into from Jan 11, 2015
Merged
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file or symbol
Failed to load files and symbols.
+36 −5
Diff settings

Always

Just for now

@@ -18,23 +18,28 @@ def calc(obj)

private

def update(obj, digest)
def update(obj, digest, visited = Set.new)
digest.update(obj.class.to_s)

if visited.include?(obj)
digest.update('recur')

This comment has been minimized.

Copy link
@mpapis

mpapis Jan 10, 2015

Member

if visited would be a hash then we could store also the digest value and set it here, would it be useful at all?

This comment has been minimized.

Copy link
@ddfreyne

ddfreyne Jan 10, 2015

Author Member

We can’t set the digest value because at the time it isn’t known yet.

This comment has been minimized.

Copy link
@mpapis

mpapis Jan 10, 2015

Member

ah I see it now, painful

return
end

case obj
when String
digest.update(obj)
when Array
obj.each do |el|
digest.update('elem')
update(el, digest)
update(el, digest, visited + [obj])
end
when Hash
obj.each do |key, value|
digest.update('key')
update(key, digest)
update(key, digest, visited + [obj])
digest.update('value')
update(value, digest)
update(value, digest, visited + [obj])
end
when Pathname
filename = obj.to_s
@@ -59,7 +64,7 @@ def update(obj, digest)
digest.update('attributes')
attributes = obj.attributes.dup
attributes.delete(:file)
update(attributes, digest)
update(attributes, digest, visited + [obj])
else
data = begin
Marshal.dump(obj)
@@ -25,6 +25,12 @@
it 'should checksum non-serializable arrays' do
subject.calc([-> {}]).must_match(CHECKSUM_REGEX)
end

it 'should checksum recursive arrays' do
array = [:a]
array << array
subject.calc(array).must_equal('mR3c98xA5ecazxx+M3h0Ss4/J20=')
end
end

describe 'for Hash' do
@@ -39,6 +45,18 @@
it 'should checksum non-serializable hashes' do
subject.calc({ a: -> {} }).must_match(CHECKSUM_REGEX)
end

it 'should checksum recursive hash keys' do
hash = {}
hash[hash] = 123
subject.calc(hash).must_equal('mKucWMhRtR/FHWNqR/EErF4qgTk=')
end

it 'should checksum recursive hash values' do
hash = {}
hash[123] = hash
subject.calc(hash).must_equal('PBiDX0nWnV+DAYB+w+xM0Kf21ZM=')
end
end

describe 'for Pathname' do
@@ -195,6 +213,14 @@
subject.calc(item).must_equal(normal_checksum)
end

describe 'with recursive attributes' do
it 'should checksum' do
item.attributes[:a] = item
subject.calc(item).must_match(CHECKSUM_REGEX)
subject.calc(item).wont_equal(normal_checksum)
end
end

describe 'with changed attributes' do
let(:attributes) { { x: 4, y: 5 } }

ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.