easytest 0.7.0 → 0.8.1

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: 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