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,485 @@
1
+ # Factory Bot Comparison
2
+
3
+ Comparing FakeDataDSL with Factory Bot and migration guide.
4
+
5
+ ## Table of Contents
6
+
7
+ - [Overview](#overview)
8
+ - [Feature Comparison](#feature-comparison)
9
+ - [Syntax Comparison](#syntax-comparison)
10
+ - [When to Use Each](#when-to-use-each)
11
+ - [Migration Guide](#migration-guide)
12
+ - [Using Together](#using-together)
13
+
14
+ ---
15
+
16
+ ## Overview
17
+
18
+ **Factory Bot** and **FakeDataDSL** serve different purposes:
19
+
20
+ | Tool | Primary Purpose |
21
+ |------|-----------------|
22
+ | **Factory Bot** | Create model instances for testing |
23
+ | **FakeDataDSL** | Generate fake data from schemas |
24
+
25
+ They can complement each other rather than compete.
26
+
27
+ ---
28
+
29
+ ## Feature Comparison
30
+
31
+ | Feature | Factory Bot | FakeDataDSL |
32
+ |---------|-------------|-------------|
33
+ | **Model Integration** | ✅ Deep Rails integration | ⚠️ Data only, not models |
34
+ | **Associations** | ✅ Automatic | ⚠️ Manual with Ref() |
35
+ | **Traits** | ✅ Built-in | ⚠️ Via overrides |
36
+ | **Sequences** | ✅ Built-in | ✅ id_sequence |
37
+ | **Callbacks** | ✅ after_create, etc. | ❌ Not available |
38
+ | **Lazy Evaluation** | ✅ Built-in | ❌ Not available |
39
+ | **DSL File** | ❌ Ruby code | ✅ Separate DSL |
40
+ | **Generation Modes** | ❌ Not available | ✅ random/edge/invalid |
41
+ | **Behaviors** | ❌ Not available | ✅ latency/failure/etc. |
42
+ | **Streaming** | ❌ Not available | ✅ Memory-efficient |
43
+ | **Deterministic** | ⚠️ With Faker.seed | ✅ Built-in seeds |
44
+ | **CLI** | ❌ Not available | ✅ Command line |
45
+ | **Non-Rails** | ⚠️ Possible | ✅ Framework agnostic |
46
+
47
+ ---
48
+
49
+ ## Syntax Comparison
50
+
51
+ ### Defining Data Shape
52
+
53
+ **Factory Bot:**
54
+ ```ruby
55
+ # spec/factories/users.rb
56
+ FactoryBot.define do
57
+ factory :user do
58
+ id { SecureRandom.uuid }
59
+ name { Faker::Name.name }
60
+ email { Faker::Internet.email }
61
+ age { rand(18..65) }
62
+ active { [true, false].sample }
63
+ role { %w[user admin moderator].sample }
64
+ created_at { rand(1..365).days.ago }
65
+ end
66
+ end
67
+ ```
68
+
69
+ **FakeDataDSL:**
70
+ ```dsl
71
+ # schemas/user.dsl
72
+ User:
73
+ id: uuid
74
+ name: name
75
+ email: email
76
+ age: number(18..65)
77
+ active: boolean
78
+ role: enum(user, admin, moderator)
79
+ created_at: past_date(1y)
80
+ ```
81
+
82
+ ### Creating Records
83
+
84
+ **Factory Bot:**
85
+ ```ruby
86
+ # Build (doesn't save)
87
+ user = build(:user)
88
+
89
+ # Create (saves to DB)
90
+ user = create(:user)
91
+
92
+ # With overrides
93
+ admin = create(:user, role: 'admin')
94
+
95
+ # Multiple
96
+ users = create_list(:user, 10)
97
+ ```
98
+
99
+ **FakeDataDSL:**
100
+ ```ruby
101
+ # Generate data hash
102
+ user_data = schema.generate
103
+
104
+ # Create model manually
105
+ user = User.create!(user_data)
106
+
107
+ # With overrides
108
+ admin = User.create!(schema.generate.merge('role' => 'admin'))
109
+
110
+ # Multiple
111
+ users_data = schema.generate_many(10)
112
+ users = User.insert_all!(users_data)
113
+ ```
114
+
115
+ ### Traits
116
+
117
+ **Factory Bot:**
118
+ ```ruby
119
+ factory :user do
120
+ name { Faker::Name.name }
121
+ role { 'user' }
122
+
123
+ trait :admin do
124
+ role { 'admin' }
125
+ end
126
+
127
+ trait :inactive do
128
+ active { false }
129
+ deactivated_at { Time.current }
130
+ end
131
+ end
132
+
133
+ # Usage
134
+ admin = create(:user, :admin)
135
+ inactive_admin = create(:user, :admin, :inactive)
136
+ ```
137
+
138
+ **FakeDataDSL:**
139
+ ```ruby
140
+ # Using helper methods
141
+ def fake_user(*traits, **overrides)
142
+ data = schema.generate
143
+
144
+ traits.each do |trait|
145
+ case trait
146
+ when :admin
147
+ data['role'] = 'admin'
148
+ when :inactive
149
+ data['active'] = false
150
+ data['deactivated_at'] = Time.current.iso8601
151
+ end
152
+ end
153
+
154
+ data.merge(overrides.stringify_keys)
155
+ end
156
+
157
+ # Usage
158
+ admin = User.create!(fake_user(:admin))
159
+ inactive_admin = User.create!(fake_user(:admin, :inactive))
160
+ ```
161
+
162
+ ### Associations
163
+
164
+ **Factory Bot:**
165
+ ```ruby
166
+ factory :post do
167
+ title { Faker::Lorem.sentence }
168
+ user # Automatically creates associated user
169
+ end
170
+
171
+ factory :comment do
172
+ body { Faker::Lorem.paragraph }
173
+ post
174
+ user
175
+ end
176
+
177
+ # Usage
178
+ post = create(:post) # Creates user automatically
179
+ post.user # => User instance
180
+ ```
181
+
182
+ **FakeDataDSL:**
183
+ ```ruby
184
+ # Manual association
185
+ user = User.create!(fake(:user))
186
+ post_data = fake(:post).merge('user_id' => user.id)
187
+ post = Post.create!(post_data)
188
+
189
+ # Or use Ref() in DSL (references previously generated)
190
+ # post.dsl
191
+ # Post:
192
+ # user_id: Ref(User.id)
193
+ ```
194
+
195
+ ### Sequences
196
+
197
+ **Factory Bot:**
198
+ ```ruby
199
+ factory :user do
200
+ sequence(:email) { |n| "user#{n}@example.com" }
201
+ sequence(:username) { |n| "user_#{n}" }
202
+ end
203
+ ```
204
+
205
+ **FakeDataDSL:**
206
+ ```dsl
207
+ User:
208
+ id: id_sequence
209
+ email: email(unique: true)
210
+ username: username
211
+ ```
212
+
213
+ ---
214
+
215
+ ## When to Use Each
216
+
217
+ ### Use Factory Bot When:
218
+
219
+ 1. **Deep Rails integration needed**
220
+ - Automatic association handling
221
+ - Callbacks (after_create, etc.)
222
+ - ActiveRecord features
223
+
224
+ 2. **Complex test setup**
225
+ - Nested associations
226
+ - Transactional rollback
227
+ - Database state management
228
+
229
+ 3. **Traits are essential**
230
+ - Many variations of same model
231
+ - Composable configurations
232
+
233
+ ### Use FakeDataDSL When:
234
+
235
+ 1. **Schema-first approach**
236
+ - Define data contracts
237
+ - Share schemas across teams
238
+ - Generate docs from schemas
239
+
240
+ 2. **Testing modes needed**
241
+ - Edge case testing
242
+ - Invalid data testing
243
+ - Validation testing
244
+
245
+ 3. **Non-Rails contexts**
246
+ - API testing
247
+ - Data migration
248
+ - Load testing
249
+
250
+ 4. **Large data volumes**
251
+ - Streaming generation
252
+ - Memory efficiency
253
+ - Database seeding
254
+
255
+ 5. **Behavior simulation**
256
+ - Latency testing
257
+ - Failure testing
258
+ - Chaos engineering
259
+
260
+ ---
261
+
262
+ ## Migration Guide
263
+
264
+ ### From Factory Bot to FakeDataDSL
265
+
266
+ #### Step 1: Convert Factories to Schemas
267
+
268
+ **Before (Factory Bot):**
269
+ ```ruby
270
+ # spec/factories/users.rb
271
+ FactoryBot.define do
272
+ factory :user do
273
+ id { SecureRandom.uuid }
274
+ name { Faker::Name.name }
275
+ email { Faker::Internet.email }
276
+ age { rand(18..65) }
277
+ role { 'user' }
278
+
279
+ trait :admin do
280
+ role { 'admin' }
281
+ end
282
+
283
+ trait :verified do
284
+ verified { true }
285
+ verified_at { Time.current }
286
+ end
287
+ end
288
+ end
289
+ ```
290
+
291
+ **After (FakeDataDSL):**
292
+ ```dsl
293
+ # spec/schemas/user.dsl
294
+ User:
295
+ id: uuid
296
+ name: name
297
+ email: email
298
+ age: number(18..65)
299
+ role: enum(user:80%, admin:10%, moderator:10%)
300
+ verified: boolean(false:80%)
301
+ verified_at?: past_date(1y)
302
+ ```
303
+
304
+ #### Step 2: Create Helper Module
305
+
306
+ ```ruby
307
+ # spec/support/fake_data.rb
308
+ module FakeDataHelpers
309
+ TRAITS = {
310
+ user: {
311
+ admin: { 'role' => 'admin' },
312
+ verified: { 'verified' => true, 'verified_at' => Time.current.iso8601 }
313
+ }
314
+ }
315
+
316
+ def fake(name, *traits, **overrides)
317
+ data = fake_schema(name).generate
318
+
319
+ traits.each do |trait|
320
+ trait_data = TRAITS.dig(name, trait) || {}
321
+ data.merge!(trait_data)
322
+ end
323
+
324
+ data.merge(overrides.stringify_keys)
325
+ end
326
+
327
+ def create_fake(name, *traits, **overrides)
328
+ model_class = name.to_s.camelize.constantize
329
+ model_class.create!(fake(name, *traits, **overrides))
330
+ end
331
+
332
+ def create_fake_list(name, count, *traits, **overrides)
333
+ count.times.map { create_fake(name, *traits, **overrides) }
334
+ end
335
+
336
+ private
337
+
338
+ def fake_schema(name)
339
+ @registry ||= FakeDataDSL::Registry.new.tap do |r|
340
+ r.load_dir('spec/schemas')
341
+ end
342
+ @registry.schema(name.to_s.camelize)
343
+ end
344
+ end
345
+ ```
346
+
347
+ #### Step 3: Update Specs
348
+
349
+ **Before:**
350
+ ```ruby
351
+ RSpec.describe User do
352
+ let(:user) { create(:user) }
353
+ let(:admin) { create(:user, :admin) }
354
+ end
355
+ ```
356
+
357
+ **After:**
358
+ ```ruby
359
+ RSpec.describe User do
360
+ include FakeDataHelpers
361
+
362
+ let(:user) { create_fake(:user) }
363
+ let(:admin) { create_fake(:user, :admin) }
364
+ end
365
+ ```
366
+
367
+ ### Gradual Migration
368
+
369
+ You can use both during migration:
370
+
371
+ ```ruby
372
+ # spec/support/factories_and_fake.rb
373
+
374
+ # Keep Factory Bot for complex cases
375
+ FactoryBot.define do
376
+ factory :order_with_items do
377
+ # Complex associations
378
+ end
379
+ end
380
+
381
+ # Use FakeDataDSL for simple cases
382
+ module FakeDataHelpers
383
+ def fake_user(**overrides)
384
+ schema.generate.merge(overrides.stringify_keys)
385
+ end
386
+ end
387
+
388
+ # In specs
389
+ RSpec.describe OrdersController do
390
+ # Use Factory Bot for complex setup
391
+ let(:order) { create(:order_with_items) }
392
+
393
+ # Use FakeDataDSL for simple data
394
+ let(:user_params) { fake_user }
395
+ end
396
+ ```
397
+
398
+ ---
399
+
400
+ ## Using Together
401
+
402
+ ### Best of Both Worlds
403
+
404
+ ```ruby
405
+ # spec/factories/users.rb
406
+ FactoryBot.define do
407
+ factory :user do
408
+ # Use FakeDataDSL for data generation
409
+ transient do
410
+ fake_data { FakeDataHelpers.fake(:user) }
411
+ end
412
+
413
+ id { fake_data['id'] }
414
+ name { fake_data['name'] }
415
+ email { fake_data['email'] }
416
+
417
+ # Keep Factory Bot traits
418
+ trait :admin do
419
+ role { 'admin' }
420
+ end
421
+
422
+ # Keep callbacks
423
+ after(:create) do |user|
424
+ user.send_welcome_email
425
+ end
426
+ end
427
+ end
428
+ ```
429
+
430
+ ### Hybrid Approach
431
+
432
+ ```ruby
433
+ # spec/support/hybrid_factories.rb
434
+
435
+ module HybridFactories
436
+ # Use FakeDataDSL for data
437
+ def fake(name, **options)
438
+ registry.schema(name.to_s.camelize).generate(**options)
439
+ end
440
+
441
+ # Use Factory Bot for model creation with associations
442
+ def create_with_fake(name, *traits, **overrides)
443
+ data = fake(name)
444
+ FactoryBot.create(name, *traits, data.merge(overrides))
445
+ end
446
+ end
447
+ ```
448
+
449
+ ### Decision Matrix
450
+
451
+ | Scenario | Recommendation |
452
+ |----------|---------------|
453
+ | Simple model, no associations | FakeDataDSL |
454
+ | Complex associations | Factory Bot |
455
+ | Edge case testing | FakeDataDSL |
456
+ | After callbacks needed | Factory Bot |
457
+ | Large batch generation | FakeDataDSL |
458
+ | Transactional tests | Factory Bot |
459
+ | API data contracts | FakeDataDSL |
460
+ | Integration tests | Either/Both |
461
+
462
+ ---
463
+
464
+ ## Summary
465
+
466
+ | Aspect | Factory Bot | FakeDataDSL |
467
+ |--------|-------------|-------------|
468
+ | Best for | Model creation | Data generation |
469
+ | Syntax | Ruby DSL | Custom DSL |
470
+ | Learning curve | Medium | Low |
471
+ | Rails integration | Excellent | Good |
472
+ | Testing modes | No | Yes |
473
+ | Streaming | No | Yes |
474
+ | Behaviors | No | Yes |
475
+
476
+ **Recommendation:** Use both! Factory Bot for complex Rails model creation, FakeDataDSL for data generation, testing modes, and behavior simulation.
477
+
478
+ ---
479
+
480
+ ## Next Steps
481
+
482
+ - [RSpec Integration](rspec.md) - RSpec testing patterns
483
+ - [Rails Integration](rails.md) - Rails-specific setup
484
+ - [CI/CD Integration](ci_cd.md) - Continuous integration
485
+