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.
- checksums.yaml +7 -0
- data/.rspec +4 -0
- data/.rubocop.yml +40 -0
- data/.yardopts +18 -0
- data/ACCESS_DOCS.md +116 -0
- data/ADVANCED_FEATURES_SUMMARY.md +245 -0
- data/CHANGELOG.md +498 -0
- data/CODE_OF_CONDUCT.md +122 -0
- data/CONTRIBUTING.md +307 -0
- data/DOCUMENTATION.md +204 -0
- data/DOCUMENTATION_GUIDE.md +194 -0
- data/LICENSE +22 -0
- data/README.md +1458 -0
- data/Rakefile +128 -0
- data/benchmark/README.md +591 -0
- data/benchmark/batch_generation.rb +63 -0
- data/benchmark/engine_comparison.rb +295 -0
- data/benchmark/single_record.rb +108 -0
- data/benchmark/streaming.rb +74 -0
- data/docs/ACTIVERECORD_INFERENCE.md +524 -0
- data/docs/API_SERVER.md +278 -0
- data/docs/CONFIG_FILE.md +315 -0
- data/docs/DATA_CONTRACTS.md +312 -0
- data/docs/ENHANCED_REPL.md +304 -0
- data/docs/FACTORY_BOT.md +271 -0
- data/docs/GITHUB_ACTION.md +420 -0
- data/docs/GRAPHQL_EXPORT.md +303 -0
- data/docs/GRAPHQL_FEDERATION.md +651 -0
- data/docs/HOW_TO_GENERATE_DOCS.md +252 -0
- data/docs/LSP.md +189 -0
- data/docs/MIGRATION_GENERATOR.md +547 -0
- data/docs/MOCK_SERVER.md +280 -0
- data/docs/NATIVE_ENGINE.md +298 -0
- data/docs/OPENAPI_EXPORT.md +252 -0
- data/docs/PERFORMANCE_MODE.md +228 -0
- data/docs/PERSONAS.md +547 -0
- data/docs/PROPERTY_TESTING.md +284 -0
- data/docs/PROTOBUF_EXPORT.md +276 -0
- data/docs/QUALITY_METRICS.md +555 -0
- data/docs/QUICK_REFERENCE.md +88 -0
- data/docs/RAILS_ENGINE.md +404 -0
- data/docs/RAILS_INTEGRATION.md +454 -0
- data/docs/README.md +175 -0
- data/docs/REPL_QUICK_REFERENCE.md +149 -0
- data/docs/RUST_INTEGRATION_GUIDE.md +1376 -0
- data/docs/SCENARIOS.md +576 -0
- data/docs/SECURITY_TESTING.md +318 -0
- data/docs/SNAPSHOT_TESTING.md +308 -0
- data/docs/STRING_TEXT_TYPES_REFERENCE.md +512 -0
- data/docs/TERRAFORM_EXPORT.md +447 -0
- data/docs/TIME_TRAVEL.md +507 -0
- data/docs/USAGE_GUIDE.md +980 -0
- data/docs/WEBHOOK_SIMULATOR.md +579 -0
- data/docs/advanced_features.md +183 -0
- data/docs/api_reference.md +153 -0
- data/docs/behaviors.md +138 -0
- data/docs/best_practices.md +191 -0
- data/docs/dsl_reference.md +172 -0
- data/docs/examples.md +162 -0
- data/docs/generation_modes.md +125 -0
- data/docs/getting_started.md +92 -0
- data/docs/index.html +177 -0
- data/docs/strategic/CLOUD_REGISTRY_ARCHITECTURE.md +268 -0
- data/docs/strategic/SIMD_OPTIMIZATION_STRATEGY.md +153 -0
- data/docs/troubleshooting.md +215 -0
- data/docs/type_reference.md +224 -0
- data/examples/hostile_mode_demo.rb +64 -0
- data/exe/synthra +6 -0
- data/ext/synthra_native/Cargo.lock +972 -0
- data/ext/synthra_native/Cargo.toml +46 -0
- data/ext/synthra_native/extconf.rb +41 -0
- data/ext/synthra_native/src/generator.rs +397 -0
- data/ext/synthra_native/src/lib.rs +229 -0
- data/ext/synthra_native/src/types.rs +1485 -0
- data/lib/generators/synthra/install_generator.rb +86 -0
- data/lib/generators/synthra/templates/api_response.dsl +15 -0
- data/lib/generators/synthra/templates/fake_data.rake +116 -0
- data/lib/generators/synthra/templates/synthra.yml +31 -0
- data/lib/generators/synthra/templates/synthra_support.rb +19 -0
- data/lib/generators/synthra/templates/user.dsl +11 -0
- data/lib/synthra/activerecord_inference.rb +394 -0
- data/lib/synthra/api.rb +381 -0
- data/lib/synthra/api_server.rb +718 -0
- data/lib/synthra/behaviors/applicator.rb +165 -0
- data/lib/synthra/behaviors/base.rb +155 -0
- data/lib/synthra/behaviors/close_connection.rb +60 -0
- data/lib/synthra/behaviors/deprecated.rb +100 -0
- data/lib/synthra/behaviors/failure.rb +69 -0
- data/lib/synthra/behaviors/latency.rb +103 -0
- data/lib/synthra/behaviors/partial_data.rb +83 -0
- data/lib/synthra/behaviors/randomize_order.rb +74 -0
- data/lib/synthra/behaviors/registry.rb +238 -0
- data/lib/synthra/behaviors/simulate_error.rb +79 -0
- data/lib/synthra/cli/commands/base.rb +105 -0
- data/lib/synthra/cli/commands/diff.rb +227 -0
- data/lib/synthra/cli/commands/docs.rb +67 -0
- data/lib/synthra/cli/commands/export.rb +150 -0
- data/lib/synthra/cli/commands/generate.rb +72 -0
- data/lib/synthra/cli/commands/import.rb +80 -0
- data/lib/synthra/cli/commands/lint.rb +53 -0
- data/lib/synthra/cli/commands/live.rb +57 -0
- data/lib/synthra/cli/commands/seed.rb +99 -0
- data/lib/synthra/cli/commands/validate.rb +28 -0
- data/lib/synthra/cli.rb +2471 -0
- data/lib/synthra/config_file.rb +129 -0
- data/lib/synthra/configuration.rb +281 -0
- data/lib/synthra/contracts_registry.rb +408 -0
- data/lib/synthra/database_seeder.rb +268 -0
- data/lib/synthra/deterministic_ids.rb +218 -0
- data/lib/synthra/documentation_generator.rb +414 -0
- data/lib/synthra/engine.rb +251 -0
- data/lib/synthra/errors.rb +1169 -0
- data/lib/synthra/export/base.rb +85 -0
- data/lib/synthra/export/csv.rb +101 -0
- data/lib/synthra/export/graphql.rb +266 -0
- data/lib/synthra/export/graphql_federation.rb +377 -0
- data/lib/synthra/export/graphviz.rb +258 -0
- data/lib/synthra/export/javascript.rb +327 -0
- data/lib/synthra/export/json_data.rb +61 -0
- data/lib/synthra/export/json_schema.rb +290 -0
- data/lib/synthra/export/openapi.rb +514 -0
- data/lib/synthra/export/protobuf.rb +483 -0
- data/lib/synthra/export/python.rb +560 -0
- data/lib/synthra/export/sql.rb +381 -0
- data/lib/synthra/export/sql_insert.rb +152 -0
- data/lib/synthra/export/terraform.rb +501 -0
- data/lib/synthra/export/type_mapping.rb +389 -0
- data/lib/synthra/export/typescript.rb +300 -0
- data/lib/synthra/export/xml_data.rb +104 -0
- data/lib/synthra/export/yaml_data.rb +56 -0
- data/lib/synthra/export.rb +404 -0
- data/lib/synthra/factory_bot_integration.rb +157 -0
- data/lib/synthra/field.rb +440 -0
- data/lib/synthra/functions/registry.rb +104 -0
- data/lib/synthra/generator/context.rb +372 -0
- data/lib/synthra/generator/engine.rb +336 -0
- data/lib/synthra/generator/faker_adapter.rb +425 -0
- data/lib/synthra/generator/modes.rb +444 -0
- data/lib/synthra/generator/resolver.rb +256 -0
- data/lib/synthra/generator/rng.rb +273 -0
- data/lib/synthra/generator/streamer.rb +63 -0
- data/lib/synthra/generator/uniqueness.rb +118 -0
- data/lib/synthra/initializer.rb +97 -0
- data/lib/synthra/limits.rb +279 -0
- data/lib/synthra/live_preview.rb +518 -0
- data/lib/synthra/loader_config.rb +78 -0
- data/lib/synthra/lsp/server.rb +689 -0
- data/lib/synthra/migration_generator.rb +301 -0
- data/lib/synthra/mixin.rb +174 -0
- data/lib/synthra/mock_server.rb +458 -0
- data/lib/synthra/native_engine.rb +304 -0
- data/lib/synthra/openapi_importer.rb +228 -0
- data/lib/synthra/output/json_formatter.rb +40 -0
- data/lib/synthra/output/ndjson_formatter.rb +55 -0
- data/lib/synthra/parser/ast.rb +1287 -0
- data/lib/synthra/parser/lexer.rb +1152 -0
- data/lib/synthra/parser/parser.rb +1664 -0
- data/lib/synthra/parser/tokens.rb +461 -0
- data/lib/synthra/performance_mode.rb +364 -0
- data/lib/synthra/personas.rb +397 -0
- data/lib/synthra/property_testing.rb +172 -0
- data/lib/synthra/quality_metrics.rb +405 -0
- data/lib/synthra/rails_test_helper.rb +248 -0
- data/lib/synthra/registry.rb +533 -0
- data/lib/synthra/relationships.rb +193 -0
- data/lib/synthra/repl/enhanced_repl.rb +607 -0
- data/lib/synthra/repl/formatter.rb +191 -0
- data/lib/synthra/scenarios.rb +423 -0
- data/lib/synthra/schema.rb +605 -0
- data/lib/synthra/schema_inheritance.rb +104 -0
- data/lib/synthra/schema_versioning.rb +212 -0
- data/lib/synthra/snapshot_testing.rb +199 -0
- data/lib/synthra/time_travel.rb +338 -0
- data/lib/synthra/type_definitions.rb +274 -0
- data/lib/synthra/types/address_location/addresses.rb +125 -0
- data/lib/synthra/types/address_location/airports.rb +200 -0
- data/lib/synthra/types/address_location/banks_hospitals.rb +207 -0
- data/lib/synthra/types/address_location/locations.rb +406 -0
- data/lib/synthra/types/base.rb +48 -0
- data/lib/synthra/types/commerce_products/commerce.rb +119 -0
- data/lib/synthra/types/commerce_products/companies.rb +71 -0
- data/lib/synthra/types/commerce_products/construction.rb +126 -0
- data/lib/synthra/types/commerce_products/products.rb +205 -0
- data/lib/synthra/types/core/collections.rb +513 -0
- data/lib/synthra/types/core/defaults.rb +76 -0
- data/lib/synthra/types/core/enums.rb +102 -0
- data/lib/synthra/types/core/identifiers.rb +445 -0
- data/lib/synthra/types/core/primitives.rb +586 -0
- data/lib/synthra/types/core/references.rb +466 -0
- data/lib/synthra/types/core/sequences.rb +304 -0
- data/lib/synthra/types/crypto/crypto.rb +162 -0
- data/lib/synthra/types/date_time/dates.rb +387 -0
- data/lib/synthra/types/finance_banking/banking.rb +424 -0
- data/lib/synthra/types/finance_banking/credit_cards.rb +24 -0
- data/lib/synthra/types/finance_banking/identifiers.rb +93 -0
- data/lib/synthra/types/formula.rb +184 -0
- data/lib/synthra/types/health_medical/medical.rb +150 -0
- data/lib/synthra/types/hostile_payloads.rb +122 -0
- data/lib/synthra/types/json_array.rb +51 -0
- data/lib/synthra/types/media_entertainment/media.rb +62 -0
- data/lib/synthra/types/naughty_string.rb +30 -0
- data/lib/synthra/types/personal_names/chinese.rb +41 -0
- data/lib/synthra/types/personal_names/identifiers.rb +187 -0
- data/lib/synthra/types/personal_names/names.rb +246 -0
- data/lib/synthra/types/personal_names/national_id.rb +89 -0
- data/lib/synthra/types/personal_names/titles_suffixes.rb +41 -0
- data/lib/synthra/types/regex.rb +248 -0
- data/lib/synthra/types/registry.rb +182 -0
- data/lib/synthra/types/repeating_element.rb +50 -0
- data/lib/synthra/types/scenario.rb +29 -0
- data/lib/synthra/types/technology_internet/apps.rb +67 -0
- data/lib/synthra/types/technology_internet/communication.rb +162 -0
- data/lib/synthra/types/technology_internet/devices.rb +80 -0
- data/lib/synthra/types/technology_internet/formats.rb +139 -0
- data/lib/synthra/types/technology_internet/networking.rb +143 -0
- data/lib/synthra/types/template.rb +92 -0
- data/lib/synthra/types/text_content/business.rb +128 -0
- data/lib/synthra/types/text_content/colors.rb +70 -0
- data/lib/synthra/types/text_content/misc.rb +237 -0
- data/lib/synthra/types/text_content/security.rb +130 -0
- data/lib/synthra/types/text_content/text_generation.rb +532 -0
- data/lib/synthra/types/travel/travel.rb +150 -0
- data/lib/synthra/utils/string_distance.rb +133 -0
- data/lib/synthra/validator/dsl_validator.rb +339 -0
- data/lib/synthra/validator/path_validator.rb +615 -0
- data/lib/synthra/version.rb +35 -0
- data/lib/synthra/webhook_simulator.rb +341 -0
- data/lib/synthra.rb +259 -0
- data/schemas/address.dsl +16 -0
- data/schemas/api_response.dsl +8 -0
- data/schemas/error_payload.dsl +9 -0
- data/schemas/order.dsl +10 -0
- data/schemas/order_item.dsl +8 -0
- data/schemas/payment.dsl +11 -0
- data/schemas/social_post.dsl +13 -0
- data/schemas/user.dsl +10 -0
- data/scripts/batch_fix_all.rb +96 -0
- data/scripts/delete_old_files.rb +32 -0
- data/scripts/fix_all_grouped_files.rb +137 -0
- data/scripts/fix_all_indentation.rb +48 -0
- data/scripts/fix_all_syntax.rb +124 -0
- data/scripts/fix_grouped_files.rb +184 -0
- data/scripts/fix_syntax_errors.rb +108 -0
- data/scripts/group_domain_types.rb +112 -0
- data/scripts/group_domain_types_fixed.rb +150 -0
- data/scripts/merge_domains_to_one_file.rb +68 -0
- data/scripts/move_existing_types.rb +130 -0
- data/scripts/split_grouped_types.rb +142 -0
- data/tech_docs/README.md +134 -0
- data/tech_docs/advanced/streaming.md +405 -0
- data/tech_docs/advanced/thread_safety.md +253 -0
- data/tech_docs/api/overview.md +485 -0
- data/tech_docs/appendices/type_chart.md +193 -0
- data/tech_docs/basic_concepts.md +383 -0
- data/tech_docs/behaviors/overview.md +346 -0
- data/tech_docs/dsl/complex_types.md +790 -0
- data/tech_docs/dsl/core_types.md +464 -0
- data/tech_docs/dsl/datetime_types.md +325 -0
- data/tech_docs/dsl/field_modifiers.md +414 -0
- data/tech_docs/dsl/grammar.md +431 -0
- data/tech_docs/dsl/schema_definition.md +399 -0
- data/tech_docs/export/README.md +276 -0
- data/tech_docs/installation.md +273 -0
- data/tech_docs/integration/ci_cd.md +707 -0
- data/tech_docs/integration/ci_cd_guide.md +579 -0
- data/tech_docs/integration/factory_bot.md +485 -0
- data/tech_docs/integration/rails.md +630 -0
- data/tech_docs/integration/rspec.md +449 -0
- data/tech_docs/modes/overview.md +350 -0
- data/tech_docs/performance/NATIVE_RUST_EXTENSION.md +1270 -0
- data/tech_docs/performance/OPTIMIZATION_GUIDE.md +901 -0
- data/tech_docs/quick_start.md +256 -0
- data/tech_docs/templates/README.md +805 -0
- data/tech_docs/tutorials/advanced.md +371 -0
- data/tech_docs/tutorials/getting_started.md +189 -0
- data/tech_docs/tutorials/intermediate.md +231 -0
- data/tech_docs/tutorials/template_gallery.md +569 -0
- data/tech_example/01_basic_usage.rb +238 -0
- data/tech_example/02_types_demo.rb +336 -0
- data/tech_example/04_cli_usage.md +429 -0
- data/tech_example/05_database_seeding.rb +283 -0
- data/tech_example/07_rspec_integration.rb +359 -0
- data/tech_example/10_custom_types.rb +387 -0
- data/tech_example/12_behaviors.rb +372 -0
- data/tech_example/13_twitter_dm_example.rb +120 -0
- data/tech_example/14_exact_json_structure.rb +253 -0
- data/tech_example/16_lsp_server.rb +56 -0
- data/tech_example/17_property_testing.rb +92 -0
- data/tech_example/18_enhanced_repl.rb +120 -0
- data/tech_example/19_security_fuzzing.rb +145 -0
- data/tech_example/NEW_FEATURES.md +169 -0
- data/tech_example/README.md +118 -0
- data/tech_example/schemas/api_response.dsl +123 -0
- data/tech_example/schemas/ecommerce.dsl +121 -0
- data/tech_example/schemas/twitter_dm.dsl +109 -0
- data/tech_example/schemas/user.dsl +36 -0
- data/vscode-extension/README.md +246 -0
- data/vscode-extension/language-configuration.json +31 -0
- data/vscode-extension/package.json +55 -0
- data/vscode-extension/snippets/fakedatadsl.json +198 -0
- data/vscode-extension/syntaxes/fakedatadsl.tmLanguage.json +128 -0
- metadata +478 -0
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
# ============================================================================
|
|
5
|
+
# FakeDataDSL - Exact JSON Structure Example
|
|
6
|
+
# ============================================================================
|
|
7
|
+
# Shows how to generate EXACTLY the JSON structure you need using
|
|
8
|
+
# ONLY built-in types (no custom register_type required).
|
|
9
|
+
#
|
|
10
|
+
# Run with: cd fake_data_dsl && ruby tech_example/14_exact_json_structure.rb
|
|
11
|
+
# Or: cd fake_data_dsl && bundle exec ruby tech_example/14_exact_json_structure.rb
|
|
12
|
+
# ============================================================================
|
|
13
|
+
|
|
14
|
+
# Load the local gem
|
|
15
|
+
$LOAD_PATH.unshift(File.expand_path('../lib', __dir__))
|
|
16
|
+
require 'fake_data_dsl'
|
|
17
|
+
require 'json'
|
|
18
|
+
|
|
19
|
+
puts "=" * 70
|
|
20
|
+
puts "Generating Exact JSON Structure (Built-in Types Only)"
|
|
21
|
+
puts "=" * 70
|
|
22
|
+
puts
|
|
23
|
+
|
|
24
|
+
# ============================================================================
|
|
25
|
+
# TARGET JSON STRUCTURE:
|
|
26
|
+
# ============================================================================
|
|
27
|
+
#
|
|
28
|
+
# {
|
|
29
|
+
# "type": "message_create",
|
|
30
|
+
# "id": "1548932749832749832",
|
|
31
|
+
# "created_timestamp": "1704898204000",
|
|
32
|
+
# "message_create": {
|
|
33
|
+
# "target": {
|
|
34
|
+
# "recipient_id": "2244994945"
|
|
35
|
+
# },
|
|
36
|
+
# "sender_id": "987654321",
|
|
37
|
+
# "message_data": {
|
|
38
|
+
# "text": "Hello! I need help with my order.",
|
|
39
|
+
# "entities": {
|
|
40
|
+
# "hashtags": [],
|
|
41
|
+
# "symbols": [],
|
|
42
|
+
# "user_mentions": [],
|
|
43
|
+
# "urls": []
|
|
44
|
+
# }
|
|
45
|
+
# }
|
|
46
|
+
# }
|
|
47
|
+
# }
|
|
48
|
+
#
|
|
49
|
+
# ============================================================================
|
|
50
|
+
|
|
51
|
+
# ============================================================================
|
|
52
|
+
# Built-in Types Used:
|
|
53
|
+
# ============================================================================
|
|
54
|
+
# - snowflake_id : 19-digit Twitter/Discord snowflake ID
|
|
55
|
+
# - unix_timestamp_ms : Unix timestamp in milliseconds as string
|
|
56
|
+
# - numeric_string_id : 9-19 digit numeric string
|
|
57
|
+
# - message_text : Chat message text using Faker
|
|
58
|
+
# - empty_array : Always returns []
|
|
59
|
+
# - const : Fixed literal value (e.g., const("message_create"))
|
|
60
|
+
# ============================================================================
|
|
61
|
+
|
|
62
|
+
puts "Built-in types available for this structure:"
|
|
63
|
+
puts " - snowflake_id : Twitter snowflake IDs (19 digits)"
|
|
64
|
+
puts " - unix_timestamp_ms : Unix timestamp in milliseconds"
|
|
65
|
+
puts " - numeric_string_id : Numeric string (9-19 digits)"
|
|
66
|
+
puts " - message_text : Chat/DM message text"
|
|
67
|
+
puts " - empty_array : Empty arrays for entities"
|
|
68
|
+
puts
|
|
69
|
+
|
|
70
|
+
# ============================================================================
|
|
71
|
+
# DEFINE THE SCHEMA (using Registry for nested schema references)
|
|
72
|
+
# ============================================================================
|
|
73
|
+
|
|
74
|
+
registry = FakeDataDSL::Registry.new
|
|
75
|
+
registry.load_string(<<~DSL)
|
|
76
|
+
TwitterDM:
|
|
77
|
+
type: const("message_create")
|
|
78
|
+
id: snowflake_id
|
|
79
|
+
created_timestamp: unix_timestamp_ms
|
|
80
|
+
message_create: MessageCreateData
|
|
81
|
+
|
|
82
|
+
MessageCreateData:
|
|
83
|
+
target: TargetData
|
|
84
|
+
sender_id: numeric_string_id
|
|
85
|
+
message_data: MessageContentData
|
|
86
|
+
|
|
87
|
+
TargetData:
|
|
88
|
+
recipient_id: numeric_string_id
|
|
89
|
+
|
|
90
|
+
MessageContentData:
|
|
91
|
+
text: message_text
|
|
92
|
+
entities: EntitiesData
|
|
93
|
+
|
|
94
|
+
EntitiesData:
|
|
95
|
+
hashtags: empty_array
|
|
96
|
+
symbols: empty_array
|
|
97
|
+
user_mentions: empty_array
|
|
98
|
+
urls: empty_array
|
|
99
|
+
DSL
|
|
100
|
+
|
|
101
|
+
schema = registry.schema("TwitterDM")
|
|
102
|
+
|
|
103
|
+
# ============================================================================
|
|
104
|
+
# GENERATE AND DISPLAY
|
|
105
|
+
# ============================================================================
|
|
106
|
+
|
|
107
|
+
puts "=" * 70
|
|
108
|
+
puts "1. GENERATED TWITTER DM"
|
|
109
|
+
puts "=" * 70
|
|
110
|
+
dm = schema.generate(registry: registry)
|
|
111
|
+
puts JSON.pretty_generate(dm)
|
|
112
|
+
puts
|
|
113
|
+
|
|
114
|
+
# ============================================================================
|
|
115
|
+
# COMPARE WITH ORIGINAL
|
|
116
|
+
# ============================================================================
|
|
117
|
+
|
|
118
|
+
original = {
|
|
119
|
+
"type" => "message_create",
|
|
120
|
+
"id" => "1548932749832749832",
|
|
121
|
+
"created_timestamp" => "1704898204000",
|
|
122
|
+
"message_create" => {
|
|
123
|
+
"target" => {
|
|
124
|
+
"recipient_id" => "2244994945"
|
|
125
|
+
},
|
|
126
|
+
"sender_id" => "987654321",
|
|
127
|
+
"message_data" => {
|
|
128
|
+
"text" => "Hello! I need help with my order.",
|
|
129
|
+
"entities" => {
|
|
130
|
+
"hashtags" => [],
|
|
131
|
+
"symbols" => [],
|
|
132
|
+
"user_mentions" => [],
|
|
133
|
+
"urls" => []
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
puts "=" * 70
|
|
140
|
+
puts "2. STRUCTURE COMPARISON"
|
|
141
|
+
puts "=" * 70
|
|
142
|
+
puts
|
|
143
|
+
puts "Original structure keys: #{original.keys}"
|
|
144
|
+
puts "Generated structure keys: #{dm.keys}"
|
|
145
|
+
puts "Keys match: #{original.keys.sort == dm.keys.sort}"
|
|
146
|
+
puts
|
|
147
|
+
puts "Original message_create keys: #{original['message_create'].keys}"
|
|
148
|
+
puts "Generated message_create keys: #{dm['message_create'].keys}"
|
|
149
|
+
puts "Nested keys match: #{original['message_create'].keys.sort == dm['message_create'].keys.sort}"
|
|
150
|
+
puts
|
|
151
|
+
puts "Original entities: #{original['message_create']['message_data']['entities']}"
|
|
152
|
+
puts "Generated entities: #{dm['message_create']['message_data']['entities']}"
|
|
153
|
+
puts "Entities match: #{original['message_create']['message_data']['entities'] == dm['message_create']['message_data']['entities']}"
|
|
154
|
+
puts
|
|
155
|
+
|
|
156
|
+
# ============================================================================
|
|
157
|
+
# TYPE VALIDATION
|
|
158
|
+
# ============================================================================
|
|
159
|
+
|
|
160
|
+
puts "=" * 70
|
|
161
|
+
puts "3. TYPE VALIDATION"
|
|
162
|
+
puts "=" * 70
|
|
163
|
+
puts
|
|
164
|
+
puts "Field validations:"
|
|
165
|
+
puts " type (should be 'message_create'): #{dm['type']} ✓" if dm['type'] == 'message_create'
|
|
166
|
+
puts " id (should be 19-digit string): #{dm['id'].length} digits ✓" if dm['id'].to_s.length >= 18
|
|
167
|
+
puts " created_timestamp (ms timestamp): #{dm['created_timestamp'].length} digits ✓" if dm['created_timestamp'].to_s.length >= 13
|
|
168
|
+
puts " sender_id (numeric string): #{dm['message_create']['sender_id']} ✓" if dm['message_create']['sender_id'].match?(/^\d+$/)
|
|
169
|
+
puts " recipient_id (numeric string): #{dm['message_create']['target']['recipient_id']} ✓" if dm['message_create']['target']['recipient_id'].match?(/^\d+$/)
|
|
170
|
+
puts " text (non-empty string): '#{dm['message_create']['message_data']['text'][0..30]}...' ✓" if dm['message_create']['message_data']['text'].is_a?(String)
|
|
171
|
+
puts " hashtags (empty array): #{dm['message_create']['message_data']['entities']['hashtags']} ✓" if dm['message_create']['message_data']['entities']['hashtags'] == []
|
|
172
|
+
puts
|
|
173
|
+
|
|
174
|
+
# ============================================================================
|
|
175
|
+
# BATCH GENERATION
|
|
176
|
+
# ============================================================================
|
|
177
|
+
|
|
178
|
+
puts "=" * 70
|
|
179
|
+
puts "4. BATCH GENERATION (3 messages)"
|
|
180
|
+
puts "=" * 70
|
|
181
|
+
puts
|
|
182
|
+
|
|
183
|
+
messages = schema.generate_many(3, registry: registry)
|
|
184
|
+
messages.each_with_index do |msg, i|
|
|
185
|
+
puts "Message #{i + 1}:"
|
|
186
|
+
puts " ID: #{msg['id']}"
|
|
187
|
+
puts " Timestamp: #{msg['created_timestamp']}"
|
|
188
|
+
puts " Sender: #{msg['message_create']['sender_id']}"
|
|
189
|
+
puts " Recipient: #{msg['message_create']['target']['recipient_id']}"
|
|
190
|
+
puts " Text: #{msg['message_create']['message_data']['text'][0..50]}..."
|
|
191
|
+
puts
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
# ============================================================================
|
|
195
|
+
# DETERMINISTIC OUTPUT
|
|
196
|
+
# ============================================================================
|
|
197
|
+
|
|
198
|
+
puts "=" * 70
|
|
199
|
+
puts "5. DETERMINISTIC OUTPUT (seed: 12345)"
|
|
200
|
+
puts "=" * 70
|
|
201
|
+
puts
|
|
202
|
+
|
|
203
|
+
dm1 = schema.generate(seed: 12345, registry: registry)
|
|
204
|
+
dm2 = schema.generate(seed: 12345, registry: registry)
|
|
205
|
+
|
|
206
|
+
puts "First generation:"
|
|
207
|
+
puts " ID: #{dm1['id']}"
|
|
208
|
+
puts " Text: #{dm1['message_create']['message_data']['text']}"
|
|
209
|
+
puts
|
|
210
|
+
puts "Second generation (same seed):"
|
|
211
|
+
puts " ID: #{dm2['id']}"
|
|
212
|
+
puts " Text: #{dm2['message_create']['message_data']['text']}"
|
|
213
|
+
puts
|
|
214
|
+
puts "Outputs identical: #{dm1 == dm2}"
|
|
215
|
+
puts
|
|
216
|
+
|
|
217
|
+
# ============================================================================
|
|
218
|
+
# AS WEBHOOK PAYLOAD
|
|
219
|
+
# ============================================================================
|
|
220
|
+
|
|
221
|
+
puts "=" * 70
|
|
222
|
+
puts "6. AS WEBHOOK PAYLOAD"
|
|
223
|
+
puts "=" * 70
|
|
224
|
+
puts
|
|
225
|
+
|
|
226
|
+
webhook_payload = {
|
|
227
|
+
"for_user_id" => schema.generate(registry: registry).dig('message_create', 'target', 'recipient_id'),
|
|
228
|
+
"direct_message_events" => schema.generate_many(2, seed: 42, registry: registry)
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
puts JSON.pretty_generate(webhook_payload)
|
|
232
|
+
puts
|
|
233
|
+
|
|
234
|
+
# ============================================================================
|
|
235
|
+
# SUMMARY
|
|
236
|
+
# ============================================================================
|
|
237
|
+
|
|
238
|
+
puts "=" * 70
|
|
239
|
+
puts "SUMMARY"
|
|
240
|
+
puts "=" * 70
|
|
241
|
+
puts
|
|
242
|
+
puts "✓ All built-in types - no register_type needed!"
|
|
243
|
+
puts "✓ Exact JSON structure match"
|
|
244
|
+
puts "✓ Deterministic output with seeds"
|
|
245
|
+
puts "✓ Batch generation supported"
|
|
246
|
+
puts "✓ Ready for API testing"
|
|
247
|
+
puts
|
|
248
|
+
puts "Available built-in types for social/messaging APIs:"
|
|
249
|
+
puts " snowflake_id, unix_timestamp_ms, numeric_string_id,"
|
|
250
|
+
puts " message_text, empty_array, social_handle, hashtag_text,"
|
|
251
|
+
puts " indices_pair"
|
|
252
|
+
puts
|
|
253
|
+
puts "=" * 70
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# =============================================================================
|
|
4
|
+
# LSP Server Example
|
|
5
|
+
# =============================================================================
|
|
6
|
+
#
|
|
7
|
+
# This example demonstrates how to use the FakeDataDSL LSP server
|
|
8
|
+
# for IDE integration.
|
|
9
|
+
#
|
|
10
|
+
# =============================================================================
|
|
11
|
+
|
|
12
|
+
require "fake_data_dsl"
|
|
13
|
+
|
|
14
|
+
# LSP server is automatically loaded with fake_data_dsl
|
|
15
|
+
# No need to require separately
|
|
16
|
+
|
|
17
|
+
puts "Starting FakeDataDSL LSP Server..."
|
|
18
|
+
puts "Connect your IDE to this server via stdin/stdout"
|
|
19
|
+
puts "Press Ctrl+C to stop"
|
|
20
|
+
|
|
21
|
+
server = FakeDataDSL::LSP::Server.new
|
|
22
|
+
begin
|
|
23
|
+
server.run
|
|
24
|
+
rescue Interrupt
|
|
25
|
+
puts "\nServer stopped."
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Example: LSP server with custom input/output
|
|
30
|
+
# This is useful for testing or custom integrations
|
|
31
|
+
|
|
32
|
+
def start_lsp_with_logging
|
|
33
|
+
# LSP server is available via FakeDataDSL::LSP::Server
|
|
34
|
+
output = File.open("lsp_output.log", "w")
|
|
35
|
+
|
|
36
|
+
server = FakeDataDSL::LSP::Server.new(input: input, output: output)
|
|
37
|
+
server.run
|
|
38
|
+
ensure
|
|
39
|
+
input&.close
|
|
40
|
+
output&.close
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Example: LSP capabilities
|
|
44
|
+
# The server supports:
|
|
45
|
+
# - textDocument/definition (go to definition)
|
|
46
|
+
# - textDocument/hover (hover documentation)
|
|
47
|
+
# - textDocument/completion (auto-completion)
|
|
48
|
+
# - textDocument/diagnostic (error reporting)
|
|
49
|
+
|
|
50
|
+
puts <<~INFO
|
|
51
|
+
LSP Server Features:
|
|
52
|
+
- Go to Definition: Jump to schema definitions from Ref(User.id)
|
|
53
|
+
- Hover: See type and behavior documentation
|
|
54
|
+
- Completion: Auto-complete types, behaviors, and schemas
|
|
55
|
+
- Diagnostics: Real-time error reporting with line/column numbers
|
|
56
|
+
INFO
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# =============================================================================
|
|
4
|
+
# Property-Based Testing Example
|
|
5
|
+
# =============================================================================
|
|
6
|
+
#
|
|
7
|
+
# This example demonstrates property-based testing with FakeDataDSL.
|
|
8
|
+
# Property-based testing verifies that properties hold for all generated data.
|
|
9
|
+
#
|
|
10
|
+
# =============================================================================
|
|
11
|
+
|
|
12
|
+
require "fake_data_dsl"
|
|
13
|
+
|
|
14
|
+
# Property testing is automatically loaded with fake_data_dsl
|
|
15
|
+
# No need to require separately
|
|
16
|
+
|
|
17
|
+
# Load schemas
|
|
18
|
+
registry = FakeDataDSL::Registry.new
|
|
19
|
+
registry.load_string(<<~DSL)
|
|
20
|
+
User:
|
|
21
|
+
id: uuid
|
|
22
|
+
name: name
|
|
23
|
+
email: email
|
|
24
|
+
age: number(18..80)
|
|
25
|
+
active: boolean(true:90%)
|
|
26
|
+
DSL
|
|
27
|
+
|
|
28
|
+
# Example 1: Verify email format
|
|
29
|
+
puts "Example 1: Verifying email format"
|
|
30
|
+
verify_property("User", count: 100, registry: registry) do |user_data|
|
|
31
|
+
email = user_data["email"]
|
|
32
|
+
expect(email).to match(/\A[\w+\-.]+@[a-z\d\-]+(\.[a-z\d\-]+)*\.[a-z]+\z/i)
|
|
33
|
+
end
|
|
34
|
+
puts "✅ All emails are valid"
|
|
35
|
+
|
|
36
|
+
# Example 2: Verify age range
|
|
37
|
+
puts "\nExample 2: Verifying age range"
|
|
38
|
+
verify_property("User", count: 100, registry: registry) do |user_data|
|
|
39
|
+
age = user_data["age"]
|
|
40
|
+
expect(age).to be_between(18, 80)
|
|
41
|
+
end
|
|
42
|
+
puts "✅ All ages are in valid range"
|
|
43
|
+
|
|
44
|
+
# Example 3: Verify UUID format
|
|
45
|
+
puts "\nExample 3: Verifying UUID format"
|
|
46
|
+
verify_property("User", count: 100, registry: registry) do |user_data|
|
|
47
|
+
uuid = user_data["id"]
|
|
48
|
+
expect(uuid).to match(/\A[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\z/i)
|
|
49
|
+
end
|
|
50
|
+
puts "✅ All UUIDs are valid"
|
|
51
|
+
|
|
52
|
+
# Example 4: Deterministic testing with seed
|
|
53
|
+
puts "\nExample 4: Deterministic testing"
|
|
54
|
+
seed = 12345
|
|
55
|
+
results1 = []
|
|
56
|
+
results2 = []
|
|
57
|
+
|
|
58
|
+
verify_property("User", count: 10, seed: seed, registry: registry) do |user_data|
|
|
59
|
+
results1 << user_data["id"]
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
verify_property("User", count: 10, seed: seed, registry: registry) do |user_data|
|
|
63
|
+
results2 << user_data["id"]
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
if results1 == results2
|
|
67
|
+
puts "✅ Same seed produces same results"
|
|
68
|
+
else
|
|
69
|
+
puts "❌ Results differ (this shouldn't happen)"
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# Example 5: Streaming for large counts
|
|
73
|
+
puts "\nExample 5: Streaming verification (memory-efficient)"
|
|
74
|
+
call_count = 0
|
|
75
|
+
verify_property_stream("User", count: 1000, registry: registry) do |user_data|
|
|
76
|
+
call_count += 1
|
|
77
|
+
expect(user_data).to be_a(Hash)
|
|
78
|
+
expect(user_data["id"]).to be_a(String)
|
|
79
|
+
end
|
|
80
|
+
puts "✅ Verified #{call_count} records via streaming"
|
|
81
|
+
|
|
82
|
+
# Example 6: Testing with different modes
|
|
83
|
+
puts "\nExample 6: Testing with edge mode"
|
|
84
|
+
verify_property("User", count: 50, mode: :edge, registry: registry) do |user_data|
|
|
85
|
+
# Edge mode may produce empty strings, nulls, etc.
|
|
86
|
+
expect(user_data["email"]).to be_a(String).or(be_nil)
|
|
87
|
+
end
|
|
88
|
+
puts "✅ Edge mode handled correctly"
|
|
89
|
+
|
|
90
|
+
puts "\n" + "=" * 60
|
|
91
|
+
puts "All property tests passed!"
|
|
92
|
+
puts "=" * 60
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# =============================================================================
|
|
4
|
+
# Enhanced REPL Example
|
|
5
|
+
# =============================================================================
|
|
6
|
+
#
|
|
7
|
+
# This example demonstrates the enhanced REPL features:
|
|
8
|
+
# - Visual table formatting
|
|
9
|
+
# - Step-through debugging
|
|
10
|
+
# - Detailed inspection
|
|
11
|
+
#
|
|
12
|
+
# =============================================================================
|
|
13
|
+
|
|
14
|
+
require "fake_data_dsl"
|
|
15
|
+
|
|
16
|
+
# Ensure REPL formatter is loaded (it's manually loaded in fake_data_dsl.rb)
|
|
17
|
+
# Access via FakeDataDSL::REPL::Formatter
|
|
18
|
+
|
|
19
|
+
# Load schemas
|
|
20
|
+
registry = FakeDataDSL::Registry.new
|
|
21
|
+
registry.load_string(<<~DSL)
|
|
22
|
+
User:
|
|
23
|
+
id: uuid
|
|
24
|
+
name: name
|
|
25
|
+
email: email
|
|
26
|
+
age: number(18..80)
|
|
27
|
+
active: boolean(true:90%)
|
|
28
|
+
created_at: timestamp
|
|
29
|
+
DSL
|
|
30
|
+
|
|
31
|
+
schema = registry.schema("User")
|
|
32
|
+
|
|
33
|
+
# Example 1: Table formatting for single record
|
|
34
|
+
puts "Example 1: Table formatting (single record)"
|
|
35
|
+
puts "=" * 60
|
|
36
|
+
record = schema.generate
|
|
37
|
+
puts FakeDataDSL::REPL::Formatter.table(record)
|
|
38
|
+
puts
|
|
39
|
+
|
|
40
|
+
# Example 2: Table formatting for multiple records
|
|
41
|
+
puts "\nExample 2: Table formatting (multiple records)"
|
|
42
|
+
puts "=" * 60
|
|
43
|
+
records = schema.generate_many(5)
|
|
44
|
+
puts FakeDataDSL::REPL::Formatter.table(records)
|
|
45
|
+
puts
|
|
46
|
+
|
|
47
|
+
# Example 3: Format value helper
|
|
48
|
+
puts "\nExample 3: Format value helper"
|
|
49
|
+
puts "=" * 60
|
|
50
|
+
test_values = [
|
|
51
|
+
"Short string",
|
|
52
|
+
"A" * 100, # Long string
|
|
53
|
+
{ "key1" => "value1", "key2" => "value2" },
|
|
54
|
+
[1, 2, 3, 4, 5],
|
|
55
|
+
nil,
|
|
56
|
+
12345
|
|
57
|
+
]
|
|
58
|
+
|
|
59
|
+
test_values.each do |value|
|
|
60
|
+
formatted = FakeDataDSL::REPL::Formatter.format_value(value, 30)
|
|
61
|
+
puts " #{value.class.name.ljust(15)} => #{formatted}"
|
|
62
|
+
end
|
|
63
|
+
puts
|
|
64
|
+
|
|
65
|
+
# Example 4: Context formatting
|
|
66
|
+
puts "\nExample 4: Context formatting"
|
|
67
|
+
puts "=" * 60
|
|
68
|
+
context = FakeDataDSL::Generator::Context.new
|
|
69
|
+
context["id"] = "550e8400-e29b-41d4-a716-446655440000"
|
|
70
|
+
context["name"] = "John Doe"
|
|
71
|
+
context["email"] = "john.doe@example.com"
|
|
72
|
+
context.depth = 1
|
|
73
|
+
context.registry = registry
|
|
74
|
+
|
|
75
|
+
puts FakeDataDSL::REPL::Formatter.format_context(context)
|
|
76
|
+
puts
|
|
77
|
+
|
|
78
|
+
# Example 5: Debug engine (simulated)
|
|
79
|
+
puts "\nExample 5: Debug engine usage"
|
|
80
|
+
puts "=" * 60
|
|
81
|
+
puts "Note: Full debug mode requires interactive REPL"
|
|
82
|
+
puts "Run: fake_data_dsl repl"
|
|
83
|
+
puts "Then use: debug User"
|
|
84
|
+
puts
|
|
85
|
+
|
|
86
|
+
# Example 6: Inspect command output
|
|
87
|
+
puts "\nExample 6: Inspect command output"
|
|
88
|
+
puts "=" * 60
|
|
89
|
+
record = schema.generate
|
|
90
|
+
puts "📊 Generated Record:"
|
|
91
|
+
puts "=" * 60
|
|
92
|
+
puts FakeDataDSL::REPL::Formatter.table(record)
|
|
93
|
+
puts
|
|
94
|
+
puts "📋 JSON Format:"
|
|
95
|
+
puts JSON.pretty_generate(record)
|
|
96
|
+
puts
|
|
97
|
+
puts "📏 Statistics:"
|
|
98
|
+
puts " Fields: #{record.keys.length}"
|
|
99
|
+
puts " Total size: #{JSON.generate(record).bytesize} bytes"
|
|
100
|
+
record.each do |key, value|
|
|
101
|
+
type = value.class.name
|
|
102
|
+
size = case value
|
|
103
|
+
when String then value.bytesize
|
|
104
|
+
when Hash then "#{value.keys.length} keys"
|
|
105
|
+
when Array then "#{value.length} items"
|
|
106
|
+
else value.inspect.length
|
|
107
|
+
end
|
|
108
|
+
puts " #{key}: #{type} (#{size})"
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
puts "\n" + "=" * 60
|
|
112
|
+
puts "Enhanced REPL examples complete!"
|
|
113
|
+
puts "=" * 60
|
|
114
|
+
puts "\nTo use the interactive REPL, run:"
|
|
115
|
+
puts " fake_data_dsl repl"
|
|
116
|
+
puts "\nAvailable commands:"
|
|
117
|
+
puts " table User - Display record in table format"
|
|
118
|
+
puts " table User 5 - Display 5 records in table format"
|
|
119
|
+
puts " debug User - Step-through debugging"
|
|
120
|
+
puts " inspect User - Detailed inspection with statistics"
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# =============================================================================
|
|
4
|
+
# Security Fuzzing (Hostile Mode) Example
|
|
5
|
+
# =============================================================================
|
|
6
|
+
#
|
|
7
|
+
# This example demonstrates using :hostile mode for security testing.
|
|
8
|
+
# Hostile mode generates attack payloads (SQL injection, XSS, etc.)
|
|
9
|
+
# for testing API endpoints and validation logic.
|
|
10
|
+
#
|
|
11
|
+
# =============================================================================
|
|
12
|
+
|
|
13
|
+
require "fake_data_dsl"
|
|
14
|
+
|
|
15
|
+
# Load schemas
|
|
16
|
+
registry = FakeDataDSL::Registry.new
|
|
17
|
+
registry.load_string(<<~DSL)
|
|
18
|
+
User:
|
|
19
|
+
id: uuid
|
|
20
|
+
name: text
|
|
21
|
+
email: text
|
|
22
|
+
comment: text
|
|
23
|
+
DSL
|
|
24
|
+
|
|
25
|
+
schema = registry.schema("User")
|
|
26
|
+
|
|
27
|
+
# Example 1: Generate hostile data
|
|
28
|
+
puts "Example 1: Generating hostile data"
|
|
29
|
+
puts "=" * 60
|
|
30
|
+
hostile_record = schema.generate(mode: :hostile)
|
|
31
|
+
puts JSON.pretty_generate(hostile_record)
|
|
32
|
+
puts
|
|
33
|
+
|
|
34
|
+
# Example 2: Generate multiple hostile records
|
|
35
|
+
puts "\nExample 2: Generating multiple hostile records"
|
|
36
|
+
puts "=" * 60
|
|
37
|
+
hostile_records = schema.generate_many(10, mode: :hostile)
|
|
38
|
+
hostile_records.each_with_index do |record, idx|
|
|
39
|
+
puts "Record #{idx + 1}:"
|
|
40
|
+
puts " name: #{record['name'].inspect}"
|
|
41
|
+
puts " email: #{record['email'].inspect}"
|
|
42
|
+
puts " comment: #{record['comment'].inspect}"
|
|
43
|
+
puts
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Example 3: Test API endpoint with hostile data
|
|
47
|
+
puts "\nExample 3: Testing API endpoint (simulated)"
|
|
48
|
+
puts "=" * 60
|
|
49
|
+
puts "Simulating API endpoint test with hostile data..."
|
|
50
|
+
|
|
51
|
+
hostile_data = schema.generate_many(100, mode: :hostile)
|
|
52
|
+
success_count = 0
|
|
53
|
+
rejected_count = 0
|
|
54
|
+
|
|
55
|
+
hostile_data.each do |payload|
|
|
56
|
+
# Simulate API endpoint validation
|
|
57
|
+
# In real scenario: response = post("/api/users", payload)
|
|
58
|
+
|
|
59
|
+
# Check if payload contains hostile patterns
|
|
60
|
+
is_hostile = payload.values.any? do |value|
|
|
61
|
+
next false unless value.is_a?(String)
|
|
62
|
+
|
|
63
|
+
# Check for SQL injection patterns
|
|
64
|
+
sql_patterns = ["' OR '1'='1", "'; DROP TABLE", "UNION SELECT"]
|
|
65
|
+
sql_patterns.any? { |pattern| value.include?(pattern) } ||
|
|
66
|
+
# Check for XSS patterns
|
|
67
|
+
xss_patterns = ["<script>", "javascript:", "onerror="]
|
|
68
|
+
xss_patterns.any? { |pattern| value.include?(pattern) } ||
|
|
69
|
+
# Check for buffer overflow (very long strings)
|
|
70
|
+
value.length > 1000
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
if is_hostile
|
|
74
|
+
rejected_count += 1
|
|
75
|
+
# In real scenario: expect(response.status).to eq(400)
|
|
76
|
+
else
|
|
77
|
+
success_count += 1
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
puts " ✅ Rejected hostile payloads: #{rejected_count}"
|
|
82
|
+
puts " ⚠️ Accepted (should be 0): #{success_count}"
|
|
83
|
+
puts
|
|
84
|
+
|
|
85
|
+
# Example 4: Property-based testing with hostile mode
|
|
86
|
+
puts "\nExample 4: Property-based testing with hostile mode"
|
|
87
|
+
puts "=" * 60
|
|
88
|
+
puts "Verifying that validation rejects hostile input..."
|
|
89
|
+
|
|
90
|
+
begin
|
|
91
|
+
require "fake_data_dsl/property_testing"
|
|
92
|
+
include FakeDataDSL::PropertyTesting
|
|
93
|
+
|
|
94
|
+
verify_property("User", count: 500, mode: :hostile, registry: registry) do |user_data|
|
|
95
|
+
# In real scenario, this would test actual validation:
|
|
96
|
+
# user = User.new(user_data)
|
|
97
|
+
# expect(user).not_to be_valid
|
|
98
|
+
|
|
99
|
+
# For this example, we just verify the data structure
|
|
100
|
+
expect(user_data).to be_a(Hash)
|
|
101
|
+
expect(user_data["id"]).to be_a(String)
|
|
102
|
+
end
|
|
103
|
+
puts "✅ Property test passed"
|
|
104
|
+
rescue LoadError
|
|
105
|
+
puts "⚠️ RSpec not available, skipping property test"
|
|
106
|
+
end
|
|
107
|
+
puts
|
|
108
|
+
|
|
109
|
+
# Example 5: Inspect hostile payloads
|
|
110
|
+
puts "\nExample 5: Available hostile payloads"
|
|
111
|
+
puts "=" * 60
|
|
112
|
+
puts "SQL Injection payloads:"
|
|
113
|
+
FakeDataDSL::HostilePayloads::SQL_INJECTION.first(5).each do |payload|
|
|
114
|
+
puts " - #{payload.inspect}"
|
|
115
|
+
end
|
|
116
|
+
puts
|
|
117
|
+
puts "XSS payloads:"
|
|
118
|
+
FakeDataDSL::HostilePayloads::XSS.first(5).each do |payload|
|
|
119
|
+
puts " - #{payload.inspect}"
|
|
120
|
+
end
|
|
121
|
+
puts
|
|
122
|
+
puts "Buffer overflow payloads:"
|
|
123
|
+
FakeDataDSL::HostilePayloads::BUFFER_OVERFLOW.first(3).each do |payload|
|
|
124
|
+
puts " - Length: #{payload.length} bytes"
|
|
125
|
+
end
|
|
126
|
+
puts
|
|
127
|
+
|
|
128
|
+
# Example 6: CLI usage
|
|
129
|
+
puts "\nExample 6: CLI usage"
|
|
130
|
+
puts "=" * 60
|
|
131
|
+
puts "Generate hostile data via CLI:"
|
|
132
|
+
puts " fake_data_dsl generate User --mode hostile"
|
|
133
|
+
puts " fake_data_dsl generate User --mode hostile --count 1000"
|
|
134
|
+
puts
|
|
135
|
+
puts "Use in REPL:"
|
|
136
|
+
puts " fake_data_dsl repl"
|
|
137
|
+
puts " > mode hostile"
|
|
138
|
+
puts " > gen User"
|
|
139
|
+
puts
|
|
140
|
+
|
|
141
|
+
puts "=" * 60
|
|
142
|
+
puts "Security fuzzing examples complete!"
|
|
143
|
+
puts "=" * 60
|
|
144
|
+
puts "\n⚠️ WARNING: Hostile mode generates actual attack payloads."
|
|
145
|
+
puts "Use only in test environments, never in production!"
|