easytest 0.6.0 → 0.8.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 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