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
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: dcbbe9e009a9ccf04769b8ccb7eca4343ea972a5
4
- data.tar.gz: 53dae10eca53508dacfb75ad940207f0f047d288
2
+ SHA256:
3
+ metadata.gz: 11b6629bbb972894e4d1ebc01916769e14a70ec4dbc0d197f990d2c6849d3ffa
4
+ data.tar.gz: d609ce71af4795164999b2219f3e70892c09c0eaca4174d73d79bc3e2d988231
5
5
  SHA512:
6
- metadata.gz: 62bceca4a54804a1e18c86a26802e3903693a61d213fa27b959e0e6a362b54470aeb22f45101ebd8b73cb5dfa90a7c1214c7d78574d3a366a679734744005007
7
- data.tar.gz: 40a0319fa994a9e82e1f55001deab434e95187819efc1ef5eaa6bdd9be015987c481b7b7097b00820974cdc43eeed815fc4b9f7d442f5388b1881549ad00eb62
6
+ metadata.gz: c44fe7b89ec3da320eca4007f0b207da6d2300999c23c167c494e281bbe96c7449f88419d1eec29dcc9f5bc987df3ecea9b1bb0b88afa7968c6e2f3d94b12237
7
+ data.tar.gz: c4e5e607debf592180547d4f7180251e38cc09958a5a2f4961ebbe91c4a52416fb2a2ceeb26c7ba0076e24999c7333716141649aace38d4152931040d8b1dc7d
@@ -0,0 +1,3 @@
1
+ --markup=markdown
2
+ --asset img:img
3
+ --output-dir docs
data/README.md CHANGED
@@ -4,10 +4,12 @@
4
4
  [![Maintainability](https://api.codeclimate.com/v1/badges/186e9cbb7003842acaf0/maintainability)](https://codeclimate.com/github/baweaver/qo/maintainability)
5
5
  [![Gem Version](https://badge.fury.io/rb/qo.svg)](https://badge.fury.io/rb/qo)
6
6
 
7
- Short for Query Object, my play at Ruby pattern matching and fluent querying
7
+ Short for Query Object, my play at Ruby pattern matching and fluent querying, [pronounced "Q-whoah"](img/whoa_lemur.png).
8
8
 
9
9
  ![Qo Lemur logo](img/qo_logo.png)
10
10
 
11
+ [Read the Docs for more detailed information](https://baweaver.github.io/qo/)
12
+
11
13
  ## How does it work?
12
14
 
13
15
  Mostly by using Ruby language features like `to_proc` and `===`.
@@ -537,7 +539,7 @@ Qo.count_by([1,2,3,2,2,2,1], &:even?)
537
539
 
538
540
  These examples will grow over the next few weeks as I think of more fun things to do with Qo. PRs welcome if you find fun uses!
539
541
 
540
- #### 5.1 - JSON
542
+ #### 5.1 - JSON and HTTP
541
543
 
542
544
  > Note that Qo does not support deep querying of hashes (yet)
543
545
 
@@ -581,6 +583,37 @@ users.select(&Qo.and(
581
583
 
582
584
  Nifty!
583
585
 
586
+ ##### Yield Self HTTP status matching
587
+
588
+ You can even use `#yield_self` to pipe values into a pattern matching block. In
589
+ this particular case it'll let you check against the type signatures of the
590
+ HTTP responses.
591
+
592
+ ```ruby
593
+ def get_url(url)
594
+ Net::HTTP.get_response(URI(url)).yield_self(&Qo.match(
595
+ Qo.m(Net::HTTPSuccess) { |response| response.body.size },
596
+ Qo.m(:*) { |response| raise response.message }
597
+ ))
598
+ end
599
+
600
+ get_url('https://github.com/baweaver/qo')
601
+ # => 142387
602
+ get_url('https://github.com/baweaver/qo/does_not_exist')
603
+ # => RuntimeError: Not Found
604
+ ```
605
+
606
+ The difference between this and case? Well, the first is you can pass this to
607
+ `yield_self` for a more inline solution. The second is that any Qo matcher can
608
+ be used in there, including predicate and content checks on the body:
609
+
610
+ ```ruby
611
+ Qo.m(Net::HTTPSuccess, body: /Qo/)
612
+ ```
613
+
614
+ You could put as many checks as you want in there, or use different Qo matchers
615
+ nested to get even further in.
616
+
584
617
  #### 5.2 - Opsy Stuff
585
618
 
586
619
  ##### 5.2.1 - NMap
data/Rakefile CHANGED
@@ -22,6 +22,13 @@ task :default => :spec
22
22
  def run_benchmark(title, **benchmarks)
23
23
  puts '', title, '=' * title.size, ''
24
24
 
25
+ # Validation
26
+ benchmarks.each do |benchmark_name, benchmark_fn|
27
+ puts "#{benchmark_name} result: #{benchmark_fn.call()}"
28
+ end
29
+
30
+ puts
31
+
25
32
  Benchmark.ips do |bm|
26
33
  benchmarks.each do |benchmark_name, benchmark_fn|
27
34
  bm.report(benchmark_name, &benchmark_fn)
@@ -31,10 +38,14 @@ def run_benchmark(title, **benchmarks)
31
38
  end
32
39
  end
33
40
 
41
+ def xrun_benchmark(title, **benchmarks) end
42
+
34
43
  # Note that the current development of Qo is NOT to be performance first, it's to
35
44
  # be readability first with performance coming later. That means that early iterations
36
45
  # may well be slower, but the net expressiveness we get is worth it in the short run.
37
46
  task :perf do
47
+ puts "Running on Qo v#{Qo::VERSION} at commit #{`git rev-parse HEAD`}"
48
+
38
49
  # Compare simple array equality. I almost think this isn't fair to Qo considering
39
50
  # no sane dev should use it for literal 1 to 1 matches like this.
40
51
 
@@ -45,7 +56,7 @@ task :perf do
45
56
  },
46
57
 
47
58
  'Qo.and': -> {
48
- Qo.and(*simple_array).call(simple_array)
59
+ Qo.and(1, 1).call(simple_array)
49
60
  }
50
61
  )
51
62
 
@@ -61,7 +72,7 @@ task :perf do
61
72
  },
62
73
 
63
74
  'Qo.and': -> {
64
- Qo.and(*range_match_set).call(range_match_target)
75
+ Qo.and(1..10, 1..10, 1..10, 1..10).call(range_match_target)
65
76
  }
66
77
  )
67
78
 
@@ -101,7 +112,37 @@ task :perf do
101
112
  },
102
113
 
103
114
  'Qo.and': -> {
104
- Qo.and(*people_array_query).call(people_array_target)
115
+ people_array_target.select(&Qo.and(/Rob/, 15..25))
116
+ }
117
+ )
118
+
119
+ people_hashes = people_array_target.map { |(name, age)| {name: name, age: age} }
120
+
121
+ run_benchmark('Hash * Hash - Hash intersection',
122
+ 'Vanilla': -> {
123
+ people_hashes.select { |person| (15..25).include?(person[:age]) && /Rob/ =~ person[:name] }
124
+ },
125
+
126
+ 'Qo.and': -> {
127
+ people_hashes.select(&Qo.and(name: /Rob/, age: 15..25))
128
+ }
129
+ )
130
+
131
+ Person = Struct.new(:name, :age)
132
+ people = [
133
+ Person.new('Robert', 22),
134
+ Person.new('Roberta', 22),
135
+ Person.new('Foo', 42),
136
+ Person.new('Bar', 17)
137
+ ]
138
+
139
+ run_benchmark('Hash * Object - Property match',
140
+ 'Vanilla': -> {
141
+ people.select { |person| (15..25).include?(person.age) && /Rob/ =~ person.name }
142
+ },
143
+
144
+ 'Qo.and': -> {
145
+ people.select(&Qo.and(name: /Rob/, age: 15..25))
105
146
  }
106
147
  )
107
148
  end
@@ -117,6 +158,17 @@ end
117
158
  # of the 2.4+ bug of lambdas not destructuring automatically, which will wreak
118
159
  # havoc on hash matchers.
119
160
 
161
+ task :kwargs_vs_positional do
162
+ def add_kw(a:, b:, c:, d:) a + b + c + d end
163
+
164
+ def add_pos(a,b,c,d) a + b + c + d end
165
+
166
+ run_benchmark('Positional vs KW Args',
167
+ 'keyword': -> { add_kw(a: 1, b: 2, c: 3, d: 4) },
168
+ 'positional': -> { add_pos(1,2,3,4) }
169
+ )
170
+ end
171
+
120
172
  task :perf_predicates do
121
173
  array = (1..1000).to_a
122
174
 
@@ -154,18 +206,18 @@ task :perf_predicates do
154
206
  end
155
207
 
156
208
  task :perf_random do
157
- # run_benchmark('Empty on blank array',
158
- # 'empty?': -> { [].empty? },
159
- # 'size == 0': -> { [].size == 0 },
160
- # 'size.zero?': -> { [].size.zero? },
161
- # )
209
+ run_benchmark('Empty on blank array',
210
+ 'empty?': -> { [].empty? },
211
+ 'size == 0': -> { [].size == 0 },
212
+ 'size.zero?': -> { [].size.zero? },
213
+ )
162
214
 
163
215
  array = (1..1000).to_a
164
- # run_benchmark('Empty on several elements array',
165
- # 'empty?': -> { array.empty? },
166
- # 'size == 0': -> { array.size == 0 },
167
- # 'size.zero?': -> { array.size.zero? },
168
- # )
216
+ run_benchmark('Empty on several elements array',
217
+ 'empty?': -> { array.empty? },
218
+ 'size == 0': -> { array.size == 0 },
219
+ 'size.zero?': -> { array.size.zero? },
220
+ )
169
221
 
170
222
  hash = array.map { |v| [v, v] }.to_h
171
223
 
@@ -0,0 +1,165 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>
7
+ Module: Qo
8
+
9
+ &mdash; Documentation by YARD 0.9.12
10
+
11
+ </title>
12
+
13
+ <link rel="stylesheet" href="css/style.css" type="text/css" charset="utf-8" />
14
+
15
+ <link rel="stylesheet" href="css/common.css" type="text/css" charset="utf-8" />
16
+
17
+ <script type="text/javascript" charset="utf-8">
18
+ pathId = "Qo";
19
+ relpath = '';
20
+ </script>
21
+
22
+
23
+ <script type="text/javascript" charset="utf-8" src="js/jquery.js"></script>
24
+
25
+ <script type="text/javascript" charset="utf-8" src="js/app.js"></script>
26
+
27
+
28
+ </head>
29
+ <body>
30
+ <div class="nav_wrap">
31
+ <iframe id="nav" src="class_list.html?1"></iframe>
32
+ <div id="resizer"></div>
33
+ </div>
34
+
35
+ <div id="main" tabindex="-1">
36
+ <div id="header">
37
+ <div id="menu">
38
+
39
+ <a href="_index.html">Index (Q)</a> &raquo;
40
+
41
+
42
+ <span class="title">Qo</span>
43
+
44
+ </div>
45
+
46
+ <div id="search">
47
+
48
+ <a class="full_list_link" id="class_list_link"
49
+ href="class_list.html">
50
+
51
+ <svg width="24" height="24">
52
+ <rect x="0" y="4" width="24" height="4" rx="1" ry="1"></rect>
53
+ <rect x="0" y="12" width="24" height="4" rx="1" ry="1"></rect>
54
+ <rect x="0" y="20" width="24" height="4" rx="1" ry="1"></rect>
55
+ </svg>
56
+ </a>
57
+
58
+ </div>
59
+ <div class="clear"></div>
60
+ </div>
61
+
62
+ <div id="content"><h1>Module: Qo
63
+
64
+
65
+
66
+ </h1>
67
+ <div class="box_info">
68
+
69
+
70
+
71
+
72
+ <dl>
73
+ <dt>Extended by:</dt>
74
+ <dd><span class='object_link'><a href="Qo/Exceptions.html" title="Qo::Exceptions (module)">Exceptions</a></span>, <span class='object_link'><a href="Qo/Helpers.html" title="Qo::Helpers (module)">Helpers</a></span>, <span class='object_link'><a href="Qo/PublicApi.html" title="Qo::PublicApi (module)">PublicApi</a></span></dd>
75
+ </dl>
76
+
77
+
78
+
79
+
80
+
81
+
82
+
83
+
84
+ <dl>
85
+ <dt>Defined in:</dt>
86
+ <dd>lib/qo.rb<span class="defines">,<br />
87
+ lib/qo/helpers.rb,<br /> lib/qo/version.rb,<br /> lib/qo/exceptions.rb,<br /> lib/qo/public_api.rb,<br /> lib/qo/matchers/base_matcher.rb,<br /> lib/qo/matchers/hash_matcher.rb,<br /> lib/qo/matchers/array_matcher.rb,<br /> lib/qo/matchers/pattern_match.rb,<br /> lib/qo/matchers/guard_block_matcher.rb</span>
88
+ </dd>
89
+ </dl>
90
+
91
+ </div>
92
+
93
+ <h2>Defined Under Namespace</h2>
94
+ <p class="children">
95
+
96
+
97
+ <strong class="modules">Modules:</strong> <span class='object_link'><a href="Qo/Exceptions.html" title="Qo::Exceptions (module)">Exceptions</a></span>, <span class='object_link'><a href="Qo/Helpers.html" title="Qo::Helpers (module)">Helpers</a></span>, <span class='object_link'><a href="Qo/Matchers.html" title="Qo::Matchers (module)">Matchers</a></span>, <span class='object_link'><a href="Qo/PublicApi.html" title="Qo::PublicApi (module)">PublicApi</a></span>
98
+
99
+
100
+
101
+
102
+ </p>
103
+
104
+ <h2>Constant Summary</h2>
105
+ <dl class="constants">
106
+
107
+ <dt id="WILDCARD_MATCH-constant" class="">WILDCARD_MATCH =
108
+
109
+ </dt>
110
+ <dd><pre class="code"><span class='symbol'>:*</span></pre></dd>
111
+
112
+ <dt id="VERSION-constant" class="">VERSION =
113
+
114
+ </dt>
115
+ <dd><pre class="code"><span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>0.2.0</span><span class='tstring_end'>&#39;</span></span></pre></dd>
116
+
117
+ </dl>
118
+
119
+
120
+
121
+
122
+
123
+
124
+
125
+
126
+
127
+
128
+
129
+
130
+
131
+
132
+ <h2>Method Summary</h2>
133
+
134
+ <h3 class="inherited">Methods included from <span class='object_link'><a href="Qo/PublicApi.html" title="Qo::PublicApi (module)">PublicApi</a></span></h3>
135
+ <p class="inherited"><span class='object_link'><a href="Qo/PublicApi.html#and-instance_method" title="Qo::PublicApi#and (method)">and</a></span>, <span class='object_link'><a href="Qo/PublicApi.html#match-instance_method" title="Qo::PublicApi#match (method)">match</a></span>, <span class='object_link'><a href="Qo/PublicApi.html#matcher-instance_method" title="Qo::PublicApi#matcher (method)">matcher</a></span>, <span class='object_link'><a href="Qo/PublicApi.html#not-instance_method" title="Qo::PublicApi#not (method)">not</a></span>, <span class='object_link'><a href="Qo/PublicApi.html#or-instance_method" title="Qo::PublicApi#or (method)">or</a></span></p>
136
+
137
+
138
+
139
+
140
+
141
+
142
+
143
+
144
+
145
+
146
+
147
+
148
+
149
+
150
+
151
+ <h3 class="inherited">Methods included from <span class='object_link'><a href="Qo/Helpers.html" title="Qo::Helpers (module)">Helpers</a></span></h3>
152
+ <p class="inherited"><span class='object_link'><a href="Qo/Helpers.html#count_by-instance_method" title="Qo::Helpers#count_by (method)">count_by</a></span>, <span class='object_link'><a href="Qo/Helpers.html#dig-instance_method" title="Qo::Helpers#dig (method)">dig</a></span></p>
153
+
154
+
155
+ </div>
156
+
157
+ <div id="footer">
158
+ Generated on Sun Apr 15 20:29:44 2018 by
159
+ <a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
160
+ 0.9.12 (ruby-2.4.4).
161
+ </div>
162
+
163
+ </div>
164
+ </body>
165
+ </html>
@@ -0,0 +1,160 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>
7
+ Module: Qo::Exceptions
8
+
9
+ &mdash; Documentation by YARD 0.9.12
10
+
11
+ </title>
12
+
13
+ <link rel="stylesheet" href="../css/style.css" type="text/css" charset="utf-8" />
14
+
15
+ <link rel="stylesheet" href="../css/common.css" type="text/css" charset="utf-8" />
16
+
17
+ <script type="text/javascript" charset="utf-8">
18
+ pathId = "Qo::Exceptions";
19
+ relpath = '../';
20
+ </script>
21
+
22
+
23
+ <script type="text/javascript" charset="utf-8" src="../js/jquery.js"></script>
24
+
25
+ <script type="text/javascript" charset="utf-8" src="../js/app.js"></script>
26
+
27
+
28
+ </head>
29
+ <body>
30
+ <div class="nav_wrap">
31
+ <iframe id="nav" src="../class_list.html?1"></iframe>
32
+ <div id="resizer"></div>
33
+ </div>
34
+
35
+ <div id="main" tabindex="-1">
36
+ <div id="header">
37
+ <div id="menu">
38
+
39
+ <a href="../_index.html">Index (E)</a> &raquo;
40
+ <span class='title'><span class='object_link'><a href="../Qo.html" title="Qo (module)">Qo</a></span></span>
41
+ &raquo;
42
+ <span class="title">Exceptions</span>
43
+
44
+ </div>
45
+
46
+ <div id="search">
47
+
48
+ <a class="full_list_link" id="class_list_link"
49
+ href="../class_list.html">
50
+
51
+ <svg width="24" height="24">
52
+ <rect x="0" y="4" width="24" height="4" rx="1" ry="1"></rect>
53
+ <rect x="0" y="12" width="24" height="4" rx="1" ry="1"></rect>
54
+ <rect x="0" y="20" width="24" height="4" rx="1" ry="1"></rect>
55
+ </svg>
56
+ </a>
57
+
58
+ </div>
59
+ <div class="clear"></div>
60
+ </div>
61
+
62
+ <div id="content"><h1>Module: Qo::Exceptions
63
+
64
+
65
+
66
+ </h1>
67
+ <div class="box_info">
68
+
69
+
70
+
71
+
72
+
73
+
74
+
75
+
76
+
77
+ <dl>
78
+ <dt>Included in:</dt>
79
+ <dd><span class='object_link'><a href="../Qo.html" title="Qo (module)">Qo</a></span>, <span class='object_link'><a href="PublicApi.html" title="Qo::PublicApi (module)">PublicApi</a></span></dd>
80
+ </dl>
81
+
82
+
83
+
84
+ <dl>
85
+ <dt>Defined in:</dt>
86
+ <dd>lib/qo/exceptions.rb</dd>
87
+ </dl>
88
+
89
+ </div>
90
+
91
+ <h2>Overview</h2><div class="docstring">
92
+ <div class="discussion">
93
+ <p>Defines common exception classes for use throughout the library</p>
94
+
95
+
96
+ </div>
97
+ </div>
98
+ <div class="tags">
99
+
100
+ <p class="tag_title">Author:</p>
101
+ <ul class="author">
102
+
103
+ <li>
104
+
105
+
106
+
107
+
108
+
109
+ <div class='inline'><p>baweaver</p>
110
+ </div>
111
+
112
+ </li>
113
+
114
+ </ul>
115
+ <p class="tag_title">Since:</p>
116
+ <ul class="since">
117
+
118
+ <li>
119
+
120
+
121
+
122
+
123
+
124
+ <div class='inline'><p>0.2.0</p>
125
+ </div>
126
+
127
+ </li>
128
+
129
+ </ul>
130
+
131
+ </div><h2>Defined Under Namespace</h2>
132
+ <p class="children">
133
+
134
+
135
+
136
+
137
+ <strong class="classes">Classes:</strong> <span class='object_link'><a href="Exceptions/MultipleMatchersProvided.html" title="Qo::Exceptions::MultipleMatchersProvided (class)">MultipleMatchersProvided</a></span>, <span class='object_link'><a href="Exceptions/NoMatchersProvided.html" title="Qo::Exceptions::NoMatchersProvided (class)">NoMatchersProvided</a></span>, <span class='object_link'><a href="Exceptions/NotAllGuardMatchersProvided.html" title="Qo::Exceptions::NotAllGuardMatchersProvided (class)">NotAllGuardMatchersProvided</a></span>
138
+
139
+
140
+ </p>
141
+
142
+
143
+
144
+
145
+
146
+
147
+
148
+
149
+
150
+ </div>
151
+
152
+ <div id="footer">
153
+ Generated on Sun Apr 15 20:29:44 2018 by
154
+ <a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
155
+ 0.9.12 (ruby-2.4.4).
156
+ </div>
157
+
158
+ </div>
159
+ </body>
160
+ </html>