fix 0.21 → 1.0.0.beta1
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
- data/LICENSE.md +2 -2
- data/README.md +64 -397
- data/lib/fix/context.rb +147 -0
- data/lib/fix/expectation_result_not_found_error.rb +5 -0
- data/lib/fix/it.rb +31 -0
- data/lib/fix/suspicious_success_error.rb +5 -0
- data/lib/fix.rb +15 -169
- data/lib/kernel.rb +2 -96
- metadata +94 -39
- data/lib/fix/doc.rb +0 -118
- data/lib/fix/dsl.rb +0 -139
- data/lib/fix/error/invalid_specification_name.rb +0 -12
- data/lib/fix/error/missing_specification_block.rb +0 -14
- data/lib/fix/error/missing_subject_block.rb +0 -15
- data/lib/fix/error/specification_not_found.rb +0 -12
- data/lib/fix/matcher.rb +0 -76
- data/lib/fix/requirement.rb +0 -119
- data/lib/fix/run.rb +0 -88
- data/lib/fix/set.rb +0 -224
data/lib/fix/it.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spectus/expectation_target'
|
4
|
+
require 'matchi/helper'
|
5
|
+
|
6
|
+
module Fix
|
7
|
+
# Wraps the target of an expectation.
|
8
|
+
class It < ::Spectus::ExpectationTarget
|
9
|
+
include ::Matchi::Helper
|
10
|
+
|
11
|
+
# Create a new expection target
|
12
|
+
#
|
13
|
+
# @param callable [#call] The object to test.
|
14
|
+
def initialize(callable, **lets)
|
15
|
+
raise unless callable.respond_to?(:call)
|
16
|
+
|
17
|
+
@callable = callable
|
18
|
+
@lets = lets
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def method_missing(name, *args, &block)
|
24
|
+
@lets.fetch(name) { super }
|
25
|
+
end
|
26
|
+
|
27
|
+
def respond_to_missing?(name, include_private = false)
|
28
|
+
@lets.key?(name) || super
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/lib/fix.rb
CHANGED
@@ -1,179 +1,25 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
require_relative "fix/error/missing_specification_block"
|
5
|
-
require_relative "fix/error/specification_not_found"
|
6
|
-
require_relative "fix/set"
|
7
|
-
require_relative "kernel"
|
8
|
-
|
9
|
-
# The Fix framework namespace provides core functionality for managing and running test specifications.
|
10
|
-
# Fix offers a unique approach to testing by clearly separating specifications from their implementations.
|
11
|
-
#
|
12
|
-
# Fix supports two primary modes of operation:
|
13
|
-
# 1. Named specifications that can be stored and referenced later
|
14
|
-
# 2. Anonymous specifications for immediate one-time testing
|
15
|
-
#
|
16
|
-
# Available matchers through the Matchi library include:
|
17
|
-
# - Basic Comparison: eq, eql, be, equal
|
18
|
-
# - Type Checking: be_an_instance_of, be_a_kind_of
|
19
|
-
# - State & Changes: change(object, method).by(n), by_at_least(n), by_at_most(n), from(old).to(new), to(new)
|
20
|
-
# - Value Testing: be_within(delta).of(value), match(regex), satisfy { |value| ... }
|
21
|
-
# - Exceptions: raise_exception(class)
|
22
|
-
# - State Testing: be_true, be_false, be_nil
|
23
|
-
# - Predicate Matchers: be_*, have_* (e.g., be_empty, have_key)
|
24
|
-
#
|
25
|
-
# @example Creating and running a named specification with various matchers
|
26
|
-
# Fix :Calculator do
|
27
|
-
# on(:add, 0.1, 0.2) do
|
28
|
-
# it SHOULD be 0.3 # Technically true but fails due to floating point precision
|
29
|
-
# it MUST be_an_instance_of(Float) # Type checking
|
30
|
-
# it MUST be_within(0.0001).of(0.3) # Proper floating point comparison
|
31
|
-
# end
|
32
|
-
#
|
33
|
-
# on(:divide, 1, 0) do
|
34
|
-
# it MUST raise_exception ZeroDivisionError # Exception testing
|
35
|
-
# end
|
36
|
-
# end
|
37
|
-
#
|
38
|
-
# Fix[:Calculator].test { Calculator.new }
|
39
|
-
#
|
40
|
-
# @example Using state change matchers
|
41
|
-
# Fix :UserAccount do
|
42
|
-
# on(:deposit, 100) do
|
43
|
-
# it MUST change(account, :balance).by(100)
|
44
|
-
# it SHOULD change(account, :updated_at)
|
45
|
-
# end
|
46
|
-
#
|
47
|
-
# on(:update_status, :premium) do
|
48
|
-
# it MUST change(account, :status).from(:basic).to(:premium)
|
49
|
-
# end
|
50
|
-
# end
|
51
|
-
#
|
52
|
-
# @example Using predicate matchers
|
53
|
-
# Fix :Collection do
|
54
|
-
# with items: [] do
|
55
|
-
# it MUST be_empty # Tests empty?
|
56
|
-
# it MUST_NOT have_errors # Tests has_errors?
|
57
|
-
# end
|
58
|
-
# end
|
59
|
-
#
|
60
|
-
# @example Complete specification with multiple matchers
|
61
|
-
# Fix :Product do
|
62
|
-
# let(:price) { 42.99 }
|
3
|
+
# Namespace for the Fix framework.
|
63
4
|
#
|
64
|
-
# it MUST be_an_instance_of Product # Type checking
|
65
|
-
# it MUST_NOT be_nil # Nil checking
|
66
|
-
#
|
67
|
-
# on(:price) do
|
68
|
-
# it MUST be_within(0.01).of(42.99) # Floating point comparison
|
69
|
-
# end
|
70
|
-
#
|
71
|
-
# with category: "electronics" do
|
72
|
-
# it MUST satisfy { |p| p.valid? } # Custom validation
|
73
|
-
#
|
74
|
-
# on(:save) do
|
75
|
-
# it MUST change(product, :updated_at) # State change
|
76
|
-
# it SHOULD_NOT raise_exception # Exception checking
|
77
|
-
# end
|
78
|
-
# end
|
79
|
-
# end
|
80
|
-
#
|
81
|
-
# @see Fix::Set For managing collections of specifications
|
82
|
-
# @see Fix::Doc For storing and retrieving specifications
|
83
|
-
# @see Fix::Dsl For the domain-specific language used in specifications
|
84
|
-
# @see Fix::Matcher For the complete list of available matchers
|
85
|
-
#
|
86
|
-
# @api public
|
87
5
|
module Fix
|
88
|
-
#
|
89
|
-
#
|
90
|
-
# @param name [Symbol, nil] Optional name to register the specification under.
|
91
|
-
# If nil, creates an anonymous specification for immediate use.
|
92
|
-
# @yieldreturn [void] Block containing the specification definition using Fix DSL
|
93
|
-
# @return [Fix::Set] A new specification set ready for testing
|
94
|
-
# @raise [Fix::Error::MissingSpecificationBlock] If no block is provided
|
95
|
-
#
|
96
|
-
# @example Create a named specification
|
97
|
-
# Fix :StringValidator do
|
98
|
-
# on(:validate, "hello@example.com") do
|
99
|
-
# it MUST be_valid_email
|
100
|
-
# it MUST satisfy { |result| result.errors.empty? }
|
101
|
-
# end
|
102
|
-
# end
|
103
|
-
#
|
104
|
-
# @example Create an anonymous specification
|
105
|
-
# Fix do
|
106
|
-
# it MUST be_positive
|
107
|
-
# it MUST be_within(0.1).of(42.0)
|
108
|
-
# end.test { 42 }
|
109
|
-
#
|
110
|
-
# @api public
|
111
|
-
def self.spec(name = nil, &block)
|
112
|
-
raise Error::MissingSpecificationBlock if block.nil?
|
113
|
-
|
114
|
-
Set.build(name, &block)
|
115
|
-
end
|
116
|
-
|
117
|
-
# Retrieves a previously registered specification by name.
|
118
|
-
#
|
119
|
-
# @param name [Symbol] The constant name of the specification to retrieve
|
120
|
-
# @return [Fix::Set] The loaded specification set ready for testing
|
121
|
-
# @raise [Fix::Error::SpecificationNotFound] If the named specification doesn't exist
|
122
|
-
#
|
123
|
-
# @example
|
124
|
-
# # Define a specification with multiple matchers
|
125
|
-
# Fix :EmailValidator do
|
126
|
-
# on(:validate, "test@example.com") do
|
127
|
-
# it MUST be_valid
|
128
|
-
# it MUST_NOT raise_exception
|
129
|
-
# it SHOULD satisfy { |result| result.score > 0.8 }
|
130
|
-
# end
|
131
|
-
# end
|
132
|
-
#
|
133
|
-
# # Later, retrieve and use it
|
134
|
-
# Fix[:EmailValidator].test { MyEmailValidator }
|
135
|
-
#
|
136
|
-
# @see #spec For creating new specifications
|
137
|
-
# @see Fix::Set#test For running tests against a specification
|
138
|
-
# @see Fix::Matcher For available matchers
|
139
|
-
#
|
140
|
-
# @api public
|
141
|
-
def self.[](name)
|
142
|
-
raise Error::SpecificationNotFound, name unless key?(name)
|
143
|
-
|
144
|
-
Set.load(name)
|
145
|
-
end
|
146
|
-
|
147
|
-
# Lists all defined specification names.
|
148
|
-
#
|
149
|
-
# @return [Array<Symbol>] Sorted array of registered specification names
|
150
|
-
#
|
151
|
-
# @example
|
152
|
-
# Fix :First do; end
|
153
|
-
# Fix :Second do; end
|
154
|
-
#
|
155
|
-
# Fix.keys #=> [:First, :Second]
|
6
|
+
# Specs are built with this method.
|
156
7
|
#
|
157
|
-
# @
|
158
|
-
|
159
|
-
|
160
|
-
end
|
161
|
-
|
162
|
-
# Checks if a specification is registered under the given name.
|
163
|
-
#
|
164
|
-
# @param name [Symbol] The name to check for
|
165
|
-
# @return [Boolean] true if a specification exists with this name, false otherwise
|
166
|
-
#
|
167
|
-
# @example
|
168
|
-
# Fix :Example do
|
169
|
-
# it MUST be_an_instance_of(Example)
|
8
|
+
# @example 42 must be equal to 42
|
9
|
+
# describe(42) do
|
10
|
+
# it { MUST equal 42 }
|
170
11
|
# end
|
171
12
|
#
|
172
|
-
#
|
173
|
-
#
|
13
|
+
# @param front_object [BasicObject] The front object.
|
14
|
+
# @param options [Hash] Some options.
|
15
|
+
# @param specs [Proc] The set of specs.
|
174
16
|
#
|
175
|
-
# @
|
176
|
-
def self.
|
177
|
-
|
17
|
+
# @raise [SystemExit] The result of the test.
|
18
|
+
def self.describe(front_object, **lets, &block)
|
19
|
+
c = Context.new(front_object, ::Defi.send(:itself), **lets)
|
20
|
+
c.instance_eval(&block)
|
178
21
|
end
|
179
22
|
end
|
23
|
+
|
24
|
+
require_relative 'kernel'
|
25
|
+
require_relative File.join('fix', 'context')
|
data/lib/kernel.rb
CHANGED
@@ -1,103 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
# Extension of the global Kernel module to provide the Fix method.
|
4
|
-
# This module provides a global entry point to the Fix testing framework,
|
5
|
-
# allowing specifications to be defined and managed from anywhere in the application.
|
6
|
-
#
|
7
|
-
# The Fix method can be used in two main ways:
|
8
|
-
# 1. Creating named specifications for reuse
|
9
|
-
# 2. Creating anonymous specifications for immediate testing
|
10
|
-
#
|
11
|
-
# @api public
|
12
3
|
module Kernel
|
13
4
|
# rubocop:disable Naming/MethodName
|
14
|
-
|
15
|
-
|
16
|
-
# both a namespace and a method name, following Ruby conventions for DSLs.
|
17
|
-
|
18
|
-
# Defines a new test specification or creates an anonymous specification set.
|
19
|
-
# When a name is provided, the specification is registered globally and can be
|
20
|
-
# referenced later using Fix[name]. Anonymous specifications are executed
|
21
|
-
# immediately and cannot be referenced later.
|
22
|
-
#
|
23
|
-
# Specifications can use three levels of requirements, following RFC 2119:
|
24
|
-
# - MUST/MUST_NOT: Absolute requirements or prohibitions
|
25
|
-
# - SHOULD/SHOULD_NOT: Strong recommendations that can be ignored with good reason
|
26
|
-
# - MAY: Optional features that can be implemented or not
|
27
|
-
#
|
28
|
-
# Available matchers include:
|
29
|
-
# - Basic Comparison: eq(expected), eql(expected), be(expected), equal(expected)
|
30
|
-
# - Type Checking: be_an_instance_of(class), be_a_kind_of(class)
|
31
|
-
# - State & Changes: change(object, method).by(n), by_at_least(n), by_at_most(n),
|
32
|
-
# from(old).to(new), to(new)
|
33
|
-
# - Value Testing: be_within(delta).of(value), match(regex),
|
34
|
-
# satisfy { |value| ... }
|
35
|
-
# - Exceptions: raise_exception(class)
|
36
|
-
# - State Testing: be_true, be_false, be_nil
|
37
|
-
# - Predicate Matchers: be_* (e.g., be_empty), have_* (e.g., have_key)
|
38
|
-
#
|
39
|
-
# @example Creating a named specification with multiple contexts and matchers
|
40
|
-
# Fix :Calculator do
|
41
|
-
# on(:add, 2, 3) do
|
42
|
-
# it MUST eq 5
|
43
|
-
# it MUST be_an_instance_of(Integer)
|
44
|
-
# end
|
45
|
-
#
|
46
|
-
# with precision: :high do
|
47
|
-
# on(:divide, 10, 3) do
|
48
|
-
# it MUST be_within(0.001).of(3.333)
|
49
|
-
# end
|
50
|
-
# end
|
51
|
-
#
|
52
|
-
# on(:divide, 1, 0) do
|
53
|
-
# it MUST raise_exception ZeroDivisionError
|
54
|
-
# end
|
55
|
-
# end
|
56
|
-
#
|
57
|
-
# @example Creating and immediately testing an anonymous specification
|
58
|
-
# Fix do
|
59
|
-
# it MUST be_positive
|
60
|
-
# it SHOULD be_even
|
61
|
-
# it MAY be_prime
|
62
|
-
# end.test { 42 }
|
63
|
-
#
|
64
|
-
# @example Testing state changes
|
65
|
-
# Fix :Account do
|
66
|
-
# on(:deposit, 100) do
|
67
|
-
# it MUST change(account, :balance).by(100)
|
68
|
-
# it SHOULD change(account, :updated_at)
|
69
|
-
# end
|
70
|
-
#
|
71
|
-
# on(:withdraw, 50) do
|
72
|
-
# it MUST change(account, :balance).by(-50)
|
73
|
-
# it MUST_NOT change(account, :status)
|
74
|
-
# end
|
75
|
-
# end
|
76
|
-
#
|
77
|
-
# @example Using predicates and custom matchers
|
78
|
-
# Fix :Collection do
|
79
|
-
# with items: [] do
|
80
|
-
# it MUST be_empty
|
81
|
-
# it MUST_NOT have_errors
|
82
|
-
# it SHOULD satisfy { |c| c.valid? && c.initialized? }
|
83
|
-
# end
|
84
|
-
# end
|
85
|
-
#
|
86
|
-
# @param name [Symbol, nil] Optional name to register the specification under
|
87
|
-
# @yield Block containing the specification definition using Fix DSL
|
88
|
-
# @return [Fix::Set] A specification set ready for testing
|
89
|
-
# @raise [Fix::Error::MissingSpecificationBlock] If no block is provided
|
90
|
-
# @raise [Fix::Error::InvalidSpecificationName] If name is not a valid constant name
|
91
|
-
#
|
92
|
-
# @see Fix::Set For managing collections of specifications
|
93
|
-
# @see Fix::Dsl For the domain-specific language used in specifications
|
94
|
-
# @see Fix::Matcher For the complete list of available matchers
|
95
|
-
# @see https://tools.ietf.org/html/rfc2119 For details about requirement levels
|
96
|
-
#
|
97
|
-
# @api public
|
98
|
-
def Fix(name = nil, &block)
|
99
|
-
::Fix.spec(name, &block)
|
5
|
+
def Fix(subject, **lets, &block)
|
6
|
+
::Fix.describe(subject, **lets, &block)
|
100
7
|
end
|
101
|
-
|
102
8
|
# rubocop:enable Naming/MethodName
|
103
9
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fix
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 1.0.0.beta1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Cyril Kato
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-01-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: defi
|
@@ -16,47 +16,113 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 2.0.3
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
26
|
+
version: 2.0.3
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: spectus
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version:
|
33
|
+
version: 3.1.1
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version:
|
40
|
+
version: 3.1.1
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: bundler
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version:
|
48
|
-
type: :
|
47
|
+
version: '2.1'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '2.1'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rake
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '13.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '13.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rubocop
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rubocop-performance
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
49
91
|
prerelease: false
|
50
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: simplecov
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
51
100
|
requirements:
|
52
101
|
- - "~>"
|
53
102
|
- !ruby/object:Gem::Version
|
54
|
-
version:
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
103
|
+
version: '0.17'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0.17'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: yard
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0.9'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0.9'
|
125
|
+
description: Specing framework for Ruby.
|
60
126
|
email: contact@cyril.email
|
61
127
|
executables: []
|
62
128
|
extensions: []
|
@@ -65,28 +131,17 @@ files:
|
|
65
131
|
- LICENSE.md
|
66
132
|
- README.md
|
67
133
|
- lib/fix.rb
|
68
|
-
- lib/fix/
|
69
|
-
- lib/fix/
|
70
|
-
- lib/fix/
|
71
|
-
- lib/fix/
|
72
|
-
- lib/fix/error/missing_subject_block.rb
|
73
|
-
- lib/fix/error/specification_not_found.rb
|
74
|
-
- lib/fix/matcher.rb
|
75
|
-
- lib/fix/requirement.rb
|
76
|
-
- lib/fix/run.rb
|
77
|
-
- lib/fix/set.rb
|
134
|
+
- lib/fix/context.rb
|
135
|
+
- lib/fix/expectation_result_not_found_error.rb
|
136
|
+
- lib/fix/it.rb
|
137
|
+
- lib/fix/suspicious_success_error.rb
|
78
138
|
- lib/kernel.rb
|
79
139
|
homepage: https://fixrb.dev/
|
80
140
|
licenses:
|
81
141
|
- MIT
|
82
142
|
metadata:
|
83
|
-
bug_tracker_uri: https://github.com/fixrb/fix/issues
|
84
|
-
changelog_uri: https://github.com/fixrb/fix/blob/main/CHANGELOG.md
|
85
|
-
documentation_uri: https://rubydoc.info/gems/fix
|
86
|
-
homepage_uri: https://fixrb.dev
|
87
143
|
source_code_uri: https://github.com/fixrb/fix
|
88
|
-
|
89
|
-
post_install_message:
|
144
|
+
post_install_message:
|
90
145
|
rdoc_options: []
|
91
146
|
require_paths:
|
92
147
|
- lib
|
@@ -94,15 +149,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
94
149
|
requirements:
|
95
150
|
- - ">="
|
96
151
|
- !ruby/object:Gem::Version
|
97
|
-
version:
|
152
|
+
version: 2.7.0
|
98
153
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
99
154
|
requirements:
|
100
|
-
- - "
|
155
|
+
- - ">"
|
101
156
|
- !ruby/object:Gem::Version
|
102
|
-
version:
|
157
|
+
version: 1.3.1
|
103
158
|
requirements: []
|
104
|
-
rubygems_version: 3.
|
105
|
-
signing_key:
|
159
|
+
rubygems_version: 3.1.2
|
160
|
+
signing_key:
|
106
161
|
specification_version: 4
|
107
|
-
summary:
|
162
|
+
summary: Specing framework for Ruby.
|
108
163
|
test_files: []
|
data/lib/fix/doc.rb
DELETED
@@ -1,118 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative "error/invalid_specification_name"
|
4
|
-
|
5
|
-
module Fix
|
6
|
-
# The Doc module serves as a central registry for storing and managing test specifications.
|
7
|
-
# It provides functionality for:
|
8
|
-
# - Storing specification classes in a structured way
|
9
|
-
# - Managing the lifecycle of specification documents
|
10
|
-
# - Extracting test specifications from context objects
|
11
|
-
# - Validating specification names
|
12
|
-
#
|
13
|
-
# The module acts as a namespace for specifications, allowing them to be:
|
14
|
-
# - Registered with unique names
|
15
|
-
# - Retrieved by name when needed
|
16
|
-
# - Protected from name collisions
|
17
|
-
# - Organized in a hierarchical structure
|
18
|
-
#
|
19
|
-
# @example Registering a new specification
|
20
|
-
# Fix::Doc.add(:Calculator, calculator_specification_class)
|
21
|
-
#
|
22
|
-
# @example Retrieving specification contexts
|
23
|
-
# contexts = Fix::Doc.fetch(:Calculator)
|
24
|
-
# specifications = Fix::Doc.extract_specifications(*contexts)
|
25
|
-
#
|
26
|
-
# @api private
|
27
|
-
module Doc
|
28
|
-
# Retrieves the array of test contexts associated with a named specification.
|
29
|
-
# These contexts define the test environment and requirements for the specification.
|
30
|
-
#
|
31
|
-
# @param name [Symbol] The name of the specification to retrieve
|
32
|
-
# @return [Array<Fix::Dsl>] Array of context classes for the specification
|
33
|
-
# @raise [NameError] If the specification name doesn't exist in the registry
|
34
|
-
#
|
35
|
-
# @example Retrieving contexts for a calculator specification
|
36
|
-
# contexts = Fix::Doc.fetch(:Calculator)
|
37
|
-
# contexts.each do |context|
|
38
|
-
# # Process each context...
|
39
|
-
# end
|
40
|
-
#
|
41
|
-
# @api private
|
42
|
-
def self.fetch(name)
|
43
|
-
const_get("#{name}::CONTEXTS")
|
44
|
-
end
|
45
|
-
|
46
|
-
# Extracts complete test specifications from a list of context classes.
|
47
|
-
# This method processes contexts to build a list of executable test specifications.
|
48
|
-
#
|
49
|
-
# Each extracted specification contains:
|
50
|
-
# - The test environment
|
51
|
-
# - The source file location
|
52
|
-
# - The requirement level (MUST, SHOULD, or MAY)
|
53
|
-
# - The list of challenges to execute
|
54
|
-
#
|
55
|
-
# @param contexts [Array<Fix::Dsl>] List of context classes to process
|
56
|
-
# @return [Array<Array>] Array of specification arrays where each contains:
|
57
|
-
# - [0] environment [Fix::Dsl] The test environment instance
|
58
|
-
# - [1] location [String] The test file location ("path:line")
|
59
|
-
# - [2] requirement [Object] The test requirement (MUST, SHOULD, or MAY)
|
60
|
-
# - [3] challenges [Array] Array of test challenges to execute
|
61
|
-
#
|
62
|
-
# @example Extracting specifications from contexts
|
63
|
-
# contexts = Fix::Doc.fetch(:Calculator)
|
64
|
-
# specifications = Fix::Doc.extract_specifications(*contexts)
|
65
|
-
# specifications.each do |env, location, requirement, challenges|
|
66
|
-
# # Process each specification...
|
67
|
-
# end
|
68
|
-
#
|
69
|
-
# @api private
|
70
|
-
def self.extract_specifications(*contexts)
|
71
|
-
contexts.flat_map do |context|
|
72
|
-
extract_context_specifications(context)
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
# Registers a new specification class under the given name in the registry.
|
77
|
-
# The name must be a valid Ruby constant name to ensure proper namespace organization.
|
78
|
-
#
|
79
|
-
# @param name [Symbol] The name to register the specification under
|
80
|
-
# @param klass [Class] The specification class to register
|
81
|
-
# @raise [Fix::Error::InvalidSpecificationName] If name is not a valid constant name
|
82
|
-
# @return [void]
|
83
|
-
#
|
84
|
-
# @example Adding a new specification
|
85
|
-
# class CalculatorSpec < Fix::Dsl
|
86
|
-
# # specification implementation...
|
87
|
-
# end
|
88
|
-
# Fix::Doc.add(:Calculator, CalculatorSpec)
|
89
|
-
#
|
90
|
-
# @example Invalid name handling
|
91
|
-
# # This will raise Fix::Error::InvalidSpecificationName
|
92
|
-
# Fix::Doc.add(:"invalid-name", some_class)
|
93
|
-
#
|
94
|
-
# @api private
|
95
|
-
def self.add(name, klass)
|
96
|
-
const_set(name, klass)
|
97
|
-
rescue ::NameError => _e
|
98
|
-
raise Error::InvalidSpecificationName, name
|
99
|
-
end
|
100
|
-
|
101
|
-
# Extracts test specifications from a single context class.
|
102
|
-
# This method processes public methods in the context to build
|
103
|
-
# a list of executable test specifications.
|
104
|
-
#
|
105
|
-
# @param context [Fix::Dsl] The context class to process
|
106
|
-
# @return [Array<Array>] Array of specification arrays
|
107
|
-
#
|
108
|
-
# @api private
|
109
|
-
def self.extract_context_specifications(context)
|
110
|
-
env = context.new
|
111
|
-
env.public_methods(false).map do |public_method|
|
112
|
-
[env] + env.public_send(public_method)
|
113
|
-
end
|
114
|
-
end
|
115
|
-
|
116
|
-
private_class_method :extract_context_specifications
|
117
|
-
end
|
118
|
-
end
|