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,630 @@
1
+ # Rails Integration
2
+
3
+ Using FakeDataDSL with Ruby on Rails applications.
4
+
5
+ ## Table of Contents
6
+
7
+ - [Setup](#setup)
8
+ - [Database Seeding](#database-seeding)
9
+ - [Test Environment](#test-environment)
10
+ - [Development Data](#development-data)
11
+ - [API Testing](#api-testing)
12
+ - [Background Jobs](#background-jobs)
13
+ - [Best Practices](#best-practices)
14
+
15
+ ---
16
+
17
+ ## Setup
18
+
19
+ ### Installation
20
+
21
+ Add to your `Gemfile`:
22
+
23
+ ```ruby
24
+ # Gemfile
25
+
26
+ # For development and test only
27
+ group :development, :test do
28
+ gem 'fake_data_dsl'
29
+ end
30
+
31
+ # Or if you want it in production (for seeding)
32
+ gem 'fake_data_dsl'
33
+ ```
34
+
35
+ Then run:
36
+
37
+ ```bash
38
+ bundle install
39
+ ```
40
+
41
+ ### Directory Structure
42
+
43
+ Create a schemas directory:
44
+
45
+ ```
46
+ app/
47
+ config/
48
+ db/
49
+ schemas/ # FakeDataDSL schemas
50
+ user.dsl
51
+ post.dsl
52
+ comment.dsl
53
+ seeds.rb
54
+ lib/
55
+ spec/
56
+ schemas/ # Test-specific schemas
57
+ api_response.dsl
58
+ ```
59
+
60
+ ### Initializer
61
+
62
+ Create `config/initializers/fake_data_dsl.rb`:
63
+
64
+ ```ruby
65
+ # config/initializers/fake_data_dsl.rb
66
+
67
+ if defined?(FakeDataDSL)
68
+ FakeDataDSL.configure do |config|
69
+ # Default generation mode
70
+ config.default_mode = :random
71
+
72
+ # Resource limits
73
+ config.limits.max_array_size = 100
74
+ config.limits.max_recursion = 5
75
+ end
76
+
77
+ # Register custom types for your domain
78
+ FakeDataDSL.register_type(:user_role) do |rng, _context, _args, _mode|
79
+ %w[user admin moderator].sample(random: rng.random)
80
+ end
81
+
82
+ # Register computed field functions
83
+ FakeDataDSL.register_function(:full_name) do |context|
84
+ "#{context['first_name']} #{context['last_name']}"
85
+ end
86
+ end
87
+ ```
88
+
89
+ ---
90
+
91
+ ## Database Seeding
92
+
93
+ ### Basic Seeds
94
+
95
+ Create `db/seeds.rb`:
96
+
97
+ ```ruby
98
+ # db/seeds.rb
99
+
100
+ require 'fake_data_dsl'
101
+
102
+ # Load all schemas
103
+ registry = FakeDataDSL::Registry.new
104
+ registry.load_dir(Rails.root.join('db/schemas'))
105
+
106
+ # Seed configuration
107
+ SEED = ENV.fetch('SEED', 12345).to_i
108
+ puts "Using seed: #{SEED}"
109
+
110
+ # Clear existing data (optional)
111
+ if Rails.env.development?
112
+ puts "Clearing existing data..."
113
+ [Comment, Post, User].each(&:delete_all)
114
+ end
115
+
116
+ # Seed users
117
+ puts "Seeding users..."
118
+ user_schema = registry.schema('User')
119
+ users_data = user_schema.generate_many(100, seed: SEED)
120
+
121
+ users = users_data.map do |data|
122
+ User.create!(
123
+ email: data['email'],
124
+ name: data['name'],
125
+ role: data['role'],
126
+ created_at: data['created_at']
127
+ )
128
+ end
129
+ puts "Created #{users.count} users"
130
+
131
+ # Seed posts
132
+ puts "Seeding posts..."
133
+ post_schema = registry.schema('Post')
134
+ posts = []
135
+
136
+ users.each do |user|
137
+ post_count = rand(0..5)
138
+ post_data = post_schema.generate_many(post_count)
139
+
140
+ post_data.each do |data|
141
+ posts << Post.create!(
142
+ user: user,
143
+ title: data['title'],
144
+ body: data['body'],
145
+ published: data['published'],
146
+ created_at: data['created_at']
147
+ )
148
+ end
149
+ end
150
+ puts "Created #{posts.count} posts"
151
+
152
+ # Seed comments
153
+ puts "Seeding comments..."
154
+ comment_schema = registry.schema('Comment')
155
+ comment_count = 0
156
+
157
+ posts.sample(posts.count / 2).each do |post|
158
+ comments_data = comment_schema.generate_many(rand(0..10))
159
+
160
+ comments_data.each do |data|
161
+ Comment.create!(
162
+ post: post,
163
+ user: users.sample,
164
+ body: data['body'],
165
+ created_at: data['created_at']
166
+ )
167
+ comment_count += 1
168
+ end
169
+ end
170
+ puts "Created #{comment_count} comments"
171
+
172
+ puts "Seeding complete!"
173
+ ```
174
+
175
+ ### Schema Files
176
+
177
+ Create `db/schemas/user.dsl`:
178
+
179
+ ```dsl
180
+ User:
181
+ email: email(unique: true)
182
+ name: name
183
+ role: enum(user:80%, admin:10%, moderator:10%)
184
+ avatar_url?: url
185
+ bio?: text(50..500)
186
+ created_at: past_date(2y)
187
+ ```
188
+
189
+ Create `db/schemas/post.dsl`:
190
+
191
+ ```dsl
192
+ Post:
193
+ title: text(20..100)
194
+ body: text(200..2000)
195
+ slug: text(10..50)
196
+ published: boolean(true:70%)
197
+ view_count: number(0..10000)
198
+ created_at: past_date(1y)
199
+ ```
200
+
201
+ ### Running Seeds
202
+
203
+ ```bash
204
+ # Basic seeding
205
+ rails db:seed
206
+
207
+ # With specific seed for reproducibility
208
+ SEED=42 rails db:seed
209
+
210
+ # Reset and reseed
211
+ rails db:reset # Runs drop, create, migrate, seed
212
+ ```
213
+
214
+ ### Rake Tasks
215
+
216
+ Create `lib/tasks/fake_data.rake`:
217
+
218
+ ```ruby
219
+ # lib/tasks/fake_data.rake
220
+
221
+ namespace :fake_data do
222
+ desc "Generate fake users"
223
+ task :users, [:count] => :environment do |_t, args|
224
+ count = (args[:count] || 10).to_i
225
+
226
+ registry = FakeDataDSL::Registry.new
227
+ registry.load_file(Rails.root.join('db/schemas/user.dsl'))
228
+
229
+ schema = registry.schema('User')
230
+
231
+ puts "Generating #{count} users..."
232
+ schema.generate_stream(count: count).each_with_index do |data, i|
233
+ User.create!(
234
+ email: data['email'],
235
+ name: data['name'],
236
+ role: data['role']
237
+ )
238
+ print '.' if (i + 1) % 100 == 0
239
+ end
240
+ puts "\nDone!"
241
+ end
242
+
243
+ desc "Clear all fake data"
244
+ task clear: :environment do
245
+ puts "Clearing data..."
246
+ [Comment, Post, User].each(&:delete_all)
247
+ puts "Done!"
248
+ end
249
+
250
+ desc "Validate all schemas"
251
+ task validate: :environment do
252
+ Dir[Rails.root.join('db/schemas/*.dsl')].each do |file|
253
+ print "Validating #{File.basename(file)}... "
254
+ begin
255
+ FakeDataDSL.load(file)
256
+ puts "✓"
257
+ rescue StandardError => e
258
+ puts "✗ #{e.message}"
259
+ end
260
+ end
261
+ end
262
+ end
263
+ ```
264
+
265
+ Usage:
266
+
267
+ ```bash
268
+ rails fake_data:users[100]
269
+ rails fake_data:clear
270
+ rails fake_data:validate
271
+ ```
272
+
273
+ ---
274
+
275
+ ## Test Environment
276
+
277
+ ### RSpec Setup
278
+
279
+ Create `spec/support/fake_data.rb`:
280
+
281
+ ```ruby
282
+ # spec/support/fake_data.rb
283
+
284
+ require 'fake_data_dsl'
285
+
286
+ module FakeDataSupport
287
+ extend ActiveSupport::Concern
288
+
289
+ included do
290
+ let(:fake_registry) do
291
+ FakeDataDSL::Registry.new.tap do |r|
292
+ r.load_dir(Rails.root.join('spec/schemas'))
293
+ end
294
+ end
295
+ end
296
+
297
+ def fake(schema_name, **options)
298
+ fake_registry.schema(schema_name.to_s.camelize).generate(**options)
299
+ end
300
+
301
+ def fake_many(schema_name, count, **options)
302
+ fake_registry.schema(schema_name.to_s.camelize).generate_many(count, **options)
303
+ end
304
+
305
+ def build_fake(model_class, **overrides)
306
+ schema_name = model_class.name
307
+ data = fake(schema_name)
308
+ model_class.new(data.merge(overrides.stringify_keys))
309
+ end
310
+
311
+ def create_fake(model_class, **overrides)
312
+ build_fake(model_class, **overrides).tap(&:save!)
313
+ end
314
+ end
315
+
316
+ RSpec.configure do |config|
317
+ config.include FakeDataSupport
318
+ end
319
+ ```
320
+
321
+ ### Usage in Specs
322
+
323
+ ```ruby
324
+ # spec/models/user_spec.rb
325
+
326
+ RSpec.describe User, type: :model do
327
+ describe "validations" do
328
+ let(:user_data) { fake(:user) }
329
+
330
+ it "is valid with fake data" do
331
+ user = User.new(user_data)
332
+ expect(user).to be_valid
333
+ end
334
+
335
+ it "handles edge cases" do
336
+ user = User.new(fake(:user, mode: :edge))
337
+ expect { user.valid? }.not_to raise_error
338
+ end
339
+ end
340
+
341
+ describe "associations" do
342
+ let(:user) { create_fake(User) }
343
+
344
+ it "has many posts" do
345
+ 3.times { create_fake(Post, user: user) }
346
+ expect(user.posts.count).to eq(3)
347
+ end
348
+ end
349
+ end
350
+ ```
351
+
352
+ ### Request Specs
353
+
354
+ ```ruby
355
+ # spec/requests/users_spec.rb
356
+
357
+ RSpec.describe "Users API", type: :request do
358
+ describe "POST /api/users" do
359
+ let(:user_params) do
360
+ fake(:user).slice('email', 'name').merge('password' => 'password123')
361
+ end
362
+
363
+ it "creates a user" do
364
+ post '/api/users', params: { user: user_params }
365
+
366
+ expect(response).to have_http_status(:created)
367
+ expect(json_response['email']).to eq(user_params['email'])
368
+ end
369
+
370
+ context "with invalid data" do
371
+ let(:user_params) { fake(:user, mode: :invalid) }
372
+
373
+ it "returns validation errors" do
374
+ post '/api/users', params: { user: user_params }
375
+
376
+ expect(response).to have_http_status(:unprocessable_entity)
377
+ end
378
+ end
379
+ end
380
+ end
381
+ ```
382
+
383
+ ---
384
+
385
+ ## Development Data
386
+
387
+ ### Development Seeds
388
+
389
+ Create `db/seeds/development.rb`:
390
+
391
+ ```ruby
392
+ # db/seeds/development.rb
393
+
394
+ return unless Rails.env.development?
395
+
396
+ require 'fake_data_dsl'
397
+
398
+ registry = FakeDataDSL::Registry.new
399
+ registry.load_dir(Rails.root.join('db/schemas'))
400
+
401
+ # Create admin user
402
+ admin_data = registry.schema('User').generate
403
+ User.find_or_create_by!(email: 'admin@example.com') do |user|
404
+ user.name = 'Admin User'
405
+ user.role = 'admin'
406
+ user.password = 'password123'
407
+ end
408
+
409
+ # Create sample data
410
+ 100.times do |i|
411
+ user_data = registry.schema('User').generate(seed: i)
412
+ user = User.create!(user_data.merge('password' => 'password123'))
413
+
414
+ rand(0..5).times do
415
+ post_data = registry.schema('Post').generate
416
+ user.posts.create!(post_data)
417
+ end
418
+
419
+ print '.' if (i + 1) % 10 == 0
420
+ end
421
+
422
+ puts "\nDevelopment data created!"
423
+ ```
424
+
425
+ ### Console Helpers
426
+
427
+ Add to `.irbrc` or create `config/initializers/console_helpers.rb`:
428
+
429
+ ```ruby
430
+ # config/initializers/console_helpers.rb
431
+
432
+ if defined?(Rails::Console)
433
+ module ConsoleHelpers
434
+ def fake_registry
435
+ @fake_registry ||= FakeDataDSL::Registry.new.tap do |r|
436
+ r.load_dir(Rails.root.join('db/schemas'))
437
+ end
438
+ end
439
+
440
+ def fake(schema_name, **options)
441
+ fake_registry.schema(schema_name.to_s.camelize).generate(**options)
442
+ end
443
+
444
+ def create_fake_user(**overrides)
445
+ User.create!(fake(:user).merge(overrides.stringify_keys))
446
+ end
447
+
448
+ def create_fake_post(user: nil, **overrides)
449
+ user ||= User.first || create_fake_user
450
+ user.posts.create!(fake(:post).merge(overrides.stringify_keys))
451
+ end
452
+ end
453
+
454
+ Rails.application.console do
455
+ include ConsoleHelpers
456
+ puts "FakeDataDSL helpers loaded: fake(:schema_name), create_fake_user, create_fake_post"
457
+ end
458
+ end
459
+ ```
460
+
461
+ Usage in console:
462
+
463
+ ```ruby
464
+ # rails console
465
+ fake(:user) # Generate user data
466
+ create_fake_user # Create and save user
467
+ create_fake_user(role: 'admin') # With overrides
468
+ create_fake_post # Create post for first user
469
+ ```
470
+
471
+ ---
472
+
473
+ ## API Testing
474
+
475
+ ### API Response Schemas
476
+
477
+ Create `spec/schemas/api_response.dsl`:
478
+
479
+ ```dsl
480
+ APIResponse:
481
+ @latency 50..200ms
482
+ @failure 2%
483
+
484
+ success: boolean(true:95%)
485
+ data: object
486
+ meta: ResponseMeta
487
+
488
+ ResponseMeta:
489
+ request_id: uuid
490
+ timestamp: now
491
+ version: enum(v1, v2)
492
+ ```
493
+
494
+ ### Controller Specs
495
+
496
+ ```ruby
497
+ # spec/controllers/api/users_controller_spec.rb
498
+
499
+ RSpec.describe Api::UsersController, type: :controller do
500
+ describe "GET #index" do
501
+ before do
502
+ 10.times { create_fake(User) }
503
+ end
504
+
505
+ it "returns users" do
506
+ get :index
507
+
508
+ expect(response).to be_successful
509
+ expect(json_response['users'].length).to eq(10)
510
+ end
511
+ end
512
+
513
+ describe "POST #create" do
514
+ let(:params) { { user: fake(:user).slice('email', 'name') } }
515
+
516
+ it "creates user" do
517
+ expect {
518
+ post :create, params: params
519
+ }.to change(User, :count).by(1)
520
+ end
521
+ end
522
+ end
523
+ ```
524
+
525
+ ---
526
+
527
+ ## Background Jobs
528
+
529
+ ### Testing with Fake Data
530
+
531
+ ```ruby
532
+ # spec/jobs/send_newsletter_job_spec.rb
533
+
534
+ RSpec.describe SendNewsletterJob, type: :job do
535
+ let(:users) { 10.times.map { create_fake(User) } }
536
+
537
+ it "sends to all users" do
538
+ expect {
539
+ described_class.perform_now(users.map(&:id))
540
+ }.to change { ActionMailer::Base.deliveries.count }.by(10)
541
+ end
542
+ end
543
+ ```
544
+
545
+ ### Generating Test Data for Jobs
546
+
547
+ ```ruby
548
+ # spec/jobs/import_job_spec.rb
549
+
550
+ RSpec.describe ImportJob, type: :job do
551
+ let(:import_data) do
552
+ fake_many(:import_record, 1000).map(&:to_json).join("\n")
553
+ end
554
+
555
+ it "imports all records" do
556
+ expect {
557
+ described_class.perform_now(import_data)
558
+ }.to change(ImportedRecord, :count).by(1000)
559
+ end
560
+ end
561
+ ```
562
+
563
+ ---
564
+
565
+ ## Best Practices
566
+
567
+ ### 1. Separate Schemas by Purpose
568
+
569
+ ```
570
+ db/schemas/ # Production seeding
571
+ spec/schemas/ # Testing only
572
+ lib/schemas/ # Shared schemas
573
+ ```
574
+
575
+ ### 2. Use Deterministic Seeds
576
+
577
+ ```ruby
578
+ # In seeds.rb
579
+ SEED = ENV.fetch('SEED', Rails.env.hash).to_i
580
+
581
+ # Always reproducible per environment
582
+ users = schema.generate_many(100, seed: SEED)
583
+ ```
584
+
585
+ ### 3. Match Your Models
586
+
587
+ ```dsl
588
+ # db/schemas/user.dsl - matches User model
589
+ User:
590
+ email: email(unique: true) # validates :email, uniqueness: true
591
+ name: name # validates :name, presence: true
592
+ role: enum(user, admin, moderator) # enum role: [:user, :admin, :moderator]
593
+ created_at: past_date(2y)
594
+ ```
595
+
596
+ ### 4. Use Transactions in Tests
597
+
598
+ ```ruby
599
+ RSpec.configure do |config|
600
+ config.use_transactional_fixtures = true
601
+ end
602
+ ```
603
+
604
+ ### 5. Avoid N+1 in Seeds
605
+
606
+ ```ruby
607
+ # Bad - N+1 queries
608
+ 100.times do
609
+ user = User.create!(fake(:user))
610
+ 5.times { Post.create!(fake(:post).merge(user_id: user.id)) }
611
+ end
612
+
613
+ # Good - Batch insert
614
+ users_data = fake_many(:user, 100)
615
+ users = User.insert_all!(users_data, returning: [:id])
616
+
617
+ posts_data = users.flat_map do |user|
618
+ 5.times.map { fake(:post).merge(user_id: user['id']) }
619
+ end
620
+ Post.insert_all!(posts_data)
621
+ ```
622
+
623
+ ---
624
+
625
+ ## Next Steps
626
+
627
+ - [RSpec Integration](rspec.md) - RSpec testing patterns
628
+ - [Factory Bot Comparison](factory_bot.md) - Migration guide
629
+ - [Database Seeding Example](../../tech_example/05_database_seeding.rb) - Code examples
630
+