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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 39373bf60c53fa0099f0f3066725d0de62448e37
4
- data.tar.gz: 460a9f149f29cd83210c72e5abd2715046329499
3
+ metadata.gz: 3d5aaed5e0ef8dd3a68421293d500d992152ad80
4
+ data.tar.gz: 54d67d56df16c00b74577fa9739991ef4d31b945
5
5
  SHA512:
6
- metadata.gz: a1cf946152d25f4eadd5db380fc7907188b0152061b6d0be39e4676442ef272c8fb1efbfce2eba421be5e869466c09fced926dec919592d1cfc3d88228604acf
7
- data.tar.gz: 39b05aa8b8d64e4608a56f241f7e97ade7a2379eb8867a315cd4480c2360d61cf4c51f90f2b5a67e421be6add9dacef01b96d3ef1c8d8d16c6d2485d4b1e570f
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.0)
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.0)
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.0)
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.0)
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
- # Prototype contains keys not in the Hash,so that's a failure.
27
- if not (prototype.keys - keys).empty?
28
- return false
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 and not (keys - prototype.keys).empty?
34
- return false
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 false
72
+ return FAILURE
50
73
  end
51
74
 
52
75
  self[key].extend(PrototypeMatch)
53
- if not self[key].prototype_match(value)
54
- return false
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] != value
62
- return false
86
+ if self[key] == value
87
+ score += 1
88
+ else
89
+ score -= 1
63
90
  end
64
91
  end
65
92
 
66
- # All other cases must be true.
67
- return true
93
+ # Return score
94
+ return score
68
95
  end
69
96
  end # module PrototypeMatch
70
97
  end # module Collapsium
@@ -8,5 +8,5 @@
8
8
  #
9
9
  module Collapsium
10
10
  # The current release version
11
- VERSION = "0.2.0".freeze
11
+ VERSION = "0.2.1".freeze
12
12
  end
@@ -15,36 +15,36 @@ describe ::Collapsium::PrototypeMatch do
15
15
  @hash.extend(::Collapsium::PrototypeMatch)
16
16
  end
17
17
 
18
- it "matches a prototype containing any individual key (non-strict)" do
18
+ it "scores positively a prototype containing any individual key (non-strict)" do
19
19
  # Keys exist in hash
20
- expect(@hash.prototype_match('a' => nil)).to be_truthy
21
- expect(@hash.prototype_match('b' => nil)).to be_truthy
22
- expect(@hash.prototype_match(c: nil)).to be_truthy
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.prototype_match(foo: nil)).to be_falsy
25
+ expect(@hash.prototype_match_score(foo: nil)).to be <= 0
26
26
  end
27
27
 
28
- it "does't match a prototype containing an individual key in strict mode" do
29
- expect(@hash.prototype_match({ 'a' => nil }, true)).to be_falsy
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 "matches nested prototypes (non-strict)" do
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.prototype_match(proto)).to be_truthy
38
+ expect(@hash.prototype_match_score(proto)).to be > 0
39
39
  end
40
40
 
41
- it "doesn't match nested prototypes (strict)" do
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.prototype_match(proto, true)).to be_falsy
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.prototype_match(proto)).to be_falsy
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.prototype_match(proto)).to be_falsy
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.0
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-05-16 00:00:00.000000000 Z
11
+ date: 2016-06-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler