qo 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +5 -5
  2. data/.yardopts +3 -0
  3. data/README.md +35 -2
  4. data/Rakefile +65 -13
  5. data/docs/Qo.html +165 -0
  6. data/docs/Qo/Exceptions.html +160 -0
  7. data/docs/Qo/Exceptions/MultipleMatchersProvided.html +257 -0
  8. data/docs/Qo/Exceptions/NoMatchersProvided.html +257 -0
  9. data/docs/Qo/Exceptions/NotAllGuardMatchersProvided.html +260 -0
  10. data/docs/Qo/Helpers.html +382 -0
  11. data/docs/Qo/Matchers.html +169 -0
  12. data/docs/Qo/Matchers/ArrayMatcher.html +459 -0
  13. data/docs/Qo/Matchers/BaseMatcher.html +493 -0
  14. data/docs/Qo/Matchers/GuardBlockMatcher.html +471 -0
  15. data/docs/Qo/Matchers/HashMatcher.html +445 -0
  16. data/docs/Qo/Matchers/PatternMatch.html +551 -0
  17. data/docs/Qo/PublicApi.html +867 -0
  18. data/docs/_index.html +258 -0
  19. data/docs/class_list.html +51 -0
  20. data/docs/css/common.css +1 -0
  21. data/docs/css/full_list.css +58 -0
  22. data/docs/css/style.css +499 -0
  23. data/docs/file.README.html +701 -0
  24. data/docs/file_list.html +56 -0
  25. data/docs/frames.html +17 -0
  26. data/docs/img/qo_logo.png +0 -0
  27. data/docs/index.html +701 -0
  28. data/docs/js/app.js +248 -0
  29. data/docs/js/full_list.js +216 -0
  30. data/docs/js/jquery.js +4 -0
  31. data/docs/method_list.html +227 -0
  32. data/docs/top-level-namespace.html +110 -0
  33. data/img/whoa_lemur.png +0 -0
  34. data/lib/qo/exceptions.rb +8 -4
  35. data/lib/qo/matchers/array_matcher.rb +34 -12
  36. data/lib/qo/matchers/base_matcher.rb +26 -11
  37. data/lib/qo/matchers/guard_block_matcher.rb +17 -3
  38. data/lib/qo/matchers/hash_matcher.rb +32 -23
  39. data/lib/qo/matchers/pattern_match.rb +2 -1
  40. data/lib/qo/public_api.rb +6 -5
  41. data/lib/qo/version.rb +1 -1
  42. data/performance_report.txt +73 -24
  43. data/qo.gemspec +2 -0
  44. metadata +61 -3
@@ -1,4 +1,16 @@
1
1
  module Qo
2
+ # A Qo Matcher is a class that acts like a Proc. It takes in a set of match
3
+ # values or key value pairs and a target value to evaluate against, and returns
4
+ # the status of that match.
5
+ #
6
+ # It is possible to override this behavior via `to_proc` overloading and
7
+ # utilization of `super` as noted in `GuardBlockMatcher`.
8
+ #
9
+ # @see Qo::Matchers::GuardBlockMatcher
10
+ #
11
+ # @author baweaver
12
+ # @since 0.2.0
13
+ #
2
14
  module Matchers
3
15
  # Base instance of matcher which is meant to take in either Array style or
4
16
  # Keyword style arguments to run a match against various datatypes.
@@ -6,7 +18,8 @@ module Qo
6
18
  # Will delegate responsibilities to either Array or Hash style matchers if
7
19
  # invoked directly.
8
20
  #
9
- # @author [baweaver]
21
+ # @author baweaver
22
+ # @since 0.2.0
10
23
  #
11
24
  class BaseMatcher
12
25
  def initialize(type, *array_matchers, **keyword_matchers)
@@ -19,7 +32,7 @@ module Qo
19
32
  #
20
33
  # data.select(&Qo[...])
21
34
  #
22
- # @return [Proc]
35
+ # @return [Proc[Any]]
23
36
  def to_proc
24
37
  @array_matchers.empty? ?
25
38
  Qo::Matchers::HashMatcher.new(@type, **@keyword_matchers).to_proc :
@@ -31,7 +44,7 @@ module Qo
31
44
  #
32
45
  # @param target [Any] Object to match against
33
46
  #
34
- # @return [type] [description]
47
+ # @return [Boolean] Result of the match
35
48
  def call(target)
36
49
  self.to_proc.call(target)
37
50
  end
@@ -39,12 +52,13 @@ module Qo
39
52
  alias_method :===, :call
40
53
  alias_method :[], :call
41
54
 
42
- # Wrapper around public send to encapsulate the matching method (any, all, none)
55
+ # Runs the relevant match method against the given collection with the
56
+ # given matcher function.
43
57
  #
44
58
  # @param collection [Enumerable] Any collection that can be enumerated over
45
- # @param fn [Proc] Function to match with
59
+ # @param fn [Proc] Function to match with
46
60
  #
47
- # @return [Enumerable] Resulting collection
61
+ # @return [Boolean] Result of the match
48
62
  private def match_with(collection, &fn)
49
63
  return collection.any?(&fn) if @type == 'or'
50
64
  return collection.none?(&fn) if @type == 'not'
@@ -68,8 +82,9 @@ module Qo
68
82
  # typical left bias of `===` can be confusing reading down a page, so
69
83
  # more of a clarity thing than anything. Also makes for nicer stack traces.
70
84
  #
71
- # @param target [Any] Target to match against
72
- # @param matcher [respond_to?(:===)]
85
+ # @param target [Any]
86
+ # Target to match against
87
+ # @param matcher [#===]
73
88
  # Anything that responds to ===, preferably in a unique and entertaining way.
74
89
  #
75
90
  # @return [Boolean]
@@ -81,7 +96,7 @@ module Qo
81
96
  # obscure errors when running against non-matching types.
82
97
  #
83
98
  # @param target [Any] Object to send to
84
- # @param matcher [respond_to?(:to_sym)] Anything that can be coerced into a method name
99
+ # @param matcher [#to_sym] Anything that can be coerced into a method name
85
100
  #
86
101
  # @return [Any] Response of sending to the method, or false if failed
87
102
  private def method_send(target, matcher)
@@ -92,8 +107,8 @@ module Qo
92
107
 
93
108
  # Predicate variant of `method_send` with the same guard concerns
94
109
  #
95
- # @param target [Any] Object to send to
96
- # @param matcher [respond_to?(:to_sym)] Anything that can be coerced into a method name
110
+ # @param target [Any] Object to send to
111
+ # @param matcher [#to_sym] Anything that can be coerced into a method name
97
112
  #
98
113
  # @return [Boolean] Success status of predicate
99
114
  private def method_matches?(target, matcher)
@@ -6,7 +6,21 @@ module Qo
6
6
  # It returns tuples of (status, result) in order to prevent masking of
7
7
  # legitimate falsy or nil values returned.
8
8
  #
9
- # @author [baweaver]
9
+ # Guard Block Matchers are best used with a PatternMatch, and chances are
10
+ # you're going to want to read that documentation first.
11
+ #
12
+ # @example
13
+ # Qo::Matchers::GuardBlockMatcher == Qo.matcher == Qo.m
14
+ #
15
+ # guard_matcher = Qo.m(Integer) { |v| v * 2 }
16
+ # guard_matcher.call(1) # => [true, 2]
17
+ # guard_matcher.call(:x) # => [false, false]
18
+ #
19
+ # @see Qo::Matchers::PatternMatch
20
+ # Pattern Match using GuardBlockMatchers
21
+ #
22
+ # @author baweaver
23
+ # @since 0.1.5
10
24
  #
11
25
  class GuardBlockMatcher < BaseMatcher
12
26
  # Identity function that returns its argument directly
@@ -25,8 +39,8 @@ module Qo
25
39
  # and potentially call through to the associated block if a base
26
40
  # matcher would have passed
27
41
  #
28
- # @return [Proc]
29
- # Any -> [Bool, Any] # (status, result) tuple
42
+ # @return [Proc[Any] - (Bool, Any)]
43
+ # (status, result) tuple
30
44
  def to_proc
31
45
  Proc.new { |target|
32
46
  super[target] ? [true, @fn.call(target)] : NON_MATCH
@@ -6,37 +6,46 @@ module Qo
6
6
  # In the case of a Hash matching against a Hash, it will compare the intersection
7
7
  # of keys and match the values against eachother.
8
8
  #
9
+ # ```ruby
10
+ # Qo[name: /Foo/, age: 30..50].call({name: 'Foo', age: 42})
11
+ # # => true
12
+ # ```
13
+ #
9
14
  # In the case of a Hash matching against an Object, it will treat the keys as
10
15
  # method property invocations to be matched against the provided values.
11
16
  #
17
+ # # ```ruby
18
+ # Qo[name: /Foo/, age: 30..50].call(Person.new('Foo', 42))
19
+ # # => true
20
+ # ```
21
+ #
12
22
  # All variants present in the BaseMatcher are present here, including 'and',
13
23
  # 'not', and 'or'.
14
24
  #
15
- # @author [baweaver]
25
+ # @author baweaver
26
+ # @since 0.2.0
16
27
  #
17
28
  class HashMatcher < BaseMatcher
18
- # Used to match against a matcher made from an Array, like:
29
+ # Wrapper around call to allow for invocation in an Enumerable function,
30
+ # such as:
19
31
  #
20
- # Qo['Foo', 'Bar']
21
- #
22
- # @param matchers [Array[respond_to?(===)]] indexed tuple to match the target object against
32
+ # ```ruby
33
+ # people.select(&Qo[name: /Foo/, age: 20..40])
34
+ # ```
23
35
  #
24
36
  # @return [Proc[Any]]
25
- # Array -> Bool # Tuple match against targets index
26
- # Object -> Bool # Boolean public send
37
+ # Proc awaiting a target to match against
27
38
  def to_proc
28
39
  Proc.new { |target| self.call(target) }
29
40
  end
30
41
 
31
42
  # Used to match against a matcher made from Keyword Arguments (a Hash)
32
43
  #
33
- # @param matchers [Hash[Any, respond_to?(:===)]]
44
+ # @param matchers [Hash[Any, #===]]
34
45
  # Any key mapping to any value that responds to `===`. Notedly more
35
46
  # satisfying when `===` does something fun.
36
47
  #
37
- # @return [Proc[Any]]
38
- # Hash -> Bool # Value matching against similar keys, will attempt to coerce to_s because JSON
39
- # Object -> Bool # Uses keys as methods with public send to `===` match against the value
48
+ # @return [Boolean] Result of the match
40
49
  def call(target)
41
50
  return true if @keyword_matchers == target
42
51
 
@@ -49,9 +58,9 @@ module Qo
49
58
 
50
59
  # Checks if a hash value matches a given matcher
51
60
  #
52
- # @param target [Any] Target of the match
53
- # @param match_key [Symbol] Key of the hash to reference
54
- # @param matcher [respond_to?(:===)] Any matcher responding to ===
61
+ # @param target [Any] Target of the match
62
+ # @param match_key [Symbol] Key of the hash to reference
63
+ # @param matcher [#===] Any matcher responding to ===
55
64
  #
56
65
  # @return [Boolean] Match status
57
66
  private def match_hash_value?(target, match_key, matcher)
@@ -66,9 +75,9 @@ module Qo
66
75
 
67
76
  # Checks if an object property matches a given matcher
68
77
  #
69
- # @param target [Any] Target of the match
70
- # @param match_property [Symbol] Property of the object to reference
71
- # @param matcher [respond_to?(:===)] Any matcher responding to ===
78
+ # @param target [Any] Target of the match
79
+ # @param match_property [Symbol] Property of the object to reference
80
+ # @param matcher [#===] Any matcher responding to ===
72
81
  #
73
82
  # @return [Boolean] Match status
74
83
  private def match_object_value?(target, match_property, matcher)
@@ -81,9 +90,9 @@ module Qo
81
90
  # Double wraps case match in order to ensure that we try against both Symbol
82
91
  # and String variants of the keys, as this is a very common mixup in Ruby.
83
92
  #
84
- # @param target [Hash] Target of the match
85
- # @param match_key [Symbol] Key to match against
86
- # @param matcher [respond_to?(:===)] Matcher
93
+ # @param target [Hash] Target of the match
94
+ # @param match_key [Symbol] Key to match against
95
+ # @param matcher [#===] Matcher
87
96
  #
88
97
  # @return [Boolean]
89
98
  private def hash_case_match?(target, match_key, matcher)
@@ -108,9 +117,9 @@ module Qo
108
117
  # Attempts to run a case match against a method call derived from a hash
109
118
  # key, and checks the result.
110
119
  #
111
- # @param target [Hash] Target of the match
112
- # @param match_property [Symbol] Method to call
113
- # @param matcher [respond_to?(:===)] Matcher
120
+ # @param target [Hash] Target of the match
121
+ # @param match_property [Symbol] Method to call
122
+ # @param matcher [#===] Matcher
114
123
  #
115
124
  # @return [Boolean]
116
125
  private def hash_method_case_match?(target, match_property, matcher)
@@ -54,7 +54,8 @@ module Qo
54
54
  #
55
55
  # We'll evaluate those options in a few experiments later.
56
56
  #
57
- # @author [baweaver]
57
+ # @author baweaver
58
+ # @since 0.2.0
58
59
  #
59
60
  class PatternMatch
60
61
  def initialize(*matchers)
@@ -5,7 +5,8 @@ module Qo
5
5
  # externally facing methods renamed or moved under pain of a look of profound
6
6
  # disappointment from the creator.
7
7
  #
8
- # @author [baweaver]
8
+ # @author baweaver
9
+ # @since 0.2.0
9
10
  #
10
11
  module PublicApi
11
12
  include Qo::Exceptions
@@ -20,7 +21,7 @@ module Qo
20
21
  # @return [Proc[Any]]
21
22
  # Any -> Bool # Given a target, will return if it "matches"
22
23
  def and(*array_matchers, **keyword_matchers)
23
- create_matcher('and', *array_matchers, **keyword_matchers)
24
+ create_matcher('and', array_matchers, keyword_matchers)
24
25
  end
25
26
 
26
27
  # The magic that lets you use `Qo[...]` instead of `Qo.and(...)`. Use wisely
@@ -36,7 +37,7 @@ module Qo
36
37
  # @return [Proc[Any]]
37
38
  # Any -> Bool # Given a target, will return if it "matches"
38
39
  def or(*array_matchers, **keyword_matchers)
39
- create_matcher('or', *array_matchers, **keyword_matchers)
40
+ create_matcher('or', array_matchers, keyword_matchers)
40
41
  end
41
42
 
42
43
  # Creates a `not` type query matcher. No conditions in this type of matcher
@@ -49,7 +50,7 @@ module Qo
49
50
  # @return [Proc[Any]]
50
51
  # Any -> Bool # Given a target, will return if it "matches"
51
52
  def not(*array_matchers, **keyword_matchers)
52
- create_matcher('not', *array_matchers, **keyword_matchers)
53
+ create_matcher('not', array_matchers, keyword_matchers)
53
54
  end
54
55
 
55
56
  # Creates a Guard Block matcher.
@@ -105,7 +106,7 @@ module Qo
105
106
  # @raises Qo::Exceptions::MultipleMatchersProvided
106
107
  #
107
108
  # @return [Qo::Matcher]
108
- private def create_matcher(type, *array_matchers, **keyword_matchers)
109
+ private def create_matcher(type, array_matchers, keyword_matchers)
109
110
  array_empty, hash_empty = array_matchers.empty?, keyword_matchers.empty?
110
111
 
111
112
  raise Qo::NoMatchersProvided if array_empty && hash_empty
@@ -1,3 +1,3 @@
1
1
  module Qo
2
- VERSION = '0.2.0'
2
+ VERSION = '0.2.1'
3
3
  end
@@ -1,60 +1,109 @@
1
+ Running on Qo v0.2.0 at commit ba999659acb51beec215fab4240a34298794a5bf
1
2
 
2
3
  Array * Array - Literal
3
4
  =======================
4
5
 
6
+ Vanilla result: true
7
+ Qo.and result: true
8
+
5
9
  Warming up --------------------------------------
6
- Vanilla 283.062k i/100ms
7
- Qo.and 48.476k i/100ms
10
+ Vanilla 278.882k i/100ms
11
+ Qo.and 83.044k i/100ms
8
12
  Calculating -------------------------------------
9
- Vanilla 9.319M2.1%) i/s - 46.705M in 5.013834s
10
- Qo.and 573.855k (± 1.3%) i/s - 2.909M in 5.069323s
13
+ Vanilla 8.950M1.7%) i/s - 44.900M in 5.018406s
14
+ Qo.and 1.062M (± 1.2%) i/s - 5.315M in 5.003728s
11
15
 
12
16
  Comparison:
13
- Vanilla: 9319318.3 i/s
14
- Qo.and: 573855.1 i/s - 16.24x slower
17
+ Vanilla: 8949563.3 i/s
18
+ Qo.and: 1062331.4 i/s - 8.42x slower
15
19
 
16
20
 
17
21
  Array * Array - Index pattern match
18
22
  ===================================
19
23
 
24
+ Vanilla result: true
25
+ Qo.and result: true
26
+
20
27
  Warming up --------------------------------------
21
- Vanilla 44.095k i/100ms
22
- Qo.and 12.753k i/100ms
28
+ Vanilla 49.757k i/100ms
29
+ Qo.and 22.362k i/100ms
23
30
  Calculating -------------------------------------
24
- Vanilla 482.805k5.9%) i/s - 2.425M in 5.041737s
25
- Qo.and 128.970k4.3%) i/s - 650.403k in 5.052438s
31
+ Vanilla 562.718k4.0%) i/s - 2.836M in 5.048960s
32
+ Qo.and 238.217k1.7%) i/s - 1.208M in 5.070540s
26
33
 
27
34
  Comparison:
28
- Vanilla: 482804.7 i/s
29
- Qo.and: 128969.8 i/s - 3.74x slower
35
+ Vanilla: 562718.0 i/s
36
+ Qo.and: 238216.8 i/s - 2.36x slower
30
37
 
