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.
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
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Fix
4
+ class SuspiciousSuccessError < ::StandardError; end
5
+ end
data/lib/fix.rb CHANGED
@@ -1,179 +1,25 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "fix/doc"
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
- # Creates a new specification set, optionally registering it under a name.
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
- # @api public
158
- def self.keys
159
- Doc.constants.sort
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
- # Fix.key?(:Example) #=> true
173
- # Fix.key?(:Missing) #=> false
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
- # @api public
176
- def self.key?(name)
177
- keys.include?(name)
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
- # This rule is disabled because Fix is intentionally capitalized to act as
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: '0.21'
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: 2025-01-03 00:00:00.000000000 Z
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: 3.0.1
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: 3.0.1
26
+ version: 2.0.3
27
27
  - !ruby/object:Gem::Dependency
28
- name: matchi
28
+ name: spectus
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 4.1.1
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: 4.1.1
40
+ version: 3.1.1
41
41
  - !ruby/object:Gem::Dependency
42
- name: spectus
42
+ name: bundler
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: 5.0.2
48
- type: :runtime
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: 5.0.2
55
- description: |
56
- Fix is a modern Ruby testing framework built around a key architectural principle:
57
- the complete separation between specifications and tests. It allows you to write
58
- pure specification documents that define expected behaviors, and then independently
59
- challenge any implementation against these specifications.
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/doc.rb
69
- - lib/fix/dsl.rb
70
- - lib/fix/error/invalid_specification_name.rb
71
- - lib/fix/error/missing_specification_block.rb
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
- rubygems_mfa_required: 'true'
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: 3.1.0
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: '0'
157
+ version: 1.3.1
103
158
  requirements: []
104
- rubygems_version: 3.3.27
105
- signing_key:
159
+ rubygems_version: 3.1.2
160
+ signing_key:
106
161
  specification_version: 4
107
- summary: Happy Path to Ruby Testing
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