easytest 0.6.0 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b604c00c58f93e811ba779e0581b57b8eed7df6ef57504bea9239083663af42c
4
- data.tar.gz: 8912feb299336ea7e242d1f7349fca2cb089af40f751f6c4478c535594eb6269
3
+ metadata.gz: 1a0b3705ffc7039bfb7ac442d22bce3abf4f6cbb4a100b2f88a637b658d462e3
4
+ data.tar.gz: f578262b1621be8e67811a048c3ce0b6c1fb592a82c482a0a945d7b97e221f0c
5
5
  SHA512:
6
- metadata.gz: 0f423c20fe3812b906a37498275cd46c5fe5ac9996b8296f0c3ae7e8889d8a73f643310a82d2e2ffbaee48c393f5a94debe3c2e20b71c1d0710fe1f16491009c
7
- data.tar.gz: 267b8496e9faea80de95d311bb5d1abb48959499b9765ff37cf588e600950f6a8a5e20b13a21af90818180ad8509d5d7ca74cd1962dc3b3e5eb0fe541f43e8f5
6
+ metadata.gz: fe5a6d95407ebccecd912cc2ef7624f449e304662004db4b361be58ccd0ec0a758ed380c8af5efc6632a1172e7acac8e6361274274fa33d6daa0a835e592affb
7
+ data.tar.gz: 406ab02728e1d3b58fa18bae5122f5af0691a72c8aaa5568b4d3d572d750419aaea8af9e2b18b15ab03aa24097b75370d1c16bd5bc220af5956820fb399ada3d
data/CHANGELOG.md CHANGED
@@ -2,6 +2,17 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
+ ## 0.8.0
6
+
7
+ - Add `before` and `after` hooks.
8
+ - Add `to_have_attributes` matcher.
9
+ - Add `to_satisfy` matcher.
10
+
11
+ ## 0.7.0
12
+
13
+ - Add `to_be_empty` matcher.
14
+ - Avoid unstable `Enumerable#sort_by` method.
15
+
5
16
  ## 0.6.0
6
17
 
7
18
  - Add `to_contain_exactly` matcher.
data/README.md CHANGED
@@ -77,6 +77,24 @@ $ easytest
77
77
 
78
78
  The test now passes! 🎉
79
79
 
80
+ ### Hooks
81
+
82
+ You can add hooks called `before` and `after` to each test case:
83
+
84
+ ```ruby
85
+ before do
86
+ # set up something...
87
+ end
88
+
89
+ after do
90
+ # clean up something...
91
+ end
92
+
93
+ test "something" do
94
+ # test something...
95
+ end
96
+ ```
97
+
80
98
  ### Skip
81
99
 
82
100
  If you want to skip any cases, you can change `test` to `skip`:
data/lib/easytest/case.rb CHANGED
@@ -9,9 +9,9 @@ module Easytest
9
9
  alias skipped? skipped
10
10
  alias only? only
11
11
 
12
- def initialize(name:, file:, skipped: false, only: false, &block)
12
+ def initialize(name:, skipped: false, only: false, &block)
13
13
  @name = name
14
- @file = file
14
+ @file = caller_locations(3, 1).first.absolute_path
15
15
  @block = block
16
16
  @skipped = skipped
17
17
  @only = only
data/lib/easytest/dsl.rb CHANGED
@@ -3,23 +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, &block)
7
+ end
8
+
9
+ def before(&block)
10
+ Easytest.add_hook Hook.new(type: :before, &block)
11
+ end
6
12
 
7
- file = caller_locations(1, 1).first.absolute_path
8
- Easytest.add_case Case.new(name: name, file: file, &block)
13
+ def after(&block)
14
+ Easytest.add_hook Hook.new(type: :after, &block)
9
15
  end
10
16
 
11
17
  def skip(name, &block)
12
18
  Utils.raise_if_no_test_name(name, method: "skip")
13
-
14
- file = caller_locations(1, 1).first.absolute_path
15
- Easytest.add_case Case.new(name: name, file: file, skipped: true, &block)
19
+ Easytest.add_case Case.new(name: name, skipped: true, &block)
16
20
  end
17
21
 
18
22
  def only(name, &block)
19
23
  Utils.raise_if_no_test_name(name, method: "only")
20
-
21
- file = caller_locations(1, 1).first.absolute_path
22
- Easytest.add_case Case.new(name: name, file: file, only: true, &block)
24
+ Easytest.add_case Case.new(name: name, only: true, &block)
23
25
  end
24
26
 
25
27
  def expect(actual = nil, &block)
