collapsium 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
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