easytest 0.7.0 → 0.8.1

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: 5f45ff0adb716aa609a9fce9fd5eaefab60b8d56e4b2708a26b56d63189c3b78
4
- data.tar.gz: 93b56e1770e0cd3a7d233580eddbd72737e56de4c5ebe405f244c6ca300f1ab9
3
+ metadata.gz: baf1f087a7353d74e8aa021313fd2f00c161af6cf5deb96552a5283e368f947f
4
+ data.tar.gz: 9ccc8f17a4911d3bc77abdd3916e4344e2965047ffe7d47d6794d88e6d8dd754
5
5
  SHA512:
6
- metadata.gz: 14fe72a70136f6aeca4f044bee8c4616d6b3ac8ee32f43bb46b1c888dd70823e73574204c32a91dd48b5df73233e217adfc9b19d6a05c2181a4df2974a4cdb1b
7
- data.tar.gz: 90bd1e9e0c2e30905e1c2b4875c29fdc93b861da2ae26cd3df8441bdd5b5bb973b27a9830fe9c5597593ca398362ebeb2b26e96dcb65d0f4a93c1ae76a56e7ac
6
+ metadata.gz: 7d907a3edc843501e6d20b408f358ca5cb0ec19b57a6ee7760577bbceff1fa078635209f439c0b5424ee72e2141c4a54ba51a8bb54c6a823406b55fd21246bd3
7
+ data.tar.gz: 7c01539bb3762b24f27f5483e86837a05844b8495c6bb9450557d610e978a9011e8c9012c39bb8c7288d7fd6296b9257583298e8c2255cf74492d271b9b83012
data/CHANGELOG.md CHANGED
@@ -2,6 +2,16 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
+ ## 0.8.1
6
+
7
+ - Improve type-checking.
8
+
9
+ ## 0.8.0
10
+
11
+ - Add `before` and `after` hooks.
12
+ - Add `to_have_attributes` matcher.
13
+ - Add `to_satisfy` matcher.
14
+
5
15
  ## 0.7.0
6
16
 
7
17
  - Add `to_be_empty` 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,24 +9,20 @@ 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 or raise)
15
15
  @block = block
16
16
  @skipped = skipped
17
17
  @only = only
18
18
  end
19
19
 
20
- def todo?
21
- block.nil?
22
- end
23
-
24
20
  def skip!
25
21
  @skipped = true
26
22
  end
27
23
 
28
24
  def run
29
- return [:todo, Reporter.new(name).report_todo] if todo?
25
+ return [:todo, Reporter.new(name).report_todo] unless block
30
26
  return [:skipped, Reporter.new(name).report_skip] if skipped?
31
27
 
32
28
  block.call
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)
@@ -49,8 +49,16 @@ module Easytest
49
49
  Matcher::Match.new(actual: actual, expected: expected, negate: negate).match!
50
50
  end
51
51
 
52
- def to_contain_exactly(*expected_items)
53
- 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!
54
62
  end
55
63
 
56
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 or raise)
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
@@ -22,6 +22,8 @@ module Easytest
22
22
  raise_match_error unless matched
23
23
  end
24
24
 
25
+ private
26
+
25
27
  def message
26
28
  raise NotImplementedError
27
29
  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
@@ -3,9 +3,9 @@ module Easytest
3
3
  class Raise < Base
4
4
  attr_reader :with_message
5
5
 
6
- def initialize(**kwargs)
7
- @with_message = kwargs.delete(:with_message)
8
- super(**kwargs)
6
+ def initialize(actual:, expected:, negate:, with_message:)
7
+ super(actual: actual, expected: expected, negate: negate)
8
+ @with_message = with_message
9
9
  end
10
10
 
11
11
  def match?
@@ -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
@@ -51,14 +51,15 @@ module Easytest
51
51
  end
52
52
 
53
53
  def find_location(error)
54
- location = error.backtrace_locations.find do |loc|
55
- loc.path.end_with?("_test.rb")
54
+ location = error.backtrace_locations&.find do |loc|
55
+ loc.path&.end_with?("_test.rb")
56
56
  end
57
57
  location or raise "Not found test location from #{error.inspect}"
58
58
  end
59
59
 
60
60
  def format_location(location)
61
- path = Pathname(location.absolute_path).relative_path_from(Dir.pwd)
61
+ absolute_path = location.absolute_path or raise
62
+ path = Pathname(absolute_path).relative_path_from(Dir.pwd)
62
63
  "# #{path}:#{location.lineno}:in `#{location.label}'"
63
64
  end
64
65
  end
@@ -18,10 +18,15 @@ 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
 
