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,359 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ # ============================================================================
5
+ # FakeDataDSL - RSpec Integration Examples
6
+ # ============================================================================
7
+ # This file demonstrates patterns for using FakeDataDSL with RSpec.
8
+ # Note: This file shows patterns, not actual runnable tests.
9
+ # ============================================================================
10
+
11
+ puts "=" * 70
12
+ puts "FakeDataDSL RSpec Integration Patterns"
13
+ puts "=" * 70
14
+ puts
15
+
16
+ # ============================================================================
17
+ # Pattern 1: Basic Test Fixture
18
+ # ============================================================================
19
+ puts "PATTERN 1: Basic Test Fixture"
20
+ puts "-" * 40
21
+
22
+ puts <<~RUBY
23
+ # spec/support/fake_data.rb
24
+ require 'fake_data_dsl'
25
+
26
+ module FakeData
27
+ def self.registry
28
+ @registry ||= begin
29
+ reg = FakeDataDSL::Registry.new
30
+ reg.load_dir('spec/schemas/')
31
+ reg
32
+ end
33
+ end
34
+
35
+ def self.user(**overrides)
36
+ registry.schema('User').generate.merge(overrides.transform_keys(&:to_s))
37
+ end
38
+
39
+ def self.order(**overrides)
40
+ registry.schema('Order').generate.merge(overrides.transform_keys(&:to_s))
41
+ end
42
+ end
43
+
44
+ # In your spec
45
+ RSpec.describe User do
46
+ let(:user_data) { FakeData.user }
47
+ let(:admin_data) { FakeData.user(role: 'admin') }
48
+
49
+ it "creates a valid user" do
50
+ user = User.new(user_data)
51
+ expect(user).to be_valid
52
+ end
53
+ end
54
+ RUBY
55
+ puts
56
+
57
+ # ============================================================================
58
+ # Pattern 2: Shared Contexts
59
+ # ============================================================================
60
+ puts "PATTERN 2: Shared Contexts"
61
+ puts "-" * 40
62
+
63
+ puts <<~RUBY
64
+ # spec/support/shared_contexts/fake_data_context.rb
65
+ RSpec.shared_context 'with fake data' do
66
+ let(:registry) do
67
+ FakeDataDSL::Registry.new.tap do |r|
68
+ r.load_dir('spec/schemas/')
69
+ end
70
+ end
71
+
72
+ let(:user_schema) { registry.schema('User') }
73
+ let(:order_schema) { registry.schema('Order') }
74
+
75
+ def fake_user(seed: nil, mode: :random, **overrides)
76
+ data = user_schema.generate(seed: seed, mode: mode)
77
+ data.merge(overrides.transform_keys(&:to_s))
78
+ end
79
+
80
+ def fake_users(count, seed: nil, mode: :random)
81
+ user_schema.generate_many(count, seed: seed, mode: mode)
82
+ end
83
+ end
84
+
85
+ # Usage
86
+ RSpec.describe UsersController do
87
+ include_context 'with fake data'
88
+
89
+ let(:user) { User.create!(fake_user) }
90
+
91
+ describe "GET #show" do
92
+ it "returns the user" do
93
+ get :show, params: { id: user.id }
94
+ expect(response).to be_successful
95
+ end
96
+ end
97
+ end
98
+ RUBY
99
+ puts
100
+
101
+ # ============================================================================
102
+ # Pattern 3: Deterministic Tests
103
+ # ============================================================================
104
+ puts "PATTERN 3: Deterministic Tests"
105
+ puts "-" * 40
106
+
107
+ puts <<~RUBY
108
+ RSpec.describe "Deterministic data generation" do
109
+ # Use fixed seeds for reproducible tests
110
+ let(:seed) { 12345 }
111
+ let(:schema) { FakeDataDSL.load('spec/schemas/user.dsl') }
112
+
113
+ it "generates consistent data with same seed" do
114
+ user1 = schema.generate(seed: seed)
115
+ user2 = schema.generate(seed: seed)
116
+
117
+ expect(user1).to eq(user2)
118
+ end
119
+
120
+ it "generates expected values" do
121
+ user = schema.generate(seed: 42)
122
+
123
+ # With seed 42, we always get these exact values
124
+ expect(user['name']).to eq('Expected Name')
125
+ expect(user['email']).to eq('expected.email@example.com')
126
+ end
127
+ end
128
+ RUBY
129
+ puts
130
+
131
+ # ============================================================================
132
+ # Pattern 4: Testing Validation
133
+ # ============================================================================
134
+ puts "PATTERN 4: Testing Validation with Modes"
135
+ puts "-" * 40
136
+
137
+ puts <<~RUBY
138
+ RSpec.describe User do
139
+ let(:schema) { FakeDataDSL.load('spec/schemas/user.dsl') }
140
+
141
+ context "with valid data" do
142
+ let(:data) { schema.generate(mode: :random) }
143
+
144
+ it "is valid" do
145
+ expect(User.new(data)).to be_valid
146
+ end
147
+ end
148
+
149
+ context "with edge case data" do
150
+ let(:data) { schema.generate(mode: :edge) }
151
+
152
+ it "handles edge cases gracefully" do
153
+ user = User.new(data)
154
+ # May or may not be valid, but shouldn't crash
155
+ expect { user.validate! }.not_to raise_error(StandardError)
156
+ end
157
+ end
158
+
159
+ context "with invalid data" do
160
+ let(:data) { schema.generate(mode: :invalid) }
161
+
162
+ it "is invalid" do
163
+ expect(User.new(data)).not_to be_valid
164
+ end
165
+ end
166
+
167
+ context "with mixed data" do
168
+ it "handles variety of inputs" do
169
+ 10.times do
170
+ data = schema.generate(mode: :mixed)
171
+ user = User.new(data)
172
+ expect { user.valid? }.not_to raise_error
173
+ end
174
+ end
175
+ end
176
+ end
177
+ RUBY
178
+ puts
179
+
180
+ # ============================================================================
181
+ # Pattern 5: Testing API Responses
182
+ # ============================================================================
183
+ puts "PATTERN 5: Testing API Responses"
184
+ puts "-" * 40
185
+
186
+ puts <<~RUBY
187
+ # spec/schemas/api_response.dsl
188
+ # APIResponse:
189
+ # @latency 50..200ms
190
+ # @failure 5%
191
+ #
192
+ # success: boolean(true:95%)
193
+ # data: User
194
+ # meta: ResponseMeta
195
+
196
+ RSpec.describe "API Client" do
197
+ let(:schema) { FakeDataDSL.load('spec/schemas/api_response.dsl') }
198
+
199
+ it "handles successful responses" do
200
+ response = schema.generate(mode: :random)
201
+
202
+ if response['success']
203
+ expect(response['data']).to be_present
204
+ end
205
+ end
206
+
207
+ it "handles failures gracefully" do
208
+ # Force failure mode
209
+ expect {
210
+ # Mock to always trigger failure
211
+ schema.generate # with @failure 100% in test schema
212
+ }.to raise_error(FakeDataDSL::Errors::SimulatedFailure)
213
+ end
214
+ end
215
+ RUBY
216
+ puts
217
+
218
+ # ============================================================================
219
+ # Pattern 6: Property-Based Testing
220
+ # ============================================================================
221
+ puts "PATTERN 6: Property-Based Testing Style"
222
+ puts "-" * 40
223
+
224
+ puts <<~RUBY
225
+ RSpec.describe "Property-based testing" do
226
+ let(:schema) { FakeDataDSL.load('spec/schemas/user.dsl') }
227
+
228
+ it "email always contains @" do
229
+ 100.times do
230
+ user = schema.generate(mode: :random)
231
+ expect(user['email']).to include('@')
232
+ end
233
+ end
234
+
235
+ it "age is always within range" do
236
+ 100.times do
237
+ user = schema.generate(mode: :random)
238
+ expect(user['age']).to be_between(18, 100)
239
+ end
240
+ end
241
+
242
+ it "handles any generated data" do
243
+ [:random, :edge, :invalid, :mixed].each do |mode|
244
+ 10.times do
245
+ data = schema.generate(mode: mode)
246
+
247
+ # Your code should handle any input without crashing
248
+ expect { process_user(data) }.not_to raise_error
249
+ end
250
+ end
251
+ end
252
+ end
253
+ RUBY
254
+ puts
255
+
256
+ # ============================================================================
257
+ # Pattern 7: FactoryBot Replacement
258
+ # ============================================================================
259
+ puts "PATTERN 7: FactoryBot-Style Helpers"
260
+ puts "-" * 40
261
+
262
+ puts <<~RUBY
263
+ # spec/support/factories.rb
264
+ module Factories
265
+ extend self
266
+
267
+ def registry
268
+ @registry ||= FakeDataDSL::Registry.new.tap do |r|
269
+ r.load_dir('spec/schemas/')
270
+ end
271
+ end
272
+
273
+ # Build (doesn't save)
274
+ def build(schema_name, **overrides)
275
+ data = registry.schema(schema_name.to_s.camelize).generate
276
+ data.merge(overrides.transform_keys(&:to_s))
277
+ end
278
+
279
+ # Create (saves to DB)
280
+ def create(schema_name, **overrides)
281
+ data = build(schema_name, **overrides)
282
+ model_class = schema_name.to_s.camelize.constantize
283
+ model_class.create!(data)
284
+ end
285
+
286
+ # Build list
287
+ def build_list(schema_name, count, **overrides)
288
+ count.times.map { build(schema_name, **overrides) }
289
+ end
290
+
291
+ # Create list
292
+ def create_list(schema_name, count, **overrides)
293
+ count.times.map { create(schema_name, **overrides) }
294
+ end
295
+ end
296
+
297
+ # Usage
298
+ RSpec.configure do |config|
299
+ config.include Factories
300
+ end
301
+
302
+ RSpec.describe Order do
303
+ let(:user) { create(:user) }
304
+ let(:order) { create(:order, user_id: user.id) }
305
+
306
+ it "belongs to user" do
307
+ expect(order.user).to eq(user)
308
+ end
309
+ end
310
+ RUBY
311
+ puts
312
+
313
+ # ============================================================================
314
+ # Pattern 8: Request Spec Helpers
315
+ # ============================================================================
316
+ puts "PATTERN 8: Request Spec Helpers"
317
+ puts "-" * 40
318
+
319
+ puts <<~RUBY
320
+ # spec/support/request_helpers.rb
321
+ module RequestHelpers
322
+ def fake_json_body(schema_name, **overrides)
323
+ schema = FakeDataDSL.load("spec/schemas/\#{schema_name}.dsl")
324
+ data = schema.generate.merge(overrides.transform_keys(&:to_s))
325
+ data.to_json
326
+ end
327
+
328
+ def post_fake_data(path, schema_name, **overrides)
329
+ post path,
330
+ params: fake_json_body(schema_name, **overrides),
331
+ headers: { 'Content-Type' => 'application/json' }
332
+ end
333
+ end
334
+
335
+ RSpec.configure do |config|
336
+ config.include RequestHelpers, type: :request
337
+ end
338
+
339
+ # Usage
340
+ RSpec.describe "Users API", type: :request do
341
+ describe "POST /users" do
342
+ it "creates a user" do
343
+ post_fake_data('/api/users', :user)
344
+ expect(response).to have_http_status(:created)
345
+ end
346
+
347
+ it "creates an admin" do
348
+ post_fake_data('/api/users', :user, role: 'admin')
349
+ expect(json_response['role']).to eq('admin')
350
+ end
351
+ end
352
+ end
353
+ RUBY
354
+ puts
355
+
356
+ puts "=" * 70
357
+ puts "RSpec integration patterns demonstrated!"
358
+ puts "=" * 70
359
+