synthra 0.1.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.
Files changed (302) hide show
  1. checksums.yaml +7 -0
  2. data/.rspec +4 -0
  3. data/.rubocop.yml +40 -0
  4. data/.yardopts +18 -0
  5. data/ACCESS_DOCS.md +116 -0
  6. data/ADVANCED_FEATURES_SUMMARY.md +245 -0
  7. data/CHANGELOG.md +498 -0
  8. data/CODE_OF_CONDUCT.md +122 -0
  9. data/CONTRIBUTING.md +307 -0
  10. data/DOCUMENTATION.md +204 -0
  11. data/DOCUMENTATION_GUIDE.md +194 -0
  12. data/LICENSE +22 -0
  13. data/README.md +1458 -0
  14. data/Rakefile +128 -0
  15. data/benchmark/README.md +591 -0
  16. data/benchmark/batch_generation.rb +63 -0
  17. data/benchmark/engine_comparison.rb +295 -0
  18. data/benchmark/single_record.rb +108 -0
  19. data/benchmark/streaming.rb +74 -0
  20. data/docs/ACTIVERECORD_INFERENCE.md +524 -0
  21. data/docs/API_SERVER.md +278 -0
  22. data/docs/CONFIG_FILE.md +315 -0
  23. data/docs/DATA_CONTRACTS.md +312 -0
  24. data/docs/ENHANCED_REPL.md +304 -0
  25. data/docs/FACTORY_BOT.md +271 -0
  26. data/docs/GITHUB_ACTION.md +420 -0
  27. data/docs/GRAPHQL_EXPORT.md +303 -0
  28. data/docs/GRAPHQL_FEDERATION.md +651 -0
  29. data/docs/HOW_TO_GENERATE_DOCS.md +252 -0
  30. data/docs/LSP.md +189 -0
  31. data/docs/MIGRATION_GENERATOR.md +547 -0
  32. data/docs/MOCK_SERVER.md +280 -0
  33. data/docs/NATIVE_ENGINE.md +298 -0
  34. data/docs/OPENAPI_EXPORT.md +252 -0
  35. data/docs/PERFORMANCE_MODE.md +228 -0
  36. data/docs/PERSONAS.md +547 -0
  37. data/docs/PROPERTY_TESTING.md +284 -0
  38. data/docs/PROTOBUF_EXPORT.md +276 -0
  39. data/docs/QUALITY_METRICS.md +555 -0
  40. data/docs/QUICK_REFERENCE.md +88 -0
  41. data/docs/RAILS_ENGINE.md +404 -0
  42. data/docs/RAILS_INTEGRATION.md +454 -0
  43. data/docs/README.md +175 -0
  44. data/docs/REPL_QUICK_REFERENCE.md +149 -0
  45. data/docs/RUST_INTEGRATION_GUIDE.md +1376 -0
  46. data/docs/SCENARIOS.md +576 -0
  47. data/docs/SECURITY_TESTING.md +318 -0
  48. data/docs/SNAPSHOT_TESTING.md +308 -0
  49. data/docs/STRING_TEXT_TYPES_REFERENCE.md +512 -0
  50. data/docs/TERRAFORM_EXPORT.md +447 -0
  51. data/docs/TIME_TRAVEL.md +507 -0
  52. data/docs/USAGE_GUIDE.md +980 -0
  53. data/docs/WEBHOOK_SIMULATOR.md +579 -0
  54. data/docs/advanced_features.md +183 -0
  55. data/docs/api_reference.md +153 -0
  56. data/docs/behaviors.md +138 -0
  57. data/docs/best_practices.md +191 -0
  58. data/docs/dsl_reference.md +172 -0
  59. data/docs/examples.md +162 -0
  60. data/docs/generation_modes.md +125 -0
  61. data/docs/getting_started.md +92 -0
  62. data/docs/index.html +177 -0
  63. data/docs/strategic/CLOUD_REGISTRY_ARCHITECTURE.md +268 -0
  64. data/docs/strategic/SIMD_OPTIMIZATION_STRATEGY.md +153 -0
  65. data/docs/troubleshooting.md +215 -0
  66. data/docs/type_reference.md +224 -0
  67. data/examples/hostile_mode_demo.rb +64 -0
  68. data/exe/synthra +6 -0
  69. data/ext/synthra_native/Cargo.lock +972 -0
  70. data/ext/synthra_native/Cargo.toml +46 -0
  71. data/ext/synthra_native/extconf.rb +41 -0
  72. data/ext/synthra_native/src/generator.rs +397 -0
  73. data/ext/synthra_native/src/lib.rs +229 -0
  74. data/ext/synthra_native/src/types.rs +1485 -0
  75. data/lib/generators/synthra/install_generator.rb +86 -0
  76. data/lib/generators/synthra/templates/api_response.dsl +15 -0
  77. data/lib/generators/synthra/templates/fake_data.rake +116 -0
  78. data/lib/generators/synthra/templates/synthra.yml +31 -0
  79. data/lib/generators/synthra/templates/synthra_support.rb +19 -0
  80. data/lib/generators/synthra/templates/user.dsl +11 -0
  81. data/lib/synthra/activerecord_inference.rb +394 -0
  82. data/lib/synthra/api.rb +381 -0
  83. data/lib/synthra/api_server.rb +718 -0
  84. data/lib/synthra/behaviors/applicator.rb +165 -0
  85. data/lib/synthra/behaviors/base.rb +155 -0
  86. data/lib/synthra/behaviors/close_connection.rb +60 -0
  87. data/lib/synthra/behaviors/deprecated.rb +100 -0
  88. data/lib/synthra/behaviors/failure.rb +69 -0
  89. data/lib/synthra/behaviors/latency.rb +103 -0
  90. data/lib/synthra/behaviors/partial_data.rb +83 -0
  91. data/lib/synthra/behaviors/randomize_order.rb +74 -0
  92. data/lib/synthra/behaviors/registry.rb +238 -0
  93. data/lib/synthra/behaviors/simulate_error.rb +79 -0
  94. data/lib/synthra/cli/commands/base.rb +105 -0
  95. data/lib/synthra/cli/commands/diff.rb +227 -0
  96. data/lib/synthra/cli/commands/docs.rb +67 -0
  97. data/lib/synthra/cli/commands/export.rb +150 -0
  98. data/lib/synthra/cli/commands/generate.rb +72 -0
  99. data/lib/synthra/cli/commands/import.rb +80 -0
  100. data/lib/synthra/cli/commands/lint.rb +53 -0
  101. data/lib/synthra/cli/commands/live.rb +57 -0
  102. data/lib/synthra/cli/commands/seed.rb +99 -0
  103. data/lib/synthra/cli/commands/validate.rb +28 -0
  104. data/lib/synthra/cli.rb +2471 -0
  105. data/lib/synthra/config_file.rb +129 -0
  106. data/lib/synthra/configuration.rb +281 -0
  107. data/lib/synthra/contracts_registry.rb +408 -0
  108. data/lib/synthra/database_seeder.rb +268 -0
  109. data/lib/synthra/deterministic_ids.rb +218 -0
  110. data/lib/synthra/documentation_generator.rb +414 -0
  111. data/lib/synthra/engine.rb +251 -0
  112. data/lib/synthra/errors.rb +1169 -0
  113. data/lib/synthra/export/base.rb +85 -0
  114. data/lib/synthra/export/csv.rb +101 -0
  115. data/lib/synthra/export/graphql.rb +266 -0
  116. data/lib/synthra/export/graphql_federation.rb +377 -0
  117. data/lib/synthra/export/graphviz.rb +258 -0
  118. data/lib/synthra/export/javascript.rb +327 -0
  119. data/lib/synthra/export/json_data.rb +61 -0
  120. data/lib/synthra/export/json_schema.rb +290 -0
  121. data/lib/synthra/export/openapi.rb +514 -0
  122. data/lib/synthra/export/protobuf.rb +483 -0
  123. data/lib/synthra/export/python.rb +560 -0
  124. data/lib/synthra/export/sql.rb +381 -0
  125. data/lib/synthra/export/sql_insert.rb +152 -0
  126. data/lib/synthra/export/terraform.rb +501 -0
  127. data/lib/synthra/export/type_mapping.rb +389 -0
  128. data/lib/synthra/export/typescript.rb +300 -0
  129. data/lib/synthra/export/xml_data.rb +104 -0
  130. data/lib/synthra/export/yaml_data.rb +56 -0
  131. data/lib/synthra/export.rb +404 -0
  132. data/lib/synthra/factory_bot_integration.rb +157 -0
  133. data/lib/synthra/field.rb +440 -0
  134. data/lib/synthra/functions/registry.rb +104 -0
  135. data/lib/synthra/generator/context.rb +372 -0
  136. data/lib/synthra/generator/engine.rb +336 -0
  137. data/lib/synthra/generator/faker_adapter.rb +425 -0
  138. data/lib/synthra/generator/modes.rb +444 -0
  139. data/lib/synthra/generator/resolver.rb +256 -0
  140. data/lib/synthra/generator/rng.rb +273 -0
  141. data/lib/synthra/generator/streamer.rb +63 -0
  142. data/lib/synthra/generator/uniqueness.rb +118 -0
  143. data/lib/synthra/initializer.rb +97 -0
  144. data/lib/synthra/limits.rb +279 -0
  145. data/lib/synthra/live_preview.rb +518 -0
  146. data/lib/synthra/loader_config.rb +78 -0
  147. data/lib/synthra/lsp/server.rb +689 -0
  148. data/lib/synthra/migration_generator.rb +301 -0
  149. data/lib/synthra/mixin.rb +174 -0
  150. data/lib/synthra/mock_server.rb +458 -0
  151. data/lib/synthra/native_engine.rb +304 -0
  152. data/lib/synthra/openapi_importer.rb +228 -0
  153. data/lib/synthra/output/json_formatter.rb +40 -0
  154. data/lib/synthra/output/ndjson_formatter.rb +55 -0
  155. data/lib/synthra/parser/ast.rb +1287 -0
  156. data/lib/synthra/parser/lexer.rb +1152 -0
  157. data/lib/synthra/parser/parser.rb +1664 -0
  158. data/lib/synthra/parser/tokens.rb +461 -0
  159. data/lib/synthra/performance_mode.rb +364 -0
  160. data/lib/synthra/personas.rb +397 -0
  161. data/lib/synthra/property_testing.rb +172 -0
  162. data/lib/synthra/quality_metrics.rb +405 -0
  163. data/lib/synthra/rails_test_helper.rb +248 -0
  164. data/lib/synthra/registry.rb +533 -0
  165. data/lib/synthra/relationships.rb +193 -0
  166. data/lib/synthra/repl/enhanced_repl.rb +607 -0
  167. data/lib/synthra/repl/formatter.rb +191 -0
  168. data/lib/synthra/scenarios.rb +423 -0
  169. data/lib/synthra/schema.rb +605 -0
  170. data/lib/synthra/schema_inheritance.rb +104 -0
  171. data/lib/synthra/schema_versioning.rb +212 -0
  172. data/lib/synthra/snapshot_testing.rb +199 -0
  173. data/lib/synthra/time_travel.rb +338 -0
  174. data/lib/synthra/type_definitions.rb +274 -0
  175. data/lib/synthra/types/address_location/addresses.rb +125 -0
  176. data/lib/synthra/types/address_location/airports.rb +200 -0
  177. data/lib/synthra/types/address_location/banks_hospitals.rb +207 -0
  178. data/lib/synthra/types/address_location/locations.rb +406 -0
  179. data/lib/synthra/types/base.rb +48 -0
  180. data/lib/synthra/types/commerce_products/commerce.rb +119 -0
  181. data/lib/synthra/types/commerce_products/companies.rb +71 -0
  182. data/lib/synthra/types/commerce_products/construction.rb +126 -0
  183. data/lib/synthra/types/commerce_products/products.rb +205 -0
  184. data/lib/synthra/types/core/collections.rb +513 -0
  185. data/lib/synthra/types/core/defaults.rb +76 -0
  186. data/lib/synthra/types/core/enums.rb +102 -0
  187. data/lib/synthra/types/core/identifiers.rb +445 -0
  188. data/lib/synthra/types/core/primitives.rb +586 -0
  189. data/lib/synthra/types/core/references.rb +466 -0
  190. data/lib/synthra/types/core/sequences.rb +304 -0
  191. data/lib/synthra/types/crypto/crypto.rb +162 -0
  192. data/lib/synthra/types/date_time/dates.rb +387 -0
  193. data/lib/synthra/types/finance_banking/banking.rb +424 -0
  194. data/lib/synthra/types/finance_banking/credit_cards.rb +24 -0
  195. data/lib/synthra/types/finance_banking/identifiers.rb +93 -0
  196. data/lib/synthra/types/formula.rb +184 -0
  197. data/lib/synthra/types/health_medical/medical.rb +150 -0
  198. data/lib/synthra/types/hostile_payloads.rb +122 -0
  199. data/lib/synthra/types/json_array.rb +51 -0
  200. data/lib/synthra/types/media_entertainment/media.rb +62 -0
  201. data/lib/synthra/types/naughty_string.rb +30 -0
  202. data/lib/synthra/types/personal_names/chinese.rb +41 -0
  203. data/lib/synthra/types/personal_names/identifiers.rb +187 -0
  204. data/lib/synthra/types/personal_names/names.rb +246 -0
  205. data/lib/synthra/types/personal_names/national_id.rb +89 -0
  206. data/lib/synthra/types/personal_names/titles_suffixes.rb +41 -0
  207. data/lib/synthra/types/regex.rb +248 -0
  208. data/lib/synthra/types/registry.rb +182 -0
  209. data/lib/synthra/types/repeating_element.rb +50 -0
  210. data/lib/synthra/types/scenario.rb +29 -0
  211. data/lib/synthra/types/technology_internet/apps.rb +67 -0
  212. data/lib/synthra/types/technology_internet/communication.rb +162 -0
  213. data/lib/synthra/types/technology_internet/devices.rb +80 -0
  214. data/lib/synthra/types/technology_internet/formats.rb +139 -0
  215. data/lib/synthra/types/technology_internet/networking.rb +143 -0
  216. data/lib/synthra/types/template.rb +92 -0
  217. data/lib/synthra/types/text_content/business.rb +128 -0
  218. data/lib/synthra/types/text_content/colors.rb +70 -0
  219. data/lib/synthra/types/text_content/misc.rb +237 -0
  220. data/lib/synthra/types/text_content/security.rb +130 -0
  221. data/lib/synthra/types/text_content/text_generation.rb +532 -0
  222. data/lib/synthra/types/travel/travel.rb +150 -0
  223. data/lib/synthra/utils/string_distance.rb +133 -0
  224. data/lib/synthra/validator/dsl_validator.rb +339 -0
  225. data/lib/synthra/validator/path_validator.rb +615 -0
  226. data/lib/synthra/version.rb +35 -0
  227. data/lib/synthra/webhook_simulator.rb +341 -0
  228. data/lib/synthra.rb +259 -0
  229. data/schemas/address.dsl +16 -0
  230. data/schemas/api_response.dsl +8 -0
  231. data/schemas/error_payload.dsl +9 -0
  232. data/schemas/order.dsl +10 -0
  233. data/schemas/order_item.dsl +8 -0
  234. data/schemas/payment.dsl +11 -0
  235. data/schemas/social_post.dsl +13 -0
  236. data/schemas/user.dsl +10 -0
  237. data/scripts/batch_fix_all.rb +96 -0
  238. data/scripts/delete_old_files.rb +32 -0
  239. data/scripts/fix_all_grouped_files.rb +137 -0
  240. data/scripts/fix_all_indentation.rb +48 -0
  241. data/scripts/fix_all_syntax.rb +124 -0
  242. data/scripts/fix_grouped_files.rb +184 -0
  243. data/scripts/fix_syntax_errors.rb +108 -0
  244. data/scripts/group_domain_types.rb +112 -0
  245. data/scripts/group_domain_types_fixed.rb +150 -0
  246. data/scripts/merge_domains_to_one_file.rb +68 -0
  247. data/scripts/move_existing_types.rb +130 -0
  248. data/scripts/split_grouped_types.rb +142 -0
  249. data/tech_docs/README.md +134 -0
  250. data/tech_docs/advanced/streaming.md +405 -0
  251. data/tech_docs/advanced/thread_safety.md +253 -0
  252. data/tech_docs/api/overview.md +485 -0
  253. data/tech_docs/appendices/type_chart.md +193 -0
  254. data/tech_docs/basic_concepts.md +383 -0
  255. data/tech_docs/behaviors/overview.md +346 -0
  256. data/tech_docs/dsl/complex_types.md +790 -0
  257. data/tech_docs/dsl/core_types.md +464 -0
  258. data/tech_docs/dsl/datetime_types.md +325 -0
  259. data/tech_docs/dsl/field_modifiers.md +414 -0
  260. data/tech_docs/dsl/grammar.md +431 -0
  261. data/tech_docs/dsl/schema_definition.md +399 -0
  262. data/tech_docs/export/README.md +276 -0
  263. data/tech_docs/installation.md +273 -0
  264. data/tech_docs/integration/ci_cd.md +707 -0
  265. data/tech_docs/integration/ci_cd_guide.md +579 -0
  266. data/tech_docs/integration/factory_bot.md +485 -0
  267. data/tech_docs/integration/rails.md +630 -0
  268. data/tech_docs/integration/rspec.md +449 -0
  269. data/tech_docs/modes/overview.md +350 -0
  270. data/tech_docs/performance/NATIVE_RUST_EXTENSION.md +1270 -0
  271. data/tech_docs/performance/OPTIMIZATION_GUIDE.md +901 -0
  272. data/tech_docs/quick_start.md +256 -0
  273. data/tech_docs/templates/README.md +805 -0
  274. data/tech_docs/tutorials/advanced.md +371 -0
  275. data/tech_docs/tutorials/getting_started.md +189 -0
  276. data/tech_docs/tutorials/intermediate.md +231 -0
  277. data/tech_docs/tutorials/template_gallery.md +569 -0
  278. data/tech_example/01_basic_usage.rb +238 -0
  279. data/tech_example/02_types_demo.rb +336 -0
  280. data/tech_example/04_cli_usage.md +429 -0
  281. data/tech_example/05_database_seeding.rb +283 -0
  282. data/tech_example/07_rspec_integration.rb +359 -0
  283. data/tech_example/10_custom_types.rb +387 -0
  284. data/tech_example/12_behaviors.rb +372 -0
  285. data/tech_example/13_twitter_dm_example.rb +120 -0
  286. data/tech_example/14_exact_json_structure.rb +253 -0
  287. data/tech_example/16_lsp_server.rb +56 -0
  288. data/tech_example/17_property_testing.rb +92 -0
  289. data/tech_example/18_enhanced_repl.rb +120 -0
  290. data/tech_example/19_security_fuzzing.rb +145 -0
  291. data/tech_example/NEW_FEATURES.md +169 -0
  292. data/tech_example/README.md +118 -0
  293. data/tech_example/schemas/api_response.dsl +123 -0
  294. data/tech_example/schemas/ecommerce.dsl +121 -0
  295. data/tech_example/schemas/twitter_dm.dsl +109 -0
  296. data/tech_example/schemas/user.dsl +36 -0
  297. data/vscode-extension/README.md +246 -0
  298. data/vscode-extension/language-configuration.json +31 -0
  299. data/vscode-extension/package.json +55 -0
  300. data/vscode-extension/snippets/fakedatadsl.json +198 -0
  301. data/vscode-extension/syntaxes/fakedatadsl.tmLanguage.json +128 -0
  302. metadata +478 -0
