pork 0.9.2 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.travis.yml +2 -0
- data/CHANGES.md +35 -0
- data/Gemfile +13 -0
- data/README.md +186 -39
- data/Rakefile +1 -1
- data/lib/mutant/integration/pork.rb +76 -0
- data/lib/pork.rb +14 -231
- data/lib/pork/auto.rb +2 -1
- data/lib/pork/context.rb +24 -0
- data/lib/pork/env.rb +18 -0
- data/lib/pork/error.rb +6 -0
- data/lib/pork/executor.rb +11 -0
- data/lib/pork/expect.rb +69 -0
- data/lib/pork/imp.rb +103 -0
- data/lib/pork/inspect.rb +97 -0
- data/lib/pork/isolate.rb +55 -0
- data/lib/pork/mode/parallel.rb +16 -0
- data/lib/pork/mode/shuffle.rb +16 -0
- data/lib/pork/should.rb +25 -0
- data/lib/pork/stat.rb +38 -0
- data/lib/pork/test.rb +17 -0
- data/lib/pork/version.rb +1 -1
- data/pork.gemspec +42 -7
- data/task/gemgem.rb +100 -51
- data/test/test_inspect.rb +41 -0
- data/test/test_isolate.rb +13 -0
- data/test/test_nested.rb +0 -21
- data/test/test_parallel.rb +12 -0
- data/test/test_shuffle.rb +12 -0
- metadata +42 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d8259f46bbdff005a8f03f13a6106bcd7a264df4
|
4
|
+
data.tar.gz: e515132bb2458ddec395e4d50971cd16f7821cb5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 334364aaa0941b31830ce6998eff0c2715376cd74cf9befcdeeb79d1c6344d10b91aa44b66e24ec8b14f3217eb67bcbfd8cc6816685a5b43ed717d69c1d3d9b3
|
7
|
+
data.tar.gz: e5aa86f3e2976666d53b831c58b5bb70831e5e8b08dfaa87fa94b4810cb7acfe7c576ffb0c5281032991c8b652f661312f84a59e30d17a7018991c11f615b727
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
data/CHANGES.md
CHANGED
@@ -1,5 +1,40 @@
|
|
1
1
|
# CHANGES
|
2
2
|
|
3
|
+
## Pork 1.0.0 -- 2014-11-20
|
4
|
+
|
5
|
+
### Bugs fixed
|
6
|
+
|
7
|
+
* Now exceptions raised in after hook are properly rescued.
|
8
|
+
* Previously runtime includes loading time, now it only includes
|
9
|
+
test running time.
|
10
|
+
|
11
|
+
### Incompatible changes
|
12
|
+
|
13
|
+
* Internal structure was completed rewritten.
|
14
|
+
* Simply `require 'pork'` would no longer introduce `Kernel#should`.
|
15
|
+
Use `require 'pork/should'` to bring it back. (`require 'pork/auto'`
|
16
|
+
would already do this for you)
|
17
|
+
* Removed `@__pork__desc__` (which is implementation detail anyway)
|
18
|
+
* Renamed `Pork.report_at_exit` to `Pork.autorun`
|
19
|
+
|
20
|
+
### Enhancement
|
21
|
+
|
22
|
+
* `Pork.autorun` also accepts a flag to enable/disable autorun.
|
23
|
+
* Introduced `Pork::Expector#expect` to replace `Kernel#should`
|
24
|
+
* `Kernel#should` is now optional and a wrapper around `Pork::Expector#expect`
|
25
|
+
|
26
|
+
* Introduced `Pork::Inspect#diff_hash`. See README.md for
|
27
|
+
`Pork.inspect_failure_mode` for detail.
|
28
|
+
* Introduced `Pork.execute_mode`. See README.md for detail
|
29
|
+
* Introduced `Pork::Isolate` which allows you to run a specific test.
|
30
|
+
* Introduced `Pork::Shuffle` which we could run tests in random order.
|
31
|
+
See README.md for `Pork.execute_mode` for detail.
|
32
|
+
* Introduced `Pork::Parallel` which we could run tests in parallel.
|
33
|
+
See README.md for `Pork.execute_mode` for detail.
|
34
|
+
|
35
|
+
* Introduced `Pork::Executor#pork_stat` to access the current stat from test.
|
36
|
+
* Introduced mutant integration.
|
37
|
+
|
3
38
|
## Pork 0.9.2 -- 2014-11-07
|
4
39
|
|
5
40
|
* Pork::Error is now a StandardError instead of an Exception.
|
data/Gemfile
ADDED
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Pork [![Build Status](https://secure.travis-ci.org/godfat/pork.png?branch=master)](http://travis-ci.org/godfat/pork)
|
1
|
+
# Pork [![Build Status](https://secure.travis-ci.org/godfat/pork.png?branch=master)](http://travis-ci.org/godfat/pork) [![Coverage Status](https://coveralls.io/repos/godfat/pork/badge.png)](https://coveralls.io/r/godfat/pork)
|
2
2
|
|
3
3
|
by Lin Jen-Shin ([godfat](http://godfat.org))
|
4
4
|
|
@@ -12,7 +12,7 @@ by Lin Jen-Shin ([godfat](http://godfat.org))
|
|
12
12
|
|
13
13
|
Pork -- Simple and clean and modular testing library.
|
14
14
|
|
15
|
-
[Bacon][]
|
15
|
+
Inspired by [Bacon][].
|
16
16
|
|
17
17
|
[Bacon]: https://github.com/chneukirchen/bacon
|
18
18
|
|
@@ -272,6 +272,98 @@ describe Hash do
|
|
272
272
|
end
|
273
273
|
```
|
274
274
|
|
275
|
+
## What if I don't want any monkey patches?
|
276
|
+
|
277
|
+
For the lazies and the greatest convenience but the least flexibility, we
|
278
|
+
could simply `require 'pork/auto'` and everything above should work.
|
279
|
+
However, as you can see, there are some monkey patches around, and you
|
280
|
+
might not want to see any of them. In this case *DON'T* require it.
|
281
|
+
|
282
|
+
Here's what `require 'pork/auto'` would do:
|
283
|
+
|
284
|
+
``` ruby
|
285
|
+
require 'pork'
|
286
|
+
require 'pork/should'
|
287
|
+
extend Pork::API
|
288
|
+
Pork.autorun
|
289
|
+
```
|
290
|
+
|
291
|
+
Here it `require 'pork/should'`, and it would load the monkey patches for
|
292
|
+
inserting `Kernel#should` shown in SYNOPSIS. This is actually optional,
|
293
|
+
and could be replaced with `Pork::Executor#expect`. For example, we could
|
294
|
+
also write it this way:
|
295
|
+
|
296
|
+
``` ruby
|
297
|
+
require 'pork'
|
298
|
+
|
299
|
+
Pork::API.describe Array do
|
300
|
+
before do
|
301
|
+
@array = []
|
302
|
+
end
|
303
|
+
|
304
|
+
after do
|
305
|
+
@array.clear
|
306
|
+
end
|
307
|
+
|
308
|
+
would 'be empty' do
|
309
|
+
expect(@array).empty?
|
310
|
+
expect(@array).not.include? 1
|
311
|
+
end
|
312
|
+
end
|
313
|
+
|
314
|
+
# or: Pork.autorun
|
315
|
+
Pork::Executor.execute.report
|
316
|
+
```
|
317
|
+
|
318
|
+
As you can see, this way we no longer use any monkey patches and we don't
|
319
|
+
even use `at_exit` hook to run tests. Also note that we could turn autorun
|
320
|
+
off by passing `false` to it:
|
321
|
+
|
322
|
+
``` ruby
|
323
|
+
Pork.autorun(false)
|
324
|
+
```
|
325
|
+
|
326
|
+
We might need to turn autorun off occasionally, for example, we do need to
|
327
|
+
turn this off when integrating [mutant][]. Passing `true` again to `autorun`
|
328
|
+
could re-enable it.
|
329
|
+
|
330
|
+
[mutant]: https://github.com/mbj/mutant
|
331
|
+
|
332
|
+
## Where's the pork command?
|
333
|
+
|
334
|
+
It's not implemented. No strong reasons. You could simply run the tests by
|
335
|
+
requiring the files defining tests, or execute them directly, with autorun
|
336
|
+
enabled. (by `require 'pork/auto'` or call `Pork.autorun`)
|
337
|
+
|
338
|
+
Here's a example command to require all test files and automatically run them.
|
339
|
+
With [Fish shell][]:
|
340
|
+
|
341
|
+
ruby -Ilib -rpork/auto -r(ls ./test/test_*.rb) -e ''
|
342
|
+
|
343
|
+
Or
|
344
|
+
|
345
|
+
ruby -Ilib -rpork/auto -r(find ./test -name '*.rb' -type f) -e ''
|
346
|
+
|
347
|
+
With Bash shell:
|
348
|
+
|
349
|
+
ruby -Ilib -rpork/auto $(ls ./test/test_*.rb | awk '{print "-r" $0}') -e ''
|
350
|
+
|
351
|
+
Personally I have a [rake task][gemgem] which would do this for me, so I just
|
352
|
+
run `rake test` to run all the tests.
|
353
|
+
|
354
|
+
[Fish shell]: http://fishshell.com/
|
355
|
+
[gemgem]: https://github.com/godfat/gemgem
|
356
|
+
|
357
|
+
## Mutant integration
|
358
|
+
|
359
|
+
Pork also ships with [mutant][] integration. Here's an example to run it:
|
360
|
+
|
361
|
+
mutant -Ilib -rjellyfish --use pork Jellyfish
|
362
|
+
|
363
|
+
for [jellyfish][].
|
364
|
+
|
365
|
+
[jellyfish]: https://github.com/godfat/jellyfish
|
366
|
+
|
275
367
|
## The API
|
276
368
|
|
277
369
|
### Kernel#should
|
@@ -323,7 +415,7 @@ end
|
|
323
415
|
The assertions would only fail whenever the result was `false` or `nil`,
|
324
416
|
otherwise pass.
|
325
417
|
|
326
|
-
### Pork::
|
418
|
+
### Pork::Expect#satisfy
|
327
419
|
|
328
420
|
If we want to have custom verifier other than the methods from questioning
|
329
421
|
object, this is it.
|
@@ -355,7 +447,7 @@ describe do
|
|
355
447
|
end
|
356
448
|
```
|
357
449
|
|
358
|
-
### Pork::
|
450
|
+
### Pork::Expect#not
|
359
451
|
|
360
452
|
An easy way to negate the expectation.
|
361
453
|
|
@@ -365,7 +457,7 @@ require 'pork/auto'
|
|
365
457
|
would{ 1.should.not.eq 2 }
|
366
458
|
```
|
367
459
|
|
368
|
-
### Pork::
|
460
|
+
### Pork::Expect#eq
|
369
461
|
|
370
462
|
To avoid warnings from Ruby, using `eq` instead of `==`. It's fine if you
|
371
463
|
still prefer using `==` if you don't care about warnings.
|
@@ -376,7 +468,7 @@ require 'pork/auto'
|
|
376
468
|
would{ 1.should.eq 1 }
|
377
469
|
```
|
378
470
|
|
379
|
-
### Pork::
|
471
|
+
### Pork::Expect#lt
|
380
472
|
|
381
473
|
To avoid warnings from Ruby, using `lt` instead of `<`. It's fine if you
|
382
474
|
still prefer using `<` if you don't care about warnings.
|
@@ -387,7 +479,7 @@ require 'pork/auto'
|
|
387
479
|
would{ 1.should.lt 2 }
|
388
480
|
```
|
389
481
|
|
390
|
-
### Pork::
|
482
|
+
### Pork::Expect#gt
|
391
483
|
|
392
484
|
To avoid warnings from Ruby, using `gt` instead of `>`. It's fine if you
|
393
485
|
still prefer using `>` if you don't care about warnings.
|
@@ -398,7 +490,7 @@ require 'pork/auto'
|
|
398
490
|
would{ 1.should.gt 0 }
|
399
491
|
```
|
400
492
|
|
401
|
-
### Pork::
|
493
|
+
### Pork::Expect#lte
|
402
494
|
|
403
495
|
To avoid warnings from Ruby, using `lte` instead of `<=`. It's fine if you
|
404
496
|
still prefer using `<=` if you don't care about warnings.
|
@@ -409,7 +501,7 @@ require 'pork/auto'
|
|
409
501
|
would{ 1.should.lte 1 }
|
410
502
|
```
|
411
503
|
|
412
|
-
### Pork::
|
504
|
+
### Pork::Expect#gte
|
413
505
|
|
414
506
|
To avoid warnings from Ruby, using `gte` instead of `>=`. It's fine if you
|
415
507
|
still prefer using `>=` if you don't care about warnings.
|
@@ -420,7 +512,7 @@ require 'pork/auto'
|
|
420
512
|
would{ 1.should.gte 1 }
|
421
513
|
```
|
422
514
|
|
423
|
-
### Pork::
|
515
|
+
### Pork::Expect#raise
|
424
516
|
|
425
517
|
Expect for exceptions! There are two ways to call it. Either you could use
|
426
518
|
lambda to wrap the questioning expression, or you could simply pass a block
|
@@ -429,7 +521,7 @@ as the questioning expression.
|
|
429
521
|
``` ruby
|
430
522
|
require 'pork/auto'
|
431
523
|
|
432
|
-
describe 'Pork::
|
524
|
+
describe 'Pork::Expect#raise' do
|
433
525
|
would 'check with a block' do
|
434
526
|
e = should.raise(RuntimeError){ raise "nnf" }
|
435
527
|
e.should.message.include?("nnf")
|
@@ -442,7 +534,7 @@ describe 'Pork::Should#raise' do
|
|
442
534
|
end
|
443
535
|
```
|
444
536
|
|
445
|
-
### Pork::
|
537
|
+
### Pork::Expect#throw
|
446
538
|
|
447
539
|
Expect for something to be thrown. There are two ways to call it. Either
|
448
540
|
you could use lambda to wrap the questioning expression, or you could
|
@@ -495,14 +587,6 @@ a string. The _default_ description is also `:default`.
|
|
495
587
|
Each `would` block would be run inside a new instance of the describing
|
496
588
|
`Pork::Executor` to isolate instance variables.
|
497
589
|
|
498
|
-
``` ruby
|
499
|
-
require 'pork/auto'
|
500
|
-
|
501
|
-
would do
|
502
|
-
desc.should.eq :default
|
503
|
-
end
|
504
|
-
```
|
505
|
-
|
506
590
|
### Pork::API.before
|
507
591
|
|
508
592
|
Each `before` block would be called before each `would` block (test case).
|
@@ -593,6 +677,32 @@ describe do
|
|
593
677
|
end
|
594
678
|
```
|
595
679
|
|
680
|
+
### Pork::Executor#expect
|
681
|
+
|
682
|
+
It is the core of `Kernel#should`. Think of:
|
683
|
+
|
684
|
+
``` ruby
|
685
|
+
object.should.eq(1)
|
686
|
+
```
|
687
|
+
|
688
|
+
is equivalent to:
|
689
|
+
|
690
|
+
``` ruby
|
691
|
+
expect(object).eq(1)
|
692
|
+
```
|
693
|
+
|
694
|
+
Also:
|
695
|
+
|
696
|
+
``` ruby
|
697
|
+
object.should('message').eq(1)
|
698
|
+
```
|
699
|
+
|
700
|
+
is equivalent to:
|
701
|
+
|
702
|
+
``` ruby
|
703
|
+
expect(object, 'message').eq(1)
|
704
|
+
```
|
705
|
+
|
596
706
|
### Pork::Executor#skip
|
597
707
|
|
598
708
|
At times we might want to skip some tests while leave the codes there without
|
@@ -647,28 +757,43 @@ describe do
|
|
647
757
|
end
|
648
758
|
```
|
649
759
|
|
650
|
-
### Pork.
|
760
|
+
### Pork.autorun
|
651
761
|
|
652
|
-
|
653
|
-
|
654
|
-
|
762
|
+
Calling this would register an `at_exit` hook to run tests at exit.
|
763
|
+
This also accepts an argument to turn on and off autorun. Calling this
|
764
|
+
multiple times is ok. (It's not thread safe though, don't call this twice
|
765
|
+
from different threads at the same time. If you really want to do this,
|
766
|
+
let's add a mutex for this)
|
655
767
|
|
656
|
-
|
657
|
-
of your tests as well if you want to handle `Pork.report` manually.
|
768
|
+
It would also exit with 0 if no error occurs or N for N errors and failures.
|
658
769
|
|
659
|
-
|
770
|
+
``` ruby
|
771
|
+
Pork.autorun # enable
|
772
|
+
Pork.autorun(false) # disable
|
773
|
+
Pork.autorun(true) # enable
|
774
|
+
```
|
660
775
|
|
661
|
-
|
662
|
-
and exit with 0 if no error occurs or N for N errors and failures.
|
776
|
+
`require 'pork/auto'` would call `Pork.autorun`
|
663
777
|
|
664
|
-
|
665
|
-
|
666
|
-
|
778
|
+
### Pork.execute_mode
|
779
|
+
|
780
|
+
By default, `Pork.execute_mode` is set to `:execute`, which would
|
781
|
+
execute all tests in a sequential manner. The other options are:
|
782
|
+
|
783
|
+
* `:execute` (default)
|
784
|
+
* `:shuffle`
|
785
|
+
* `:parallel`
|
786
|
+
|
787
|
+
With `:shuffle`, it would execute all tests in a random order. It would be
|
788
|
+
slightly slower than `:execute`. With `:parallel`, it would run tests with
|
789
|
+
8 threads concurrently, and of course, the orders are all random as well.
|
790
|
+
You'll need to make sure your tests are thread safe or random tests would
|
791
|
+
fail with this mode.
|
792
|
+
|
793
|
+
Pass the symbol to it to use the mode:
|
667
794
|
|
668
795
|
``` ruby
|
669
|
-
|
670
|
-
extend Pork::API
|
671
|
-
Pork.report_at_exit
|
796
|
+
Pork.execute_mode :shuffle
|
672
797
|
```
|
673
798
|
|
674
799
|
### Pork.inspect_failure_mode
|
@@ -683,13 +808,35 @@ really long, it would even use `diff` to show the difference.
|
|
683
808
|
This is because if the actual string is long, it would be quite painful to
|
684
809
|
find the actual difference for human without assistance.
|
685
810
|
|
811
|
+
Additionally, if both the actually object and expected object are hashes,
|
812
|
+
and if the actually hash is fairly large, it would also try to differentiate
|
813
|
+
the two and give you a more readable result like:
|
814
|
+
|
815
|
+
```
|
816
|
+
Pork::Failure: Expect
|
817
|
+
Hash with key path: "categories:0:chats:0:mentor:username"
|
818
|
+
"Expect Name".==("Actual Name") to return true
|
819
|
+
```
|
820
|
+
|
821
|
+
For this:
|
822
|
+
|
823
|
+
``` ruby
|
824
|
+
mentor = {"Some" => "Random", "Data" => "Here", "This's" => "Large"}
|
825
|
+
expect("categories" => [{"chats" => [{"mentor" =>
|
826
|
+
mentor.merge("username" => "Actual Name")}]}]).eq \
|
827
|
+
"categories" => [{"chats" => [{"mentor" =>
|
828
|
+
mentor.merge("username" => "Expect Name")}]}]
|
829
|
+
```
|
830
|
+
|
831
|
+
This should much improve the time to figure out why it's failing.
|
832
|
+
|
686
833
|
However, this might not really be desired at times. So we should be able to
|
687
834
|
switch between each mode. For now, we have the following modes:
|
688
835
|
|
689
|
-
*
|
690
|
-
*
|
691
|
-
*
|
692
|
-
*
|
836
|
+
* `:auto` (default)
|
837
|
+
* `:inline`
|
838
|
+
* `:newline`
|
839
|
+
* `:diff`
|
693
840
|
|
694
841
|
If we want to force to a specific mode, here's how we would do:
|
695
842
|
|
data/Rakefile
CHANGED
@@ -0,0 +1,76 @@
|
|
1
|
+
|
2
|
+
require 'pork'
|
3
|
+
require 'pork/isolate'
|
4
|
+
require 'stringio'
|
5
|
+
|
6
|
+
module Mutant
|
7
|
+
class Integration
|
8
|
+
class Pork < self
|
9
|
+
register 'pork'
|
10
|
+
|
11
|
+
# Return integration compatible to currently loaded pork
|
12
|
+
#
|
13
|
+
# @return [Integration]
|
14
|
+
#
|
15
|
+
# @api private
|
16
|
+
#
|
17
|
+
def self.build
|
18
|
+
new
|
19
|
+
end
|
20
|
+
|
21
|
+
# Setup pork integration
|
22
|
+
#
|
23
|
+
# @return [self]
|
24
|
+
#
|
25
|
+
# @api private
|
26
|
+
#
|
27
|
+
def setup
|
28
|
+
Dir['test/**/test_*.rb'].each do |path|
|
29
|
+
require "./#{path}"
|
30
|
+
end
|
31
|
+
::Pork.autorun(false)
|
32
|
+
self
|
33
|
+
end
|
34
|
+
memoize :setup
|
35
|
+
|
36
|
+
# Return report for test
|
37
|
+
#
|
38
|
+
# @param [Pork::Test] test
|
39
|
+
#
|
40
|
+
# @return [Test::Result]
|
41
|
+
#
|
42
|
+
# @api private
|
43
|
+
#
|
44
|
+
# rubocop:disable MethodLength
|
45
|
+
#
|
46
|
+
def run(test)
|
47
|
+
stat = ::Pork::Executor.isolate(test.expression.syntax,
|
48
|
+
::Pork::Stat.new(StringIO.new))
|
49
|
+
|
50
|
+
Result::Test.new(
|
51
|
+
test: nil,
|
52
|
+
mutation: nil,
|
53
|
+
output: stat.io.string,
|
54
|
+
runtime: Time.now - stat.start,
|
55
|
+
passed: stat.passed?
|
56
|
+
)
|
57
|
+
end
|
58
|
+
|
59
|
+
# Return all available tests
|
60
|
+
#
|
61
|
+
# @return [Enumerable<Test>]
|
62
|
+
#
|
63
|
+
# @api private
|
64
|
+
#
|
65
|
+
def all_tests
|
66
|
+
::Pork::Executor.all_tests.keys.inject([]) do |tests, description|
|
67
|
+
expression = Expression.try_parse(description) or next tests
|
68
|
+
tests << Test.new(self, expression)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
memoize :all_tests
|
72
|
+
|
73
|
+
end # Pork
|
74
|
+
|
75
|
+
end # Integration
|
76
|
+
end # Mutant
|