26
+ hooks = hooks_by_file.fetch(file, [])
27
+ before_hooks = hooks.filter(&:before?)
28
+ after_hooks = hooks.filter(&:after?)
29
+
25
30
  reports = []
26
31
 
27
32
  cases_per_file.each do |c|
@@ -29,7 +34,12 @@ module Easytest
29
34
  c.skip!
30
35
  end
31
36
 
32
- 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
33
43
 
34
44
  case result
35
45
  when :passed
@@ -82,6 +92,14 @@ module Easytest
82
92
  cases << new_case
83
93
  end
84
94
 
95
+ def hooks
96
+ @hooks ||= []
97
+ end
98
+
99
+ def add_hook(hook)
100
+ hooks << hook
101
+ end
102
+
85
103
  private
86
104
 
87
105
  def total_count
@@ -1,3 +1,3 @@
1
1
  module Easytest
2
- VERSION = "0.7.0"
2
+ VERSION = "0.8.1"
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"
@@ -19,6 +20,7 @@ require_relative "easytest/matcher/contain_exactly"
19
20
  require_relative "easytest/matcher/empty"
20
21
  require_relative "easytest/matcher/equal"
21
22
  require_relative "easytest/matcher/false"
23
+ require_relative "easytest/matcher/have_attributes"
22
24
  require_relative "easytest/matcher/include"
23
25
  require_relative "easytest/matcher/instance_of"
24
26
  require_relative "easytest/matcher/kind_of"
@@ -26,6 +28,7 @@ require_relative "easytest/matcher/match"
26
28
  require_relative "easytest/matcher/nil"
27
29
  require_relative "easytest/matcher/raise"
28
30
  require_relative "easytest/matcher/raise_nothing"
31
+ require_relative "easytest/matcher/satisfy"
29
32
  require_relative "easytest/matcher/true"
30
33
 
31
34
  module Easytest
@@ -34,7 +37,11 @@ module Easytest
34
37
  end
35
38
 
36
39
  def self.add_case(new_case)
37
- @runner.cases << new_case
40
+ @runner.add_case(new_case)
41
+ end
42
+
43
+ def self.add_hook(hook)
44
+ @runner.add_hook(hook)
38
45
  end
39
46
 
40
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,10 +7,10 @@ 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
- # Negate an expectation.
13
- def not: () -> instance
12
+ # Negate this expectation.
13
+ def not: () -> Expectation
14
14
 
15
15
  # Expect to equal the given object.
16
16
  def to_eq: (untyped expected) -> void
@@ -47,21 +47,39 @@ module Easytest
47
47
  def to_match: (untyped expected) -> void
48
48
 
49
49
  # Expect to contain all the given items regardless of order.
50
- 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
51
57
 
52
58
  # Expect to raise the given exception or an exception with the given message.
53
- def to_raise: (Class expected, ?(String | Regexp) with_message) -> void
59
+ def to_raise: (Class expected, ?(String | Regexp)? with_message) -> void
54
60
  | ((String | Regexp) expected) -> void
55
61
 
56
62
  # Expect to raise nothing.
57
63
  def to_raise_nothing: () -> void
58
64
  end
65
+
66
+ # A test case.
67
+ class Case
68
+ # A test case name.
69
+ attr_reader name: String
70
+ end
59
71
  end
60
72
 
61
73
  module Kernel
62
74
  # TODO: Can we avoid `RBS::DuplicatedMethodDefinitionError` "::Kernel#test has duplicated definitions"?
63
75
  # def test: (String name) ?{ () -> void } -> void
64
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
+
65
83
  # Skip the given test case.
66
84
  def skip: (String name) { () -> void } -> void
67
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.7.0
4
+ version: 0.8.1
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 00:00:00.000000000 Z
11
+ date: 2022-10-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rainbow
@@ -42,6 +42,7 @@ 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
@@ -49,6 +50,7 @@ files:
49
50
  - lib/easytest/matcher/empty.rb
50
51
  - lib/easytest/matcher/equal.rb
51
52
  - lib/easytest/matcher/false.rb
53
+ - lib/easytest/matcher/have_attributes.rb
52
54
  - lib/easytest/matcher/include.rb
53
55
  - lib/easytest/matcher/instance_of.rb
54
56
  - lib/easytest/matcher/kind_of.rb
@@ -56,6 +58,7 @@ files:
56
58
  - lib/easytest/matcher/nil.rb
57
59
  - lib/easytest/matcher/raise.rb
58
60
  - lib/easytest/matcher/raise_nothing.rb
61
+ - lib/easytest/matcher/satisfy.rb
59
62
  - lib/easytest/matcher/true.rb
60
63
  - lib/easytest/reporter.rb
61
64
  - lib/easytest/runner.rb