Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .ruby-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
jruby-1.7.17
jruby-1.7.23
2 changes: 1 addition & 1 deletion crimp.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Gem::Specification.new do |spec|
spec.name = "crimp"
spec.version = Crimp::VERSION
spec.authors = ["BBC News"]
spec.email = ["FutureMediaNewsRubyGems@bbc.co.uk"]
spec.email = ["D&ENewsFrameworksTeam@bbc.co.uk"]
spec.summary = %q{Creating an md5 hash of a number, string, array, or hash in Ruby}
spec.description = <<-EOS.gsub /^\s+/, ""
Shamelessly lifted from http://stackoverflow.com/questions/6461812/creating-an-md5-hash-of-a-number-string-array-or-hash-in-ruby
Expand Down
27 changes: 26 additions & 1 deletion lib/crimp.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
require 'crimp/version'
require 'digest'

class Numeric
# see http://patshaughnessy.net/2014/1/9/how-big-is-a-bignum
def bignum?
self >= 4611686018427387904
end
end

module Crimp
def self.signature(obj)
Digest::MD5.hexdigest stringify(obj)
Expand Down Expand Up @@ -44,6 +51,24 @@ def self.parse_hash(hash)
end

def self.to_string(obj)
"#{obj}#{obj.class}"
"#{obj}#{legacy_class(obj)}"
end

# This is for legacy/compatibilty reason:
#
# Ruby 2.1
# 2.class => Fixnum
# Ruby >= 2.4
# 2.class => Integer
#
# Say you have a huge number of stored keys and you migrate your app from 2.1 to >= 2.4
# this would cause a change of the signature for a subset of the keys which would be hard
# to debug especially for nested data structures.
#
def self.legacy_class(obj)
return obj.class unless obj.is_a?(Numeric)
return 'Float' if obj.is_a?(Float)
return 'Bignum' if obj.bignum?
'Fixnum'
end
end
2 changes: 1 addition & 1 deletion lib/crimp/version.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module Crimp
VERSION = '0.1.2'.freeze
VERSION = '0.2.0'.freeze
end
43 changes: 31 additions & 12 deletions spec/crimp_spec.rb
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
require 'spec_helper'

describe Crimp do
let (:hash) { { a: { b: 'b', c: 'c' }, d: 'd' } }
let (:hash_unordered) { { d: 'd', a: { c: 'c', b: 'b' } } }
let (:array) { [1, 2, 3, [4, [5, 6]]] }
let (:array_unordered) { [3, 2, 1, [[5, 6], 4]] }
let(:hash) { { a: { b: 'b', c: 'c' }, d: 'd' } }
let(:hash_with_numbers) { { a: { b: 1, c: 3.14 }, d: 'd' } }
let(:hash_unordered) { { d: 'd', a: { c: 'c', b: 'b' } } }
let(:array) { [1, 2, 3, [4, [5, 6]]] }
let(:array_unordered) { [3, 2, 1, [[5, 6], 4]] }

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this cover the full range of data types you're wanting to test against? No booleans, nil values, non-UTF-8 character strings, etc?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes test coverage is weak, the new version of Crimp i'm working on has better tests tho.


describe '.signature' do
context 'given a Hash' do
specify { expect(subject.signature(hash)).to be_a String }

it 'returns MD5 hash of stringified Hash' do
expect(subject.signature(hash)).to eq(Digest::MD5.hexdigest(subject.stringify(hash)))
Copy link
Contributor Author

@ettomatic ettomatic Aug 10, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:(

expect(subject.signature(hash)).to eq('68d07febc4f47f56fa6ef5de063a77b1')
end

it 'does not modify original hash' do
Expand All @@ -24,11 +23,15 @@
end
end

context 'given an Array' do
specify { expect(subject.signature(array)).to be_a String }
context 'Given an hash with numbers' do
it 'returns MD5 hash of stringified hash' do
expect(subject.signature(hash_with_numbers)).to eq 'b1fec09904b6ff36c92e3bd48234def7'
end
end

context 'given an Array' do
it 'returns MD5 hash of stringified Array' do
expect(subject.signature(array)).to eq(Digest::MD5.hexdigest(subject.stringify(array)))
expect(subject.signature(array)).to eq('4dc4e1161c9315db0bc43c0201b3ec05')
end

it 'does not modify original array' do
Expand All @@ -40,12 +43,28 @@
expect(original_array).to eq(expected_array)
end
end

context 'Given an integer' do
it 'returns MD5 hash of an Integer' do
expect(subject.signature(123)).to eq '519d3381631851be66711f6d7dfbb4f8'
end
end

context 'Given an Bignum' do
it 'returns MD5 hash of a Bignum' do
expect(subject.signature(9999999999999999999)).to eq 'f00e75abca720e18fd4213e2a6de96c6'
end
end

context 'Given an float' do
it 'returns MD5 hash of a Float' do
expect(subject.signature(3.14)).to eq 'b07d506e3701fddd083ae9095df43218'
end
end
end

describe '.stringify' do
context 'given a Hash' do
specify { expect(subject.stringify(hash)).to be_a String }

it 'returns equal strings for differently ordered hashes' do
expect(subject.stringify(hash)).to eq(subject.stringify(hash_unordered))
end
Expand Down