31
38
 
32
39
  Array * Object - Predicate match
33
40
  ================================
34
41
 
42
+ Vanilla result: false
43
+ Qo.and result: false
44
+
35
45
  Warming up --------------------------------------
36
- Vanilla 138.847k i/100ms
37
- Qo.and 16.157k i/100ms
46
+ Vanilla 145.056k i/100ms
47
+ Qo.and 27.888k i/100ms
38
48
  Calculating -------------------------------------
39
- Vanilla 2.153M3.9%) i/s - 10.830M in 5.037676s
40
- Qo.and 174.879k3.8%) i/s - 888.635k in 5.089311s
49
+ Vanilla 2.204M4.4%) i/s - 11.024M in 5.011429s
50
+ Qo.and 323.232k2.4%) i/s - 1.618M in 5.007142s
41
51
 
42
52
  Comparison:
43
- Vanilla: 2153240.3 i/s
44
- Qo.and: 174878.6 i/s - 12.31x slower
53
+ Vanilla: 2204056.6 i/s
54
+ Qo.and: 323232.5 i/s - 6.82x slower
45
55
 
46
56
 
47
57
  Array * Array - Select index pattern match
48
58
  ==========================================
49
59
 
60
+ Vanilla result: [["Robert", 22], ["Roberta", 22]]
61
+ Qo.and result: [["Robert", 22], ["Roberta", 22]]
62
+
63
+ Warming up --------------------------------------
64
+ Vanilla 14.343k i/100ms
65
+ Qo.and 7.454k i/100ms
66
+ Calculating -------------------------------------
67
+ Vanilla 149.518k (± 2.9%) i/s - 760.179k in 5.088601s
68
+ Qo.and 77.519k (± 2.8%) i/s - 387.608k in 5.004058s
69
+
70
+ Comparison:
71
+ Vanilla: 149517.6 i/s
72
+ Qo.and: 77519.5 i/s - 1.93x slower
73
+
74
+
75
+ Hash * Hash - Hash intersection
76
+ ===============================
77
+
78
+ Vanilla result: [{:name=>"Robert", :age=>22}, {:name=>"Roberta", :age=>22}]
79
+ Qo.and result: [{:name=>"Robert", :age=>22}, {:name=>"Roberta", :age=>22}]
80
+
81
+ Warming up --------------------------------------
82
+ Vanilla 36.214k i/100ms
83
+ Qo.and 5.050k i/100ms
84
+ Calculating -------------------------------------
85
+ Vanilla 411.041k (± 2.3%) i/s - 2.064M in 5.024556s
86
+ Qo.and 50.029k (± 5.0%) i/s - 252.500k in 5.060014s
87
+
88
+ Comparison:
89
+ Vanilla: 411041.4 i/s
90
+ Qo.and: 50028.6 i/s - 8.22x slower
91
+
92
+
93
+ Hash * Object - Property match
94
+ ==============================
95
+
96
+ Vanilla result: [#<struct Person name="Robert", age=22>, #<struct Person name="Roberta", age=22>]
97
+ Qo.and result: [#<struct Person name="Robert", age=22>, #<struct Person name="Roberta", age=22>]
98
+
50
99
  Warming up --------------------------------------
51
- Vanilla 13.175k i/100ms
52
- Qo.and 21.534k i/100ms
100
+ Vanilla 36.167k i/100ms
101
+ Qo.and 5.263k i/100ms
53
102
  Calculating -------------------------------------
54
- Vanilla 137.128k (± 3.6%) i/s - 685.100k in 5.002872s
55
- Qo.and 240.447k2.7%) i/s - 1.206M in 5.019112s
103
+ Vanilla 411.057k (± 3.4%) i/s - 2.062M in 5.021612s
104
+ Qo.and 52.776k4.0%) i/s - 268.413k in 5.094233s
56
105
 
