cake-tester 0.2.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.
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'test_result'
4
+
5
+ class TestNeutral < TestResult
6
+
7
+ def initialize(title, message = nil)
8
+ super(title)
9
+ @message = message
10
+ end
11
+
12
+ def report(spacer_count = 0)
13
+ super
14
+ if @message.nil?
15
+ Printer.neutral("#{@spacer}(-) #{@title}")
16
+ else
17
+ Printer.neutral("#{@spacer} #{@title}: #{@message}")
18
+ end
19
+ end
20
+
21
+ def neutrals
22
+ 1
23
+ end
24
+ end
25
+
26
+ class AssertNeutral < AssertResult
27
+ def report(spacer_count)
28
+ super
29
+ Printer.neutral(@spacer + format_message)
30
+ end
31
+ end
@@ -0,0 +1,25 @@
1
+ # TestOptions
2
+ #
3
+ # @param fail_on_first_expect, default value will be set to true
4
+ #
5
+ class TestOptions
6
+ def fail_on_first_expect
7
+ return true if @fail_on_first_expect.nil?
8
+
9
+ @fail_on_first_expect
10
+ end
11
+
12
+ # @param fail_on_first_expect [Boolean]
13
+ def initialize(fail_on_first_expect: nil)
14
+ @fail_on_first_expect = fail_on_first_expect
15
+ end
16
+
17
+ # Maps options from parent onto this instance. If childy already has a setting,
18
+ # it will not be overwritten.
19
+ # @param parent [TestOptions]
20
+ def map_from_parent(parent)
21
+ return if parent.nil?
22
+
23
+ @fail_on_first_expect = @fail_on_first_expect.nil? ? parent.fail_on_first_expect : @fail_on_first_expect
24
+ end
25
+ end
data/lib/test_pass.rb ADDED
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'test_result'
4
+
5
+ # A successful test result
6
+ class TestPass < TestResult
7
+ def report(spacer_count = 0)
8
+ super
9
+
10
+ Printer.pass("#{@spacer}(O) #{@title}")
11
+ end
12
+
13
+ def successes
14
+ 1
15
+ end
16
+ end
17
+
18
+ # A successful assertion result
19
+ class AssertPass < AssertResult
20
+ def initialize
21
+ super(nil)
22
+ end
23
+ end
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Contains the base class for all test and assertion results
4
+ module Result
5
+ def successes
6
+ 0
7
+ end
8
+
9
+ def failures
10
+ 0
11
+ end
12
+
13
+ def neutrals
14
+ 0
15
+ end
16
+
17
+ private
18
+
19
+ def generate_spacer(spacer_count)
20
+ @spacer = ''
21
+ return if spacer_count.zero?
22
+
23
+ (0..(spacer_count - 1)).each do |i|
24
+ @spacer += if i < (spacer_count - 1)
25
+ ' '
26
+ else
27
+ ' `-'
28
+ end
29
+ end
30
+ end
31
+ end
32
+
33
+ # @abstract Contains the base class for all test results
34
+ class TestResult
35
+ include Result
36
+
37
+ def initialize(title)
38
+ @title = title
39
+ end
40
+
41
+ def report(spacer_count = 0)
42
+ generate_spacer(spacer_count)
43
+ end
44
+ end
45
+
46
+ # @abstract Contains the base class for all assertion results
47
+ class AssertResult
48
+ include Result
49
+ attr_writer :index
50
+
51
+ def initialize(message, index)
52
+ @message = message
53
+ @index = index
54
+ end
55
+
56
+ def report(spacer_count = 0)
57
+ generate_spacer(spacer_count)
58
+ end
59
+
60
+ private
61
+
62
+ def format_message
63
+ # Asserts will always be indented, thus the 4 spaces
64
+ if @index.nil?
65
+ " #{@message}"
66
+ else
67
+ " [##{@index}] #{@message}"
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../lib/cake'
4
+
5
+ TestRunner.new('Test Runner - Basic', [
6
+ Group.new('Group Basic', [
7
+ Test.new(
8
+ 'True should be true',
9
+ assertions: proc { [Expect::IsTrue.new(true)] }
10
+ )
11
+ ])
12
+ ])
@@ -0,0 +1,102 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../lib/cake'
4
+
5
+ teardown_counter = 0
6
+
7
+ TestRunner.new('Test Runner - Context', [
8
+ Test.new(
9
+ 'Action should set "actual"',
10
+ action: ->(_test) { true },
11
+ assertions: ->(test) { [Expect::IsTrue.new(test.actual)] }
12
+ ),
13
+ Test.new(
14
+ 'Action can set "actual" and "expected"',
15
+ action: ->(test) {
16
+ value = 'foo'
17
+ test.actual = value
18
+ test.expected = value
19
+ },
20
+ assertions: ->(test) { [Expect::Equals.new(actual: test.actual, expected: test.expected)] }
21
+ ),
22
+ Test.new(
23
+ 'Other variables can be declared in context',
24
+ action: ->(test) {
25
+ test.foo = 'bar'
26
+ },
27
+ assertions: ->(test) {
28
+ [Expect::Equals.new(
29
+ actual: test.foo,
30
+ expected: 'bar'
31
+ )]
32
+ }
33
+ ),
34
+ Test.new(
35
+ 'Siblings should not affect each other',
36
+ assertions: ->(test) {
37
+ [Expect::IsNil.new(test.foo)]
38
+ }
39
+ ),
40
+ Test.new(
41
+ 'Values can be set in setup',
42
+ setup: ->(test) {
43
+ test.actual = true
44
+ test.expected = true
45
+ test.foo = 'bar'
46
+ },
47
+ assertions:
48
+ ->(test) {
49
+ [
50
+ Expect::Equals.new(actual: test.foo, expected: 'bar'),
51
+ Expect::Equals.new(actual: test.actual, expected: test.expected)
52
+ ]
53
+ }
54
+ ),
55
+ Test.new(
56
+ 'Values can be modified in teardown',
57
+ setup: ->(_test) {
58
+ teardown_counter += 1
59
+ },
60
+ assertions: ->(_test) {
61
+ [
62
+ Expect::IsTrue.new(teardown_counter.positive?)
63
+ ]
64
+ },
65
+ teardown: ->(_test) {
66
+ teardown_counter = 0
67
+ }
68
+ ),
69
+ Test.new(
70
+ 'Teardown reset value',
71
+ assertions: ->(_test) {
72
+ [
73
+ Expect::IsTrue.new(teardown_counter.zero?)
74
+ ]
75
+ }
76
+ ),
77
+ Group.new('Groups can assign context', [
78
+ Test.new(
79
+ 'Group can pass context to children',
80
+ assertions: ->(test) { [Expect::Equals.new(actual: test.foo, expected: 'bar')] }
81
+ ),
82
+ Test.new(
83
+ 'Children can override parent context',
84
+ action: ->(test) { test.foo = 'baz' },
85
+ assertions: ->(test) { [Expect::Equals.new(actual: test.foo, expected: 'baz')] }
86
+ )
87
+ ], setup: ->(test) {
88
+ test.foo = 'bar'
89
+ }),
90
+ Group.new('Groups can modify values in teardown after children have run', [
91
+ Test.new(
92
+ 'Teardown counter should be 1',
93
+ assertions: proc { [Expect::Equals.new(actual: teardown_counter, expected: 1)] }
94
+ )
95
+ ],
96
+ setup: proc { teardown_counter += 1 },
97
+ teardown: proc { teardown_counter = 0 }),
98
+ Test.new(
99
+ 'Teardown reset value',
100
+ assertions: proc { [Expect::Equals.new(actual: teardown_counter, expected: 0)] }
101
+ )
102
+ ])
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../lib/cake'
4
+
5
+ TestRunner.new('Simple Test with no groups', [
6
+ Test.new(
7
+ 'True is true - assertion',
8
+ assertions: proc {
9
+ [Expect::IsTrue.new(true)]
10
+ }
11
+ ),
12
+ Test.new(
13
+ 'Equals, true is equal to true',
14
+ assertions: proc {
15
+ [Expect::Equals.new(actual: true, expected: true)]
16
+ }
17
+ ),
18
+ Test.new(
19
+ 'IsNotEqual, true is not equal to false',
20
+ assertions: proc {
21
+ [Expect::IsNotEqual.new(actual: true, not_expected: false)]
22
+ }
23
+ ),
24
+ Test.new(
25
+ 'IsNil, nil is nil',
26
+ assertions: proc {
27
+ [Expect::IsNil.new(nil)]
28
+ }
29
+ ),
30
+ Test.new(
31
+ 'IsNotNil, true is not nil',
32
+ assertions: proc {
33
+ [Expect::IsNotNil.new(true)]
34
+ }
35
+ ),
36
+ Test.new('RespondTo, true responds to is_a?',
37
+ assertions: proc {
38
+ [Expect::RespondTo.new(true, :is_a?)]
39
+ }),
40
+ Test.new('Undefined, true does not respond to foo',
41
+ assertions: proc {
42
+ [Expect::Undefined.new(true, :foo)]
43
+ }),
44
+ Test.new('DoesNotRepondTo, is a synonym for Undefined',
45
+ assertions: proc {
46
+ [Expect::DoesNotRespondTo.new(true, :foo)]
47
+ })
48
+ ])
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../lib/cake'
4
+
5
+ TestRunner.new('All of these should fail in various ways', [
6
+ Test.new('Should report multiple failures',
7
+ assertions: proc {
8
+ [
9
+ Expect::Equals.new(actual: true, expected: false),
10
+ # This line is meant to pass
11
+ Expect::IsTrue.new(true),
12
+ Expect::IsFalse.new(true),
13
+ Expect::IsTrue.new(false)
14
+ ]
15
+ },
16
+ options: TestOptions.new(fail_on_first_expect: false)),
17
+ Test.new('Should report only one failure by default',
18
+ assertions: proc {
19
+ [
20
+ Expect::Equals.new(actual: true, expected: false),
21
+ # This line is meant to pass
22
+ Expect::IsTrue.new(true),
23
+ # This is a failure, but shouldn't be run
24
+ Expect::IsFalse.new(true),
25
+ # This is also a failure, and shouldn't be run
26
+ Expect::IsTrue.new(false)
27
+ ]
28
+ }),
29
+ Test.new('Should report only one failure if fail_on_first_expect is true',
30
+ assertions: proc {
31
+ [
32
+ Expect::Equals.new(actual: true, expected: false),
33
+ # This line is meant to pass
34
+ Expect::IsTrue.new(true),
35
+ # This is a failure, but shouldn't be run
36
+ Expect::IsFalse.new(true),
37
+ # This is also a failure, and shouldn't be run
38
+ Expect::IsTrue.new(false)
39
+ ]
40
+ },
41
+ options: TestOptions.new(fail_on_first_expect: true)),
42
+ Group.new('Groups should report as failed when at least one test has failed', [
43
+ Test.new('This test should fail', assertions: proc { [Expect::IsTrue.new(false)] }),
44
+ Test.new('This test should pass', assertions: proc { [Expect::IsTrue.new(true)] })
45
+ ])
46
+ ])
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../lib/cake'
4
+
5
+ TestRunner.new('Test Groups', [
6
+ Group.new('Should run all children tests', [
7
+ Test.new(
8
+ 'True should be true',
9
+ assertions: proc { [Expect::IsTrue.new(true)] }
10
+ ),
11
+ Test.new('False should be false',
12
+ assertions: proc { [Expect::IsFalse.new(false)] })
13
+ ]),
14
+ Group.new('Nested Group - Parent', [
15
+ Group.new('Nested Group - Child', [
16
+ Test.new('Nested test should pass',
17
+ assertions: proc { [Expect::IsTrue.new(true)] })
18
+ ])
19
+ ])
20
+ ])
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../lib/cake'
4
+
5
+ TestRunner.new('Test Runner Cake Test', [
6
+ Group.new('Runs a group', [
7
+ Test.new(
8
+ 'Test in group runs',
9
+ assertions: proc { [Expect::IsTrue.new(true)] }
10
+ )
11
+ ]),
12
+ Group.new('Runs a nested group, parent', [
13
+ Group.new('Runs a nested group, child', [
14
+ Test.new('Test in a nested group runs',
15
+ assertions: proc { [Expect::IsTrue.new(true)] })
16
+ ])
17
+ ]),
18
+ Test.new('Individual test runs',
19
+ assertions: proc { [Expect::IsTrue.new(true)] })
20
+ ])
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../lib/cake'
4
+
5
+ TestRunner.new('Test Runner can skip', skip: true)
6
+ TestRunner.new(
7
+ 'Test Runner with children can skip', [
8
+ Group.new('This group should be skipped', [
9
+ Test.new('This test should be skipped', assertions: proc {
10
+ [Expect::IsTrue.new(true)]
11
+ })
12
+ ]),
13
+ Test.new('This test should be skipped', assertions: proc {
14
+ [Expect::IsTrue.new(true)]
15
+ })
16
+ ],
17
+ skip: true
18
+ )
19
+
20
+ TestRunner.new('Test Runner - Children marked skipped should skip', [
21
+ Group.new('Group - Group marked as skip should be skipped', [
22
+ Test.new('Children of skipped group should also be skipped', assertions: proc {
23
+ [Expect::IsTrue.new(true)]
24
+ })
25
+ ], skip: true),
26
+ Group.new('Group - Siblings not marked as skipped should not be skipped', [
27
+ Test.new('This test should not be skipped', assertions: proc {
28
+ [Expect::IsTrue.new(true)]
29
+ })
30
+ ]),
31
+ Test.new('Test - Tests marked as skip should be skipped', assertions: proc {
32
+ [Expect::IsTrue.new(true)]
33
+ }, skip: true),
34
+ Test.new('Test - Siblings of skipped test should not be skipped', assertions: proc {
35
+ [Expect::IsTrue.new(true)]
36
+ })
37
+ ])
metadata ADDED
@@ -0,0 +1,83 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cake-tester
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ platform: ruby
6
+ authors:
7
+ - Polyhedra
8
+ - C. Lee Spruit
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2023-12-11 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: ''
15
+ email:
16
+ executables:
17
+ - cake
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - ".gitignore"
22
+ - ".rubocop.yml"
23
+ - ".solargraph.yml"
24
+ - CHANGELOG.md
25
+ - Gemfile
26
+ - Gemfile.lock
27
+ - LICENSE
28
+ - README.md
29
+ - Rakefile
30
+ - bin/cake
31
+ - bin/collector.rb
32
+ - bin/runner.rb
33
+ - bin/settings.rb
34
+ - cake-tester.gemspec
35
+ - lib/cake.rb
36
+ - lib/contextual/child.rb
37
+ - lib/contextual/context.rb
38
+ - lib/contextual/group.rb
39
+ - lib/contextual/node.rb
40
+ - lib/contextual/parent.rb
41
+ - lib/contextual/test.rb
42
+ - lib/contextual/test_runner.rb
43
+ - lib/expect.rb
44
+ - lib/helpers/filter_settings.rb
45
+ - lib/helpers/printer.rb
46
+ - lib/test_failure.rb
47
+ - lib/test_message.rb
48
+ - lib/test_neutral.rb
49
+ - lib/test_options.rb
50
+ - lib/test_pass.rb
51
+ - lib/test_result.rb
52
+ - test/test_basic.cake.rb
53
+ - test/test_context.cake.rb
54
+ - test/test_expects.cake.rb
55
+ - test/test_failures.cake.rb
56
+ - test/test_group.cake.rb
57
+ - test/test_runner.cake.rb
58
+ - test/test_skip.cake.rb
59
+ homepage: https://github.com/Polyhedra-Studio/Cake-Ruby
60
+ licenses:
61
+ - MPL-2.0
62
+ metadata:
63
+ rubygems_mfa_required: 'true'
64
+ post_install_message:
65
+ rdoc_options: []
66
+ require_paths:
67
+ - lib
68
+ required_ruby_version: !ruby/object:Gem::Requirement
69
+ requirements:
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ version: 2.7.0
73
+ required_rubygems_version: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ requirements: []
79
+ rubygems_version: 3.4.10
80
+ signing_key:
81
+ specification_version: 4
82
+ summary: The lightweight, explicit testing framework for Ruby.
83
+ test_files: []