anyway_config 2.8.1 → 2.9.1

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.
@@ -0,0 +1,139 @@
1
+ # Testing configuration
2
+
3
+ ## Contents
4
+
5
+ 1. Test values live in YAML
6
+ 2. Test the config class
7
+ 3. Test code that uses a config
8
+ 4. ENV in tests
9
+ 5. CI and asset precompilation
10
+
11
+ ## 1. Test values live in YAML
12
+
13
+ Put deterministic values in the `test:` section of `config/<name>.yml`:
14
+
15
+ ```yaml
16
+ # config/fly_deploy.yml
17
+ test:
18
+ rest_api_url: http://localhost:3002/fake_fly
19
+ api_token: test-token
20
+ org_slug: test-org
21
+ ```
22
+
23
+ - The test suite then needs no secrets and no credentials key.
24
+ - Integrations that use a `configured?` predicate stay off in test when their secrets are absent.
25
+ - Use obviously fake values (`test-token`, `sk_test_fake`). Never copy real secrets.
26
+
27
+ ## 2. Test the config class
28
+
29
+ Test the logic that you added: predicates, derived values, adapters, validations.
30
+ Do not test that Anyway Config reads YAML.
31
+
32
+ Build an instance with explicit values. Other sources do not override them:
33
+
34
+ ```ruby
35
+ # spec/configs/smtp_config_spec.rb
36
+ RSpec.describe SMTPConfig do
37
+ subject(:config) { described_class.new(address: "smtp.example.com", port: 587, username: "u") }
38
+
39
+ it { is_expected.to be_configured }
40
+
41
+ specify do
42
+ expect(config.to_settings).to include(address: "smtp.example.com", user_name: "u")
43
+ end
44
+
45
+ context "without address" do
46
+ subject(:config) { described_class.new(address: nil) }
47
+
48
+ it { is_expected.not_to be_configured }
49
+ end
50
+ end
51
+ ```
52
+
53
+ Check the ENV mapping and type coercion with `with_env`.
54
+ The helper is included automatically for specs in `spec/configs/` or with `type: :config`:
55
+
56
+ ```ruby
57
+ RSpec.describe AnycableProConfig, type: :config do
58
+ it "parses a comma-separated safelist" do
59
+ with_env("ANYCABLE_PRO_GITHUB_SAFELIST" => "alice,bob") do
60
+ expect(described_class.new.github_safelist).to eq(%w[alice bob])
61
+ end
62
+ end
63
+ end
64
+ ```
65
+
66
+ `with_env` sets the variables, clears the Anyway ENV cache and restores both after the block.
67
+ Pass `nil` to delete a variable.
68
+ Elsewhere, require `"anyway/testing/helpers"` and include `Anyway::Testing::Helpers`
69
+ (this also works for Minitest).
70
+
71
+ Check `required` validations:
72
+
73
+ ```ruby
74
+ it "requires the magic link key" do
75
+ expect { described_class.new(magic_link_key: "") }
76
+ .to raise_error(Anyway::Config::ValidationError, /magic_link_key/)
77
+ end
78
+ ```
79
+
80
+ `required ..., env:` checks the environment once, when the class loads.
81
+ A stub in a test cannot change it, so do not test environment-scoped `required` in unit tests.
82
+
83
+ Check an environment-dependent default:
84
+
85
+ ```ruby
86
+ it "enables analytics in production by default" do
87
+ allow(Rails).to receive(:env).and_return(ActiveSupport::StringInquirer.new("production"))
88
+
89
+ expect(described_class.new(analytics_enabled: nil)).to be_analytics_enabled
90
+ end
91
+ ```
92
+
93
+ ## 3. Test code that uses a config
94
+
95
+ ### Inject a config
96
+
97
+ If the class takes the config as an argument, pass an instance with explicit values.
98
+ This is the preferred way:
99
+
100
+ ```ruby
101
+ let(:config) { FlyDeploy::Config.new(api_token: "t", rest_api_url: "http://fake") }
102
+ let(:client) { FlyDeploy::Client.new(config) }
103
+ ```
104
+
105
+ ### Stub the singleton
106
+
107
+ If the code calls the singleton (`AppConfig.cables_quota`), stub the class method.
108
+ `delegate_missing_to` defines `respond_to_missing?`, so verified partial doubles accept the stub:
109
+
110
+ ```ruby
111
+ before { allow(AppConfig).to receive(:analytics_enabled?).and_return(true) }
112
+ ```
113
+
114
+ Read expected values from the config instead of hard-coding them:
115
+
116
+ ```ruby
117
+ expect(account.cables_quota).to eq(AppConfig.cables_quota)
118
+ ```
119
+
120
+ ### Do not mutate the singleton
121
+
122
+ Do not assign attributes on the shared instance (`AppConfig.cables_quota = 10`).
123
+ The value leaks into other tests. Stub the method or inject an instance.
124
+
125
+ ## 4. ENV in tests
126
+
127
+ - The singleton loads once per process. `with_env` does not change it.
128
+ Use `with_env` together with `described_class.new`, not with `AppConfig.some_value`.
129
+ - Do not assign `ENV[...]` directly. Anyway Config caches parsed ENV,
130
+ and a missed restore leaks into other tests. Use `with_env`.
131
+ - A gem that reads `ENV` itself (for example, Pay) is outside Anyway Config.
132
+ Set and restore its variable in an `around` hook.
133
+
134
+ ## 5. CI and asset precompilation
135
+
136
+ - `bin/rails assets:precompile` with `SECRET_KEY_BASE_DUMMY=1` skips `required` validations.
137
+ - In other jobs without secrets, set `ANYWAY_SUPPRESS_VALIDATIONS=1`.
138
+ - Turn on `config.anyway_config.enforce_config_schema = true` so that the test suite
139
+ fails on a mistyped key in YAML or credentials.
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: anyway_config
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.8.1
4
+ version: 2.9.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vladimir Dementyev
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-07-23 00:00:00.000000000 Z
11
+ date: 2026-10-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ruby-next-core
@@ -130,7 +130,10 @@ files:
130
130
  - lib/.rbnext/3.0/anyway/config.rb
