smartest 0.1.0 → 0.2.0.alpha2

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.
@@ -2,12 +2,45 @@
2
2
 
3
3
  module Smartest
4
4
  class Suite
5
- attr_reader :tests, :fixture_classes, :matcher_modules
5
+ attr_reader :tests, :fixture_classes, :matcher_modules, :around_suite_hooks, :around_test_hooks
6
6
 
7
7
  def initialize
8
8
  @tests = TestRegistry.new
9
9
  @fixture_classes = FixtureClassRegistry.new
10
10
  @matcher_modules = MatcherRegistry.new
11
+ @around_suite_hooks = []
12
+ @around_test_hooks = []
13
+ @around_test_hooks_by_file = Hash.new { |hash, path| hash[path] = [] }
14
+ @around_suite_hook_depth = 0
15
+ end
16
+
17
+ def add_around_test_hook(location, hook)
18
+ if running_around_suite_hook?
19
+ @around_test_hooks << hook
20
+ else
21
+ @around_test_hooks_by_file[path_for(location)] << hook
22
+ end
23
+ end
24
+
25
+ def around_test_hooks_for(location)
26
+ @around_test_hooks_by_file[path_for(location)].dup
27
+ end
28
+
29
+ def around_suite_hook
30
+ @around_suite_hook_depth += 1
31
+ yield
32
+ ensure
33
+ @around_suite_hook_depth -= 1
34
+ end
35
+
36
+ private
37
+
38
+ def running_around_suite_hook?
39
+ @around_suite_hook_depth.positive?
40
+ end
41
+
42
+ def path_for(location)
43
+ File.expand_path(location.absolute_path || location.path)
11
44
  end
12
45
  end
13
46
  end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Smartest
4
+ class SuiteRun
5
+ attr_reader :result
6
+
7
+ def initialize(&block)
8
+ @block = block
9
+ @ran = false
10
+ @result = nil
11
+ end
12
+
13
+ def run
14
+ raise AroundSuiteRunError, "around_suite hook called suite.run more than once" if ran?
15
+
16
+ @ran = true
17
+ @result = @block.call
18
+ end
19
+
20
+ def ran?
21
+ @ran
22
+ end
23
+ end
24
+ end
@@ -2,9 +2,9 @@
2
2
 
3
3
  module Smartest
4
4
  class TestCase
5
- attr_reader :name, :metadata, :block, :location, :fixture_names
5
+ attr_reader :name, :metadata, :block, :location, :fixture_names, :around_test_hooks
6
6
 
7
- def initialize(name:, metadata:, block:, location:)
7
+ def initialize(name:, metadata:, block:, location:, around_test_hooks: [])
8
8
  raise ArgumentError, "test name is required" if name.nil? || name.to_s.empty?
9
9
  raise ArgumentError, "test block is required" unless block
10
10
 
@@ -12,6 +12,7 @@ module Smartest
12
12
  @metadata = metadata
13
13
  @block = block
14
14
  @location = location
15
+ @around_test_hooks = around_test_hooks.dup.freeze
15
16
  @fixture_names = ParameterExtractor.required_keyword_names(block, usage: :test)
16
17
  end
17
18
 
@@ -2,13 +2,14 @@
2
2
 
3
3
  module Smartest
4
4
  class TestResult
5
- attr_reader :test_case, :status, :error, :duration, :cleanup_errors
5
+ attr_reader :test_case, :status, :error, :duration, :cleanup_errors, :reason
6
6
 
7
7
  def self.passed(test_case:, duration:, cleanup_errors: [])
8
8
  new(
9
9
  test_case: test_case,
10
10
  status: :passed,
11
11
  error: nil,
12
+ reason: nil,
12
13
  duration: duration,
13
14
  cleanup_errors: cleanup_errors
14
15
  )
@@ -19,15 +20,39 @@ module Smartest
19
20
  test_case: test_case,
20
21
  status: :failed,
21
22
  error: error,
23
+ reason: nil,
22
24
  duration: duration,
23
25
  cleanup_errors: cleanup_errors
24
26
  )
25
27
  end
26
28
 
27
- def initialize(test_case:, status:, error:, duration:, cleanup_errors:)
29
+ def self.skipped(test_case:, reason:, duration:, cleanup_errors: [])
30
+ new(
31
+ test_case: test_case,
32
+ status: :skipped,
33
+ error: nil,
34
+ reason: reason,
35
+ duration: duration,
36
+ cleanup_errors: cleanup_errors
37
+ )
38
+ end
39
+
40
+ def self.pending(test_case:, reason:, duration:, cleanup_errors: [])
41
+ new(
42
+ test_case: test_case,
43
+ status: :pending,
44
+ error: nil,
45
+ reason: reason,
46
+ duration: duration,
47
+ cleanup_errors: cleanup_errors
48
+ )
49
+ end
50
+
51
+ def initialize(test_case:, status:, error:, reason:, duration:, cleanup_errors:)
28
52
  @test_case = test_case
29
53
  @status = status
30
54
  @error = error
55
+ @reason = reason
31
56
  @duration = duration
32
57
  @cleanup_errors = cleanup_errors
33
58
  end
@@ -39,5 +64,13 @@ module Smartest
39
64
  def failed?
40
65
  status == :failed
41
66
  end
67
+
68
+ def skipped?
69
+ status == :skipped
70
+ end
71
+
72
+ def pending?
73
+ status == :pending
74
+ end
42
75
  end
43
76
  end
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Smartest
4
+ class TestRun
5
+ attr_reader :result
6
+
7
+ def initialize(fixture_classes:, matcher_modules:, &block)
8
+ @fixture_classes = FixtureClassRegistry.new
9
+ fixture_classes.each { |fixture_class| @fixture_classes.add(fixture_class) }
10
+
11
+ @matcher_modules = MatcherRegistry.new
12
+ matcher_modules.each { |matcher_module| @matcher_modules.add(matcher_module) }
13
+
14
+ @block = block
15
+ @ran = false
16
+ @result = nil
17
+ end
18
+
19
+ def run
20
+ raise AroundTestRunError, "around_test hook called test.run more than once" if ran?
21
+
22
+ @ran = true
23
+ @result = @block.call(
24
+ fixture_classes: @fixture_classes,
25
+ matcher_modules: @matcher_modules
26
+ )
27
+ end
28
+
29
+ def ran?
30
+ @ran
31
+ end
32
+
33
+ def add_fixture_class(klass)
34
+ raise AroundTestRunError, "use_fixture must be called before test.run" if ran?
35
+
36
+ reject_suite_fixture_class!(klass)
37
+ @fixture_classes.add(klass)
38
+ end
39
+
40
+ def add_matcher_module(matcher_module)
41
+ raise AroundTestRunError, "use_matcher must be called before test.run" if ran?
42
+
43
+ @matcher_modules.add(matcher_module)
44
+ end
45
+
46
+ private
47
+
48
+ def reject_suite_fixture_class!(klass)
49
+ return unless klass.is_a?(Class) && klass <= Fixture
50
+
51
+ suite_fixture_names = klass.fixture_definitions.each_value.filter_map do |definition|
52
+ definition.name if definition.scope == :suite
53
+ end
54
+
55
+ raise AroundTestFixtureScopeError.new(klass, suite_fixture_names) if suite_fixture_names.any?
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Smartest
4
+ class TestRunState
5
+ attr_reader :pending_reason
6
+
7
+ def pending(reason = nil)
8
+ @pending_reason = StatusReason.normalize(reason)
9
+ nil
10
+ end
11
+
12
+ def pending?
13
+ !@pending_reason.nil?
14
+ end
15
+ end
16
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Smartest
4
- VERSION = "0.1.0"
4
+ VERSION = "0.2.0.alpha2"
5
5
  end
data/lib/smartest.rb CHANGED
@@ -11,6 +11,10 @@ require_relative "smartest/fixture_class_registry"
11
11
  require_relative "smartest/matcher_registry"
12
12
  require_relative "smartest/fixture_set"
13
13
  require_relative "smartest/suite"
14
+ require_relative "smartest/suite_run"
15
+ require_relative "smartest/test_run_state"
16
+ require_relative "smartest/test_run"
17
+ require_relative "smartest/hook_contexts"
14
18
  require_relative "smartest/expectations"
15
19
  require_relative "smartest/expectation_target"
16
20
  require_relative "smartest/matchers"