@@ -0,0 +1,449 @@
1
+ # RSpec Integration
2
+
3
+ Using FakeDataDSL with RSpec for testing.
4
+
5
+ ## Table of Contents
6
+
7
+ - [Setup](#setup)
8
+ - [Basic Usage](#basic-usage)
9
+ - [Shared Contexts](#shared-contexts)
10
+ - [Testing Modes](#testing-modes)
11
+ - [Factory Patterns](#factory-patterns)
12
+ - [Best Practices](#best-practices)
13
+
14
+ ---
15
+
16
+ ## Setup
17
+
18
+ ### Configuration
19
+
20
+ Create `spec/support/fake_data.rb`:
21
+
22
+ ```ruby
23
+ require 'fake_data_dsl'
24
+
25
+ RSpec.configure do |config|
26
+ config.before(:suite) do
27
+ # Load schemas once
28
+ $fake_data_registry = FakeDataDSL::Registry.new
29
+ $fake_data_registry.load_dir('spec/schemas/')
30
+ end
31
+ end
32
+
33
+ # Helper module
34
+ module FakeDataHelpers
35
+ def fake_schema(name)
36
+ $fake_data_registry.schema(name.to_s.camelize)
37
+ end
38
+
39
+ def fake(name, **options)
40
+ fake_schema(name).generate(**options)
41
+ end
42
+
43
+ def fake_many(name, count, **options)
44
+ fake_schema(name).generate_many(count, **options)
45
+ end
46
+ end
47
+
48
+ RSpec.configure do |config|
49
+ config.include FakeDataHelpers
50
+ end
51
+ ```
52
+
53
+ ### Directory Structure
54
+
55
+ ```
56
+ spec/
57
+ ├── schemas/
58
+ │ ├── user.dsl
59
+ │ ├── order.dsl
60
+ │ └── product.dsl
61
+ ├── support/
62
+ │ └── fake_data.rb
63
+ └── spec_helper.rb
64
+ ```
65
+
66
+ ### spec_helper.rb
67
+
68
+ ```ruby
69
+ require_relative 'support/fake_data'
70
+ ```
71
+
72
+ ---
73
+
74
+ ## Basic Usage
75
+
76
+ ### Simple Test
77
+
78
+ ```ruby
79
+ RSpec.describe User do
80
+ let(:user_data) { fake(:user) }
81
+
82
+ it "creates a valid user" do
83
+ user = User.new(user_data)
84
+ expect(user).to be_valid
85
+ end
86
+ end
87
+ ```
88
+
89
+ ### With Overrides
90
+
91
+ ```ruby
92
+ RSpec.describe User do
93
+ let(:admin_data) { fake(:user).merge('role' => 'admin') }
94
+
95
+ it "creates an admin" do
96
+ admin = User.new(admin_data)
97
+ expect(admin.role).to eq('admin')
98
+ end
99
+ end
100
+ ```
101
+
102
+ ### Deterministic Tests
103
+
104
+ ```ruby
105
+ RSpec.describe User do
106
+ let(:seed) { 12345 }
107
+ let(:user_data) { fake(:user, seed: seed) }
108
+
109
+ it "generates consistent data" do
110
+ # Same seed = same data every time
111
+ expect(user_data['email']).to eq(fake(:user, seed: seed)['email'])
112
+ end
113
+ end
114
+ ```
115
+
116
+ ---
117
+
118
+ ## Shared Contexts
119
+
120
+ ### Basic Context
121
+
122
+ ```ruby
123
+ # spec/support/contexts/fake_data_context.rb
124
+ RSpec.shared_context 'with fake data' do
125
+ let(:registry) { $fake_data_registry }
126
+
127
+ def build_fake(schema_name, **overrides)
128
+ data = registry.schema(schema_name.to_s.camelize).generate
129
+ data.merge(overrides.stringify_keys)
130
+ end
131
+
132
+ def create_fake(schema_name, **overrides)
133
+ data = build_fake(schema_name, **overrides)
134
+ model_class = schema_name.to_s.camelize.constantize
135
+ model_class.create!(data)
136
+ end
137
+ end
138
+ ```
139
+
140
+ ### Usage
141
+
142
+ ```ruby
143
+ RSpec.describe OrdersController do
144
+ include_context 'with fake data'
145
+
146
+ let(:user) { create_fake(:user) }
147
+ let(:order) { create_fake(:order, user_id: user.id) }
148
+
149
+ describe "GET #show" do
150
+ it "returns the order" do
151
+ get :show, params: { id: order.id }
152
+ expect(response).to be_successful
153
+ end
154
+ end
155
+ end
156
+ ```
157
+
158
+ ### Mode-Specific Context
159
+
160
+ ```ruby
161
+ RSpec.shared_context 'with edge case data' do
162
+ let(:user_data) { fake(:user, mode: :edge) }
163
+ let(:order_data) { fake(:order, mode: :edge) }
164
+ end
165
+
166
+ RSpec.shared_context 'with invalid data' do
167
+ let(:user_data) { fake(:user, mode: :invalid) }
168
+ let(:order_data) { fake(:order, mode: :invalid) }
169
+ end
170
+ ```
171
+
172
+ ---
173
+
174
+ ## Testing Modes
175
+
176
+ ### Random Mode (Default)
177
+
178
+ ```ruby
179
+ RSpec.describe "Happy path" do
180
+ let(:data) { fake(:user, mode: :random) }
181
+
182
+ it "processes valid data" do
183
+ expect(process(data)).to be_success
184
+ end
185
+ end
186
+ ```
187
+
188
+ ### Edge Mode
189
+
190
+ ```ruby
191
+ RSpec.describe "Edge cases" do
192
+ let(:data) { fake(:user, mode: :edge) }
193
+
194
+ it "handles edge cases" do
195
+ # Edge data may include empty strings, min/max values
196
+ expect { process(data) }.not_to raise_error
197
+ end
198
+ end
199
+ ```
200
+
201
+ ### Invalid Mode
202
+
203
+ ```ruby
204
+ RSpec.describe "Validation" do
205
+ let(:data) { fake(:user, mode: :invalid) }
206
+
207
+ it "rejects invalid data" do
208
+ user = User.new(data)
209
+ expect(user).not_to be_valid
210
+ end
211
+ end
212
+ ```
213
+
214
+ ### Comprehensive Testing
215
+
216
+ ```ruby
217
+ RSpec.describe User do
218
+ describe "handles all input types" do
219
+ %i[random edge invalid mixed].each do |mode|
220
+ context "with #{mode} data" do
221
+ let(:data) { fake(:user, mode: mode) }
222
+
223
+ it "doesn't crash" do
224
+ expect { User.new(data).validate }.not_to raise_error
225
+ end
226
+ end
227
+ end
228
+ end
229
+ end
230
+ ```
231
+
232
+ ---
233
+
234
+ ## Factory Patterns
235
+
236
+ ### Factory-Like Interface
237
+
238
+ ```ruby
239
+ # spec/support/fake_factories.rb
240
+ module FakeFactories
241
+ extend self
242
+
243
+ def registry
244
+ @registry ||= FakeDataDSL::Registry.new.tap do |r|
245
+ r.load_dir('spec/schemas/')
246
+ end
247
+ end
248
+
249
+ def build(name, **attrs)
250
+ data = registry.schema(name.to_s.camelize).generate
251
+ data.merge(attrs.stringify_keys)
252
+ end
253
+
254
+ def create(name, **attrs)
255
+ data = build(name, **attrs)
256
+ name.to_s.camelize.constantize.create!(data)
257
+ end
258
+
259
+ def build_list(name, count, **attrs)
260
+ count.times.map { build(name, **attrs) }
261
+ end
262
+
263
+ def create_list(name, count, **attrs)
264
+ count.times.map { create(name, **attrs) }
265
+ end
266
+ end
267
+
268
+ # Global methods
269
+ def build(name, **attrs)
270
+ FakeFactories.build(name, **attrs)
271
+ end
272
+
273
+ def create(name, **attrs)
274
+ FakeFactories.create(name, **attrs)
275
+ end
276
+
277
+ def build_list(name, count, **attrs)
278
+ FakeFactories.build_list(name, count, **attrs)
279
+ end
280
+
281
+ def create_list(name, count, **attrs)
282
+ FakeFactories.create_list(name, count, **attrs)
283
+ end
284
+ ```
285
+
286
+ ### Usage
287
+
288
+ ```ruby
289
+ RSpec.describe "with factory pattern" do
290
+ let(:user) { create(:user) }
291
+ let(:admin) { create(:user, role: 'admin') }
292
+ let(:users) { create_list(:user, 10) }
293
+
294
+ it "creates related records" do
295
+ order = create(:order, user_id: user.id)
296
+ expect(order.user).to eq(user)
297
+ end
298
+ end
299
+ ```
300
+
301
+ ### Traits Pattern
302
+
303
+ ```ruby
304
+ module FakeFactories
305
+ TRAITS = {
306
+ user: {
307
+ admin: { role: 'admin' },
308
+ verified: { verified: true, verified_at: Time.current },
309
+ inactive: { status: 'inactive' }
310
+ },
311
+ order: {
312
+ completed: { status: 'completed', completed_at: Time.current },
313
+ cancelled: { status: 'cancelled', cancelled_at: Time.current }
314
+ }
315
+ }
316
+
317
+ def build(name, *traits, **attrs)
318
+ data = registry.schema(name.to_s.camelize).generate
319
+
320
+ # Apply traits
321
+ traits.each do |trait|
322
+ trait_attrs = TRAITS.dig(name, trait) || {}
323
+ data.merge!(trait_attrs.stringify_keys)
324
+ end
325
+
326
+ data.merge(attrs.stringify_keys)
327
+ end
328
+ end
329
+
330
+ # Usage
331
+ user = build(:user, :admin, :verified)
332
+ order = build(:order, :completed)
333
+ ```
334
+
335
+ ---
336
+
337
+ ## Best Practices
338
+
339
+ ### 1. Use Deterministic Seeds for Debugging
340
+
341
+ ```ruby
342
+ RSpec.describe "Flaky test debugging" do
343
+ # Run with specific seed to reproduce
344
+ let(:seed) { ENV['FAKE_SEED']&.to_i || rand(1..10000) }
345
+ let(:data) { fake(:user, seed: seed) }
346
+
347
+ before do
348
+ puts "Using seed: #{seed}" if ENV['DEBUG']
349
+ end
350
+
351
+ it "processes data" do
352
+ # If fails, rerun with FAKE_SEED=<seed> to reproduce
353
+ expect(process(data)).to be_success
354
+ end
355
+ end
356
+ ```
357
+
358
+ ### 2. Test All Modes Systematically
359
+
360
+ ```ruby
361
+ RSpec.describe UserService do
362
+ shared_examples "handles input" do |mode|
363
+ let(:input) { fake(:user, mode: mode) }
364
+
365
+ it "doesn't crash with #{mode} data" do
366
+ expect { subject.process(input) }.not_to raise_error
367
+ end
368
+ end
369
+
370
+ include_examples "handles input", :random
371
+ include_examples "handles input", :edge
372
+ include_examples "handles input", :invalid
373
+ end
374
+ ```
375
+
376
+ ### 3. Isolate Schema Loading
377
+
378
+ ```ruby
379
+ # Load once, use many times
380
+ RSpec.configure do |config|
381
+ config.before(:suite) do
382
+ $fake_data_registry = FakeDataDSL::Registry.new
383
+ $fake_data_registry.load_dir('spec/schemas/')
384
+ end
385
+ end
386
+ ```
387
+
388
+ ### 4. Use Overrides Sparingly
389
+
390
+ ```ruby
391
+ # Good - minimal override for specific test
392
+ let(:admin) { fake(:user).merge('role' => 'admin') }
393
+
394
+ # Avoid - too many overrides, defeats purpose
395
+ let(:user) do
396
+ fake(:user).merge(
397
+ 'name' => 'Test User',
398
+ 'email' => 'test@example.com',
399
+ 'age' => 30,
400
+ # ...
401
+ )
402
+ end
403
+ ```
404
+
405
+ ### 5. Clean Up Generated Data
406
+
407
+ ```ruby
408
+ RSpec.configure do |config|
409
+ config.after(:each) do
410
+ # If using database
411
+ DatabaseCleaner.clean
412
+ end
413
+ end
414
+ ```
415
+
416
+ ---
417
+
418
+ ## Request Specs
419
+
420
+ ```ruby
421
+ RSpec.describe "Users API", type: :request do
422
+ describe "POST /api/users" do
423
+ let(:user_params) { fake(:user).slice('name', 'email') }
424
+
425
+ it "creates user" do
426
+ post '/api/users', params: { user: user_params }
427
+ expect(response).to have_http_status(:created)
428
+ end
429
+
430
+ context "with invalid data" do
431
+ let(:user_params) { fake(:user, mode: :invalid).slice('name', 'email') }
432
+
433
+ it "returns errors" do
434
+ post '/api/users', params: { user: user_params }
435
+ expect(response).to have_http_status(:unprocessable_entity)
436
+ end
437
+ end
438
+ end
439
+ end
440
+ ```
441
+
442
+ ---
443
+
444
+ ## Next Steps
445
+
446
+ - [Rails Integration](rails.md) - Rails-specific patterns
447
+ - [Examples](../../tech_example/07_rspec_integration.rb) - More examples
448
+ - [Generation Modes](../modes/overview.md) - Mode details
449
+