fingerprintable 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/lib/fingerprintable/fingerprinter.rb +44 -9
- data/lib/fingerprintable/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 974d5bf19592f7d2d35c604e7f4f5c6b5ad118250a113ca4d6d5c2b3fdc44d8a
|
4
|
+
data.tar.gz: 780b8605200414ccc134278a06bb413823747432c2552380c20433462f0aafaf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 98f96e9544657589b1af8a3844d3176d7171ca796dbec1aa0587833b7599b38e7a7d9df69b9df037f1475086eb171c86d14b9029e3754006fc75868aa31bb6c2
|
7
|
+
data.tar.gz: cc8a16d45ea75a4edec6f1c1789736e625bdb39e3f62e8c9eea36bced14fc9c953dadd815fb6f294a6ec527ab9c917b1df3756d0945fc989e8f5bfdda9edad75
|
data/Gemfile.lock
CHANGED
@@ -3,7 +3,6 @@
|
|
3
3
|
module Fingerprintable
|
4
4
|
class Fingerprinter
|
5
5
|
attr_reader :attributes,
|
6
|
-
:cache,
|
7
6
|
:fallback_to_string,
|
8
7
|
:ignore,
|
9
8
|
:object
|
@@ -21,6 +20,25 @@ module Fingerprintable
|
|
21
20
|
@attributes = ((object.instance_variables | attributes) - ignore).map(&:to_sym).sort
|
22
21
|
@cache = cache || {}
|
23
22
|
@cache[object] = next_cache_id
|
23
|
+
@fingerprinted = false
|
24
|
+
end
|
25
|
+
|
26
|
+
def cache
|
27
|
+
fingerprint unless @fingerprinted
|
28
|
+
@cache
|
29
|
+
end
|
30
|
+
|
31
|
+
def diff(other_fingerprinter)
|
32
|
+
raise "Passed object (#{other_fingerprinter.class.name}) does not match the fingerprinter object class: #{object.class.name}" if object.class != other_fingerprinter.object.class
|
33
|
+
|
34
|
+
values = object_values_hash
|
35
|
+
other_values = other_fingerprinter.object_values_hash
|
36
|
+
|
37
|
+
(attributes | other_fingerprinter.attributes).reject { |e| values[e] == other_values[e] }
|
38
|
+
end
|
39
|
+
|
40
|
+
def diff?(other_fingerprinter)
|
41
|
+
diff(other_fingerprinter).any?
|
24
42
|
end
|
25
43
|
|
26
44
|
def deep_convert_and_sort(obj)
|
@@ -34,7 +52,7 @@ module Fingerprintable
|
|
34
52
|
when Array
|
35
53
|
obj.map { |v| deep_convert_and_sort(v) }.sort.to_s
|
36
54
|
when Hash
|
37
|
-
Hash[obj.map { |k, v| [k, deep_convert_and_sort(v)] }].sort.to_s
|
55
|
+
Hash[obj.map { |k, v| [deep_convert_and_sort(k), deep_convert_and_sort(v)] }].sort.to_s
|
38
56
|
when Module
|
39
57
|
obj.name
|
40
58
|
else
|
@@ -44,12 +62,35 @@ module Fingerprintable
|
|
44
62
|
|
45
63
|
def fingerprint
|
46
64
|
@fingerprint ||= begin
|
65
|
+
@fingerprinted = true
|
47
66
|
Digest::MD5.hexdigest(to_s)
|
48
67
|
end
|
49
68
|
end
|
50
69
|
|
70
|
+
def object_values_hash
|
71
|
+
@object_values_hash ||= Hash[attributes.map do |attr|
|
72
|
+
[attr, object.instance_variable_get(attr)]
|
73
|
+
end]
|
74
|
+
end
|
75
|
+
|
51
76
|
def to_s
|
52
|
-
@to_s ||= deep_convert_and_sort(
|
77
|
+
@to_s ||= deep_convert_and_sort(object_values_hash).to_s
|
78
|
+
end
|
79
|
+
|
80
|
+
def self.diff(obj1, obj2)
|
81
|
+
f1 = if obj1.respond_to?(:fingerprinter)
|
82
|
+
obj1.fingerprinter
|
83
|
+
else
|
84
|
+
Fingerprinter.new(object: obj1)
|
85
|
+
end
|
86
|
+
|
87
|
+
f2 = if obj2.respond_to?(:fingerprinter)
|
88
|
+
obj2.fingerprinter
|
89
|
+
else
|
90
|
+
Fingerprinter.new(object: obj2)
|
91
|
+
end
|
92
|
+
|
93
|
+
f1.diff(f2)
|
53
94
|
end
|
54
95
|
|
55
96
|
private
|
@@ -79,11 +120,5 @@ module Fingerprintable
|
|
79
120
|
# "#{SecureRandom.uuid}-#{@cache.count}"
|
80
121
|
@cache.count
|
81
122
|
end
|
82
|
-
|
83
|
-
def object_value_hash
|
84
|
-
Hash[attributes.map do |attr|
|
85
|
-
[attr, object.instance_variable_get(attr)]
|
86
|
-
end]
|
87
|
-
end
|
88
123
|
end
|
89
124
|
end
|