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.
- checksums.yaml +7 -0
- data/.gitignore +3 -0
- data/.rubocop.yml +24 -0
- data/.solargraph.yml +22 -0
- data/CHANGELOG.md +7 -0
- data/Gemfile +9 -0
- data/Gemfile.lock +79 -0
- data/LICENSE +373 -0
- data/README.md +88 -0
- data/Rakefile +10 -0
- data/bin/cake +34 -0
- data/bin/collector.rb +90 -0
- data/bin/runner.rb +133 -0
- data/bin/settings.rb +36 -0
- data/cake-tester.gemspec +18 -0
- data/lib/cake.rb +6 -0
- data/lib/contextual/child.rb +20 -0
- data/lib/contextual/context.rb +32 -0
- data/lib/contextual/group.rb +45 -0
- data/lib/contextual/node.rb +80 -0
- data/lib/contextual/parent.rb +191 -0
- data/lib/contextual/test.rb +151 -0
- data/lib/contextual/test_runner.rb +71 -0
- data/lib/expect.rb +154 -0
- data/lib/helpers/filter_settings.rb +94 -0
- data/lib/helpers/printer.rb +146 -0
- data/lib/test_failure.rb +54 -0
- data/lib/test_message.rb +23 -0
- data/lib/test_neutral.rb +31 -0
- data/lib/test_options.rb +25 -0
- data/lib/test_pass.rb +23 -0
- data/lib/test_result.rb +70 -0
- data/test/test_basic.cake.rb +12 -0
- data/test/test_context.cake.rb +102 -0
- data/test/test_expects.cake.rb +48 -0
- data/test/test_failures.cake.rb +46 -0
- data/test/test_group.cake.rb +20 -0
- data/test/test_runner.cake.rb +20 -0
- data/test/test_skip.cake.rb +37 -0
- metadata +83 -0
data/lib/test_neutral.rb
ADDED
@@ -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
|
data/lib/test_options.rb
ADDED
@@ -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
|
data/lib/test_result.rb
ADDED
@@ -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,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: []
|