collapsium 0.2.0 → 0.2.1
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 +4 -4
- data/Gemfile.lock +4 -4
- data/lib/collapsium/prototype_match.rb +40 -13
- data/lib/collapsium/version.rb +1 -1
- data/spec/prototype_match_spec.rb +32 -13
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3d5aaed5e0ef8dd3a68421293d500d992152ad80
|
4
|
+
data.tar.gz: 54d67d56df16c00b74577fa9739991ef4d31b945
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 49b9758e50fa515fff8390fcd44ea17c65aca94ed6c3840eb0d4bea306e21a12b16b62aed98c637fb6905beec5d9d24958a9316a332391f6edaa20e84c486d0a
|
7
|
+
data.tar.gz: e702efb9a4addf4c669c3abd2b8c559ccab374896f29ef183ef6da9b580e128138e3dcd2d989ef0d826e43d1a14888b22d36d9f6f0a0369ab76f9228b01db14a
|
data/Gemfile.lock
CHANGED
@@ -1,18 +1,18 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
collapsium (0.2.
|
4
|
+
collapsium (0.2.1)
|
5
5
|
|
6
6
|
GEM
|
7
7
|
remote: https://rubygems.org/
|
8
8
|
specs:
|
9
9
|
ast (2.2.0)
|
10
|
-
codeclimate-test-reporter (0.5.
|
10
|
+
codeclimate-test-reporter (0.5.1)
|
11
11
|
simplecov (>= 0.7.1, < 1.0.0)
|
12
12
|
diff-lcs (1.2.5)
|
13
13
|
docile (1.1.5)
|
14
14
|
json (1.8.3)
|
15
|
-
parser (2.3.1.
|
15
|
+
parser (2.3.1.2)
|
16
16
|
ast (~> 2.2)
|
17
17
|
powerpack (0.1.1)
|
18
18
|
rainbow (2.1.0)
|
@@ -36,7 +36,7 @@ GEM
|
|
36
36
|
rainbow (>= 1.99.1, < 3.0)
|
37
37
|
ruby-progressbar (~> 1.7)
|
38
38
|
unicode-display_width (~> 1.0, >= 1.0.1)
|
39
|
-
ruby-progressbar (1.8.
|
39
|
+
ruby-progressbar (1.8.1)
|
40
40
|
simplecov (0.11.2)
|
41
41
|
docile (~> 1.1.0)
|
42
42
|
json (~> 1.8)
|
@@ -11,6 +11,9 @@ module Collapsium
|
|
11
11
|
##
|
12
12
|
# Provides prototype matching for Hashes. See #prototype_match
|
13
13
|
module PrototypeMatch
|
14
|
+
# Large negative integer for failures we can't express otherwise in scoring.
|
15
|
+
FAILURE = -2147483648
|
16
|
+
|
14
17
|
##
|
15
18
|
# Given a prototype Hash, returns true if (recursively):
|
16
19
|
# - this hash contains all the prototype's keys, and
|
@@ -23,22 +26,42 @@ module Collapsium
|
|
23
26
|
# not present in the prototype.
|
24
27
|
# @return (Boolean) True if matching succeeds, false otherwise.
|
25
28
|
def prototype_match(prototype, strict = false)
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
+
return prototype_match_score(prototype, strict) > 0
|
30
|
+
end
|
31
|
+
|
32
|
+
##
|
33
|
+
# Calculates a matching score for matching the prototype. A score of 0 or
|
34
|
+
# less is not a match, and the higher the score, the better the match is.
|
35
|
+
#
|
36
|
+
# @param prototype (Hash) The prototype to match against.
|
37
|
+
# @param strict (Boolean) If true, this Hash may not contain keys that are
|
38
|
+
# not present in the prototype.
|
39
|
+
# @return (Integer) Greater than zero for positive matches, equal to or
|
40
|
+
# less than zero for mismatches.
|
41
|
+
def prototype_match_score(prototype, strict = false)
|
42
|
+
# The prototype contains keys that are not in the Hash. That's a failure,
|
43
|
+
# and the level of failure is the number of missing keys.
|
44
|
+
missing = (prototype.keys - keys).length
|
45
|
+
if missing > 0
|
46
|
+
return -missing
|
29
47
|
end
|
30
48
|
|
31
49
|
# In strict evaluation, the Hash may also not contain keys that are not
|
32
50
|
# in the prototoype.
|
33
|
-
if strict
|
34
|
-
|
51
|
+
if strict
|
52
|
+
missing = (keys - prototype.keys).length
|
53
|
+
if missing > 0
|
54
|
+
return -missing
|
55
|
+
end
|
35
56
|
end
|
36
57
|
|
37
58
|
# Now we have to examine the prototype's values.
|
59
|
+
score = 0
|
38
60
|
prototype.each do |key, value|
|
39
61
|
# We can skip any nil values in the prototype. They exist only to ensure
|
40
|
-
# the key is present.
|
62
|
+
# the key is present. We do increase the score for a matched key, though!
|
41
63
|
if value.nil?
|
64
|
+
score += 1
|
42
65
|
next
|
43
66
|
end
|
44
67
|
|
@@ -46,25 +69,29 @@ module Collapsium
|
|
46
69
|
# and we have to recurse into this Hash.
|
47
70
|
if value.is_a?(Hash)
|
48
71
|
if not self[key].is_a?(Hash)
|
49
|
-
return
|
72
|
+
return FAILURE
|
50
73
|
end
|
51
74
|
|
52
75
|
self[key].extend(PrototypeMatch)
|
53
|
-
|
54
|
-
|
76
|
+
recurse_score = self[key].prototype_match_score(value)
|
77
|
+
if recurse_score < 0
|
78
|
+
return recurse_score
|
55
79
|
end
|
80
|
+
score += recurse_score
|
56
81
|
|
57
82
|
next
|
58
83
|
end
|
59
84
|
|
60
85
|
# Otherwise the prototype value must be equal to the Hash's value
|
61
|
-
if self[key]
|
62
|
-
|
86
|
+
if self[key] == value
|
87
|
+
score += 1
|
88
|
+
else
|
89
|
+
score -= 1
|
63
90
|
end
|
64
91
|
end
|
65
92
|
|
66
|
-
#
|
67
|
-
return
|
93
|
+
# Return score
|
94
|
+
return score
|
68
95
|
end
|
69
96
|
end # module PrototypeMatch
|
70
97
|
end # module Collapsium
|
data/lib/collapsium/version.rb
CHANGED
@@ -15,36 +15,36 @@ describe ::Collapsium::PrototypeMatch do
|
|
15
15
|
@hash.extend(::Collapsium::PrototypeMatch)
|
16
16
|
end
|
17
17
|
|
18
|
-
it "
|
18
|
+
it "scores positively a prototype containing any individual key (non-strict)" do
|
19
19
|
# Keys exist in hash
|
20
|
-
expect(@hash.
|
21
|
-
expect(@hash.
|
22
|
-
expect(@hash.
|
20
|
+
expect(@hash.prototype_match_score('a' => nil)).to be > 0
|
21
|
+
expect(@hash.prototype_match_score('b' => nil)).to be > 0
|
22
|
+
expect(@hash.prototype_match_score(c: nil)).to be > 0
|
23
23
|
|
24
24
|
# Key doesn't exist in hash
|
25
|
-
expect(@hash.
|
25
|
+
expect(@hash.prototype_match_score(foo: nil)).to be <= 0
|
26
26
|
end
|
27
27
|
|
28
|
-
it "
|
29
|
-
expect(@hash.
|
28
|
+
it "scores negatively a prototype containing an individual key in strict mode" do
|
29
|
+
expect(@hash.prototype_match_score({ 'a' => nil }, true)).to be <= 0
|
30
30
|
end
|
31
31
|
|
32
|
-
it "
|
32
|
+
it "scores positively nested prototypes (non-strict)" do
|
33
33
|
proto = {
|
34
34
|
c: {
|
35
35
|
'd' => nil,
|
36
36
|
}
|
37
37
|
}
|
38
|
-
expect(@hash.
|
38
|
+
expect(@hash.prototype_match_score(proto)).to be > 0
|
39
39
|
end
|
40
40
|
|
41
|
-
it "
|
41
|
+
it "scores negatively nested prototypes (strict)" do
|
42
42
|
proto = {
|
43
43
|
c: {
|
44
44
|
'd' => nil,
|
45
45
|
}
|
46
46
|
}
|
47
|
-
expect(@hash.
|
47
|
+
expect(@hash.prototype_match_score(proto, true)).to be <= 0
|
48
48
|
end
|
49
49
|
|
50
50
|
it "fails if a value type mismatches a prototype value's type" do
|
@@ -53,7 +53,7 @@ describe ::Collapsium::PrototypeMatch do
|
|
53
53
|
'd' => {},
|
54
54
|
}
|
55
55
|
}
|
56
|
-
expect(@hash.
|
56
|
+
expect(@hash.prototype_match_score(proto)).to be <= 0
|
57
57
|
end
|
58
58
|
|
59
59
|
it "fails if a value mismatches a prototype value" do
|
@@ -62,6 +62,25 @@ describe ::Collapsium::PrototypeMatch do
|
|
62
62
|
'd' => 42,
|
63
63
|
}
|
64
64
|
}
|
65
|
-
expect(@hash.
|
65
|
+
expect(@hash.prototype_match_score(proto)).to be <= 0
|
66
|
+
end
|
67
|
+
|
68
|
+
it "succeeds if a value matches a prototype value" do
|
69
|
+
proto = {
|
70
|
+
c: {
|
71
|
+
'd' => 4,
|
72
|
+
}
|
73
|
+
}
|
74
|
+
expect(@hash.prototype_match_score(proto)).to be > 0
|
75
|
+
end
|
76
|
+
|
77
|
+
it "matches prototypes" do
|
78
|
+
# Keys exist in hash
|
79
|
+
expect(@hash.prototype_match('a' => nil)).to be_truthy
|
80
|
+
expect(@hash.prototype_match('b' => nil)).to be_truthy
|
81
|
+
expect(@hash.prototype_match(c: nil)).to be_truthy
|
82
|
+
|
83
|
+
# Key doesn't exist in hash
|
84
|
+
expect(@hash.prototype_match(foo: nil)).to be_falsey
|
66
85
|
end
|
67
86
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: collapsium
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jens Finkhaeuser
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-06-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|