@@ -14,15 +14,15 @@ module Easytest
14
14
  end
15
15
 
16
16
  def to_be_nil
17
- Matcher::Nil.new(actual: actual, negate: negate).match!
17
+ Matcher::Nil.new(actual: actual, expected: nil, negate: negate).match!
18
18
  end
19
19
 
20
20
  def to_be_true
21
- Matcher::True.new(actual: actual, negate: negate).match!
21
+ Matcher::True.new(actual: actual, expected: true, negate: negate).match!
22
22
  end
23
23
 
24
24
  def to_be_false
25
- Matcher::False.new(actual: actual, negate: negate).match!
25
+ Matcher::False.new(actual: actual, expected: false, negate: negate).match!
26
26
  end
27
27
 
28
28
  def to_be_a(expected)
@@ -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_be_empty
41
+ Matcher::Empty.new(actual: actual, expected: nil, negate: negate).match!
42
+ end
43
+
40
44
  def to_include(expected)
41
45
  Matcher::Include.new(actual: actual, expected: expected, negate: negate).match!
42
46
  end
@@ -45,8 +49,16 @@ module Easytest
45
49
  Matcher::Match.new(actual: actual, expected: expected, negate: negate).match!
46
50
  end
47
51
 
48
- def to_contain_exactly(*expected_items)
49
- Matcher::ContainExactly.new(actual: actual, expected: expected_items, negate: negate).match!
52
+ def to_contain_exactly(*expected)
53
+ Matcher::ContainExactly.new(actual: actual, expected: expected, negate: negate).match!
54
+ end
55
+
56
+ def to_have_attributes(**expected)
57
+ Matcher::HaveAttributes.new(actual: actual, expected: expected, negate: negate).match!
58
+ end
59
+
60
+ def to_satisfy(&expected)
61
+ Matcher::Satisfy.new(actual: actual, expected: expected, negate: negate).match!
50
62
  end
51
63
 
52
64
  def to_raise(expected, with_message = nil)
@@ -0,0 +1,27 @@
1
+ module Easytest
2
+ class Hook
3
+ attr_reader :file
4
+ attr_reader :type
5
+ attr_reader :block
6
+
7
+ def initialize(type:, &block)
8
+ raise ArgumentError, "" unless [:before, :after].include?(type)
9
+
10
+ @file = caller_locations(3, 1).first.absolute_path
11
+ @type = type
12
+ @block = block
13
+ end
14
+
15
+ def run(test_case)
16
+ block.call(test_case)
17
+ end
18
+
19
+ def before?
20
+ type == :before
21
+ end
22
+
23
+ def after?
24
+ type == :after
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,13 @@
1
+ module Easytest
2
+ module Matcher
3
+ class Empty < Base
4
+ def match?
5
+ actual.empty?
6
+ end
7
+
8
+ def message
9
+ "empty"
10
+ end
11
+ end
12
+ end
13
+ end
@@ -1,10 +1,6 @@
1
1
  module Easytest
2
2
  module Matcher
3
3
  class False < Base
4
- def initialize(actual:, negate:)
5
- super(actual: actual, expected: false, negate: negate)
6
- end
7
-
8
4
  def match?
9
5
  actual == expected
10
6
  end
@@ -0,0 +1,15 @@
1
+ module Easytest
2
+ module Matcher
3
+ class HaveAttributes < Base
4
+ def match?
5
+ expected.all? do |name, value|
6
+ actual.send(name) == value
7
+ end
8
+ end
9
+
10
+ def message
11
+ "have attributes"
12
+ end
13
+ end
14
+ end
15
+ end
@@ -1,10 +1,6 @@
1
1
  module Easytest
2
2
  module Matcher
3
3
  class Nil < Base
4
- def initialize(actual:, negate:)
5
- super(actual: actual, expected: nil, negate: negate)
6
- end
7
-
8
4
  def match?
9
5
  actual.nil?
10
6
  end
@@ -0,0 +1,13 @@
1
+ module Easytest
2
+ module Matcher
3
+ class Satisfy < Base
4
+ def match?
5
+ expected.call(actual) == true
6
+ end
7
+
8
+ def message
9
+ "satisfy"
10
+ end
11
+ end
12
+ end
13
+ end
@@ -1,10 +1,6 @@
1
1
  module Easytest
2
2
  module Matcher
3
3
  class True < Base
4
- def initialize(actual:, negate:)
5
- super(actual: actual, expected: true, negate: negate)
6
- end
7
-
8
4
  def match?
9
5
  actual == expected
10
6
  end
@@ -18,19 +18,28 @@ module Easytest
18
18
 
19
19
  def run
20
20
  include_only_case = cases.any?(&:only?)
21
+ hooks_by_file = hooks.group_by(&:file)
21
22
 
22
23
  cases.group_by(&:file).each do |file, cases_per_file|
23
24
  self.file_count += 1
24
25
 
25
- reports = []
26
+ hooks = hooks_by_file.fetch(file, [])
27
+ before_hooks = hooks.filter(&:before?)
28
+ after_hooks = hooks.filter(&:after?)
26
29
 
30
+ reports = []
27
31
 
28
32
  cases_per_file.each do |c|
29
33
  if include_only_case && !c.only?
30
34
  c.skip!
31
35
  end
32
36
 
33
- result, report = c.run
37
+ begin
38
+ before_hooks.each { |hook| hook.run(c) }
39
+ result, report = c.run
40
+ ensure
41
+ after_hooks.each { |hook| hook.run(c) }
42
+ end
34
43
 
35
44
  case result
36
45
  when :passed
@@ -56,19 +65,7 @@ module Easytest
56
65
  puts "#{Rainbow(" FAIL ").bright.bg(:red)} #{link}"
57
66
  end
58
67
 
59
- reports
60
- .sort_by do |result, _|
61
- case result
62
- when :skipped, :todo
63
- 0
64
- else
65
- 1
66
- end
67
- end
68
- .each do |result, report|
69
- puts report.gsub(/^/, " ").gsub(/^\s+$/, "")
70
- puts "" if result == :failed
71
- end
68
+ print_reports(reports)
72
69
  end
73
70
 
74
71
  if no_tests?
@@ -95,6 +92,14 @@ module Easytest
95
92
  cases << new_case
96
93
  end
97
94
 
95
+ def hooks
96
+ @hooks ||= []
97
+ end
98
+
99
+ def add_hook(hook)
100
+ hooks << hook
101
+ end
102
+
98
103
  private
99
104
 
100
105
  def total_count
@@ -109,6 +114,20 @@ module Easytest
109
114
  total_count == 0
110
115
  end
111
116
 
117
+ def print_reports(reports)
118
+ unexecuted = [:skipped, :todo]
119
+ indent = " "
120
+
121
+ reports.each do |result, report|
122
+ puts Utils.indent_text(report, indent) if unexecuted.include?(result)
123
+ end
124
+
125
+ reports.each do |result, report|
126
+ puts Utils.indent_text(report, indent) unless unexecuted.include?(result)
127
+ puts "" if result == :failed
128
+ end
129
+ end
130
+
112
131
  def elapsed_time
113
132
  Time.now - start_time
114
133
  end
@@ -20,5 +20,9 @@ module Easytest
20
20
  def pluralize(singular, count)
21
21
  count == 1 ? singular : "#{singular}s"
22
22
  end
23
+
24
+ def indent_text(text, indent_string)
25
+ text.gsub(/^(.+)/, "#{indent_string}\\1")
26
+ end
23
27
  end
24
28
  end
@@ -1,3 +1,3 @@
1
1
  module Easytest
2
- VERSION = "0.6.0"
2
+ VERSION = "0.8.0"
3
3
  end
data/lib/easytest.rb CHANGED
@@ -7,6 +7,7 @@ require_relative "easytest/case"
7
7
  require_relative "easytest/dsl"
8
8
  require_relative "easytest/errors"
9
9
  require_relative "easytest/expectation"
10
+ require_relative "easytest/hook"
10
11
  require_relative "easytest/reporter"
11
12
  require_relative "easytest/runner"
12
13
  require_relative "easytest/utils"
@@ -16,8 +17,10 @@ require_relative "easytest/matcher/base"
16
17
  require_relative "easytest/matcher/be"
17
18
  require_relative "easytest/matcher/be_a"
18
19
  require_relative "easytest/matcher/contain_exactly"
20
+ require_relative "easytest/matcher/empty"
19
21
  require_relative "easytest/matcher/equal"
20
22
  require_relative "easytest/matcher/false"
23
+ require_relative "easytest/matcher/have_attributes"
21
24
  require_relative "easytest/matcher/include"
22
25
  require_relative "easytest/matcher/instance_of"
23
26
  require_relative "easytest/matcher/kind_of"
@@ -25,6 +28,7 @@ require_relative "easytest/matcher/match"
25
28
  require_relative "easytest/matcher/nil"
26
29
  require_relative "easytest/matcher/raise"
27
30
  require_relative "easytest/matcher/raise_nothing"
31
+ require_relative "easytest/matcher/satisfy"
28
32
  require_relative "easytest/matcher/true"
29
33
 
30
34
  module Easytest
@@ -33,7 +37,11 @@ module Easytest
33
37
  end
34
38
 
35
39
  def self.add_case(new_case)
36
- @runner.cases << new_case
40
+ @runner.add_case(new_case)
41
+ end
42
+
43
+ def self.add_hook(hook)
44
+ @runner.add_hook(hook)
37
45
  end
38
46
 
39
47
  def self.run
data/sig/easytest.rbs CHANGED
@@ -1,4 +1,4 @@
1
- # A easy testing framework.
1
+ # An easy testing framework.
2
2
  module Easytest
3
3
  # The Easytest version.
4
4
  VERSION: String
@@ -7,7 +7,7 @@ module Easytest
7
7
  module DSL
8
8
  end
9
9
 
10
- # Define methods for the Easytest DSL.
10
+ # An expectation in test cases.
11
11
  class Expectation
12
12
  # Negate an expectation.
13
13
  def not: () -> instance
@@ -37,6 +37,9 @@ module Easytest
37
37
  # Expect to be an instance of the given class (module).
38
38
  def to_be_instance_of: (Module expected) -> void
39
39
 
40
+ # Expect to be empty.
41
+ def to_be_empty: () -> void
42
+
40
43
  # Expect to include the given object.
41
44
  def to_include: (untyped expected) -> void
42
45
 
@@ -44,7 +47,13 @@ module Easytest
44
47
  def to_match: (untyped expected) -> void
45
48
 
46
49
  # Expect to contain all the given items regardless of order.
47
- def to_contain_exactly: (*untyped expected_items) -> void
50
+ def to_contain_exactly: (*untyped expected) -> void
51
+
52
+ # Expect to have the given attributes.
53
+ def to_have_attributes: (**untyped expected) -> void
54
+
55
+ # Expect to satisfy a condition that the given block returns `true`.
56
+ def to_satisfy: () { (untyped actual) -> bool } -> void
48
57
 
49
58
  # Expect to raise the given exception or an exception with the given message.
50
59
  def to_raise: (Class expected, ?(String | Regexp) with_message) -> void
@@ -53,12 +62,24 @@ module Easytest
53
62
  # Expect to raise nothing.
54
63
  def to_raise_nothing: () -> void
55
64
  end
65
+
66
+ # A test case.
67
+ class Case
68
+ # Return a test case name.
69
+ def name: () -> String
70
+ end
56
71
  end
57
72
 
58
73
  module Kernel
59
74
  # TODO: Can we avoid `RBS::DuplicatedMethodDefinitionError` "::Kernel#test has duplicated definitions"?
60
75
  # def test: (String name) ?{ () -> void } -> void
61
76
 
77
+ # Run the given block before each test case.
78
+ def before: () { (Easytest::Case case) -> void } -> void
79
+
80
+ # Run the given block after each test case.
81
+ def after: () { (Easytest::Case case) -> void } -> void
82
+
62
83
  # Skip the given test case.
63
84
  def skip: (String name) { () -> void } -> void
64
85
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: easytest
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.8.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-07 00:00:00.000000000 Z
11
+ date: 2022-10-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rainbow
@@ -42,12 +42,15 @@ files:
42
42
  - lib/easytest/dsl.rb
43
43
  - lib/easytest/errors.rb
44
44
  - lib/easytest/expectation.rb
45
+ - lib/easytest/hook.rb
45
46
  - lib/easytest/matcher/base.rb
46
47
  - lib/easytest/matcher/be.rb
47
48
  - lib/easytest/matcher/be_a.rb
48
49
  - lib/easytest/matcher/contain_exactly.rb
50
+ - lib/easytest/matcher/empty.rb
49
51
  - lib/easytest/matcher/equal.rb
50
52
  - lib/easytest/matcher/false.rb
53
+ - lib/easytest/matcher/have_attributes.rb
51
54
  - lib/easytest/matcher/include.rb
52
55
  - lib/easytest/matcher/instance_of.rb
53
56
  - lib/easytest/matcher/kind_of.rb
@@ -55,6 +58,7 @@ files:
55
58
  - lib/easytest/matcher/nil.rb
56
59
  - lib/easytest/matcher/raise.rb
57
60
  - lib/easytest/matcher/raise_nothing.rb
61
+ - lib/easytest/matcher/satisfy.rb
58
62
  - lib/easytest/matcher/true.rb
59
63
  - lib/easytest/reporter.rb
60
64
  - lib/easytest/runner.rb