easytest 0.8.1 → 0.9.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 +11 -1
- data/lib/easytest/case.rb +1 -1
- data/lib/easytest/cli.rb +75 -26
- data/lib/easytest/dsl.rb +5 -5
- data/lib/easytest/hook.rb +1 -1
- data/lib/easytest/matcher/contain_exactly.rb +1 -1
- data/lib/easytest/runner.rb +39 -28
- data/lib/easytest/version.rb +1 -1
- data/lib/easytest.rb +7 -3
- metadata +16 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9a953eabbcc6eb08f30507561d26309fd305983f9f6be7f0c2e2e1a1ce3410b5
|
4
|
+
data.tar.gz: 86ae0173c242a2069944836dcf48795960f29af50f3bb62c41aae2f079cc86df
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: aeabfbd63843ff8edb06d2929f65c20c6a748da8f85f2d60b67dc87b7e446776cb76f524ae6ca48aae0601846a9f4da48b1d961f71f32b502697cff9a98e09e5
|
7
|
+
data.tar.gz: 87f634738fa05e63a1ac0e544965b15b72b6e66b44eccf806102894318f042eb286890cf1c559815c6681f958ec499e06fcbddae2fdee989c76430a7ff6460c2
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -27,7 +27,7 @@ You can read more about Easytest on the [official website](https://ybiquitous.gi
|
|
27
27
|
|
28
28
|
## Usage
|
29
29
|
|
30
|
-
|
30
|
+
This section explains easy usage.
|
31
31
|
|
32
32
|
First, put `test/addition_test.rb` as below:
|
33
33
|
|
@@ -126,3 +126,13 @@ test "addition"
|
|
126
126
|
```
|
127
127
|
|
128
128
|
To-do cases will be reported as "todo".
|
129
|
+
|
130
|
+
### Watch
|
131
|
+
|
132
|
+
If you want to run tests immediately when changing code, specify the `--watch` option:
|
133
|
+
|
134
|
+
```console
|
135
|
+
$ easytest --watch
|
136
|
+
```
|
137
|
+
|
138
|
+
This *watch* mode is useful during development.
|
data/lib/easytest/case.rb
CHANGED
@@ -9,7 +9,7 @@ module Easytest
|
|
9
9
|
alias skipped? skipped
|
10
10
|
alias only? only
|
11
11
|
|
12
|
-
def initialize(name:, skipped: false, only: false,
|
12
|
+
def initialize(name:, skipped: false, only: false, block: nil)
|
13
13
|
@name = name
|
14
14
|
@file = (caller_locations(3, 1)&.first&.absolute_path or raise)
|
15
15
|
@block = block
|
data/lib/easytest/cli.rb
CHANGED
@@ -8,9 +8,14 @@ module Easytest
|
|
8
8
|
FATAL = 2
|
9
9
|
|
10
10
|
def run
|
11
|
-
exit_code =
|
11
|
+
exit_code = parse_argv
|
12
12
|
return exit_code if exit_code
|
13
13
|
|
14
|
+
if watch?
|
15
|
+
watch_files
|
16
|
+
return SUCCESS
|
17
|
+
end
|
18
|
+
|
14
19
|
Easytest.start
|
15
20
|
setup
|
16
21
|
successful = Easytest.run
|
@@ -21,33 +26,41 @@ module Easytest
|
|
21
26
|
|
22
27
|
attr_reader :argv
|
23
28
|
attr_reader :start_time
|
29
|
+
attr_reader :options
|
30
|
+
attr_reader :parser
|
24
31
|
|
25
32
|
def initialize(argv)
|
26
33
|
@argv = argv
|
27
34
|
@start_time = Time.now
|
35
|
+
@options = {}
|
36
|
+
@parser = init_parser
|
28
37
|
end
|
29
38
|
|
30
|
-
def
|
31
|
-
|
39
|
+
def init_parser
|
40
|
+
OptionParser.new do |op|
|
41
|
+
op.program_name = "easytest"
|
42
|
+
op.version = "#{op.program_name} #{Easytest::VERSION}"
|
32
43
|
|
33
|
-
|
34
|
-
|
35
|
-
|
44
|
+
op.on "-w", "--watch" do
|
45
|
+
options[:watch] = true
|
46
|
+
end
|
36
47
|
|
37
|
-
|
48
|
+
op.on "--help" do
|
38
49
|
options[:help] = true
|
39
50
|
end
|
40
51
|
|
41
|
-
|
52
|
+
op.on "--version" do
|
42
53
|
options[:version] = true
|
43
54
|
end
|
44
55
|
end
|
56
|
+
end
|
45
57
|
|
58
|
+
def parse_argv
|
46
59
|
begin
|
47
60
|
parser.parse!(argv)
|
48
61
|
|
49
62
|
if options[:help]
|
50
|
-
puts help
|
63
|
+
puts help
|
51
64
|
return SUCCESS
|
52
65
|
end
|
53
66
|
|
@@ -63,37 +76,73 @@ module Easytest
|
|
63
76
|
end
|
64
77
|
end
|
65
78
|
|
66
|
-
def help
|
79
|
+
def help
|
80
|
+
program = Rainbow(parser.program_name).green
|
81
|
+
heading = ->(text) { Rainbow(text).bright }
|
82
|
+
secondary = ->(text) { Rainbow(text).dimgray }
|
83
|
+
option = ->(text) { Rainbow(text).yellow }
|
84
|
+
prompt = ->() { Rainbow("$").cyan }
|
85
|
+
|
67
86
|
<<~MSG
|
68
|
-
#{
|
69
|
-
#{
|
87
|
+
#{heading["USAGE"]}
|
88
|
+
#{program} [options] [<file, directory, or pattern>...]
|
70
89
|
|
71
|
-
#{
|
72
|
-
--
|
73
|
-
--
|
90
|
+
#{heading["OPTIONS"]}
|
91
|
+
#{option["-w, --watch"]} Watch file changes and rerun test
|
92
|
+
#{option["--help"]} Show help
|
93
|
+
#{option["--version"]} Show version
|
74
94
|
|
75
|
-
#{
|
76
|
-
# Run all tests (test/**/*_test.rb)
|
77
|
-
|
95
|
+
#{heading["EXAMPLES"]}
|
96
|
+
#{secondary["# Run all tests (test/**/*_test.rb)"]}
|
97
|
+
#{prompt[]} #{program}
|
78
98
|
|
79
|
-
# Run only test files
|
80
|
-
|
99
|
+
#{secondary["# Run only test files"]}
|
100
|
+
#{prompt[]} #{program} test/example_test.rb
|
81
101
|
|
82
|
-
# Run only test files in
|
83
|
-
|
102
|
+
#{secondary["# Run only test files in given directories"]}
|
103
|
+
#{prompt[]} #{program} test/example
|
84
104
|
|
85
|
-
# Run only test files that matches
|
86
|
-
|
105
|
+
#{secondary["# Run only test files that matches given patterns"]}
|
106
|
+
#{prompt[]} #{program} example
|
87
107
|
MSG
|
88
108
|
end
|
89
109
|
|
90
110
|
def setup
|
91
|
-
|
92
|
-
.map { |file| File.absolute_path(file) }
|
111
|
+
test_files
|
93
112
|
.filter do |file|
|
94
113
|
argv.empty? || argv.any? { |pattern| file.include?(pattern) }
|
95
114
|
end
|
96
115
|
.each { |test_file| load test_file }
|
97
116
|
end
|
117
|
+
|
118
|
+
def test_files
|
119
|
+
Dir.glob(Easytest.test_files_location).map do |file|
|
120
|
+
File.absolute_path(file)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
def watch?
|
125
|
+
options[:watch] == true
|
126
|
+
end
|
127
|
+
|
128
|
+
def watch_files
|
129
|
+
require "listen"
|
130
|
+
listener = Listen.to(Easytest.test_dir, only: /_test\.rb$/) do |modified, added|
|
131
|
+
Easytest.start(no_tests_forbidden: false)
|
132
|
+
test_files.intersection(modified + added).each do |file|
|
133
|
+
load(file)
|
134
|
+
end
|
135
|
+
Easytest.run
|
136
|
+
end
|
137
|
+
listener.start
|
138
|
+
|
139
|
+
begin
|
140
|
+
puts "Start watching \"#{Easytest.test_files_location}\" changed. Press Ctrl-C to stop."
|
141
|
+
sleep
|
142
|
+
rescue Interrupt
|
143
|
+
puts
|
144
|
+
puts "Stopped watching."
|
145
|
+
end
|
146
|
+
end
|
98
147
|
end
|
99
148
|
end
|
data/lib/easytest/dsl.rb
CHANGED
@@ -3,25 +3,25 @@ module Easytest
|
|
3
3
|
refine Kernel do
|
4
4
|
def test(name, &block)
|
5
5
|
Utils.raise_if_no_test_name(name, method: "test")
|
6
|
-
Easytest.add_case Case.new(name: name,
|
6
|
+
Easytest.add_case Case.new(name: name, block: block)
|
7
7
|
end
|
8
8
|
|
9
9
|
def before(&block)
|
10
|
-
Easytest.add_hook Hook.new(type: :before,
|
10
|
+
Easytest.add_hook Hook.new(type: :before, block: block)
|
11
11
|
end
|
12
12
|
|
13
13
|
def after(&block)
|
14
|
-
Easytest.add_hook Hook.new(type: :after,
|
14
|
+
Easytest.add_hook Hook.new(type: :after, block: block)
|
15
15
|
end
|
16
16
|
|
17
17
|
def skip(name, &block)
|
18
18
|
Utils.raise_if_no_test_name(name, method: "skip")
|
19
|
-
Easytest.add_case Case.new(name: name, skipped: true,
|
19
|
+
Easytest.add_case Case.new(name: name, skipped: true, block: block)
|
20
20
|
end
|
21
21
|
|
22
22
|
def only(name, &block)
|
23
23
|
Utils.raise_if_no_test_name(name, method: "only")
|
24
|
-
Easytest.add_case Case.new(name: name, only: true,
|
24
|
+
Easytest.add_case Case.new(name: name, only: true, block: block)
|
25
25
|
end
|
26
26
|
|
27
27
|
def expect(actual = nil, &block)
|
data/lib/easytest/hook.rb
CHANGED
data/lib/easytest/runner.rb
CHANGED
@@ -1,21 +1,5 @@
|
|
1
1
|
module Easytest
|
2
2
|
class Runner
|
3
|
-
attr_reader :start_time
|
4
|
-
attr_accessor :passed_count
|
5
|
-
attr_accessor :failed_count
|
6
|
-
attr_accessor :skipped_count
|
7
|
-
attr_accessor :todo_count
|
8
|
-
attr_accessor :file_count
|
9
|
-
|
10
|
-
def initialize(start_time: Time.now)
|
11
|
-
@start_time = start_time
|
12
|
-
@passed_count = 0
|
13
|
-
@failed_count = 0
|
14
|
-
@skipped_count = 0
|
15
|
-
@todo_count = 0
|
16
|
-
@file_count = 0
|
17
|
-
end
|
18
|
-
|
19
3
|
def run
|
20
4
|
include_only_case = cases.any?(&:only?)
|
21
5
|
hooks_by_file = hooks.group_by(&:file)
|
@@ -27,6 +11,7 @@ module Easytest
|
|
27
11
|
before_hooks = hooks.filter(&:before?)
|
28
12
|
after_hooks = hooks.filter(&:after?)
|
29
13
|
|
14
|
+
# @type var reports: Array[[Symbol, String]]
|
30
15
|
reports = []
|
31
16
|
|
32
17
|
cases_per_file.each do |c|
|
@@ -34,12 +19,13 @@ module Easytest
|
|
34
19
|
c.skip!
|
35
20
|
end
|
36
21
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
22
|
+
result, report =
|
23
|
+
begin
|
24
|
+
before_hooks.each { |hook| hook.run(c) }
|
25
|
+
c.run
|
26
|
+
ensure
|
27
|
+
after_hooks.each { |hook| hook.run(c) }
|
28
|
+
end
|
43
29
|
|
44
30
|
case result
|
45
31
|
when :passed
|
@@ -69,12 +55,7 @@ module Easytest
|
|
69
55
|
end
|
70
56
|
|
71
57
|
if no_tests?
|
72
|
-
|
73
|
-
#{Rainbow("Oops. No tests found!").red.bright}
|
74
|
-
|
75
|
-
#{Rainbow("Put `#{Easytest.test_files_location}` files to include at least one test case.").red}
|
76
|
-
#{Rainbow("Or specify a pattern that matches an existing test file.").red}
|
77
|
-
MSG
|
58
|
+
print_error_for_no_tests if no_tests_forbidden?
|
78
59
|
false
|
79
60
|
else
|
80
61
|
puts ""
|
@@ -102,6 +83,26 @@ module Easytest
|
|
102
83
|
|
103
84
|
private
|
104
85
|
|
86
|
+
attr_reader :start_time
|
87
|
+
attr_reader :no_tests_forbidden
|
88
|
+
alias no_tests_forbidden? no_tests_forbidden
|
89
|
+
|
90
|
+
attr_accessor :passed_count
|
91
|
+
attr_accessor :failed_count
|
92
|
+
attr_accessor :skipped_count
|
93
|
+
attr_accessor :todo_count
|
94
|
+
attr_accessor :file_count
|
95
|
+
|
96
|
+
def initialize(start_time: Time.now, no_tests_forbidden: true)
|
97
|
+
@start_time = start_time
|
98
|
+
@no_tests_forbidden = no_tests_forbidden
|
99
|
+
@passed_count = 0
|
100
|
+
@failed_count = 0
|
101
|
+
@skipped_count = 0
|
102
|
+
@todo_count = 0
|
103
|
+
@file_count = 0
|
104
|
+
end
|
105
|
+
|
105
106
|
def total_count
|
106
107
|
passed_count + failed_count + skipped_count + todo_count
|
107
108
|
end
|
@@ -114,6 +115,15 @@ module Easytest
|
|
114
115
|
total_count == 0
|
115
116
|
end
|
116
117
|
|
118
|
+
def print_error_for_no_tests
|
119
|
+
$stderr.puts <<~MSG
|
120
|
+
#{Rainbow("Oops. No tests found!").red.bright}
|
121
|
+
|
122
|
+
#{Rainbow("Put `#{Easytest.test_files_location}` files to include at least one test case.").red}
|
123
|
+
#{Rainbow("Or specify a pattern that matches an existing test file.").red}
|
124
|
+
MSG
|
125
|
+
end
|
126
|
+
|
117
127
|
def print_reports(reports)
|
118
128
|
unexecuted = [:skipped, :todo]
|
119
129
|
indent = " "
|
@@ -133,6 +143,7 @@ module Easytest
|
|
133
143
|
end
|
134
144
|
|
135
145
|
def summary
|
146
|
+
# @type var list: Array[String]
|
136
147
|
list = []
|
137
148
|
|
138
149
|
if failed_count > 0
|
data/lib/easytest/version.rb
CHANGED
data/lib/easytest.rb
CHANGED
@@ -32,8 +32,8 @@ require_relative "easytest/matcher/satisfy"
|
|
32
32
|
require_relative "easytest/matcher/true"
|
33
33
|
|
34
34
|
module Easytest
|
35
|
-
def self.start
|
36
|
-
@runner = Runner.new
|
35
|
+
def self.start(no_tests_forbidden: true)
|
36
|
+
@runner = Runner.new(no_tests_forbidden: no_tests_forbidden)
|
37
37
|
end
|
38
38
|
|
39
39
|
def self.add_case(new_case)
|
@@ -48,7 +48,11 @@ module Easytest
|
|
48
48
|
@runner.run
|
49
49
|
end
|
50
50
|
|
51
|
+
def self.test_dir
|
52
|
+
"test"
|
53
|
+
end
|
54
|
+
|
51
55
|
def self.test_files_location
|
52
|
-
"
|
56
|
+
"#{test_dir}/**/*_test.rb"
|
53
57
|
end
|
54
58
|
end
|
metadata
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: easytest
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.9.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Masafumi Koba
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-10-
|
11
|
+
date: 2022-10-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: listen
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '3.7'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '3.7'
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: rainbow
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|