sus 0.33.1 → 0.35.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 +4 -4
- checksums.yaml.gz.sig +0 -0
- data/context/{usage.md → getting-started.md} +58 -37
- data/context/index.yaml +22 -0
- data/context/mocking.md +100 -30
- data/context/{shared.md → shared-contexts.md} +29 -2
- data/lib/sus/assertions.rb +93 -20
- data/lib/sus/base.rb +13 -1
- data/lib/sus/be.rb +84 -0
- data/lib/sus/be_truthy.rb +16 -0
- data/lib/sus/be_within.rb +25 -0
- data/lib/sus/clock.rb +21 -0
- data/lib/sus/config.rb +59 -2
- data/lib/sus/context.rb +28 -5
- data/lib/sus/describe.rb +14 -0
- data/lib/sus/expect.rb +23 -0
- data/lib/sus/file.rb +38 -0
- data/lib/sus/filter.rb +21 -0
- data/lib/sus/fixtures/temporary_directory_context.rb +27 -0
- data/lib/sus/fixtures.rb +1 -0
- data/lib/sus/have/all.rb +8 -0
- data/lib/sus/have/any.rb +8 -0
- data/lib/sus/have.rb +42 -0
- data/lib/sus/have_duration.rb +16 -0
- data/lib/sus/identity.rb +44 -1
- data/lib/sus/integrations.rb +1 -0
- data/lib/sus/it.rb +33 -0
- data/lib/sus/it_behaves_like.rb +16 -0
- data/lib/sus/let.rb +3 -0
- data/lib/sus/mock.rb +53 -15
- data/lib/sus/output/backtrace.rb +31 -1
- data/lib/sus/output/bar.rb +17 -0
- data/lib/sus/output/buffered.rb +32 -1
- data/lib/sus/output/lines.rb +10 -0
- data/lib/sus/output/messages.rb +28 -5
- data/lib/sus/output/null.rb +18 -4
- data/lib/sus/output/progress.rb +29 -1
- data/lib/sus/output/status.rb +13 -0
- data/lib/sus/output/structured.rb +14 -1
- data/lib/sus/output/text.rb +33 -1
- data/lib/sus/output/xterm.rb +11 -1
- data/lib/sus/output.rb +9 -0
- data/lib/sus/raise_exception.rb +16 -0
- data/lib/sus/receive.rb +85 -3
- data/lib/sus/registry.rb +20 -1
- data/lib/sus/respond_to.rb +30 -3
- data/lib/sus/shared.rb +16 -0
- data/lib/sus/tree.rb +10 -0
- data/lib/sus/version.rb +2 -1
- data/lib/sus/with.rb +18 -0
- data/readme.md +12 -0
- data/releases.md +8 -0
- data.tar.gz.sig +0 -0
- metadata +6 -4
- metadata.gz.sig +0 -0
data/lib/sus/registry.rb
CHANGED
|
@@ -19,25 +19,34 @@ require_relative "include_context"
|
|
|
19
19
|
require_relative "let"
|
|
20
20
|
|
|
21
21
|
module Sus
|
|
22
|
+
# Represents a registry of test files and contexts.
|
|
22
23
|
class Registry
|
|
24
|
+
# The glob pattern used to find Ruby files in directories.
|
|
23
25
|
DIRECTORY_GLOB = "**/*.rb"
|
|
24
26
|
|
|
25
|
-
#
|
|
27
|
+
# Initialize a new registry.
|
|
28
|
+
# @parameter options [Hash] Options to pass to the base context.
|
|
26
29
|
def initialize(**options)
|
|
27
30
|
@base = Sus.base(self, **options)
|
|
28
31
|
@loaded = {}
|
|
29
32
|
end
|
|
30
33
|
|
|
34
|
+
# @attribute [Class] The base test context class.
|
|
31
35
|
attr :base
|
|
32
36
|
|
|
37
|
+
# Print a representation of this registry.
|
|
38
|
+
# @parameter output [Output] The output target.
|
|
33
39
|
def print(output)
|
|
34
40
|
output.write("Test Registry")
|
|
35
41
|
end
|
|
36
42
|
|
|
43
|
+
# @returns [String] A string representation of this registry.
|
|
37
44
|
def to_s
|
|
38
45
|
@base&.identity&.to_s || self.class.name
|
|
39
46
|
end
|
|
40
47
|
|
|
48
|
+
# Load a test file or directory.
|
|
49
|
+
# @parameter path [String] The path to load (file or directory).
|
|
41
50
|
def load(path)
|
|
42
51
|
if ::File.directory?(path)
|
|
43
52
|
load_directory(path)
|
|
@@ -46,24 +55,34 @@ module Sus
|
|
|
46
55
|
end
|
|
47
56
|
end
|
|
48
57
|
|
|
58
|
+
# Load a single test file.
|
|
59
|
+
# @parameter path [String] The path to the test file.
|
|
49
60
|
private def load_file(path)
|
|
50
61
|
@loaded[path] ||= @base.file(path)
|
|
51
62
|
end
|
|
52
63
|
|
|
64
|
+
# Load all Ruby files in a directory.
|
|
65
|
+
# @parameter path [String] The directory path.
|
|
53
66
|
private def load_directory(path)
|
|
54
67
|
::Dir.glob(::File.join(path, DIRECTORY_GLOB), &self.method(:load_file))
|
|
55
68
|
end
|
|
56
69
|
|
|
70
|
+
# Execute all tests in the registry.
|
|
71
|
+
# @parameter assertions [Assertions] Optional assertions instance to use.
|
|
72
|
+
# @returns [Assertions] The assertions instance with results.
|
|
57
73
|
def call(assertions = Assertions.default)
|
|
58
74
|
@base.call(assertions)
|
|
59
75
|
|
|
60
76
|
return assertions
|
|
61
77
|
end
|
|
62
78
|
|
|
79
|
+
# Iterate over all test cases in the registry.
|
|
80
|
+
# @yields {|test| ...} Each test case.
|
|
63
81
|
def each(...)
|
|
64
82
|
@base.each(...)
|
|
65
83
|
end
|
|
66
84
|
|
|
85
|
+
# @returns [Hash] The child contexts and tests.
|
|
67
86
|
def children
|
|
68
87
|
@base.children
|
|
69
88
|
end
|
data/lib/sus/respond_to.rb
CHANGED
|
@@ -1,16 +1,22 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
# Released under the MIT License.
|
|
4
|
-
# Copyright, 2022, by Samuel Williams.
|
|
4
|
+
# Copyright, 2022-2025, by Samuel Williams.
|
|
5
5
|
|
|
6
6
|
module Sus
|
|
7
|
+
# Represents a predicate that checks if an object responds to a method.
|
|
7
8
|
class RespondTo
|
|
9
|
+
# Represents a constraint on method parameters.
|
|
8
10
|
class WithParameters
|
|
9
|
-
#
|
|
11
|
+
# Initialize a new WithParameters constraint.
|
|
12
|
+
# @parameter parameters [Array(Symbol)] List of method parameters in the expected order, must include at least all required parameters but can also list optional parameters.
|
|
10
13
|
def initialize(parameters)
|
|
11
14
|
@parameters = parameters
|
|
12
15
|
end
|
|
13
16
|
|
|
17
|
+
# Evaluate this constraint against method parameters.
|
|
18
|
+
# @parameter assertions [Assertions] The assertions instance to use.
|
|
19
|
+
# @parameter subject [Array] The method parameters to check.
|
|
14
20
|
def call(assertions, subject)
|
|
15
21
|
parameters = @parameters.dup
|
|
16
22
|
|
|
@@ -32,15 +38,23 @@ module Sus
|
|
|
32
38
|
end
|
|
33
39
|
end
|
|
34
40
|
|
|
41
|
+
# Represents a constraint on method keyword options.
|
|
35
42
|
class WithOptions
|
|
43
|
+
# Initialize a new WithOptions constraint.
|
|
44
|
+
# @parameter options [Array(Symbol)] The option names that should be present.
|
|
36
45
|
def initialize(options)
|
|
37
46
|
@options = options
|
|
38
47
|
end
|
|
39
|
-
|
|
48
|
+
|
|
49
|
+
# Print a representation of this constraint.
|
|
50
|
+
# @parameter output [Output] The output target.
|
|
40
51
|
def print(output)
|
|
41
52
|
output.write("with options ", :variable, @options.inspect)
|
|
42
53
|
end
|
|
43
54
|
|
|
55
|
+
# Evaluate this constraint against method parameters.
|
|
56
|
+
# @parameter assertions [Assertions] The assertions instance to use.
|
|
57
|
+
# @parameter subject [Array] The method parameters to check.
|
|
44
58
|
def call(assertions, subject)
|
|
45
59
|
options = {}
|
|
46
60
|
@options.each{|name| options[name] = nil}
|
|
@@ -57,21 +71,31 @@ module Sus
|
|
|
57
71
|
end
|
|
58
72
|
end
|
|
59
73
|
|
|
74
|
+
# Initialize a new RespondTo predicate.
|
|
75
|
+
# @parameter method [Symbol, String] The method name to check for.
|
|
60
76
|
def initialize(method)
|
|
61
77
|
@method = method
|
|
62
78
|
@parameters = nil
|
|
63
79
|
@options = nil
|
|
64
80
|
end
|
|
65
81
|
|
|
82
|
+
# Specify that the method should have specific keyword options.
|
|
83
|
+
# @parameter options [Array(Symbol)] The option names that should be present.
|
|
84
|
+
# @returns [RespondTo] Returns self for method chaining.
|
|
66
85
|
def with_options(*options)
|
|
67
86
|
@options = WithOptions.new(options)
|
|
68
87
|
return self
|
|
69
88
|
end
|
|
70
89
|
|
|
90
|
+
# Print a representation of this predicate.
|
|
91
|
+
# @parameter output [Output] The output target.
|
|
71
92
|
def print(output)
|
|
72
93
|
output.write("respond to ", :variable, @method.to_s, :reset)
|
|
73
94
|
end
|
|
74
95
|
|
|
96
|
+
# Evaluate this predicate against a subject.
|
|
97
|
+
# @parameter assertions [Assertions] The assertions instance to use.
|
|
98
|
+
# @parameter subject [Object] The subject to evaluate.
|
|
75
99
|
def call(assertions, subject)
|
|
76
100
|
assertions.nested(self) do |assertions|
|
|
77
101
|
condition = subject.respond_to?(@method)
|
|
@@ -87,6 +111,9 @@ module Sus
|
|
|
87
111
|
end
|
|
88
112
|
|
|
89
113
|
class Base
|
|
114
|
+
# Create a predicate that checks if the subject responds to a method.
|
|
115
|
+
# @parameter method [Symbol, String] The method name to check for.
|
|
116
|
+
# @returns [RespondTo] A new RespondTo predicate.
|
|
90
117
|
def respond_to(method)
|
|
91
118
|
RespondTo.new(method)
|
|
92
119
|
end
|
data/lib/sus/shared.rb
CHANGED
|
@@ -6,10 +6,18 @@
|
|
|
6
6
|
require_relative "context"
|
|
7
7
|
|
|
8
8
|
module Sus
|
|
9
|
+
# Represents a shared test context that can be reused across multiple test files.
|
|
9
10
|
module Shared
|
|
11
|
+
# @attribute [String] The name of the shared context.
|
|
10
12
|
attr_accessor :name
|
|
13
|
+
|
|
14
|
+
# @attribute [Proc] The block containing the shared test code.
|
|
11
15
|
attr_accessor :block
|
|
12
16
|
|
|
17
|
+
# Build a new Shared context.
|
|
18
|
+
# @parameter name [String] The name of the shared context.
|
|
19
|
+
# @parameter block [Proc] The block containing the shared test code.
|
|
20
|
+
# @returns [Module] A new Shared module.
|
|
13
21
|
def self.build(name, block)
|
|
14
22
|
base = Module.new
|
|
15
23
|
base.extend(Shared)
|
|
@@ -19,15 +27,23 @@ module Sus
|
|
|
19
27
|
return base
|
|
20
28
|
end
|
|
21
29
|
|
|
30
|
+
# Called when this module is included in a test class.
|
|
31
|
+
# @parameter base [Class] The class including this module.
|
|
22
32
|
def included(base)
|
|
23
33
|
base.class_exec(&self.block)
|
|
24
34
|
end
|
|
25
35
|
|
|
36
|
+
# Called when this module is prepended to a test class.
|
|
37
|
+
# @parameter base [Class] The class prepending this module.
|
|
26
38
|
def prepended(base)
|
|
27
39
|
base.class_exec(&self.block)
|
|
28
40
|
end
|
|
29
41
|
end
|
|
30
42
|
|
|
43
|
+
# Create a new shared test context.
|
|
44
|
+
# @parameter name [String] The name of the shared context.
|
|
45
|
+
# @yields {...} The block containing the shared test code.
|
|
46
|
+
# @returns [Shared] A new Shared module.
|
|
31
47
|
def self.Shared(name, &block)
|
|
32
48
|
Shared.build(name, block)
|
|
33
49
|
end
|
data/lib/sus/tree.rb
CHANGED
|
@@ -4,11 +4,18 @@
|
|
|
4
4
|
# Copyright, 2023, by Samuel Williams.
|
|
5
5
|
|
|
6
6
|
module Sus
|
|
7
|
+
# Represents a tree structure of test contexts.
|
|
7
8
|
class Tree
|
|
9
|
+
# Initialize a new Tree.
|
|
10
|
+
# @parameter context [Object] The root context.
|
|
8
11
|
def initialize(context)
|
|
9
12
|
@context = context
|
|
10
13
|
end
|
|
11
14
|
|
|
15
|
+
# Traverse the tree, yielding each context.
|
|
16
|
+
# @parameter current [Object] The current context (defaults to root).
|
|
17
|
+
# @yields {|context| ...} Each context in the tree.
|
|
18
|
+
# @returns [Hash] A hash representation of the tree.
|
|
12
19
|
def traverse(current = @context, &block)
|
|
13
20
|
node = {}
|
|
14
21
|
|
|
@@ -23,6 +30,9 @@ module Sus
|
|
|
23
30
|
return node
|
|
24
31
|
end
|
|
25
32
|
|
|
33
|
+
# Convert the tree to JSON.
|
|
34
|
+
# @parameter options [Hash, nil] Options to pass to JSON.generate.
|
|
35
|
+
# @returns [String] A JSON representation of the tree.
|
|
26
36
|
def to_json(options = nil)
|
|
27
37
|
traverse do |context|
|
|
28
38
|
[context.identity.to_s, context.description.to_s, context.leaf?]
|
data/lib/sus/version.rb
CHANGED
data/lib/sus/with.rb
CHANGED
|
@@ -6,12 +6,23 @@
|
|
|
6
6
|
require_relative "context"
|
|
7
7
|
|
|
8
8
|
module Sus
|
|
9
|
+
# Represents a test context with specific conditions or variables.
|
|
9
10
|
module With
|
|
10
11
|
extend Context
|
|
11
12
|
|
|
13
|
+
# @attribute [String] The subject description of this context.
|
|
12
14
|
attr_accessor :subject
|
|
15
|
+
|
|
16
|
+
# @attribute [Hash] The variables available in this context.
|
|
13
17
|
attr_accessor :variables
|
|
14
18
|
|
|
19
|
+
# Build a new with block class.
|
|
20
|
+
# @parameter parent [Class] The parent context class.
|
|
21
|
+
# @parameter subject [String] The subject description.
|
|
22
|
+
# @parameter variables [Hash] Variables to make available in the context.
|
|
23
|
+
# @parameter unique [Boolean] Whether the identity should be unique.
|
|
24
|
+
# @yields {...} Optional block containing nested tests.
|
|
25
|
+
# @returns [Class] A new with block class.
|
|
15
26
|
def self.build(parent, subject, variables, unique: true, &block)
|
|
16
27
|
base = Class.new(parent)
|
|
17
28
|
base.singleton_class.prepend(With)
|
|
@@ -36,6 +47,8 @@ module Sus
|
|
|
36
47
|
return base
|
|
37
48
|
end
|
|
38
49
|
|
|
50
|
+
# Print a representation of this with block.
|
|
51
|
+
# @parameter output [Output] The output target.
|
|
39
52
|
def print(output)
|
|
40
53
|
self.superclass.print(output)
|
|
41
54
|
|
|
@@ -47,6 +60,11 @@ module Sus
|
|
|
47
60
|
end
|
|
48
61
|
|
|
49
62
|
module Context
|
|
63
|
+
# Define a new test context with specific conditions or variables.
|
|
64
|
+
# @parameter subject [String | Nil] Optional subject description. If nil, uses variables.inspect.
|
|
65
|
+
# @parameter unique [Boolean] Whether the identity should be unique.
|
|
66
|
+
# @parameter variables [Hash] Variables to make available in the context.
|
|
67
|
+
# @yields {...} Optional block containing nested tests.
|
|
50
68
|
def with(subject = nil, unique: true, **variables, &block)
|
|
51
69
|
subject ||= variables.inspect
|
|
52
70
|
|
data/readme.md
CHANGED
|
@@ -25,10 +25,22 @@ Please see the [project documentation](https://socketry.github.io/sus/) for more
|
|
|
25
25
|
|
|
26
26
|
- [Getting Started](https://socketry.github.io/sus/guides/getting-started/index) - This guide explains how to use the `sus` gem to write tests for your Ruby projects.
|
|
27
27
|
|
|
28
|
+
- [Mocking](https://socketry.github.io/sus/guides/mocking/index) - This guide explains how to use mocking in sus to isolate dependencies and verify interactions in your tests.
|
|
29
|
+
|
|
30
|
+
- [Shared Test Behaviors and Fixtures](https://socketry.github.io/sus/guides/shared-contexts/index) - This guide explains how to use shared test contexts and fixtures in sus to reduce duplication and ensure consistent test behavior across your test suite.
|
|
31
|
+
|
|
28
32
|
## Releases
|
|
29
33
|
|
|
30
34
|
Please see the [project releases](https://socketry.github.io/sus/releases/index) for all releases.
|
|
31
35
|
|
|
36
|
+
### v0.35.0
|
|
37
|
+
|
|
38
|
+
- Add `Sus::Fixtures::TemporaryDirectoryContext`.
|
|
39
|
+
|
|
40
|
+
### v0.34.0
|
|
41
|
+
|
|
42
|
+
- Allow `expect(...).to receive(...)` to accept one or more calls (at least once).
|
|
43
|
+
|
|
32
44
|
### v0.33.0
|
|
33
45
|
|
|
34
46
|
- Add support for `agent-context` gem.
|
data/releases.md
CHANGED
data.tar.gz.sig
CHANGED
|
Binary file
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: sus
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.35.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Samuel Williams
|
|
@@ -51,9 +51,10 @@ files:
|
|
|
51
51
|
- bin/sus-host
|
|
52
52
|
- bin/sus-parallel
|
|
53
53
|
- bin/sus-tree
|
|
54
|
+
- context/getting-started.md
|
|
55
|
+
- context/index.yaml
|
|
54
56
|
- context/mocking.md
|
|
55
|
-
- context/shared.md
|
|
56
|
-
- context/usage.md
|
|
57
|
+
- context/shared-contexts.md
|
|
57
58
|
- lib/sus.rb
|
|
58
59
|
- lib/sus/assertions.rb
|
|
59
60
|
- lib/sus/base.rb
|
|
@@ -68,6 +69,7 @@ files:
|
|
|
68
69
|
- lib/sus/file.rb
|
|
69
70
|
- lib/sus/filter.rb
|
|
70
71
|
- lib/sus/fixtures.rb
|
|
72
|
+
- lib/sus/fixtures/temporary_directory_context.rb
|
|
71
73
|
- lib/sus/have.rb
|
|
72
74
|
- lib/sus/have/all.rb
|
|
73
75
|
- lib/sus/have/any.rb
|
|
@@ -123,7 +125,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
123
125
|
- !ruby/object:Gem::Version
|
|
124
126
|
version: '0'
|
|
125
127
|
requirements: []
|
|
126
|
-
rubygems_version: 3.6.
|
|
128
|
+
rubygems_version: 3.6.9
|
|
127
129
|
specification_version: 4
|
|
128
130
|
summary: A fast and scalable test runner.
|
|
129
131
|
test_files: []
|
metadata.gz.sig
CHANGED
|
Binary file
|