131
131
  - lib/.rbnext/3.0/anyway/loaders.rb
132
132
  - lib/.rbnext/3.0/anyway/loaders/base.rb
133
+ - lib/.rbnext/3.0/anyway/loaders/ejson.rb
133
134
  - lib/.rbnext/3.0/anyway/loaders/yaml.rb
135
+ - lib/.rbnext/3.0/anyway/rails/loaders/credentials.rb
136
+ - lib/.rbnext/3.0/anyway/rails/loaders/secrets.rb
134
137
  - lib/.rbnext/3.0/anyway/tracing.rb
135
138
  - lib/.rbnext/3.1/anyway/config.rb
136
139
  - lib/.rbnext/3.1/anyway/dynamic_config.rb
@@ -194,6 +197,10 @@ files:
194
197
  - lib/rails/commands/local_credentials/local_credentials_command.rb
195
198
  - sig/anyway_config.rbs
196
199
  - sig/manifest.yaml
200
+ - skills/anyway-config/SKILL.md
201
+ - skills/anyway-config/references/docs.md
202
+ - skills/anyway-config/references/organizing.md
203
+ - skills/anyway-config/references/testing.md
197
204
  homepage: http://github.com/palkan/anyway_config
198
205
  licenses:
199
206
  - MIT
@@ -204,6 +211,8 @@ metadata:
204
211
  homepage_uri: http://github.com/palkan/anyway_config
205
212
  source_code_uri: http://github.com/palkan/anyway_config
206
213
  funding_uri: https://github.com/sponsors/palkan
214
+ hyperdrive_targets: railties
215
+ hyperdrive_artifacts: skill
207
216
  post_install_message:
208
217
  rdoc_options: []
209
218
  require_paths: