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,183 @@
|
|
|
1
|
+
# Advanced Features
|
|
2
|
+
|
|
3
|
+
Advanced features for complex data generation scenarios.
|
|
4
|
+
|
|
5
|
+
## Cross-Schema References
|
|
6
|
+
|
|
7
|
+
Reference fields from other schemas:
|
|
8
|
+
|
|
9
|
+
```ruby
|
|
10
|
+
User:
|
|
11
|
+
id: uuid
|
|
12
|
+
name: name
|
|
13
|
+
|
|
14
|
+
Order:
|
|
15
|
+
id: uuid
|
|
16
|
+
user_id: reference(User, id) # References User's id
|
|
17
|
+
total: number(10..1000)
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
**Benefits:**
|
|
21
|
+
- Maintain referential integrity
|
|
22
|
+
- Generate related data sets
|
|
23
|
+
- Test foreign key relationships
|
|
24
|
+
|
|
25
|
+
## Custom Functions
|
|
26
|
+
|
|
27
|
+
Define custom generation logic:
|
|
28
|
+
|
|
29
|
+
```ruby
|
|
30
|
+
# Register a custom function
|
|
31
|
+
FakeDataDSL.register_function(:generate_slug) do |context|
|
|
32
|
+
name = context["name"] || "default"
|
|
33
|
+
name.downcase.gsub(/\s+/, '-')
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Use in schema
|
|
37
|
+
User:
|
|
38
|
+
name: name
|
|
39
|
+
slug: custom(:generate_slug)
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
**Function context:**
|
|
43
|
+
- Receives current generation context
|
|
44
|
+
- Can access previously generated fields
|
|
45
|
+
- Returns generated value
|
|
46
|
+
|
|
47
|
+
## Streaming Generation
|
|
48
|
+
|
|
49
|
+
Generate large datasets efficiently:
|
|
50
|
+
|
|
51
|
+
```ruby
|
|
52
|
+
schema = registry.schema('User')
|
|
53
|
+
|
|
54
|
+
# Stream records (lazy evaluation)
|
|
55
|
+
schema.generate_many_stream(1000).each do |record|
|
|
56
|
+
# Process each record
|
|
57
|
+
puts record
|
|
58
|
+
end
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
**Benefits:**
|
|
62
|
+
- Memory efficient
|
|
63
|
+
- Can process records as they're generated
|
|
64
|
+
- Suitable for large datasets
|
|
65
|
+
|
|
66
|
+
## Deterministic Generation
|
|
67
|
+
|
|
68
|
+
Use seeds for reproducible data:
|
|
69
|
+
|
|
70
|
+
```ruby
|
|
71
|
+
# Set seed
|
|
72
|
+
FakeDataDSL.configure do |config|
|
|
73
|
+
config.seed = 12345
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# Generate (same seed = same data)
|
|
77
|
+
record1 = schema.generate
|
|
78
|
+
record2 = schema.generate
|
|
79
|
+
# record1 and record2 are deterministic
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
**Use cases:**
|
|
83
|
+
- Reproducible tests
|
|
84
|
+
- Debugging
|
|
85
|
+
- Consistent demo data
|
|
86
|
+
|
|
87
|
+
## Formula Fields
|
|
88
|
+
|
|
89
|
+
Compute values from other fields:
|
|
90
|
+
|
|
91
|
+
```ruby
|
|
92
|
+
Order:
|
|
93
|
+
quantity: number(1..10)
|
|
94
|
+
unit_price: number(10..100)
|
|
95
|
+
total: formula(quantity * unit_price)
|
|
96
|
+
tax: formula(total * 0.08)
|
|
97
|
+
grand_total: formula(total + tax)
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
**Supported operations:**
|
|
101
|
+
- Arithmetic: `+`, `-`, `*`, `/`
|
|
102
|
+
- Field references: `price`, `quantity`
|
|
103
|
+
- Constants: `0.08`, `100`
|
|
104
|
+
|
|
105
|
+
## Template Fields
|
|
106
|
+
|
|
107
|
+
String interpolation with field values:
|
|
108
|
+
|
|
109
|
+
```ruby
|
|
110
|
+
User:
|
|
111
|
+
first_name: first_name
|
|
112
|
+
last_name: last_name
|
|
113
|
+
greeting: template("Hello {first_name} {last_name}!")
|
|
114
|
+
email_template: template("{first_name}.{last_name}@example.com")
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
**Placeholders:**
|
|
118
|
+
- `{field_name}` - Replaced with field value
|
|
119
|
+
- Supports multiple placeholders
|
|
120
|
+
|
|
121
|
+
## Conditional Fields
|
|
122
|
+
|
|
123
|
+
Fields that depend on other fields:
|
|
124
|
+
|
|
125
|
+
```ruby
|
|
126
|
+
User:
|
|
127
|
+
is_admin: boolean
|
|
128
|
+
admin_key: text if is_admin
|
|
129
|
+
is_active: boolean
|
|
130
|
+
deactivated_at: date if !is_active
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
**Conditions:**
|
|
134
|
+
- `if field_name` - When field is truthy
|
|
135
|
+
- `if !field_name` - When field is falsy
|
|
136
|
+
|
|
137
|
+
## Uniqueness Constraints
|
|
138
|
+
|
|
139
|
+
Ensure unique values:
|
|
140
|
+
|
|
141
|
+
```ruby
|
|
142
|
+
User:
|
|
143
|
+
email: email unique
|
|
144
|
+
username: username unique
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
**Scope:**
|
|
148
|
+
- Per-schema generation
|
|
149
|
+
- Per-Engine instance
|
|
150
|
+
- Resets between runs
|
|
151
|
+
|
|
152
|
+
## Resource Limits
|
|
153
|
+
|
|
154
|
+
Configure limits to prevent DoS:
|
|
155
|
+
|
|
156
|
+
```ruby
|
|
157
|
+
FakeDataDSL.configure do |config|
|
|
158
|
+
config.max_recursion = 10
|
|
159
|
+
config.max_array_size = 1000
|
|
160
|
+
config.max_text_length = 10000
|
|
161
|
+
config.max_latency = 5000 # milliseconds
|
|
162
|
+
end
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
## Observability
|
|
166
|
+
|
|
167
|
+
Add logging and metrics:
|
|
168
|
+
|
|
169
|
+
```ruby
|
|
170
|
+
FakeDataDSL.configure do |config|
|
|
171
|
+
config.logger = Logger.new(STDOUT)
|
|
172
|
+
config.metrics_collector = MyMetricsCollector.new
|
|
173
|
+
config.on_field_generated = proc do |schema, field, value|
|
|
174
|
+
puts "Generated #{field} for #{schema}: #{value}"
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
## See Also
|
|
180
|
+
|
|
181
|
+
- [Examples](examples.md) - Advanced usage examples
|
|
182
|
+
- [API Reference](api_reference.md) - Programmatic API
|
|
183
|
+
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
# API Reference
|
|
2
|
+
|
|
3
|
+
Programmatic API for FakeDataDSL.
|
|
4
|
+
|
|
5
|
+
## Registry
|
|
6
|
+
|
|
7
|
+
The `Registry` class manages schema definitions.
|
|
8
|
+
|
|
9
|
+
### Loading Schemas
|
|
10
|
+
|
|
11
|
+
```ruby
|
|
12
|
+
registry = FakeDataDSL::Registry.new
|
|
13
|
+
|
|
14
|
+
# Load from file
|
|
15
|
+
registry.load_file('schemas/user.dsl')
|
|
16
|
+
|
|
17
|
+
# Load from string
|
|
18
|
+
registry.load_string(<<~DSL)
|
|
19
|
+
User:
|
|
20
|
+
id: uuid
|
|
21
|
+
name: name
|
|
22
|
+
DSL
|
|
23
|
+
|
|
24
|
+
# Load from directory
|
|
25
|
+
registry.load_dir('schemas/')
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### Accessing Schemas
|
|
29
|
+
|
|
30
|
+
```ruby
|
|
31
|
+
# Get a schema
|
|
32
|
+
schema = registry.schema('User')
|
|
33
|
+
|
|
34
|
+
# Check if schema exists
|
|
35
|
+
if registry.schema?('User')
|
|
36
|
+
# ...
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# List all schema names
|
|
40
|
+
names = registry.names
|
|
41
|
+
# => ["User", "Order", "Product"]
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Schema
|
|
45
|
+
|
|
46
|
+
The `Schema` class represents a data schema.
|
|
47
|
+
|
|
48
|
+
### Generating Data
|
|
49
|
+
|
|
50
|
+
```ruby
|
|
51
|
+
schema = registry.schema('User')
|
|
52
|
+
|
|
53
|
+
# Generate single record
|
|
54
|
+
record = schema.generate
|
|
55
|
+
# => { "id" => "...", "name" => "..." }
|
|
56
|
+
|
|
57
|
+
# Generate multiple records
|
|
58
|
+
records = schema.generate_many(10)
|
|
59
|
+
# => Array of 10 records
|
|
60
|
+
|
|
61
|
+
# Stream records (lazy)
|
|
62
|
+
schema.generate_many_stream(1000).each do |record|
|
|
63
|
+
# Process each record
|
|
64
|
+
end
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Configuration
|
|
68
|
+
|
|
69
|
+
```ruby
|
|
70
|
+
# Set default mode
|
|
71
|
+
schema.default_mode = :edge
|
|
72
|
+
|
|
73
|
+
# Generate with specific mode
|
|
74
|
+
record = schema.generate(mode: :invalid)
|
|
75
|
+
|
|
76
|
+
# Generate with overrides
|
|
77
|
+
record = schema.generate(overrides: { "name" => "Custom Name" })
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Configuration
|
|
81
|
+
|
|
82
|
+
Global configuration:
|
|
83
|
+
|
|
84
|
+
```ruby
|
|
85
|
+
FakeDataDSL.configure do |config|
|
|
86
|
+
# Seed for deterministic generation
|
|
87
|
+
config.seed = 12345
|
|
88
|
+
|
|
89
|
+
# Resource limits
|
|
90
|
+
config.max_recursion = 10
|
|
91
|
+
config.max_array_size = 1000
|
|
92
|
+
config.max_text_length = 10000
|
|
93
|
+
config.max_latency = 5000
|
|
94
|
+
|
|
95
|
+
# Observability
|
|
96
|
+
config.logger = Logger.new(STDOUT)
|
|
97
|
+
config.metrics_collector = MyMetricsCollector.new
|
|
98
|
+
config.on_field_generated = proc do |schema, field, value|
|
|
99
|
+
# Custom callback
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## Custom Types
|
|
105
|
+
|
|
106
|
+
Register custom types:
|
|
107
|
+
|
|
108
|
+
```ruby
|
|
109
|
+
FakeDataDSL.register_type(:my_type) do |rng, context, args|
|
|
110
|
+
# Generate value
|
|
111
|
+
"custom_value_#{rng.int(1, 100)}"
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
# Use in schema
|
|
115
|
+
MySchema:
|
|
116
|
+
value: my_type
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## Custom Functions
|
|
120
|
+
|
|
121
|
+
Register custom functions:
|
|
122
|
+
|
|
123
|
+
```ruby
|
|
124
|
+
FakeDataDSL.register_function(:slugify) do |context|
|
|
125
|
+
name = context["name"] || "default"
|
|
126
|
+
name.downcase.gsub(/\s+/, '-')
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
# Use in schema
|
|
130
|
+
User:
|
|
131
|
+
name: name
|
|
132
|
+
slug: custom(:slugify)
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## Custom Behaviors
|
|
136
|
+
|
|
137
|
+
Register custom behaviors:
|
|
138
|
+
|
|
139
|
+
```ruby
|
|
140
|
+
FakeDataDSL.register_behavior(:my_behavior) do |field, args|
|
|
141
|
+
# Custom behavior logic
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
# Use in schema
|
|
145
|
+
User:
|
|
146
|
+
name: name @my_behavior(arg1, arg2)
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## See Also
|
|
150
|
+
|
|
151
|
+
- [Getting Started](getting_started.md) - Basic usage
|
|
152
|
+
- [DSL Reference](dsl_reference.md) - DSL syntax
|
|
153
|
+
|
data/docs/behaviors.md
ADDED
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
# Behaviors Guide
|
|
2
|
+
|
|
3
|
+
Behaviors modify how data is generated, adding delays, failures, and other effects.
|
|
4
|
+
|
|
5
|
+
## Available Behaviors
|
|
6
|
+
|
|
7
|
+
### Latency
|
|
8
|
+
|
|
9
|
+
Add delays to simulate network or processing time:
|
|
10
|
+
|
|
11
|
+
```ruby
|
|
12
|
+
User:
|
|
13
|
+
@latency 100ms # Schema-level: all fields delayed
|
|
14
|
+
id: uuid
|
|
15
|
+
name: name @latency 50ms # Field-level: specific delay
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
**Arguments:**
|
|
19
|
+
- Duration: `100ms`, `2s`, `500ms`, etc.
|
|
20
|
+
- Range: `@latency 50ms..200ms` (random delay in range)
|
|
21
|
+
|
|
22
|
+
### Failure
|
|
23
|
+
|
|
24
|
+
Simulate failures with a probability:
|
|
25
|
+
|
|
26
|
+
```ruby
|
|
27
|
+
User:
|
|
28
|
+
@failure 5% # 5% chance of failure
|
|
29
|
+
id: uuid
|
|
30
|
+
name: name @failure 1% # 1% chance for this field
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
**Arguments:**
|
|
34
|
+
- Percentage: `5%`, `10%`, `0.5%`
|
|
35
|
+
|
|
36
|
+
### Partial Data
|
|
37
|
+
|
|
38
|
+
Sometimes omit fields:
|
|
39
|
+
|
|
40
|
+
```ruby
|
|
41
|
+
User:
|
|
42
|
+
@partial_data 20% # 20% chance of missing fields
|
|
43
|
+
id: uuid
|
|
44
|
+
name: name
|
|
45
|
+
email: email
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
**Arguments:**
|
|
49
|
+
- Percentage: `20%`, `10%`
|
|
50
|
+
|
|
51
|
+
### Randomize Order
|
|
52
|
+
|
|
53
|
+
Randomize field generation order:
|
|
54
|
+
|
|
55
|
+
```ruby
|
|
56
|
+
User:
|
|
57
|
+
@randomize_order
|
|
58
|
+
id: uuid
|
|
59
|
+
name: name
|
|
60
|
+
email: email
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Simulate Error
|
|
64
|
+
|
|
65
|
+
Simulate specific errors:
|
|
66
|
+
|
|
67
|
+
```ruby
|
|
68
|
+
User:
|
|
69
|
+
@simulate_error StandardError, "Database connection failed"
|
|
70
|
+
id: uuid
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
**Arguments:**
|
|
74
|
+
- Error class: `StandardError`, `TimeoutError`, etc.
|
|
75
|
+
- Message: Error message string
|
|
76
|
+
|
|
77
|
+
### Close Connection
|
|
78
|
+
|
|
79
|
+
Simulate connection closure:
|
|
80
|
+
|
|
81
|
+
```ruby
|
|
82
|
+
User:
|
|
83
|
+
@close_connection
|
|
84
|
+
id: uuid
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Behavior Placement
|
|
88
|
+
|
|
89
|
+
### Schema-Level
|
|
90
|
+
|
|
91
|
+
Apply to all fields in a schema:
|
|
92
|
+
|
|
93
|
+
```ruby
|
|
94
|
+
User:
|
|
95
|
+
@latency 100ms
|
|
96
|
+
@failure 5%
|
|
97
|
+
id: uuid
|
|
98
|
+
name: name
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Field-Level
|
|
102
|
+
|
|
103
|
+
Apply to specific fields:
|
|
104
|
+
|
|
105
|
+
```ruby
|
|
106
|
+
User:
|
|
107
|
+
id: uuid @latency 50ms
|
|
108
|
+
name: name @failure 1%
|
|
109
|
+
email: email @partial_data 10%
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## Combining Behaviors
|
|
113
|
+
|
|
114
|
+
You can combine multiple behaviors:
|
|
115
|
+
|
|
116
|
+
```ruby
|
|
117
|
+
User:
|
|
118
|
+
@latency 100ms
|
|
119
|
+
@failure 5%
|
|
120
|
+
id: uuid @latency 50ms # Field-level overrides schema-level
|
|
121
|
+
name: name @failure 1%
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## Custom Behaviors
|
|
125
|
+
|
|
126
|
+
Register custom behaviors:
|
|
127
|
+
|
|
128
|
+
```ruby
|
|
129
|
+
FakeDataDSL.register_behavior(:my_behavior) do |field, args|
|
|
130
|
+
# Custom behavior logic
|
|
131
|
+
end
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## See Also
|
|
135
|
+
|
|
136
|
+
- [Generation Modes](generation_modes.md) - How behaviors interact with modes
|
|
137
|
+
- [Examples](examples.md) - Real-world usage
|
|
138
|
+
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
# Best Practices
|
|
2
|
+
|
|
3
|
+
Tips and recommendations for using FakeDataDSL effectively.
|
|
4
|
+
|
|
5
|
+
## Schema Organization
|
|
6
|
+
|
|
7
|
+
### Use Descriptive Names
|
|
8
|
+
|
|
9
|
+
```ruby
|
|
10
|
+
# Good
|
|
11
|
+
User:
|
|
12
|
+
id: uuid
|
|
13
|
+
email: email
|
|
14
|
+
|
|
15
|
+
# Bad
|
|
16
|
+
U:
|
|
17
|
+
i: uuid
|
|
18
|
+
e: email
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
### Group Related Schemas
|
|
22
|
+
|
|
23
|
+
```ruby
|
|
24
|
+
# schemas/users.dsl
|
|
25
|
+
User:
|
|
26
|
+
id: uuid
|
|
27
|
+
name: name
|
|
28
|
+
|
|
29
|
+
# schemas/orders.dsl
|
|
30
|
+
Order:
|
|
31
|
+
id: uuid
|
|
32
|
+
user_id: reference(User, id)
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### Use Comments
|
|
36
|
+
|
|
37
|
+
```ruby
|
|
38
|
+
User:
|
|
39
|
+
# Primary identifier
|
|
40
|
+
id: uuid
|
|
41
|
+
|
|
42
|
+
# User's email address (must be unique)
|
|
43
|
+
email: email unique
|
|
44
|
+
|
|
45
|
+
# Optional phone number
|
|
46
|
+
phone: phone optional
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Type Selection
|
|
50
|
+
|
|
51
|
+
### Choose Appropriate Types
|
|
52
|
+
|
|
53
|
+
```ruby
|
|
54
|
+
# Good - specific types
|
|
55
|
+
User:
|
|
56
|
+
email: email
|
|
57
|
+
age: number(18..65)
|
|
58
|
+
created_at: past_date(days: 365)
|
|
59
|
+
|
|
60
|
+
# Bad - generic types
|
|
61
|
+
User:
|
|
62
|
+
email: text
|
|
63
|
+
age: text
|
|
64
|
+
created_at: text
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Use Ranges for Numbers
|
|
68
|
+
|
|
69
|
+
```ruby
|
|
70
|
+
# Good - realistic ranges
|
|
71
|
+
age: number(18..65)
|
|
72
|
+
price: number(min: 10, max: 1000)
|
|
73
|
+
|
|
74
|
+
# Bad - too wide
|
|
75
|
+
age: number(0..1000)
|
|
76
|
+
price: number
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Performance
|
|
80
|
+
|
|
81
|
+
### Use Streaming for Large Datasets
|
|
82
|
+
|
|
83
|
+
```ruby
|
|
84
|
+
# Good - memory efficient
|
|
85
|
+
schema.generate_many_stream(10000).each do |record|
|
|
86
|
+
process(record)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# Bad - loads all into memory
|
|
90
|
+
records = schema.generate_many(10000)
|
|
91
|
+
records.each { |r| process(r) }
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Limit Resource Usage
|
|
95
|
+
|
|
96
|
+
```ruby
|
|
97
|
+
# Configure limits
|
|
98
|
+
FakeDataDSL.configure do |config|
|
|
99
|
+
config.max_array_size = 100
|
|
100
|
+
config.max_text_length = 1000
|
|
101
|
+
end
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## Testing
|
|
105
|
+
|
|
106
|
+
### Use Deterministic Seeds
|
|
107
|
+
|
|
108
|
+
```ruby
|
|
109
|
+
# In tests
|
|
110
|
+
FakeDataDSL.configure { |c| c.seed = 12345 }
|
|
111
|
+
|
|
112
|
+
# Generate same data every time
|
|
113
|
+
record1 = schema.generate
|
|
114
|
+
record2 = schema.generate
|
|
115
|
+
# record1 == record2 (with same seed)
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### Test Edge Cases
|
|
119
|
+
|
|
120
|
+
```ruby
|
|
121
|
+
# Generate edge cases
|
|
122
|
+
edge_records = schema.generate_many(100, mode: :edge)
|
|
123
|
+
|
|
124
|
+
# Test validation
|
|
125
|
+
edge_records.each do |record|
|
|
126
|
+
expect { validate(record) }.not_to raise_error
|
|
127
|
+
end
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### Test Invalid Data
|
|
131
|
+
|
|
132
|
+
```ruby
|
|
133
|
+
# Generate invalid data
|
|
134
|
+
invalid_records = schema.generate_many(100, mode: :invalid)
|
|
135
|
+
|
|
136
|
+
# Test error handling
|
|
137
|
+
invalid_records.each do |record|
|
|
138
|
+
expect { create(record) }.to raise_error(ValidationError)
|
|
139
|
+
end
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
## Security
|
|
143
|
+
|
|
144
|
+
### Validate Input
|
|
145
|
+
|
|
146
|
+
```ruby
|
|
147
|
+
# Always validate generated data
|
|
148
|
+
record = schema.generate
|
|
149
|
+
validate_record(record) # Your validation logic
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### Use Limits
|
|
153
|
+
|
|
154
|
+
```ruby
|
|
155
|
+
# Prevent DoS
|
|
156
|
+
FakeDataDSL.configure do |config|
|
|
157
|
+
config.max_recursion = 10
|
|
158
|
+
config.max_array_size = 1000
|
|
159
|
+
end
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
## Maintainability
|
|
163
|
+
|
|
164
|
+
### Version Control Schemas
|
|
165
|
+
|
|
166
|
+
```ruby
|
|
167
|
+
# Keep schemas in version control
|
|
168
|
+
# schemas/v1/user.dsl
|
|
169
|
+
# schemas/v2/user.dsl
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### Document Complex Schemas
|
|
173
|
+
|
|
174
|
+
```ruby
|
|
175
|
+
# Complex schema with explanation
|
|
176
|
+
Order:
|
|
177
|
+
# Calculated from quantity and unit_price
|
|
178
|
+
total: formula(quantity * unit_price)
|
|
179
|
+
|
|
180
|
+
# Tax is 8% of total
|
|
181
|
+
tax: formula(total * 0.08)
|
|
182
|
+
|
|
183
|
+
# Grand total includes tax
|
|
184
|
+
grand_total: formula(total + tax)
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
## See Also
|
|
188
|
+
|
|
189
|
+
- [Examples](examples.md) - Real-world examples
|
|
190
|
+
- [Troubleshooting](troubleshooting.md) - Common issues
|
|
191
|
+
|