spec_forge 0.4.0 → 0.6.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
- data/.standard.yml +4 -0
- data/CHANGELOG.md +145 -1
- data/README.md +49 -638
- data/flake.lock +3 -3
- data/flake.nix +8 -2
- data/lib/spec_forge/attribute/chainable.rb +208 -20
- data/lib/spec_forge/attribute/factory.rb +141 -12
- data/lib/spec_forge/attribute/faker.rb +64 -15
- data/lib/spec_forge/attribute/global.rb +96 -0
- data/lib/spec_forge/attribute/literal.rb +15 -2
- data/lib/spec_forge/attribute/matcher.rb +188 -13
- data/lib/spec_forge/attribute/parameterized.rb +45 -20
- data/lib/spec_forge/attribute/regex.rb +55 -5
- data/lib/spec_forge/attribute/resolvable.rb +48 -5
- data/lib/spec_forge/attribute/resolvable_array.rb +62 -4
- data/lib/spec_forge/attribute/resolvable_hash.rb +62 -4
- data/lib/spec_forge/attribute/store.rb +65 -0
- data/lib/spec_forge/attribute/transform.rb +33 -5
- data/lib/spec_forge/attribute/variable.rb +37 -6
- data/lib/spec_forge/attribute.rb +168 -66
- data/lib/spec_forge/backtrace_formatter.rb +26 -3
- data/lib/spec_forge/callbacks.rb +79 -0
- data/lib/spec_forge/cli/actions.rb +27 -0
- data/lib/spec_forge/cli/command.rb +78 -24
- data/lib/spec_forge/cli/init.rb +11 -1
- data/lib/spec_forge/cli/new.rb +54 -3
- data/lib/spec_forge/cli/run.rb +20 -0
- data/lib/spec_forge/cli.rb +16 -5
- data/lib/spec_forge/configuration.rb +94 -25
- data/lib/spec_forge/context/callbacks.rb +91 -0
- data/lib/spec_forge/context/global.rb +72 -0
- data/lib/spec_forge/context/store.rb +148 -0
- data/lib/spec_forge/context/variables.rb +91 -0
- data/lib/spec_forge/context.rb +36 -0
- data/lib/spec_forge/core_ext/rspec.rb +24 -4
- data/lib/spec_forge/error.rb +267 -113
- data/lib/spec_forge/factory.rb +33 -14
- data/lib/spec_forge/filter.rb +87 -0
- data/lib/spec_forge/forge.rb +170 -0
- data/lib/spec_forge/http/backend.rb +99 -29
- data/lib/spec_forge/http/client.rb +23 -13
- data/lib/spec_forge/http/request.rb +74 -62
- data/lib/spec_forge/http/verb.rb +79 -0
- data/lib/spec_forge/http.rb +105 -0
- data/lib/spec_forge/loader.rb +254 -0
- data/lib/spec_forge/matchers.rb +130 -0
- data/lib/spec_forge/normalizer/configuration.rb +24 -11
- data/lib/spec_forge/normalizer/constraint.rb +22 -9
- data/lib/spec_forge/normalizer/expectation.rb +31 -12
- data/lib/spec_forge/normalizer/factory.rb +24 -11
- data/lib/spec_forge/normalizer/factory_reference.rb +32 -13
- data/lib/spec_forge/normalizer/global_context.rb +88 -0
- data/lib/spec_forge/normalizer/spec.rb +39 -16
- data/lib/spec_forge/normalizer.rb +255 -41
- data/lib/spec_forge/runner/callbacks.rb +246 -0
- data/lib/spec_forge/runner/debug_proxy.rb +213 -0
- data/lib/spec_forge/runner/listener.rb +54 -0
- data/lib/spec_forge/runner/metadata.rb +58 -0
- data/lib/spec_forge/runner/state.rb +99 -0
- data/lib/spec_forge/runner.rb +133 -119
- data/lib/spec_forge/spec/expectation/constraint.rb +95 -20
- data/lib/spec_forge/spec/expectation.rb +43 -51
- data/lib/spec_forge/spec.rb +83 -96
- data/lib/spec_forge/type.rb +36 -4
- data/lib/spec_forge/version.rb +4 -1
- data/lib/spec_forge.rb +161 -76
- metadata +20 -5
- data/spec_forge/factories/user.yml +0 -4
- data/spec_forge/forge_helper.rb +0 -37
- data/spec_forge/specs/users.yml +0 -65
@@ -2,18 +2,41 @@
|
|
2
2
|
|
3
3
|
module SpecForge
|
4
4
|
#
|
5
|
-
# Used internally by RSpec
|
6
|
-
#
|
5
|
+
# Used internally by RSpec to format backtraces for test failures
|
6
|
+
# Customizes error output to make it more readable and useful for SpecForge
|
7
7
|
#
|
8
8
|
module BacktraceFormatter
|
9
|
+
#
|
10
|
+
# Returns the RSpec backtrace formatter instance
|
11
|
+
# Lazily initializes the formatter on first access
|
12
|
+
#
|
13
|
+
# @return [RSpec::Core::BacktraceFormatter] The backtrace formatter
|
14
|
+
#
|
9
15
|
def self.formatter
|
10
16
|
@formatter ||= RSpec::Core::BacktraceFormatter.new
|
11
17
|
end
|
12
18
|
|
19
|
+
#
|
20
|
+
# Formats a single backtrace line
|
21
|
+
# Delegates to the RSpec formatter
|
22
|
+
#
|
23
|
+
# @param line [String] The backtrace line to format
|
24
|
+
#
|
25
|
+
# @return [String] The formatted backtrace line
|
26
|
+
#
|
13
27
|
def self.backtrace_line(line)
|
14
28
|
formatter.backtrace_line(line)
|
15
29
|
end
|
16
30
|
|
31
|
+
#
|
32
|
+
# Formats a complete backtrace for an example
|
33
|
+
# Adds the YAML location to the front of the backtrace for better context
|
34
|
+
#
|
35
|
+
# @param backtrace [Array<String>] The raw backtrace lines
|
36
|
+
# @param example_metadata [Hash] Metadata about the failing example
|
37
|
+
#
|
38
|
+
# @return [Array<String>] The formatted backtrace with YAML location first
|
39
|
+
#
|
17
40
|
def self.format_backtrace(backtrace, example_metadata)
|
18
41
|
backtrace = SpecForge.backtrace_cleaner.clean(backtrace)
|
19
42
|
|
@@ -21,7 +44,7 @@ module SpecForge
|
|
21
44
|
line_number = example_metadata[:example_group][:line_number]
|
22
45
|
|
23
46
|
# Add the yaml location to the front so it's the first thing people see
|
24
|
-
["#{location}:#{line_number}"] + backtrace
|
47
|
+
["#{location}:#{line_number}"] + backtrace[0..50]
|
25
48
|
end
|
26
49
|
end
|
27
50
|
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SpecForge
|
4
|
+
#
|
5
|
+
# Manages user-defined callbacks for test lifecycle events
|
6
|
+
#
|
7
|
+
# This singleton class stores and executes callback functions that
|
8
|
+
# users can register to run at specific points in the test lifecycle.
|
9
|
+
# Each callback receives a context object containing relevant state
|
10
|
+
# information for that point in execution.
|
11
|
+
#
|
12
|
+
# @example Registering and using a callback
|
13
|
+
# SpecForge::Callbacks.register(:my_callback) do |context|
|
14
|
+
# puts "Running test: #{context.expectation_name}"
|
15
|
+
# end
|
16
|
+
#
|
17
|
+
class Callbacks < Hash
|
18
|
+
include Singleton
|
19
|
+
|
20
|
+
class << self
|
21
|
+
#
|
22
|
+
# Registers a new callback for a specific event
|
23
|
+
#
|
24
|
+
# @param name [String, Symbol] The name of the callback event
|
25
|
+
# @param block [Proc] The callback function to execute
|
26
|
+
#
|
27
|
+
# @raise [ArgumentError] If no block is provided
|
28
|
+
#
|
29
|
+
def register(name, &block)
|
30
|
+
raise ArgumentError, "A block must be provided" unless block.is_a?(Proc)
|
31
|
+
|
32
|
+
if registered?(name)
|
33
|
+
warn("Callback #{name.in_quotes} is already registered. It will be overwritten")
|
34
|
+
end
|
35
|
+
|
36
|
+
instance[name.to_s] = block
|
37
|
+
end
|
38
|
+
|
39
|
+
#
|
40
|
+
# Checks if a callback is registered for the given event
|
41
|
+
#
|
42
|
+
# @param name [String, Symbol] The name of the callback event
|
43
|
+
#
|
44
|
+
# @return [Boolean] True if the callback exists
|
45
|
+
#
|
46
|
+
def registered?(name)
|
47
|
+
instance.key?(name.to_s)
|
48
|
+
end
|
49
|
+
|
50
|
+
#
|
51
|
+
# Returns all registered callback names
|
52
|
+
#
|
53
|
+
# @return [Array<String>] List of registered callback names
|
54
|
+
#
|
55
|
+
def registered_names
|
56
|
+
instance.keys
|
57
|
+
end
|
58
|
+
|
59
|
+
#
|
60
|
+
# Executes a named callback with the provided context
|
61
|
+
#
|
62
|
+
# @param name [String, Symbol] The name of the callback to run
|
63
|
+
# @param context [Object] Context object containing state data
|
64
|
+
#
|
65
|
+
# @raise [ArgumentError] If the callback is not registered
|
66
|
+
#
|
67
|
+
def run(name, context)
|
68
|
+
callback = instance[name.to_s]
|
69
|
+
raise ArgumentError, "Callback #{name.in_quotes} is not defined" if callback.nil?
|
70
|
+
|
71
|
+
if callback.arity == 0
|
72
|
+
callback.call
|
73
|
+
else
|
74
|
+
callback.call(context)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -2,17 +2,44 @@
|
|
2
2
|
|
3
3
|
module SpecForge
|
4
4
|
class CLI
|
5
|
+
#
|
6
|
+
# Provides helper methods for CLI actions such as file generation
|
7
|
+
# and template rendering through Thor::Actions integration.
|
8
|
+
#
|
9
|
+
# @example Using actions in a command
|
10
|
+
# actions.template("my_template.tt", "destination/path.rb")
|
11
|
+
#
|
5
12
|
module Actions
|
13
|
+
#
|
14
|
+
# Internal Ruby hook, called when the module is included in another file
|
15
|
+
#
|
16
|
+
# @param base [Class] The class that included this module
|
17
|
+
#
|
6
18
|
def self.included(base)
|
19
|
+
#
|
20
|
+
# Returns an ActionContext instance for performing file operations
|
21
|
+
#
|
22
|
+
# @return [ActionContext] The action context for this command
|
23
|
+
#
|
7
24
|
base.define_method(:actions) do
|
8
25
|
@actions ||= ActionContext.new
|
9
26
|
end
|
10
27
|
end
|
11
28
|
end
|
12
29
|
|
30
|
+
#
|
31
|
+
# Provides a context for Thor actions that configures paths and options
|
32
|
+
#
|
33
|
+
# @private
|
34
|
+
#
|
13
35
|
class ActionContext < Thor
|
14
36
|
include Thor::Actions
|
15
37
|
|
38
|
+
#
|
39
|
+
# Creates a new action context with SpecForge template paths configured
|
40
|
+
#
|
41
|
+
# @return [ActionContext] A new context for Thor actions
|
42
|
+
#
|
16
43
|
def initialize(...)
|
17
44
|
self.class.source_root(File.expand_path("../../templates", __dir__))
|
18
45
|
self.destination_root = SpecForge.root
|
@@ -2,20 +2,55 @@
|
|
2
2
|
|
3
3
|
module SpecForge
|
4
4
|
class CLI
|
5
|
+
#
|
6
|
+
# Base class for CLI commands that provides common functionality and
|
7
|
+
# defines the DSL for declaring command properties.
|
8
|
+
#
|
9
|
+
# @example Defining a simple command
|
10
|
+
# class MyCommand < Command
|
11
|
+
# command_name "my_command"
|
12
|
+
# syntax "my_command [options]"
|
13
|
+
# summary "Does something awesome"
|
14
|
+
# description "A longer description of what this command does"
|
15
|
+
#
|
16
|
+
# option "-f", "--force", "Force the operation"
|
17
|
+
#
|
18
|
+
# def call
|
19
|
+
# # Command implementation
|
20
|
+
# end
|
21
|
+
# end
|
22
|
+
#
|
5
23
|
class Command
|
6
24
|
include CLI::Actions
|
7
25
|
|
8
26
|
class << self
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
27
|
+
#
|
28
|
+
# Sets the command's name
|
29
|
+
#
|
30
|
+
attr_writer :command_name
|
31
|
+
|
32
|
+
#
|
33
|
+
# Sets the command's syntax string
|
34
|
+
#
|
35
|
+
attr_writer :syntax
|
36
|
+
|
37
|
+
#
|
38
|
+
# Sets the command's detailed description
|
39
|
+
#
|
40
|
+
attr_writer :description
|
41
|
+
|
42
|
+
#
|
43
|
+
# Sets a brief summary of the command
|
44
|
+
#
|
45
|
+
attr_writer :summary
|
46
|
+
|
47
|
+
#
|
48
|
+
# Sets the command's available options
|
49
|
+
#
|
50
|
+
attr_writer :options
|
16
51
|
|
17
52
|
#
|
18
|
-
#
|
53
|
+
# Sets the command's name
|
19
54
|
#
|
20
55
|
# @param name [String] The name of the command
|
21
56
|
#
|
@@ -24,37 +59,37 @@ module SpecForge
|
|
24
59
|
end
|
25
60
|
|
26
61
|
#
|
27
|
-
#
|
62
|
+
# Sets the command's syntax
|
28
63
|
#
|
29
|
-
# @param syntax [String]
|
64
|
+
# @param syntax [String] The command syntax to display in help
|
30
65
|
#
|
31
66
|
def syntax(syntax)
|
32
67
|
self.syntax = syntax
|
33
68
|
end
|
34
69
|
|
35
70
|
#
|
36
|
-
#
|
71
|
+
# Sets the command's description, displayed in detailed help
|
37
72
|
#
|
38
|
-
# @param description [String]
|
73
|
+
# @param description [String] The detailed command description
|
39
74
|
#
|
40
75
|
def description(description)
|
41
76
|
self.description = description
|
42
77
|
end
|
43
78
|
|
44
79
|
#
|
45
|
-
#
|
80
|
+
# Sets the command's summary, displayed in command list
|
46
81
|
#
|
47
|
-
# @param summary [String]
|
82
|
+
# @param summary [String] The short command summary
|
48
83
|
#
|
49
84
|
def summary(summary)
|
50
85
|
self.summary = summary
|
51
86
|
end
|
52
87
|
|
53
88
|
#
|
54
|
-
#
|
89
|
+
# Adds an example of how to use the command
|
55
90
|
#
|
56
|
-
# @param command [String] The example
|
57
|
-
# @param description [String] Description of the example
|
91
|
+
# @param command [String] The example command
|
92
|
+
# @param description [String] Description of what the example does
|
58
93
|
#
|
59
94
|
def example(command, description)
|
60
95
|
@examples ||= []
|
@@ -64,7 +99,10 @@ module SpecForge
|
|
64
99
|
end
|
65
100
|
|
66
101
|
#
|
67
|
-
#
|
102
|
+
# Adds a command line option
|
103
|
+
#
|
104
|
+
# @param args [Array<String>] The option flags (e.g., "-f", "--force")
|
105
|
+
# @yield [value] Block to handle the option value
|
68
106
|
#
|
69
107
|
def option(*args, &block)
|
70
108
|
@options ||= []
|
@@ -73,9 +111,9 @@ module SpecForge
|
|
73
111
|
end
|
74
112
|
|
75
113
|
#
|
76
|
-
#
|
114
|
+
# Adds command aliases
|
77
115
|
#
|
78
|
-
# @param
|
116
|
+
# @param aliases [Array<String>] Alias names for this command
|
79
117
|
#
|
80
118
|
def aliases(*aliases)
|
81
119
|
@aliases ||= []
|
@@ -86,7 +124,7 @@ module SpecForge
|
|
86
124
|
#
|
87
125
|
# Registers the command with Commander
|
88
126
|
#
|
89
|
-
# @param context [Commander::Command]
|
127
|
+
# @param context [Commander::Command] The Commander context
|
90
128
|
#
|
91
129
|
# @private
|
92
130
|
#
|
@@ -112,11 +150,27 @@ module SpecForge
|
|
112
150
|
end
|
113
151
|
end
|
114
152
|
|
115
|
-
|
153
|
+
#
|
154
|
+
# Command arguments passed from the command line
|
155
|
+
#
|
156
|
+
# @return [Array] The positional arguments
|
157
|
+
#
|
158
|
+
attr_reader :arguments
|
159
|
+
|
160
|
+
#
|
161
|
+
# Command options passed from the command line
|
162
|
+
#
|
163
|
+
# @return [Hash] The flag arguments
|
164
|
+
#
|
165
|
+
attr_reader :options
|
116
166
|
|
117
167
|
#
|
118
|
-
#
|
119
|
-
#
|
168
|
+
# Creates a new command instance
|
169
|
+
#
|
170
|
+
# @param arguments [Array] Any positional arguments from the command line
|
171
|
+
# @param options [Hash] Any flag arguments from the command line
|
172
|
+
#
|
173
|
+
# @return [Command] A new command instance
|
120
174
|
#
|
121
175
|
def initialize(arguments, options)
|
122
176
|
@arguments = arguments
|
data/lib/spec_forge/cli/init.rb
CHANGED
@@ -2,13 +2,23 @@
|
|
2
2
|
|
3
3
|
module SpecForge
|
4
4
|
class CLI
|
5
|
+
#
|
6
|
+
# Command for initializing a new SpecForge project structure
|
7
|
+
#
|
8
|
+
# @example Creating a new SpecForge project
|
9
|
+
# spec_forge init
|
10
|
+
#
|
5
11
|
class Init < Command
|
6
12
|
command_name "init"
|
7
13
|
syntax "init"
|
8
14
|
summary "Initializes directory structure and configuration files"
|
9
15
|
|
16
|
+
#
|
17
|
+
# Creates the "spec_forge", "spec_forge/factories", and "spec_forge/specs" directories
|
18
|
+
# Also creates the "spec_forge.rb" initialization file
|
19
|
+
#
|
10
20
|
def call
|
11
|
-
base_path = SpecForge.
|
21
|
+
base_path = SpecForge.forge_path
|
12
22
|
actions.empty_directory "#{base_path}/factories"
|
13
23
|
actions.empty_directory "#{base_path}/specs"
|
14
24
|
|
data/lib/spec_forge/cli/new.rb
CHANGED
@@ -2,6 +2,15 @@
|
|
2
2
|
|
3
3
|
module SpecForge
|
4
4
|
class CLI
|
5
|
+
#
|
6
|
+
# Command for generating new specs or factories
|
7
|
+
#
|
8
|
+
# @example Creating a new spec
|
9
|
+
# spec_forge new spec users
|
10
|
+
#
|
11
|
+
# @example Creating a new factory
|
12
|
+
# spec_forge new factory user
|
13
|
+
#
|
5
14
|
class New < Command
|
6
15
|
command_name "new"
|
7
16
|
summary "Create a new spec or factory"
|
@@ -19,6 +28,9 @@ module SpecForge
|
|
19
28
|
|
20
29
|
aliases :generate, :g
|
21
30
|
|
31
|
+
#
|
32
|
+
# Creates a new spec or factory file in the corresponding directory using templates
|
33
|
+
#
|
22
34
|
def call
|
23
35
|
type = arguments.first.downcase
|
24
36
|
name = arguments.second
|
@@ -40,7 +52,7 @@ module SpecForge
|
|
40
52
|
def create_new_spec(name)
|
41
53
|
actions.template(
|
42
54
|
"new_spec.tt",
|
43
|
-
SpecForge.
|
55
|
+
SpecForge.forge_path.join("specs", "#{name}.yml"),
|
44
56
|
context: Proxy.new(name).call
|
45
57
|
)
|
46
58
|
end
|
@@ -48,20 +60,59 @@ module SpecForge
|
|
48
60
|
def create_new_factory(name)
|
49
61
|
actions.template(
|
50
62
|
"new_factory.tt",
|
51
|
-
SpecForge.
|
63
|
+
SpecForge.forge_path.join("factories", "#{name}.yml"),
|
52
64
|
context: Proxy.new(name).call
|
53
65
|
)
|
54
66
|
end
|
55
67
|
|
68
|
+
#
|
69
|
+
# Helper class for passing template variables to Thor templates
|
70
|
+
#
|
71
|
+
# @example Creating a proxy with a name
|
72
|
+
# proxy = Proxy.new("user")
|
73
|
+
# proxy.singular_name # => "user"
|
74
|
+
# proxy.plural_name # => "users"
|
75
|
+
#
|
56
76
|
class Proxy
|
57
|
-
|
77
|
+
#
|
78
|
+
# The original name passed to the command
|
79
|
+
#
|
80
|
+
# @return [String]
|
81
|
+
#
|
82
|
+
attr_reader :original_name
|
58
83
|
|
84
|
+
#
|
85
|
+
# The singular form of the name
|
86
|
+
#
|
87
|
+
# @return [String]
|
88
|
+
#
|
89
|
+
attr_reader :singular_name
|
90
|
+
|
91
|
+
#
|
92
|
+
# The plural form of the name
|
93
|
+
#
|
94
|
+
# @return [String]
|
95
|
+
#
|
96
|
+
attr_reader :plural_name
|
97
|
+
|
98
|
+
#
|
99
|
+
# Creates a new Proxy with the specified name
|
100
|
+
#
|
101
|
+
# @param name [String] The resource name to pluralize/singularize
|
102
|
+
#
|
103
|
+
# @return [Proxy] A new proxy instance
|
104
|
+
#
|
59
105
|
def initialize(name)
|
60
106
|
@original_name = name
|
61
107
|
@plural_name = name.pluralize
|
62
108
|
@singular_name = name.singularize
|
63
109
|
end
|
64
110
|
|
111
|
+
#
|
112
|
+
# Returns a binding for use in templates
|
113
|
+
#
|
114
|
+
# @return [Binding] A binding containing template variables
|
115
|
+
#
|
65
116
|
def call
|
66
117
|
binding
|
67
118
|
end
|
data/lib/spec_forge/cli/run.rb
CHANGED
@@ -2,6 +2,21 @@
|
|
2
2
|
|
3
3
|
module SpecForge
|
4
4
|
class CLI
|
5
|
+
#
|
6
|
+
# Command for running SpecForge tests with filtering options
|
7
|
+
#
|
8
|
+
# @example Running all specs
|
9
|
+
# spec_forge run
|
10
|
+
#
|
11
|
+
# @example Running specific file
|
12
|
+
# spec_forge run users
|
13
|
+
#
|
14
|
+
# @example Running specific spec
|
15
|
+
# spec_forge run users:create_user
|
16
|
+
#
|
17
|
+
# @example Running specific expectation
|
18
|
+
# spec_forge run users:create_user:"POST /users"
|
19
|
+
#
|
5
20
|
class Run < Command
|
6
21
|
command_name "run"
|
7
22
|
syntax "run [target]"
|
@@ -26,6 +41,9 @@ module SpecForge
|
|
26
41
|
|
27
42
|
# option "-n", "--no-docs", "Do not generate OpenAPI documentation on completion"
|
28
43
|
|
44
|
+
#
|
45
|
+
# Loads and runs all specs, or a subset of specs based on the provided arguments
|
46
|
+
#
|
29
47
|
def call
|
30
48
|
return SpecForge.run if arguments.blank?
|
31
49
|
|
@@ -53,6 +71,8 @@ module SpecForge
|
|
53
71
|
# Example with name:
|
54
72
|
# "users:show_user:'GET /users/:id - Returns 404 due to missing user'"
|
55
73
|
#
|
74
|
+
# @private
|
75
|
+
#
|
56
76
|
def extract_filter(input)
|
57
77
|
# Note: Only split 3 because the expectation name can have colons in them.
|
58
78
|
file_name, spec_name, expectation_name = input.split(":", 3).map(&:strip)
|
data/lib/spec_forge/cli.rb
CHANGED
@@ -7,15 +7,26 @@ require_relative "cli/new"
|
|
7
7
|
require_relative "cli/run"
|
8
8
|
|
9
9
|
module SpecForge
|
10
|
+
#
|
11
|
+
# Command-line interface for SpecForge that provides the overall command structure
|
12
|
+
# and entry point for the CLI functionality.
|
13
|
+
#
|
14
|
+
# @example Running the default command
|
15
|
+
# SpecForge::CLI.new.run
|
16
|
+
#
|
17
|
+
# @example Running a specific command
|
18
|
+
# # From command line: spec_forge init
|
19
|
+
#
|
10
20
|
class CLI
|
11
21
|
include Commander::Methods
|
12
22
|
|
13
|
-
COMMANDS = [Init, New, Run]
|
14
|
-
|
15
23
|
#
|
16
|
-
#
|
24
|
+
# @return [Array<SpecForge::CLI::Command>] All available commands
|
17
25
|
#
|
18
|
-
|
26
|
+
COMMANDS = [Init, New, Run].freeze
|
27
|
+
|
28
|
+
#
|
29
|
+
# Runs the CLI application, setting up program information and registering commands
|
19
30
|
#
|
20
31
|
def run
|
21
32
|
program :name, "SpecForge"
|
@@ -30,7 +41,7 @@ module SpecForge
|
|
30
41
|
end
|
31
42
|
|
32
43
|
#
|
33
|
-
# Registers the
|
44
|
+
# Registers the command classes with Commander
|
34
45
|
#
|
35
46
|
# @private
|
36
47
|
#
|