easytest 0.3.1 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -0
- data/README.md +19 -2
- data/lib/easytest/case.rb +19 -20
- data/lib/easytest/cli.rb +1 -1
- data/lib/easytest/dsl.rb +9 -0
- data/lib/easytest/expectation.rb +4 -0
- data/lib/easytest/matcher/include.rb +13 -0
- data/lib/easytest/reporter.rb +34 -16
- data/lib/easytest/runner.rb +49 -14
- data/lib/easytest/version.rb +1 -1
- data/lib/easytest.rb +1 -0
- data/sig/easytest.rbs +7 -0
- metadata +2 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e87217a9622ad5c57a2b97d64fc8e0a6cf32c264b53901644740b4727363d1bf
|
4
|
+
data.tar.gz: 5703988217fdf9bc1e0aad99c2c5609a6e159e80d546124f0108ba4414dc1638
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 98e353f726337a6d5b2b9aaad59a4bca8801f06885dc2e9f8f5c0dce6655e2d8e5ab178ede9f7d3b229e2e4f92b8896a5895454d211c8222570cf8e81ababea5
|
7
|
+
data.tar.gz: 88eff8410c841dffd3457beb20a3f78aaba46347ce724a680d9420f0e7831ce37d1ddcef9233a29758049a8b5e336f183781dc572b89531cd7472276984e5bb5
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -42,7 +42,7 @@ Then, run `easytest`:
|
|
42
42
|
```console
|
43
43
|
$ easytest
|
44
44
|
FAIL test/addition_test.rb
|
45
|
-
|
45
|
+
✕ addition (should equal)
|
46
46
|
|
47
47
|
Expected: 2
|
48
48
|
Received: 3
|
@@ -73,4 +73,21 @@ $ easytest
|
|
73
73
|
|
74
74
|
The test now passes! 🎉
|
75
75
|
|
76
|
-
|
76
|
+
### Skip
|
77
|
+
|
78
|
+
If you want to skip a case, you can change `test` to `skip`:
|
79
|
+
|
80
|
+
```diff
|
81
|
+
-test "addition" do
|
82
|
+
+skip "addition" do
|
83
|
+
expect(1 + 2).to_eq 2
|
84
|
+
end
|
85
|
+
```
|
86
|
+
|
87
|
+
### To-do
|
88
|
+
|
89
|
+
If you want to write a to-do case, you can use `test` without a block:
|
90
|
+
|
91
|
+
```ruby
|
92
|
+
test "addition"
|
93
|
+
```
|
data/lib/easytest/case.rb
CHANGED
@@ -3,35 +3,34 @@ module Easytest
|
|
3
3
|
attr_reader :name
|
4
4
|
attr_reader :file
|
5
5
|
attr_reader :block
|
6
|
-
|
6
|
+
attr_reader :skipped
|
7
|
+
alias skipped? skipped
|
7
8
|
|
8
|
-
def initialize(name:, file:, &block)
|
9
|
+
def initialize(name:, file:, skipped: false, &block)
|
9
10
|
@name = name
|
10
11
|
@file = file
|
11
12
|
@block = block
|
12
|
-
@
|
13
|
+
@skipped = skipped
|
13
14
|
end
|
14
15
|
|
15
|
-
def
|
16
|
-
block.
|
17
|
-
true
|
18
|
-
rescue MatchError, FatalError => error
|
19
|
-
loc = find_location(error) or raise
|
20
|
-
|
21
|
-
self.report = Reporter.new(
|
22
|
-
name: name,
|
23
|
-
error: error,
|
24
|
-
file: loc.absolute_path,
|
25
|
-
location: loc.to_s,
|
26
|
-
).report or raise
|
27
|
-
|
28
|
-
false
|
16
|
+
def todo?
|
17
|
+
block.nil?
|
29
18
|
end
|
30
19
|
|
31
|
-
|
20
|
+
def run
|
21
|
+
if todo?
|
22
|
+
return [:todo, Reporter.new(name).report_todo]
|
23
|
+
end
|
24
|
+
|
25
|
+
if skipped?
|
26
|
+
return [:skipped, Reporter.new(name).report_skip]
|
27
|
+
end
|
32
28
|
|
33
|
-
|
34
|
-
|
29
|
+
block.call
|
30
|
+
[:passed, nil]
|
31
|
+
rescue MatchError, FatalError => error
|
32
|
+
report = Reporter.new(name).report_error(error) or raise error
|
33
|
+
[:failed, report]
|
35
34
|
end
|
36
35
|
end
|
37
36
|
end
|
data/lib/easytest/cli.rb
CHANGED
@@ -66,7 +66,7 @@ module Easytest
|
|
66
66
|
def help(parser)
|
67
67
|
<<~MSG
|
68
68
|
#{Rainbow("USAGE").bright}
|
69
|
-
#{parser.program_name} [options] [
|
69
|
+
#{parser.program_name} [options] [<file, directory, or pattern>...]
|
70
70
|
|
71
71
|
#{Rainbow("OPTIONS").bright}
|
72
72
|
--help Show help
|
data/lib/easytest/dsl.rb
CHANGED
@@ -2,10 +2,19 @@ module Easytest
|
|
2
2
|
module DSL
|
3
3
|
refine Kernel do
|
4
4
|
def test(name, &block)
|
5
|
+
raise FatalError, "`test` requires a name" if name.nil? || name.empty?
|
6
|
+
|
5
7
|
file = caller_locations(1, 1).first.absolute_path
|
6
8
|
Easytest.add_case Case.new(name: name, file: file, &block)
|
7
9
|
end
|
8
10
|
|
11
|
+
def skip(name, &block)
|
12
|
+
raise FatalError, "`skip` requires a name" if name.nil? || name.empty?
|
13
|
+
|
14
|
+
file = caller_locations(1, 1).first.absolute_path
|
15
|
+
Easytest.add_case Case.new(name: name, file: file, skipped: true, &block)
|
16
|
+
end
|
17
|
+
|
9
18
|
def expect(actual = nil, &block)
|
10
19
|
Expectation.new(actual, &block)
|
11
20
|
end
|
data/lib/easytest/expectation.rb
CHANGED
@@ -37,6 +37,10 @@ module Easytest
|
|
37
37
|
Matcher::InstanceOf.new(actual: actual, expected: expected, negate: negate).match!
|
38
38
|
end
|
39
39
|
|
40
|
+
def to_include(expected)
|
41
|
+
Matcher::Include.new(actual: actual, expected: expected, negate: negate).match!
|
42
|
+
end
|
43
|
+
|
40
44
|
def to_raise(expected)
|
41
45
|
raise FatalError, "`to_raise` requires a block like `expect { ... }.to_raise`" unless block
|
42
46
|
raise FatalError, "`not.to_raise` can cause a false positive, so use `to_not_raise` instead" if negate?
|
data/lib/easytest/reporter.rb
CHANGED
@@ -1,47 +1,65 @@
|
|
1
1
|
module Easytest
|
2
2
|
class Reporter
|
3
3
|
attr_reader :name
|
4
|
-
attr_reader :error
|
5
|
-
attr_reader :file
|
6
|
-
attr_reader :location
|
7
4
|
|
8
|
-
def initialize(name
|
5
|
+
def initialize(name)
|
9
6
|
@name = name
|
10
|
-
@error = error
|
11
|
-
@file = file
|
12
|
-
@location = location
|
13
7
|
end
|
14
8
|
|
15
|
-
def
|
9
|
+
def report_error(error)
|
16
10
|
case error
|
17
11
|
when MatchError
|
18
|
-
report_match_error
|
12
|
+
report_match_error(error)
|
19
13
|
when FatalError
|
20
|
-
report_fatal_error
|
14
|
+
report_fatal_error(error)
|
21
15
|
end
|
22
16
|
end
|
23
17
|
|
18
|
+
def report_skip
|
19
|
+
Rainbow("⚠ skipped \"#{name}\"").yellow
|
20
|
+
end
|
21
|
+
|
22
|
+
def report_todo
|
23
|
+
Rainbow("✎ todo \"#{name}\"").magenta
|
24
|
+
end
|
25
|
+
|
24
26
|
private
|
25
27
|
|
26
|
-
def report_match_error
|
28
|
+
def report_match_error(error)
|
29
|
+
loc = find_location(error)
|
30
|
+
|
27
31
|
<<~MSG
|
28
|
-
#{Rainbow("
|
32
|
+
#{Rainbow("✕ #{name}").red.bright} #{Rainbow("(#{error.message})").dimgray}
|
29
33
|
|
30
34
|
#{Rainbow("Expected: #{error.expected.inspect}").green}
|
31
35
|
#{Rainbow("Received: #{error.actual.inspect}").red}
|
32
36
|
|
33
|
-
#{Rainbow(
|
37
|
+
#{Rainbow(format_location(loc)).dimgray}
|
34
38
|
MSG
|
35
39
|
end
|
36
40
|
|
37
|
-
def report_fatal_error
|
41
|
+
def report_fatal_error(error)
|
42
|
+
loc = find_location(error)
|
43
|
+
|
38
44
|
<<~MSG
|
39
|
-
#{Rainbow("
|
45
|
+
#{Rainbow("✕ #{name}").red.bright}
|
40
46
|
|
41
47
|
#{Rainbow(error.message).red}
|
42
48
|
|
43
|
-
#{Rainbow(
|
49
|
+
#{Rainbow(format_location(loc)).dimgray}
|
44
50
|
MSG
|
45
51
|
end
|
52
|
+
|
53
|
+
def find_location(error)
|
54
|
+
location = error.backtrace_locations.find do |loc|
|
55
|
+
loc.path.end_with?("_test.rb")
|
56
|
+
end
|
57
|
+
location or raise "Not found test location from #{error.inspect}"
|
58
|
+
end
|
59
|
+
|
60
|
+
def format_location(location)
|
61
|
+
path = Pathname(location.absolute_path).relative_path_from(Dir.pwd)
|
62
|
+
"# #{path}:#{location.lineno}:in `#{location.label}'"
|
63
|
+
end
|
46
64
|
end
|
47
65
|
end
|
data/lib/easytest/runner.rb
CHANGED
@@ -3,12 +3,16 @@ module Easytest
|
|
3
3
|
attr_reader :start_time
|
4
4
|
attr_accessor :passed_count
|
5
5
|
attr_accessor :failed_count
|
6
|
+
attr_accessor :skipped_count
|
7
|
+
attr_accessor :todo_count
|
6
8
|
attr_accessor :file_count
|
7
9
|
|
8
10
|
def initialize(start_time: Time.now)
|
9
11
|
@start_time = start_time
|
10
12
|
@passed_count = 0
|
11
13
|
@failed_count = 0
|
14
|
+
@skipped_count = 0
|
15
|
+
@todo_count = 0
|
12
16
|
@file_count = 0
|
13
17
|
end
|
14
18
|
|
@@ -16,26 +20,49 @@ module Easytest
|
|
16
20
|
cases_by_file = cases.group_by { |c| c.file }
|
17
21
|
cases_by_file.each do |file, cases|
|
18
22
|
self.file_count += 1
|
23
|
+
|
19
24
|
reports = []
|
20
25
|
|
21
26
|
cases.each do |c|
|
22
|
-
|
27
|
+
result, report = c.run
|
23
28
|
|
24
|
-
|
29
|
+
case result
|
30
|
+
when :passed
|
25
31
|
self.passed_count += 1
|
26
|
-
|
32
|
+
when :failed
|
27
33
|
self.failed_count += 1
|
28
|
-
|
34
|
+
when :skipped
|
35
|
+
self.skipped_count += 1
|
36
|
+
when :todo
|
37
|
+
self.todo_count += 1
|
38
|
+
else
|
39
|
+
raise "Unknown result: #{result.inspect}"
|
29
40
|
end
|
41
|
+
|
42
|
+
reports << [result, report] if report
|
30
43
|
end
|
31
44
|
|
32
45
|
link = Utils.terminal_hyperlink(file)
|
33
|
-
|
46
|
+
|
47
|
+
if reports.none? { |result, _| result == :failed }
|
34
48
|
puts "#{Rainbow(" PASS ").bright.bg(:green)} #{link}"
|
35
49
|
else
|
36
50
|
puts "#{Rainbow(" FAIL ").bright.bg(:red)} #{link}"
|
37
|
-
reports.each { |report| puts report ; puts "" }
|
38
51
|
end
|
52
|
+
|
53
|
+
reports
|
54
|
+
.sort_by do |result, _|
|
55
|
+
case result
|
56
|
+
when :skipped, :todo
|
57
|
+
0
|
58
|
+
else
|
59
|
+
1
|
60
|
+
end
|
61
|
+
end
|
62
|
+
.each do |result, report|
|
63
|
+
puts report.gsub(/^/, " ").gsub(/^\s+$/, "")
|
64
|
+
puts "" if result == :failed
|
65
|
+
end
|
39
66
|
end
|
40
67
|
|
41
68
|
if no_tests?
|
@@ -65,7 +92,7 @@ module Easytest
|
|
65
92
|
private
|
66
93
|
|
67
94
|
def total_count
|
68
|
-
passed_count + failed_count
|
95
|
+
passed_count + failed_count + skipped_count + todo_count
|
69
96
|
end
|
70
97
|
|
71
98
|
def all_passed?
|
@@ -81,16 +108,24 @@ module Easytest
|
|
81
108
|
end
|
82
109
|
|
83
110
|
def summary
|
84
|
-
|
111
|
+
list = []
|
85
112
|
|
86
|
-
if failed_count
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
113
|
+
if failed_count > 0
|
114
|
+
list << Rainbow("#{failed_count} failed").red.bright
|
115
|
+
end
|
116
|
+
|
117
|
+
if skipped_count > 0
|
118
|
+
list << Rainbow("#{skipped_count} skipped").yellow.bright
|
91
119
|
end
|
92
120
|
|
93
|
-
|
121
|
+
if todo_count > 0
|
122
|
+
list << Rainbow("#{todo_count} todo").magenta.bright
|
123
|
+
end
|
124
|
+
|
125
|
+
list << Rainbow("#{passed_count} passed").green.bright
|
126
|
+
list << "#{total_count} total #{Rainbow("(#{file_count} files)").dimgray}"
|
127
|
+
|
128
|
+
list.join(", ")
|
94
129
|
end
|
95
130
|
end
|
96
131
|
end
|
data/lib/easytest/version.rb
CHANGED
data/lib/easytest.rb
CHANGED
@@ -17,6 +17,7 @@ require_relative "easytest/matcher/be"
|
|
17
17
|
require_relative "easytest/matcher/be_a"
|
18
18
|
require_relative "easytest/matcher/equal"
|
19
19
|
require_relative "easytest/matcher/false"
|
20
|
+
require_relative "easytest/matcher/include"
|
20
21
|
require_relative "easytest/matcher/instance_of"
|
21
22
|
require_relative "easytest/matcher/kind_of"
|
22
23
|
require_relative "easytest/matcher/nil"
|
data/sig/easytest.rbs
CHANGED
@@ -21,12 +21,19 @@ module Easytest
|
|
21
21
|
def to_be_false: () -> void
|
22
22
|
def to_be_true: () -> void
|
23
23
|
|
24
|
+
def to_include: (untyped expected) -> void
|
25
|
+
|
24
26
|
def to_raise: ((Class | String | Regexp) expected) -> void
|
25
27
|
def to_not_raise: () -> void
|
26
28
|
end
|
27
29
|
end
|
28
30
|
|
29
31
|
module Kernel
|
32
|
+
# TODO: Can we avoid `RBS::DuplicatedMethodDefinitionError` "::Kernel#test has duplicated definitions"?
|
33
|
+
# def test: (String name) ?{ () -> void } -> void
|
34
|
+
|
35
|
+
def skip: (String name) { () -> void } -> void
|
36
|
+
|
30
37
|
def expect: (untyped actual) -> Easytest::Expectation
|
31
38
|
| { () -> void } -> Easytest::Expectation
|
32
39
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: easytest
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Masafumi Koba
|
@@ -47,6 +47,7 @@ files:
|
|
47
47
|
- lib/easytest/matcher/be_a.rb
|
48
48
|
- lib/easytest/matcher/equal.rb
|
49
49
|
- lib/easytest/matcher/false.rb
|
50
|
+
- lib/easytest/matcher/include.rb
|
50
51
|
- lib/easytest/matcher/instance_of.rb
|
51
52
|
- lib/easytest/matcher/kind_of.rb
|
52
53
|
- lib/easytest/matcher/nil.rb
|