spec_forge 0.1.0 → 0.3.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/CHANGELOG.md +67 -2
- data/README.md +366 -143
- data/flake.nix +2 -2
- data/lib/spec_forge/attribute/chainable.rb +19 -16
- data/lib/spec_forge/attribute/factory.rb +6 -18
- data/lib/spec_forge/attribute/faker.rb +56 -20
- data/lib/spec_forge/attribute/literal.rb +4 -0
- data/lib/spec_forge/attribute/resolvable.rb +4 -6
- data/lib/spec_forge/attribute/resolvable_array.rb +4 -0
- data/lib/spec_forge/attribute/resolvable_hash.rb +4 -0
- data/lib/spec_forge/attribute/variable.rb +6 -13
- data/lib/spec_forge/attribute.rb +3 -12
- data/lib/spec_forge/cli/init.rb +2 -9
- data/lib/spec_forge/configuration.rb +58 -0
- data/lib/spec_forge/factory.rb +4 -4
- data/lib/spec_forge/http/backend.rb +42 -8
- data/lib/spec_forge/http/client.rb +2 -2
- data/lib/spec_forge/http/request.rb +11 -14
- data/lib/spec_forge/normalizer/configuration.rb +77 -0
- data/lib/spec_forge/normalizer/expectation.rb +1 -0
- data/lib/spec_forge/normalizer/spec.rb +1 -0
- data/lib/spec_forge/normalizer.rb +14 -11
- data/lib/spec_forge/runner.rb +98 -72
- data/lib/spec_forge/spec/expectation/constraint.rb +2 -5
- data/lib/spec_forge/spec/expectation.rb +32 -13
- data/lib/spec_forge/spec.rb +20 -14
- data/lib/spec_forge/version.rb +1 -1
- data/lib/spec_forge.rb +20 -11
- data/lib/templates/forge_helper.tt +48 -0
- data/spec_forge/forge_helper.rb +37 -0
- data/spec_forge/specs/users.yml +6 -4
- metadata +7 -8
- data/lib/spec_forge/config.rb +0 -84
- data/lib/spec_forge/environment.rb +0 -71
- data/lib/spec_forge/normalizer/config.rb +0 -104
- data/lib/templates/config.tt +0 -19
- data/spec_forge/config.yml +0 -19
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: spec_forge
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bryan
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2025-02-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -177,8 +177,7 @@ files:
|
|
177
177
|
- lib/spec_forge/cli/init.rb
|
178
178
|
- lib/spec_forge/cli/new.rb
|
179
179
|
- lib/spec_forge/cli/run.rb
|
180
|
-
- lib/spec_forge/
|
181
|
-
- lib/spec_forge/environment.rb
|
180
|
+
- lib/spec_forge/configuration.rb
|
182
181
|
- lib/spec_forge/error.rb
|
183
182
|
- lib/spec_forge/factory.rb
|
184
183
|
- lib/spec_forge/http.rb
|
@@ -187,7 +186,7 @@ files:
|
|
187
186
|
- lib/spec_forge/http/request.rb
|
188
187
|
- lib/spec_forge/http/verb.rb
|
189
188
|
- lib/spec_forge/normalizer.rb
|
190
|
-
- lib/spec_forge/normalizer/
|
189
|
+
- lib/spec_forge/normalizer/configuration.rb
|
191
190
|
- lib/spec_forge/normalizer/constraint.rb
|
192
191
|
- lib/spec_forge/normalizer/expectation.rb
|
193
192
|
- lib/spec_forge/normalizer/factory.rb
|
@@ -199,9 +198,9 @@ files:
|
|
199
198
|
- lib/spec_forge/spec/expectation/constraint.rb
|
200
199
|
- lib/spec_forge/type.rb
|
201
200
|
- lib/spec_forge/version.rb
|
202
|
-
- lib/templates/
|
203
|
-
- spec_forge/config.yml
|
201
|
+
- lib/templates/forge_helper.tt
|
204
202
|
- spec_forge/factories/user.yml
|
203
|
+
- spec_forge/forge_helper.rb
|
205
204
|
- spec_forge/specs/users.yml
|
206
205
|
homepage: https://github.com/itsthedevman/spec_forge
|
207
206
|
licenses:
|
@@ -220,7 +219,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
220
219
|
requirements:
|
221
220
|
- - ">="
|
222
221
|
- !ruby/object:Gem::Version
|
223
|
-
version: 3.
|
222
|
+
version: '3.2'
|
224
223
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
225
224
|
requirements:
|
226
225
|
- - ">="
|
data/lib/spec_forge/config.rb
DELETED
@@ -1,84 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module SpecForge
|
4
|
-
#
|
5
|
-
# Represents `config.yml`
|
6
|
-
#
|
7
|
-
class Config < Struct.new(:base_url, :authorization, :factories, :environment)
|
8
|
-
#
|
9
|
-
# authorization: {}
|
10
|
-
#
|
11
|
-
class Authorization < Struct.new(:header, :value)
|
12
|
-
attr_predicate :header, :value
|
13
|
-
end
|
14
|
-
|
15
|
-
#
|
16
|
-
# factories: {}
|
17
|
-
#
|
18
|
-
class Factories < Struct.new(:paths, :auto_discover)
|
19
|
-
attr_predicate :paths, :auto_discover
|
20
|
-
end
|
21
|
-
|
22
|
-
#
|
23
|
-
# environment: {}
|
24
|
-
#
|
25
|
-
class Environment < Struct.new(:use, :preload, :models_path)
|
26
|
-
attr_predicate :use, :preload, :models_path
|
27
|
-
|
28
|
-
def initialize(string_or_hash)
|
29
|
-
use, preload, models_path = "", "", ""
|
30
|
-
|
31
|
-
# "rails" or other preset
|
32
|
-
if string_or_hash.is_a?(String)
|
33
|
-
use = string_or_hash
|
34
|
-
else
|
35
|
-
string_or_hash => {use:, preload:, models_path:}
|
36
|
-
end
|
37
|
-
|
38
|
-
super(use:, preload:, models_path:)
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
############################################################################
|
43
|
-
|
44
|
-
#
|
45
|
-
# Creates a config with the user's config overlaid on the default
|
46
|
-
#
|
47
|
-
def initialize
|
48
|
-
config = Normalizer.default_config.deep_merge(load_from_file)
|
49
|
-
normalized = Normalizer.normalize_config!(config)
|
50
|
-
|
51
|
-
super(
|
52
|
-
base_url: normalized.delete(:base_url),
|
53
|
-
authorization: transform_authorization(normalized),
|
54
|
-
factories: transform_factories(normalized),
|
55
|
-
environment: transform_environment(normalized)
|
56
|
-
)
|
57
|
-
end
|
58
|
-
|
59
|
-
private
|
60
|
-
|
61
|
-
def load_from_file
|
62
|
-
path = SpecForge.forge.join("config.yml")
|
63
|
-
return unless File.exist?(path)
|
64
|
-
|
65
|
-
erb = ERB.new(File.read(path)).result
|
66
|
-
YAML.safe_load(erb, aliases: true, symbolize_names: true)
|
67
|
-
end
|
68
|
-
|
69
|
-
def transform_authorization(hash)
|
70
|
-
# The intention for authorization hash is to support different authorization schemes
|
71
|
-
# authorization: {default: {}, admin: {}, dev: {}}
|
72
|
-
# But I won't know exactly what will be defined - `to_struct` will handle that.
|
73
|
-
hash[:authorization].transform_values { |v| Authorization.new(**v) }.to_struct
|
74
|
-
end
|
75
|
-
|
76
|
-
def transform_factories(hash)
|
77
|
-
Factories.new(**hash[:factories])
|
78
|
-
end
|
79
|
-
|
80
|
-
def transform_environment(hash)
|
81
|
-
Environment.new(hash[:environment])
|
82
|
-
end
|
83
|
-
end
|
84
|
-
end
|
@@ -1,71 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module SpecForge
|
4
|
-
class Environment
|
5
|
-
attr_reader :environment, :framework
|
6
|
-
|
7
|
-
#
|
8
|
-
# Creates a new environment loader
|
9
|
-
#
|
10
|
-
# @param environment [Config::Environment] The environment to load
|
11
|
-
#
|
12
|
-
def initialize(environment = SpecForge.config.environment)
|
13
|
-
@environment = environment
|
14
|
-
@framework = environment.use
|
15
|
-
end
|
16
|
-
|
17
|
-
#
|
18
|
-
# Loads the environment
|
19
|
-
#
|
20
|
-
def load
|
21
|
-
load_framework
|
22
|
-
load_preload
|
23
|
-
|
24
|
-
self
|
25
|
-
end
|
26
|
-
|
27
|
-
private
|
28
|
-
|
29
|
-
def load_framework
|
30
|
-
case framework
|
31
|
-
when "rails"
|
32
|
-
load_rails
|
33
|
-
else
|
34
|
-
load_generic
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
def load_rails
|
39
|
-
path = SpecForge.root.join("config", "environment.rb")
|
40
|
-
|
41
|
-
if File.exist?(path)
|
42
|
-
require path
|
43
|
-
else
|
44
|
-
warn <<~WARNING.chomp
|
45
|
-
SpecForge warning: Config attribute "environment" set to "rails" but Rails environment (config/environment.rb) does not exist.
|
46
|
-
Factories or model-dependent features may not function as expected.
|
47
|
-
- For non-Rails projects, set your environment's 'models_path' or 'preload' in your config.yml
|
48
|
-
- To disable this warning, set 'environment: ""' in your config.yml.
|
49
|
-
WARNING
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
def load_generic
|
54
|
-
return unless environment.models_path? && environment.models_path.present?
|
55
|
-
|
56
|
-
models_path = SpecForge.root.join(environment.models_path)
|
57
|
-
return if !File.exist?(models_path)
|
58
|
-
|
59
|
-
Dir[models_path.join("**/*.rb")].each { |file| require file }
|
60
|
-
end
|
61
|
-
|
62
|
-
def load_preload
|
63
|
-
return unless environment.preload? && environment.preload.present?
|
64
|
-
|
65
|
-
path = SpecForge.root.join(environment.preload)
|
66
|
-
return if !File.exist?(path)
|
67
|
-
|
68
|
-
require path
|
69
|
-
end
|
70
|
-
end
|
71
|
-
end
|
@@ -1,104 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module SpecForge
|
4
|
-
class Normalizer
|
5
|
-
class Config < Normalizer
|
6
|
-
STRUCTURE = {
|
7
|
-
environment: {
|
8
|
-
# Allows for a shorthand:
|
9
|
-
# environment: rails
|
10
|
-
# Long form:
|
11
|
-
# environment:
|
12
|
-
# use: rails
|
13
|
-
type: [String, Hash],
|
14
|
-
default: "rails",
|
15
|
-
structure: {
|
16
|
-
use: {type: String, default: "rails"},
|
17
|
-
preload: {type: String, default: ""},
|
18
|
-
models_path: {
|
19
|
-
type: String,
|
20
|
-
aliases: %i[models],
|
21
|
-
default: ""
|
22
|
-
}
|
23
|
-
}
|
24
|
-
},
|
25
|
-
base_url: {type: String}, # Required
|
26
|
-
authorization: {
|
27
|
-
type: Hash,
|
28
|
-
default: {
|
29
|
-
# Default is a key on this hash
|
30
|
-
default: {}
|
31
|
-
},
|
32
|
-
structure: {
|
33
|
-
default: {
|
34
|
-
type: Hash,
|
35
|
-
structure: {
|
36
|
-
header: {type: String, default: ""},
|
37
|
-
value: {type: String, default: ""}
|
38
|
-
}
|
39
|
-
}
|
40
|
-
}
|
41
|
-
},
|
42
|
-
factories: {
|
43
|
-
type: Hash,
|
44
|
-
default: {},
|
45
|
-
structure: {
|
46
|
-
paths: {
|
47
|
-
type: Array,
|
48
|
-
default: []
|
49
|
-
},
|
50
|
-
auto_discover: {
|
51
|
-
type: [TrueClass, FalseClass],
|
52
|
-
default: true
|
53
|
-
}
|
54
|
-
}
|
55
|
-
}
|
56
|
-
}.freeze
|
57
|
-
end
|
58
|
-
|
59
|
-
# On Normalizer
|
60
|
-
class << self
|
61
|
-
#
|
62
|
-
# Generates an empty config hash
|
63
|
-
#
|
64
|
-
# @return [Hash]
|
65
|
-
#
|
66
|
-
def default_config
|
67
|
-
Config.default
|
68
|
-
end
|
69
|
-
|
70
|
-
#
|
71
|
-
# Normalizes a config hash by standardizing its keys while ensuring the required data
|
72
|
-
# is provided or defaulted.
|
73
|
-
# Raises InvalidStructureError if anything is missing/invalid type
|
74
|
-
#
|
75
|
-
# @param input [Hash] The hash to normalize
|
76
|
-
#
|
77
|
-
# @return [Hash] A normalized hash as a new instance
|
78
|
-
#
|
79
|
-
def normalize_config!(input)
|
80
|
-
raise_errors! do
|
81
|
-
normalize_config(input)
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
|
-
#
|
86
|
-
# Normalize a config hash
|
87
|
-
# Used internally by .normalize_config, but is available for utility
|
88
|
-
#
|
89
|
-
# @param config [Hash] Config representation as a Hash
|
90
|
-
#
|
91
|
-
# @return [Array] Two item array
|
92
|
-
# First - The normalized hash
|
93
|
-
# Second - Array of errors, if any
|
94
|
-
#
|
95
|
-
# @private
|
96
|
-
#
|
97
|
-
def normalize_config(config)
|
98
|
-
raise InvalidTypeError.new(config, Hash, for: "config") unless Type.hash?(config)
|
99
|
-
|
100
|
-
Normalizer::Config.new("config", config).normalize
|
101
|
-
end
|
102
|
-
end
|
103
|
-
end
|
104
|
-
end
|
data/lib/templates/config.tt
DELETED
@@ -1,19 +0,0 @@
|
|
1
|
-
# Sets the base URL prefix for all API requests. All test paths will be appended to this URL.
|
2
|
-
base_url: http://localhost:3000
|
3
|
-
|
4
|
-
# Configures the global authorization header and value for API requests.
|
5
|
-
authorization:
|
6
|
-
default:
|
7
|
-
header: Authorization
|
8
|
-
value: <%= default_authorization_value %>
|
9
|
-
|
10
|
-
factories:
|
11
|
-
## Optional: Overrides default FactoryBot definition paths for discovering factories
|
12
|
-
## By default, FactoryBot will look in "spec/factories" and "test/factories"
|
13
|
-
# paths:
|
14
|
-
# - custom/factories/path
|
15
|
-
|
16
|
-
## Optional: Enable/disable automatic factory discovery, default: true
|
17
|
-
## Note: Disabling auto discovery will only disable FactoryBot's auto discovery. Any factories
|
18
|
-
## defined in "spec_forge/factories" will still be loaded.
|
19
|
-
# auto_discover: false
|
data/spec_forge/config.yml
DELETED
@@ -1,19 +0,0 @@
|
|
1
|
-
# Sets the base URL prefix for all API requests. All test paths will be appended to this URL.
|
2
|
-
base_url: http://localhost:3000
|
3
|
-
|
4
|
-
# Configures the global authorization header and value for API requests.
|
5
|
-
authorization:
|
6
|
-
default:
|
7
|
-
header: Authorization
|
8
|
-
value: Bearer <%= ENV.fetch("API_TOKEN", "") %>
|
9
|
-
|
10
|
-
factories:
|
11
|
-
## Optional: Overrides default FactoryBot definition paths for discovering factories
|
12
|
-
## By default, FactoryBot will look in "spec/factories" and "test/factories"
|
13
|
-
# paths:
|
14
|
-
# - custom/factories/path
|
15
|
-
|
16
|
-
## Optional: Enable/disable automatic factory discovery, default: true
|
17
|
-
## Note: Disabling auto discovery will only disable FactoryBot's auto discovery. Any factories
|
18
|
-
## defined in "spec_forge/factories" will still be loaded.
|
19
|
-
# auto_discover: false
|