57
106
  Comparison:
58
- Qo.and: 240447.2 i/s
59
- Vanilla: 137128.2 i/s - 1.75x slower
107
+ Vanilla: 411057.2 i/s
108
+ Qo.and: 52775.9 i/s - 7.79x slower
60
109
 
data/qo.gemspec CHANGED
@@ -26,4 +26,6 @@ Gem::Specification.new do |spec|
26
26
  spec.add_development_dependency "guard"
27
27
  spec.add_development_dependency "guard-rspec"
28
28
  spec.add_development_dependency "benchmark-ips"
29
+ spec.add_development_dependency "yard"
30
+ spec.add_development_dependency "redcarpet"
29
31
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: qo
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
  - Brandon Weaver
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-04-16 00:00:00.000000000 Z
11
+ date: 2018-04-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -94,6 +94,34 @@ dependencies:
94
94
  - - ">="
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: yard
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: redcarpet
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
97
125
  description:
98
126
  email:
99
127
  - keystonelemur@gmail.com
@@ -105,6 +133,7 @@ files:
105
133
  - ".pryrc"
106
134
  - ".rspec"
107
135
  - ".travis.yml"
136
+ - ".yardopts"
108
137
  - CODE_OF_CONDUCT.md
109
138
  - Gemfile
110
139
  - Guardfile
@@ -114,8 +143,37 @@ files:
114
143
  - bin/console
115
144
  - bin/setup
116
145
  - docs/.gitkeep
146
+ - docs/Qo.html
147
+ - docs/Qo/Exceptions.html
148
+ - docs/Qo/Exceptions/MultipleMatchersProvided.html
149
+ - docs/Qo/Exceptions/NoMatchersProvided.html
150
+ - docs/Qo/Exceptions/NotAllGuardMatchersProvided.html
151
+ - docs/Qo/Helpers.html
152
+ - docs/Qo/Matchers.html
153
+ - docs/Qo/Matchers/ArrayMatcher.html
154
+ - docs/Qo/Matchers/BaseMatcher.html
155
+ - docs/Qo/Matchers/GuardBlockMatcher.html
156
+ - docs/Qo/Matchers/HashMatcher.html
157
+ - docs/Qo/Matchers/PatternMatch.html
158
+ - docs/Qo/PublicApi.html
117
159
  - docs/_config.yml
160
+ - docs/_index.html
161
+ - docs/class_list.html
162
+ - docs/css/common.css
163
+ - docs/css/full_list.css
164
+ - docs/css/style.css
165
+ - docs/file.README.html
166
+ - docs/file_list.html
167
+ - docs/frames.html
168
+ - docs/img/qo_logo.png
169
+ - docs/index.html
170
+ - docs/js/app.js
171
+ - docs/js/full_list.js
172
+ - docs/js/jquery.js
173
+ - docs/method_list.html
174
+ - docs/top-level-namespace.html
118
175
  - img/qo_logo.png
176
+ - img/whoa_lemur.png
119
177
  - lib/qo.rb
120
178
  - lib/qo/exceptions.rb
121
179
  - lib/qo/helpers.rb
@@ -148,7 +206,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
148
206
  version: '0'
149
207
  requirements: []
150
208
  rubyforge_project:
151
- rubygems_version: 2.6.14.1
209
+ rubygems_version: 2.7.6
152
210
  signing_key:
153
211
  specification_version: 4
154
212
  summary: Qo is a querying library for Ruby pattern matching