middle_squid 1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +13 -0
- data/.travis.yml +3 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +674 -0
- data/README.md +227 -0
- data/Rakefile +7 -0
- data/bin/middle_squid +7 -0
- data/lib/middle_squid/actions.rb +77 -0
- data/lib/middle_squid/adapter.rb +54 -0
- data/lib/middle_squid/adapters/squid.rb +57 -0
- data/lib/middle_squid/backends/keyboard.rb +31 -0
- data/lib/middle_squid/backends/thin.rb +14 -0
- data/lib/middle_squid/blacklist.rb +67 -0
- data/lib/middle_squid/builder.rb +159 -0
- data/lib/middle_squid/cli.rb +119 -0
- data/lib/middle_squid/core_ext/hash.rb +29 -0
- data/lib/middle_squid/database.rb +47 -0
- data/lib/middle_squid/exceptions.rb +4 -0
- data/lib/middle_squid/helpers.rb +74 -0
- data/lib/middle_squid/indexer.rb +194 -0
- data/lib/middle_squid/runner.rb +37 -0
- data/lib/middle_squid/server.rb +84 -0
- data/lib/middle_squid/uri.rb +31 -0
- data/lib/middle_squid/version.rb +3 -0
- data/lib/middle_squid.rb +46 -0
- data/middle_squid.gemspec +37 -0
- data/middle_squid_wrapper.sh +4 -0
- data/test/helper.rb +26 -0
- data/test/resources/backslash/cat/list +1 -0
- data/test/resources/black/ads/domains +2 -0
- data/test/resources/black/ads/urls +1 -0
- data/test/resources/black/tracker/domains +2 -0
- data/test/resources/black/tracker/urls +2 -0
- data/test/resources/copy_of_duplicates/cat/copy_of_list +2 -0
- data/test/resources/copy_of_duplicates/cat/list +2 -0
- data/test/resources/copy_of_duplicates/copy_of_cat/copy_of_list +2 -0
- data/test/resources/copy_of_duplicates/copy_of_cat/list +2 -0
- data/test/resources/duplicates/cat/copy_of_list +2 -0
- data/test/resources/duplicates/cat/list +2 -0
- data/test/resources/duplicates/copy_of_cat/copy_of_list +2 -0
- data/test/resources/duplicates/copy_of_cat/list +2 -0
- data/test/resources/empty/cat/emptylist +0 -0
- data/test/resources/empty_path/cat/list +1 -0
- data/test/resources/expressions/cat/list +3 -0
- data/test/resources/gray/isp/domains +2 -0
- data/test/resources/gray/isp/urls +1 -0
- data/test/resources/gray/news/domains +2 -0
- data/test/resources/hello.rb +2 -0
- data/test/resources/invalid_byte/cat/list +1 -0
- data/test/resources/mixed/cat/list +2 -0
- data/test/resources/subdirectory/cat/ignore/.gitkeep +0 -0
- data/test/resources/trailing_space/cat/list +2 -0
- data/test/test_actions.rb +76 -0
- data/test/test_adapter.rb +61 -0
- data/test/test_blacklist.rb +189 -0
- data/test/test_builder.rb +89 -0
- data/test/test_cli.rb +105 -0
- data/test/test_database.rb +20 -0
- data/test/test_hash.rb +28 -0
- data/test/test_helper.rb +76 -0
- data/test/test_indexer.rb +457 -0
- data/test/test_keyboard.rb +79 -0
- data/test/test_runner.rb +56 -0
- data/test/test_server.rb +86 -0
- data/test/test_squid.rb +110 -0
- data/test/test_thin.rb +7 -0
- data/test/test_uri.rb +69 -0
- metadata +363 -0
@@ -0,0 +1,457 @@
|
|
1
|
+
require File.expand_path '../helper', __FILE__
|
2
|
+
|
3
|
+
class TestIndexer < MiniTest::Test
|
4
|
+
include MiddleSquid::Database
|
5
|
+
|
6
|
+
make_my_diffs_pretty!
|
7
|
+
|
8
|
+
def setup
|
9
|
+
@obj = MiddleSquid::Indexer.new
|
10
|
+
@path = File.expand_path '../resources', __FILE__
|
11
|
+
|
12
|
+
db.transaction
|
13
|
+
|
14
|
+
db.execute 'DELETE FROM domains'
|
15
|
+
db.execute 'DELETE FROM urls'
|
16
|
+
|
17
|
+
db.execute 'INSERT INTO domains (category, host) VALUES (?, ?)',
|
18
|
+
['test', '.anidb.net']
|
19
|
+
|
20
|
+
db.execute 'INSERT INTO urls (category, host, path) VALUES (?, ?, ?)',
|
21
|
+
['test', '.test.com', 'path']
|
22
|
+
|
23
|
+
db.commit
|
24
|
+
end
|
25
|
+
|
26
|
+
def has_test_data?
|
27
|
+
has_domain = !!db.get_first_row(
|
28
|
+
"SELECT 1 FROM domains WHERE category = 'test' AND host = '.anidb.net' AND rowid = 1 LIMIT 1"
|
29
|
+
)
|
30
|
+
|
31
|
+
has_url = !!db.get_first_row(
|
32
|
+
"SELECT 1 FROM urls WHERE category = 'test' AND host = '.test.com' AND path = 'path/' AND rowid = 1 LIMIT 1"
|
33
|
+
)
|
34
|
+
|
35
|
+
has_domain || has_url
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_minimal_no_blacklist_used
|
39
|
+
@obj.full_index = false
|
40
|
+
|
41
|
+
stdout, stderr = capture_io do
|
42
|
+
@obj.index [File.join(@path, 'black')]
|
43
|
+
end
|
44
|
+
|
45
|
+
assert_equal "nothing to do in minimal indexing mode\n", stdout
|
46
|
+
|
47
|
+
assert_match 'ERROR', stderr
|
48
|
+
|
49
|
+
assert has_test_data?
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_empty_rollback
|
53
|
+
stdout, stderr = capture_io do
|
54
|
+
@obj.index [File.join(@path, 'empty')]
|
55
|
+
end
|
56
|
+
|
57
|
+
assert_match 'indexing cat/emptylist', stdout
|
58
|
+
assert_match 'reverting changes', stdout
|
59
|
+
|
60
|
+
assert_match 'ERROR: nothing to commit', stderr
|
61
|
+
|
62
|
+
assert has_test_data?
|
63
|
+
end
|
64
|
+
|
65
|
+
def test_full_index
|
66
|
+
stdout, stderr = capture_io do
|
67
|
+
@obj.index [File.join(@path, 'black')]
|
68
|
+
end
|
69
|
+
|
70
|
+
refute has_test_data?
|
71
|
+
|
72
|
+
domains = db.execute 'SELECT category, host FROM domains'
|
73
|
+
assert_equal [
|
74
|
+
['ads', '.ads.google.com'],
|
75
|
+
['ads', '.doubleclick.net'],
|
76
|
+
['tracker', '.xiti.com'],
|
77
|
+
['tracker', '.google-analytics.com'],
|
78
|
+
], domains
|
79
|
+
|
80
|
+
urls = db.execute 'SELECT category, host, path FROM urls'
|
81
|
+
assert_equal [
|
82
|
+
['ads', '.google.com', 'adsense/'],
|
83
|
+
['tracker', '.feedproxy.google.com', '~r/'],
|
84
|
+
['tracker', '.cloudfront-labs.amazonaws.com', 'x.png/'],
|
85
|
+
], urls
|
86
|
+
|
87
|
+
assert_match 'indexing ads/urls', stdout
|
88
|
+
assert_match 'indexing ads/domains', stdout
|
89
|
+
assert_match 'indexing tracker/urls', stdout
|
90
|
+
assert_match 'indexing tracker/domains', stdout
|
91
|
+
assert_match 'indexed 2 categorie(s): ["ads", "tracker"]', stdout
|
92
|
+
assert_match 'found 4 domain(s)', stdout
|
93
|
+
assert_match 'found 3 url(s)', stdout
|
94
|
+
assert_match 'found 0 duplicate(s)', stdout
|
95
|
+
assert_match 'found 0 ignored expression(s)', stdout
|
96
|
+
assert_match 'committing changes', stdout
|
97
|
+
|
98
|
+
assert_empty stderr
|
99
|
+
end
|
100
|
+
|
101
|
+
def test_index_multiple
|
102
|
+
stdout, stderr = capture_io do
|
103
|
+
@obj.index [
|
104
|
+
File.join(@path, 'black'),
|
105
|
+
File.join(@path, 'gray'),
|
106
|
+
]
|
107
|
+
end
|
108
|
+
|
109
|
+
refute has_test_data?
|
110
|
+
|
111
|
+
domains = db.execute 'SELECT category, host FROM domains'
|
112
|
+
assert_equal [
|
113
|
+
['ads', '.ads.google.com'],
|
114
|
+
['ads', '.doubleclick.net'],
|
115
|
+
['tracker', '.xiti.com'],
|
116
|
+
['tracker', '.google-analytics.com'],
|
117
|
+
['isp', '.000webhost.com'],
|
118
|
+
['isp', '.comcast.com'],
|
119
|
+
['news', '.reddit.com'],
|
120
|
+
['news', '.news.ycombinator.com'],
|
121
|
+
], domains
|
122
|
+
|
123
|
+
urls = db.execute 'SELECT category, host, path FROM urls'
|
124
|
+
assert_equal [
|
125
|
+
['ads', '.google.com', 'adsense/'],
|
126
|
+
['tracker', '.feedproxy.google.com', '~r/'],
|
127
|
+
['tracker', '.cloudfront-labs.amazonaws.com', 'x.png/'],
|
128
|
+
['isp', '.telus.com', 'content/internet/'],
|
129
|
+
], urls
|
130
|
+
|
131
|
+
assert_match 'indexed 4 categorie(s): ["ads", "tracker", "isp", "news"]', stdout
|
132
|
+
assert_match 'found 8 domain(s)', stdout
|
133
|
+
assert_match 'found 4 url(s)', stdout
|
134
|
+
assert_match 'found 0 duplicate(s)', stdout
|
135
|
+
|
136
|
+
assert_empty stderr
|
137
|
+
end
|
138
|
+
|
139
|
+
def test_ignore_subdirectories
|
140
|
+
stdout, stderr = capture_io do
|
141
|
+
@obj.index [File.join(@path, 'subdirectory')]
|
142
|
+
end
|
143
|
+
|
144
|
+
refute_match 'cat/ignore', stdout
|
145
|
+
assert has_test_data?
|
146
|
+
end
|
147
|
+
|
148
|
+
def test_minimal_indexing
|
149
|
+
@obj.blacklists = [MiddleSquid::BlackList.new('ads')]
|
150
|
+
@obj.full_index = false
|
151
|
+
|
152
|
+
stdout, stderr = capture_io do
|
153
|
+
@obj.index [File.join(@path, 'black')]
|
154
|
+
end
|
155
|
+
|
156
|
+
refute has_test_data?
|
157
|
+
|
158
|
+
domains = db.execute 'SELECT category, host FROM domains'
|
159
|
+
assert_equal [
|
160
|
+
['ads', '.ads.google.com'],
|
161
|
+
['ads', '.doubleclick.net'],
|
162
|
+
], domains
|
163
|
+
|
164
|
+
urls = db.execute 'SELECT category, host, path FROM urls'
|
165
|
+
assert_equal [
|
166
|
+
['ads', '.google.com', 'adsense/'],
|
167
|
+
], urls
|
168
|
+
|
169
|
+
refute_match 'tracker', stdout
|
170
|
+
assert_match 'indexed 1 categorie(s): ["ads"]', stdout
|
171
|
+
|
172
|
+
assert_empty stderr
|
173
|
+
end
|
174
|
+
|
175
|
+
def test_not_found
|
176
|
+
stdout, stderr = capture_io do
|
177
|
+
@obj.index [File.join(@path, '404')]
|
178
|
+
end
|
179
|
+
|
180
|
+
assert has_test_data?
|
181
|
+
|
182
|
+
assert_match "reading #{File.join @path, '404'}", stdout
|
183
|
+
|
184
|
+
assert_match "WARNING: #{File.join @path, '404'}: no such directory\n", stderr
|
185
|
+
assert_match "ERROR: nothing to commit", stderr
|
186
|
+
end
|
187
|
+
|
188
|
+
def test_multiple_not_found
|
189
|
+
stdout, stderr = capture_io do
|
190
|
+
@obj.index [
|
191
|
+
File.join(@path, '404'),
|
192
|
+
File.join(@path, 'gray'),
|
193
|
+
]
|
194
|
+
end
|
195
|
+
|
196
|
+
refute has_test_data?
|
197
|
+
|
198
|
+
assert_match "reading #{File.join @path, '404'}", stdout
|
199
|
+
assert_match "reading #{File.join @path, 'gray'}", stdout
|
200
|
+
|
201
|
+
assert_match "WARNING: #{File.join @path, '404'}: no such directory\n", stderr
|
202
|
+
end
|
203
|
+
|
204
|
+
def test_mixed_content
|
205
|
+
stdout, stderr = capture_io do
|
206
|
+
@obj.index [File.join(@path, 'mixed')]
|
207
|
+
end
|
208
|
+
|
209
|
+
refute has_test_data?
|
210
|
+
|
211
|
+
domains = db.execute 'SELECT category, host FROM domains'
|
212
|
+
assert_equal [
|
213
|
+
['cat', '.domain.com'],
|
214
|
+
], domains
|
215
|
+
|
216
|
+
urls = db.execute 'SELECT category, host, path FROM urls'
|
217
|
+
assert_equal [
|
218
|
+
['cat', '.url.com', 'path/'],
|
219
|
+
], urls
|
220
|
+
end
|
221
|
+
|
222
|
+
def test_backslash
|
223
|
+
stdout, stderr = capture_io do
|
224
|
+
@obj.index [File.join(@path, 'backslash')]
|
225
|
+
end
|
226
|
+
|
227
|
+
refute has_test_data?
|
228
|
+
|
229
|
+
domains = db.execute 'SELECT category, host FROM domains'
|
230
|
+
assert_empty domains
|
231
|
+
|
232
|
+
urls = db.execute 'SELECT category, host, path FROM urls'
|
233
|
+
assert_equal [
|
234
|
+
['cat', '.google.com', 'path/to/file/'],
|
235
|
+
], urls
|
236
|
+
end
|
237
|
+
|
238
|
+
def test_invalid_byte
|
239
|
+
stdout, stderr = capture_io do
|
240
|
+
@obj.index [File.join(@path, 'invalid_byte')]
|
241
|
+
end
|
242
|
+
|
243
|
+
refute has_test_data?
|
244
|
+
|
245
|
+
domains = db.execute 'SELECT category, host FROM domains'
|
246
|
+
assert_empty domains
|
247
|
+
|
248
|
+
urls = db.execute 'SELECT category, host, path FROM urls'
|
249
|
+
assert_equal [
|
250
|
+
['cat', '.host.com', 'path_with__invalid_byte/'],
|
251
|
+
], urls
|
252
|
+
end
|
253
|
+
|
254
|
+
def test_empty_path_as_domain
|
255
|
+
stdout, stderr = capture_io do
|
256
|
+
@obj.index [File.join(@path, 'empty_path')]
|
257
|
+
end
|
258
|
+
|
259
|
+
refute has_test_data?
|
260
|
+
|
261
|
+
domains = db.execute 'SELECT category, host FROM domains'
|
262
|
+
assert_equal [
|
263
|
+
['cat', '.host.com'],
|
264
|
+
], domains
|
265
|
+
|
266
|
+
urls = db.execute 'SELECT category, host, path FROM urls'
|
267
|
+
assert_empty urls
|
268
|
+
end
|
269
|
+
|
270
|
+
def test_duplicates
|
271
|
+
stdout, stderr = capture_io do
|
272
|
+
@obj.index [
|
273
|
+
File.join(@path, 'duplicates'),
|
274
|
+
File.join(@path, 'copy_of_duplicates'),
|
275
|
+
]
|
276
|
+
end
|
277
|
+
|
278
|
+
refute has_test_data?
|
279
|
+
|
280
|
+
domains = db.execute 'SELECT category, host FROM domains'
|
281
|
+
assert_equal [
|
282
|
+
['cat', '.host.com'],
|
283
|
+
['copy_of_cat', '.host.com'],
|
284
|
+
], domains
|
285
|
+
|
286
|
+
urls = db.execute 'SELECT category, host, path FROM urls'
|
287
|
+
assert_equal [
|
288
|
+
['cat', '.host.com', 'path/'],
|
289
|
+
['copy_of_cat', '.host.com', 'path/'],
|
290
|
+
], urls
|
291
|
+
|
292
|
+
assert_match 'found 12 duplicate(s)', stdout
|
293
|
+
assert_match 'found 0 ignored expression(s)', stdout
|
294
|
+
|
295
|
+
assert_empty stderr
|
296
|
+
end
|
297
|
+
|
298
|
+
def test_missing_category
|
299
|
+
bl = MiddleSquid::BlackList.new '404'
|
300
|
+
@obj.blacklists = [bl, bl] # should not cause duplicate output
|
301
|
+
|
302
|
+
stdout, stderr = capture_io do
|
303
|
+
@obj.index [File.join(@path, 'black')]
|
304
|
+
end
|
305
|
+
|
306
|
+
refute has_test_data?
|
307
|
+
|
308
|
+
assert_match 'WARNING: could not find ["404"]', stderr
|
309
|
+
end
|
310
|
+
|
311
|
+
def test_expressions
|
312
|
+
stdout, stderr = capture_io do
|
313
|
+
@obj.index [File.join(@path, 'expressions')]
|
314
|
+
end
|
315
|
+
|
316
|
+
assert has_test_data?
|
317
|
+
|
318
|
+
assert_match 'found 3 ignored expression(s)', stdout
|
319
|
+
assert_match 'ERROR: nothing to commit', stderr
|
320
|
+
end
|
321
|
+
|
322
|
+
def test_aliases
|
323
|
+
@obj.full_index = false
|
324
|
+
@obj.blacklists = [
|
325
|
+
MiddleSquid::BlackList.new('cat_name', aliases: ['ads'])
|
326
|
+
]
|
327
|
+
|
328
|
+
stdout, stderr = capture_io do
|
329
|
+
@obj.index [File.join(@path, 'black')]
|
330
|
+
end
|
331
|
+
|
332
|
+
refute has_test_data?
|
333
|
+
|
334
|
+
domains = db.execute 'SELECT category, host FROM domains'
|
335
|
+
assert_equal [
|
336
|
+
['cat_name', '.ads.google.com'],
|
337
|
+
['cat_name', '.doubleclick.net'],
|
338
|
+
], domains
|
339
|
+
|
340
|
+
urls = db.execute 'SELECT category, host, path FROM urls'
|
341
|
+
assert_equal [
|
342
|
+
['cat_name', '.google.com', 'adsense/'],
|
343
|
+
], urls
|
344
|
+
|
345
|
+
refute_match 'tracker', stdout
|
346
|
+
assert_match 'indexing ads/', stdout
|
347
|
+
assert_match 'indexed 1 categorie(s): ["cat_name"]', stdout
|
348
|
+
|
349
|
+
assert_empty stderr
|
350
|
+
end
|
351
|
+
|
352
|
+
def test_domains_only
|
353
|
+
@obj.entries = [:domain]
|
354
|
+
|
355
|
+
stdout, stderr = capture_io do
|
356
|
+
@obj.index [File.join(@path, 'black')]
|
357
|
+
end
|
358
|
+
|
359
|
+
refute has_test_data?
|
360
|
+
|
361
|
+
domains = db.execute 'SELECT category, host FROM domains'
|
362
|
+
assert_equal [
|
363
|
+
['ads', '.ads.google.com'],
|
364
|
+
['ads', '.doubleclick.net'],
|
365
|
+
['tracker', '.xiti.com'],
|
366
|
+
['tracker', '.google-analytics.com'],
|
367
|
+
], domains
|
368
|
+
|
369
|
+
urls = db.execute 'SELECT category, host, path FROM urls'
|
370
|
+
assert_empty urls
|
371
|
+
|
372
|
+
assert_match 'found 4 domain(s)', stdout
|
373
|
+
assert_match 'found 0 url(s)', stdout
|
374
|
+
assert_match 'found 3 ignored expression(s)', stdout
|
375
|
+
|
376
|
+
assert_empty stderr
|
377
|
+
end
|
378
|
+
|
379
|
+
def test_urls_only
|
380
|
+
@obj.entries = [:url]
|
381
|
+
|
382
|
+
stdout, stderr = capture_io do
|
383
|
+
@obj.index [File.join(@path, 'black')]
|
384
|
+
end
|
385
|
+
|
386
|
+
refute has_test_data?
|
387
|
+
|
388
|
+
domains = db.execute 'SELECT category, host FROM domains'
|
389
|
+
assert_empty domains
|
390
|
+
|
391
|
+
urls = db.execute 'SELECT category, host, path FROM urls'
|
392
|
+
assert_equal [
|
393
|
+
['ads', '.google.com', 'adsense/'],
|
394
|
+
['tracker', '.feedproxy.google.com', '~r/'],
|
395
|
+
['tracker', '.cloudfront-labs.amazonaws.com', 'x.png/'],
|
396
|
+
], urls
|
397
|
+
|
398
|
+
assert_match 'found 0 domain(s)', stdout
|
399
|
+
assert_match 'found 3 url(s)', stdout
|
400
|
+
assert_match 'found 4 ignored expression(s)', stdout
|
401
|
+
|
402
|
+
assert_empty stderr
|
403
|
+
end
|
404
|
+
|
405
|
+
def test_append
|
406
|
+
@obj.append = true
|
407
|
+
|
408
|
+
stdout, stderr = capture_io do
|
409
|
+
@obj.index [File.join(@path, 'black')]
|
410
|
+
end
|
411
|
+
|
412
|
+
assert has_test_data?, 'should not be truncated'
|
413
|
+
refute_match 'truncating', stdout
|
414
|
+
|
415
|
+
assert_match 'found 4 domain(s)', stdout
|
416
|
+
assert_match 'found 3 url(s)', stdout
|
417
|
+
end
|
418
|
+
|
419
|
+
def test_quiet
|
420
|
+
@obj.quiet = true
|
421
|
+
|
422
|
+
stdout, stderr = capture_io do
|
423
|
+
@obj.index [File.join(@path, 'black')]
|
424
|
+
end
|
425
|
+
|
426
|
+
assert_empty stdout
|
427
|
+
assert_empty stderr
|
428
|
+
end
|
429
|
+
|
430
|
+
def test_quiet_errors
|
431
|
+
@obj.quiet = true
|
432
|
+
|
433
|
+
stdout, stderr = capture_io do
|
434
|
+
@obj.index []
|
435
|
+
end
|
436
|
+
|
437
|
+
assert_empty stdout
|
438
|
+
assert_match 'nothing to commit', stderr
|
439
|
+
end
|
440
|
+
|
441
|
+
def test_strip_spaces
|
442
|
+
stdout, stderr = capture_io do
|
443
|
+
@obj.index [File.join(@path, 'trailing_space')]
|
444
|
+
end
|
445
|
+
|
446
|
+
refute has_test_data?
|
447
|
+
|
448
|
+
domains = db.execute 'SELECT category, host FROM domains'
|
449
|
+
assert_empty domains
|
450
|
+
|
451
|
+
urls = db.execute 'SELECT category, host, path FROM urls'
|
452
|
+
assert_equal [
|
453
|
+
['cat', '.before.com', 'path/'],
|
454
|
+
['cat', '.after.com', 'path/'],
|
455
|
+
], urls
|
456
|
+
end
|
457
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
require File.expand_path '../helper', __FILE__
|
2
|
+
|
3
|
+
class TestKeyboard < MiniTest::Test
|
4
|
+
def test_receive_line
|
5
|
+
bag = []
|
6
|
+
|
7
|
+
input = MiddleSquid::Backends::Keyboard.new nil, proc {|*args|
|
8
|
+
bag << args
|
9
|
+
}
|
10
|
+
|
11
|
+
input.receive_line 'hello world'
|
12
|
+
|
13
|
+
assert_equal ['hello world'], bag.shift
|
14
|
+
assert_empty bag
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_encoding_fix
|
18
|
+
bag = []
|
19
|
+
|
20
|
+
input = MiddleSquid::Backends::Keyboard.new nil, proc {|line| bag << line }
|
21
|
+
|
22
|
+
input.receive_line 'hello world'.force_encoding(Encoding::ASCII_8BIT)
|
23
|
+
|
24
|
+
assert_equal Encoding::UTF_8, bag.shift.encoding
|
25
|
+
assert_empty bag
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_input_eof
|
29
|
+
input = MiddleSquid::Backends::Keyboard.new nil, proc {|line| nil }
|
30
|
+
|
31
|
+
Timeout::timeout 1 do
|
32
|
+
EM.run { input.receive_data "\x00" }
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_line_buffer
|
37
|
+
bag = []
|
38
|
+
|
39
|
+
input = MiddleSquid::Backends::Keyboard.new nil, proc {|*args| bag << args }
|
40
|
+
input.receive_data 'h'
|
41
|
+
input.receive_data 'e'
|
42
|
+
input.receive_data 'l'
|
43
|
+
input.receive_data 'l'
|
44
|
+
input.receive_data 'o'
|
45
|
+
input.receive_data ' '
|
46
|
+
input.receive_data 'w'
|
47
|
+
input.receive_data 'o'
|
48
|
+
input.receive_data 'r'
|
49
|
+
input.receive_data 'l'
|
50
|
+
input.receive_data 'd'
|
51
|
+
input.receive_data "\n"
|
52
|
+
|
53
|
+
assert_equal ['hello world'], bag.shift
|
54
|
+
assert_empty bag
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_buffer_is_always_cleared
|
58
|
+
bag = []
|
59
|
+
|
60
|
+
input = MiddleSquid::Backends::Keyboard.new nil, proc {|*args|
|
61
|
+
bag << args
|
62
|
+
throw :skip
|
63
|
+
}
|
64
|
+
|
65
|
+
catch :skip do
|
66
|
+
input.receive_data 'a'
|
67
|
+
input.receive_data "\n"
|
68
|
+
end
|
69
|
+
|
70
|
+
catch :skip do
|
71
|
+
input.receive_data 'b'
|
72
|
+
input.receive_data "\n"
|
73
|
+
end
|
74
|
+
|
75
|
+
assert_equal ['a'], bag.shift
|
76
|
+
assert_equal ['b'], bag.shift
|
77
|
+
assert_empty bag
|
78
|
+
end
|
79
|
+
end
|
data/test/test_runner.rb
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
require File.expand_path '../helper', __FILE__
|
2
|
+
|
3
|
+
class TestRunner < MiniTest::Test
|
4
|
+
def test_invalid_config
|
5
|
+
fake_builder = Class.new
|
6
|
+
def fake_builder.handler; nil; end
|
7
|
+
|
8
|
+
error = assert_raises MiddleSquid::Error do
|
9
|
+
MiddleSquid::Runner.new fake_builder
|
10
|
+
end
|
11
|
+
|
12
|
+
assert_equal 'Invalid handler. Did you call Builder#run in your configuration file?', error.message
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_run
|
16
|
+
handler = proc { self }
|
17
|
+
|
18
|
+
custom_actions = { :my_action => proc { self } }
|
19
|
+
|
20
|
+
fake_adapter = MiniTest::Mock.new
|
21
|
+
fake_adapter.expect :handler=, nil do |wrapper|
|
22
|
+
assert_respond_to wrapper, :call
|
23
|
+
assert_instance_of MiddleSquid::Runner, wrapper.call
|
24
|
+
end
|
25
|
+
fake_adapter.expect :start, nil, []
|
26
|
+
|
27
|
+
fake_builder = Class.new
|
28
|
+
fake_builder.define_singleton_method(:handler) { handler }
|
29
|
+
fake_builder.define_singleton_method(:adapter) { fake_adapter }
|
30
|
+
fake_builder.define_singleton_method(:custom_actions) { custom_actions }
|
31
|
+
|
32
|
+
EM.run {
|
33
|
+
@obj = MiddleSquid::Runner.new fake_builder
|
34
|
+
verify_server
|
35
|
+
EM.next_tick { EM.stop }
|
36
|
+
}
|
37
|
+
|
38
|
+
fake_adapter.verify
|
39
|
+
|
40
|
+
verify_custom_actions
|
41
|
+
end
|
42
|
+
|
43
|
+
def verify_server
|
44
|
+
assert_instance_of MiddleSquid::Server, @obj.server
|
45
|
+
assert_equal '127.0.0.1', @obj.server.host
|
46
|
+
assert @obj.server.port > 0, 'port'
|
47
|
+
end
|
48
|
+
|
49
|
+
def verify_custom_actions
|
50
|
+
assert_equal @obj, @obj.my_action
|
51
|
+
|
52
|
+
assert_raises NoMethodError do
|
53
|
+
@obj.not_found
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
data/test/test_server.rb
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
require File.expand_path '../helper', __FILE__
|
2
|
+
|
3
|
+
class TestServer < MiniTest::Test
|
4
|
+
include Rack::Test::Methods
|
5
|
+
|
6
|
+
def setup
|
7
|
+
@server = MiddleSquid::Server.new
|
8
|
+
@app = Thin::Async::Test.new @server.method(:handler)
|
9
|
+
end
|
10
|
+
|
11
|
+
def app
|
12
|
+
@app
|
13
|
+
end
|
14
|
+
|
15
|
+
def token_for(&block)
|
16
|
+
token = nil
|
17
|
+
|
18
|
+
EM.run {
|
19
|
+
token = @server.token_for block
|
20
|
+
EM.next_tick { EM.stop }
|
21
|
+
}
|
22
|
+
|
23
|
+
token
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_start_stop
|
27
|
+
EM.run {
|
28
|
+
assert_nil @server.host
|
29
|
+
assert_nil @server.port
|
30
|
+
|
31
|
+
@server.start
|
32
|
+
|
33
|
+
assert_equal '127.0.0.1', @server.host
|
34
|
+
assert_instance_of Fixnum, @server.port
|
35
|
+
assert @server.port > 0
|
36
|
+
|
37
|
+
@server.stop
|
38
|
+
|
39
|
+
assert_nil @server.host
|
40
|
+
assert_nil @server.port
|
41
|
+
|
42
|
+
EM.next_tick { EM.stop }
|
43
|
+
}
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_not_found
|
47
|
+
get '/not_found'
|
48
|
+
|
49
|
+
assert_equal 404, last_response.status
|
50
|
+
assert_equal 'text/plain', last_response['Content-Type']
|
51
|
+
assert_equal '[MiddleSquid] Invalid Token', last_response.body
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_token
|
55
|
+
bag = []
|
56
|
+
|
57
|
+
tk = token_for {|*args|
|
58
|
+
bag << args
|
59
|
+
bag << Fiber.current
|
60
|
+
}
|
61
|
+
|
62
|
+
get '/' + tk
|
63
|
+
|
64
|
+
assert_equal 200, last_response.status
|
65
|
+
assert_empty last_response.body
|
66
|
+
|
67
|
+
(req, res), fiber = bag
|
68
|
+
|
69
|
+
assert_instance_of Rack::Request, req
|
70
|
+
assert_instance_of Thin::AsyncResponse, res
|
71
|
+
|
72
|
+
refute_same fiber, Fiber.current
|
73
|
+
end
|
74
|
+
|
75
|
+
def test_rack_reply
|
76
|
+
tk = token_for {
|
77
|
+
[418, {'Hello'=>'World'}, ['hello world']]
|
78
|
+
}
|
79
|
+
|
80
|
+
get '/' + tk
|
81
|
+
|
82
|
+
assert_equal 418, last_response.status
|
83
|
+
assert_equal 'World', last_response['HELLO']
|
84
|
+
assert_equal 'hello world', last_response.body
|
85
|
+
end
|
86
|
+
end
|