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
data/docs/MOCK_SERVER.md
ADDED
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
# Mock Server
|
|
2
|
+
|
|
3
|
+
A **production-ready mock server** with API recording and replay capabilities.
|
|
4
|
+
|
|
5
|
+
## Quick Start
|
|
6
|
+
|
|
7
|
+
```ruby
|
|
8
|
+
# Start mock server
|
|
9
|
+
FakeDataDSL::MockServer.start(
|
|
10
|
+
schema_dir: "schemas/",
|
|
11
|
+
port: 3000
|
|
12
|
+
)
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Features
|
|
16
|
+
|
|
17
|
+
- 🎲 **Schema-based generation** - Generate data from your DSL schemas
|
|
18
|
+
- 📼 **Recording mode** - Record real API responses for replay
|
|
19
|
+
- ⏱️ **Behavior simulation** - Simulate latency and failures
|
|
20
|
+
- 🔒 **Rate limiting** - Protect against overuse
|
|
21
|
+
- 🌐 **CORS support** - Ready for frontend development
|
|
22
|
+
|
|
23
|
+
## Configuration
|
|
24
|
+
|
|
25
|
+
```ruby
|
|
26
|
+
FakeDataDSL::MockServer.start(
|
|
27
|
+
schema_dir: "schemas/",
|
|
28
|
+
port: 3000,
|
|
29
|
+
recording: true, # Enable recording
|
|
30
|
+
recordings_dir: "recordings/", # Where to save recordings
|
|
31
|
+
cors: true, # Enable CORS
|
|
32
|
+
rate_limit: 100, # Requests per minute (0 = unlimited)
|
|
33
|
+
default_mode: :random # Default generation mode
|
|
34
|
+
)
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## API Endpoints
|
|
38
|
+
|
|
39
|
+
### Schema Endpoints
|
|
40
|
+
|
|
41
|
+
| Method | Path | Description |
|
|
42
|
+
|--------|------|-------------|
|
|
43
|
+
| GET | `/api/schemas` | List all schemas |
|
|
44
|
+
| GET | `/api/:schema` | Generate single record |
|
|
45
|
+
| GET | `/api/:schema/batch` | Generate batch |
|
|
46
|
+
| GET | `/api/:schema/stream` | Stream NDJSON |
|
|
47
|
+
| POST | `/api/:schema` | Generate with overrides |
|
|
48
|
+
| GET | `/api/:schema/schema` | Get schema info |
|
|
49
|
+
|
|
50
|
+
### Recording Endpoints
|
|
51
|
+
|
|
52
|
+
| Method | Path | Description |
|
|
53
|
+
|--------|------|-------------|
|
|
54
|
+
| POST | `/api/recordings/:name` | Save a recording |
|
|
55
|
+
| GET | `/api/recordings/:name` | Replay a recording |
|
|
56
|
+
|
|
57
|
+
## Generation Parameters
|
|
58
|
+
|
|
59
|
+
All generation endpoints accept:
|
|
60
|
+
|
|
61
|
+
- `seed` - Random seed for deterministic output
|
|
62
|
+
- `mode` - Generation mode: random, edge, invalid, hostile, mixed
|
|
63
|
+
- `count` - Number of records (batch/stream only)
|
|
64
|
+
|
|
65
|
+
### Examples
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
# Generate with seed
|
|
69
|
+
curl "http://localhost:3000/api/user?seed=42"
|
|
70
|
+
|
|
71
|
+
# Generate edge cases
|
|
72
|
+
curl "http://localhost:3000/api/user?mode=edge"
|
|
73
|
+
|
|
74
|
+
# Generate batch
|
|
75
|
+
curl "http://localhost:3000/api/user/batch?count=100&seed=42"
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Recording & Replay
|
|
79
|
+
|
|
80
|
+
### Save Recording
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
# Record a response manually
|
|
84
|
+
curl -X POST http://localhost:3000/api/recordings/users_list \
|
|
85
|
+
-H "Content-Type: application/json" \
|
|
86
|
+
-d '{
|
|
87
|
+
"data": [
|
|
88
|
+
{"id": 1, "name": "Real User 1"},
|
|
89
|
+
{"id": 2, "name": "Real User 2"}
|
|
90
|
+
],
|
|
91
|
+
"content_type": "application/json"
|
|
92
|
+
}'
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### Replay Recording
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
# Get the recorded response
|
|
99
|
+
curl http://localhost:3000/api/recordings/users_list
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### Automatic Recording
|
|
103
|
+
|
|
104
|
+
With `recording: true`, all generation responses are automatically saved:
|
|
105
|
+
|
|
106
|
+
```ruby
|
|
107
|
+
FakeDataDSL::MockServer.start(
|
|
108
|
+
schema_dir: "schemas/",
|
|
109
|
+
recording: true,
|
|
110
|
+
recordings_dir: "recordings/"
|
|
111
|
+
)
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Recordings are saved as `{schema_name}_{timestamp}.json`.
|
|
115
|
+
|
|
116
|
+
## Behavior Simulation
|
|
117
|
+
|
|
118
|
+
Schemas with behaviors are honored by the mock server:
|
|
119
|
+
|
|
120
|
+
```
|
|
121
|
+
User:
|
|
122
|
+
@latency 50..200ms
|
|
123
|
+
@failure 5%
|
|
124
|
+
|
|
125
|
+
id: uuid
|
|
126
|
+
name: name
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
When this schema is requested:
|
|
130
|
+
- Responses will be delayed 50-200ms
|
|
131
|
+
- 5% of requests will return 500 error
|
|
132
|
+
|
|
133
|
+
## Rate Limiting
|
|
134
|
+
|
|
135
|
+
```ruby
|
|
136
|
+
FakeDataDSL::MockServer.start(
|
|
137
|
+
schema_dir: "schemas/",
|
|
138
|
+
rate_limit: 100 # 100 requests per minute per IP
|
|
139
|
+
)
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
When rate limited:
|
|
143
|
+
```json
|
|
144
|
+
{
|
|
145
|
+
"error": "Rate limit exceeded"
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
HTTP Status: 429
|
|
149
|
+
|
|
150
|
+
## CORS Support
|
|
151
|
+
|
|
152
|
+
CORS is enabled by default:
|
|
153
|
+
|
|
154
|
+
```ruby
|
|
155
|
+
# Default headers
|
|
156
|
+
Access-Control-Allow-Origin: *
|
|
157
|
+
Access-Control-Allow-Methods: GET, POST, OPTIONS
|
|
158
|
+
Access-Control-Allow-Headers: Content-Type, Authorization
|
|
159
|
+
Access-Control-Max-Age: 86400
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
Disable CORS:
|
|
163
|
+
```ruby
|
|
164
|
+
FakeDataDSL::MockServer.start(
|
|
165
|
+
schema_dir: "schemas/",
|
|
166
|
+
cors: false
|
|
167
|
+
)
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
## Async Mode
|
|
171
|
+
|
|
172
|
+
Start server in background:
|
|
173
|
+
|
|
174
|
+
```ruby
|
|
175
|
+
server = FakeDataDSL::MockServer.new(schema_dir: "schemas/", port: 3000)
|
|
176
|
+
|
|
177
|
+
# Start in background thread
|
|
178
|
+
server.start_async
|
|
179
|
+
|
|
180
|
+
# Do other work...
|
|
181
|
+
|
|
182
|
+
# Stop when done
|
|
183
|
+
server.stop
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
## Use Cases
|
|
187
|
+
|
|
188
|
+
### Frontend Development
|
|
189
|
+
|
|
190
|
+
```ruby
|
|
191
|
+
# Start mock server for frontend dev
|
|
192
|
+
FakeDataDSL::MockServer.start(
|
|
193
|
+
schema_dir: "schemas/",
|
|
194
|
+
port: 3000,
|
|
195
|
+
cors: true,
|
|
196
|
+
default_mode: :random
|
|
197
|
+
)
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
### Integration Testing
|
|
201
|
+
|
|
202
|
+
```ruby
|
|
203
|
+
# In test setup
|
|
204
|
+
before(:all) do
|
|
205
|
+
@server = FakeDataDSL::MockServer.new(
|
|
206
|
+
schema_dir: "spec/fixtures/schemas/",
|
|
207
|
+
port: 3001
|
|
208
|
+
)
|
|
209
|
+
@thread = @server.start_async
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
after(:all) do
|
|
213
|
+
@server.stop
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
it "fetches users from API" do
|
|
217
|
+
response = HTTParty.get("http://localhost:3001/api/user?seed=42")
|
|
218
|
+
expect(response["id"]).to be_present
|
|
219
|
+
end
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
### Contract Testing
|
|
223
|
+
|
|
224
|
+
```ruby
|
|
225
|
+
# Record real API responses
|
|
226
|
+
FakeDataDSL::MockServer.start(
|
|
227
|
+
schema_dir: "schemas/",
|
|
228
|
+
recording: true,
|
|
229
|
+
recordings_dir: "contracts/"
|
|
230
|
+
)
|
|
231
|
+
|
|
232
|
+
# Later, replay for testing
|
|
233
|
+
curl http://localhost:3000/api/recordings/user_response
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
## File Structure
|
|
237
|
+
|
|
238
|
+
When recording is enabled:
|
|
239
|
+
|
|
240
|
+
```
|
|
241
|
+
recordings/
|
|
242
|
+
├── User_1706123456.json
|
|
243
|
+
├── User_1706123457.json
|
|
244
|
+
├── Order_1706123458.json
|
|
245
|
+
└── custom_response.json
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
Recording format:
|
|
249
|
+
```json
|
|
250
|
+
{
|
|
251
|
+
"data": { "id": "...", "name": "..." },
|
|
252
|
+
"recorded_at": "2026-01-24T10:30:00Z",
|
|
253
|
+
"schema": "User",
|
|
254
|
+
"content_type": "application/json"
|
|
255
|
+
}
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
## Comparison: MockServer vs APIServer
|
|
259
|
+
|
|
260
|
+
| Feature | MockServer | APIServer |
|
|
261
|
+
|---------|------------|-----------|
|
|
262
|
+
| Purpose | Development/Testing | Production |
|
|
263
|
+
| Recording | ✅ Yes | ❌ No |
|
|
264
|
+
| Authentication | ❌ No | ✅ Yes |
|
|
265
|
+
| Metrics | ❌ No | ✅ Yes |
|
|
266
|
+
| Rate Limiting | ✅ Basic | ✅ Advanced |
|
|
267
|
+
| Caching | ❌ No | ✅ Yes |
|
|
268
|
+
| Rack Support | ❌ No | ✅ Yes |
|
|
269
|
+
|
|
270
|
+
Use **MockServer** for:
|
|
271
|
+
- Frontend development
|
|
272
|
+
- Integration testing
|
|
273
|
+
- Contract testing
|
|
274
|
+
- API prototyping
|
|
275
|
+
|
|
276
|
+
Use **APIServer** for:
|
|
277
|
+
- Production deployment
|
|
278
|
+
- Public APIs
|
|
279
|
+
- Services requiring auth
|
|
280
|
+
- High-traffic scenarios
|
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
# Native Rust Engine
|
|
2
|
+
|
|
3
|
+
The FakeDataDSL Native Engine provides **ultra-high-performance** data generation using Rust and the `fake-rs` library. It achieves **3-4 million records per second**, which is **100-250x faster** than the pure Ruby implementation.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- ⚡ **3-4 million records/sec** generation speed
|
|
8
|
+
- 🌍 **Multi-locale support** (English, French, German, Japanese, Chinese, etc.)
|
|
9
|
+
- 🔧 **Configurable thread count** (default: 2 threads)
|
|
10
|
+
- 📁 **Direct file output** (JSONL, JSON, CSV)
|
|
11
|
+
- 🎲 **Deterministic seeding** for reproducible results
|
|
12
|
+
- 💾 **Memory efficient** for large datasets
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
### Prerequisites
|
|
17
|
+
|
|
18
|
+
1. **Rust** (1.70+): Install via [rustup](https://rustup.rs/)
|
|
19
|
+
```bash
|
|
20
|
+
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
2. **rb_sys gem**: For Ruby-Rust integration
|
|
24
|
+
```bash
|
|
25
|
+
gem install rb_sys
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### Compile the Extension
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
cd fake_data_dsl
|
|
32
|
+
bundle exec rake compile
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### Verify Installation
|
|
36
|
+
|
|
37
|
+
```ruby
|
|
38
|
+
require 'fake_data_dsl'
|
|
39
|
+
|
|
40
|
+
if FakeDataDSL::NativeEngine.available?
|
|
41
|
+
puts "Native engine available!"
|
|
42
|
+
puts FakeDataDSL::NativeEngine.performance_info
|
|
43
|
+
else
|
|
44
|
+
puts "Native engine not available - using Ruby engine"
|
|
45
|
+
end
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Usage
|
|
49
|
+
|
|
50
|
+
### Basic Generation
|
|
51
|
+
|
|
52
|
+
```ruby
|
|
53
|
+
require 'fake_data_dsl'
|
|
54
|
+
|
|
55
|
+
schema = FakeDataDSL.parse(<<~DSL)
|
|
56
|
+
User:
|
|
57
|
+
id: uuid
|
|
58
|
+
name: name
|
|
59
|
+
email: email
|
|
60
|
+
age: number(18..80)
|
|
61
|
+
active: boolean
|
|
62
|
+
DSL
|
|
63
|
+
|
|
64
|
+
# Generate using native engine
|
|
65
|
+
users = schema.generate_many(100_000, engine: :native, seed: 42)
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Generate to File (Fastest)
|
|
69
|
+
|
|
70
|
+
For maximum performance with large datasets, generate directly to file:
|
|
71
|
+
|
|
72
|
+
```ruby
|
|
73
|
+
# Generate 10 million records to JSONL (one JSON per line)
|
|
74
|
+
schema.generate_to_file(10_000_000, "users.jsonl", format: "jsonl")
|
|
75
|
+
|
|
76
|
+
# Generate CSV
|
|
77
|
+
schema.generate_to_file(1_000_000, "users.csv", format: "csv")
|
|
78
|
+
|
|
79
|
+
# Generate JSON array
|
|
80
|
+
schema.generate_to_file(100_000, "users.json", format: "json")
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Thread Control
|
|
84
|
+
|
|
85
|
+
By default, the native engine uses **2 threads** to leave resources for other work. You can customize this:
|
|
86
|
+
|
|
87
|
+
```ruby
|
|
88
|
+
# Use 4 threads
|
|
89
|
+
schema.generate_to_file(10_000_000, "users.jsonl", threads: 4)
|
|
90
|
+
|
|
91
|
+
# Use all available cores (fastest for single job)
|
|
92
|
+
schema.generate_to_file(10_000_000, "users.jsonl", threads: 0)
|
|
93
|
+
|
|
94
|
+
# Use 1 thread (minimal resource usage)
|
|
95
|
+
schema.generate_to_file(10_000_000, "users.jsonl", threads: 1)
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
| Threads | Use Case |
|
|
99
|
+
|---------|----------|
|
|
100
|
+
| `nil` (default) | 2 threads - balanced for general use |
|
|
101
|
+
| `0` | All cores - maximum speed for single job |
|
|
102
|
+
| `1` | Minimal - when running many parallel jobs |
|
|
103
|
+
| `4-8` | Good balance for multi-process environments |
|
|
104
|
+
|
|
105
|
+
### Locale Support
|
|
106
|
+
|
|
107
|
+
The native engine supports multiple locales for authentic names:
|
|
108
|
+
|
|
109
|
+
```ruby
|
|
110
|
+
# English (uses fast pre-generated pools)
|
|
111
|
+
schema.generate_to_file(1_000_000, "users_en.jsonl", locale: "en")
|
|
112
|
+
|
|
113
|
+
# French
|
|
114
|
+
schema.generate_to_file(1_000_000, "users_fr.jsonl", locale: "fr_fr")
|
|
115
|
+
|
|
116
|
+
# German
|
|
117
|
+
schema.generate_to_file(1_000_000, "users_de.jsonl", locale: "de_de")
|
|
118
|
+
|
|
119
|
+
# Japanese
|
|
120
|
+
schema.generate_to_file(1_000_000, "users_ja.jsonl", locale: "ja_jp")
|
|
121
|
+
|
|
122
|
+
# Chinese (Simplified)
|
|
123
|
+
schema.generate_to_file(1_000_000, "users_zh.jsonl", locale: "zh_cn")
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
**Supported Locales:**
|
|
127
|
+
- `en` - English (fast mode)
|
|
128
|
+
- `fr_fr` - French
|
|
129
|
+
- `de_de` - German
|
|
130
|
+
- `ja_jp` - Japanese
|
|
131
|
+
- `zh_cn` - Chinese (Simplified)
|
|
132
|
+
- `zh_tw` - Chinese (Traditional)
|
|
133
|
+
- `pt_br` - Portuguese (Brazil)
|
|
134
|
+
- `it_it` - Italian
|
|
135
|
+
- `ar_sa` - Arabic
|
|
136
|
+
|
|
137
|
+
### Using NativeEngine Class Directly
|
|
138
|
+
|
|
139
|
+
For more control, use the `NativeEngine` class directly:
|
|
140
|
+
|
|
141
|
+
```ruby
|
|
142
|
+
# Create engine with options
|
|
143
|
+
engine = FakeDataDSL::NativeEngine.new(
|
|
144
|
+
schema,
|
|
145
|
+
locale: "en",
|
|
146
|
+
threads: 4
|
|
147
|
+
)
|
|
148
|
+
|
|
149
|
+
# Generate records
|
|
150
|
+
records = engine.generate_many(100_000, seed: 42)
|
|
151
|
+
|
|
152
|
+
# Generate to file
|
|
153
|
+
engine.generate_to_file(10_000_000, "users.jsonl", format: "jsonl")
|
|
154
|
+
|
|
155
|
+
# Stream records
|
|
156
|
+
engine.stream(1_000_000) do |record|
|
|
157
|
+
process(record)
|
|
158
|
+
end
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
## Performance Benchmarks
|
|
162
|
+
|
|
163
|
+
| Records | Time | Rate |
|
|
164
|
+
|---------|------|------|
|
|
165
|
+
| 1M | 0.3s | ~3.5M/sec |
|
|
166
|
+
| 5M | 1.5s | ~3.3M/sec |
|
|
167
|
+
| 10M | 2.7s | **~3.7M/sec** |
|
|
168
|
+
| 20M | 5.3s | ~3.8M/sec |
|
|
169
|
+
|
|
170
|
+
### Comparison: Ruby vs Native
|
|
171
|
+
|
|
172
|
+
| Engine | 10M Records | Rate |
|
|
173
|
+
|--------|-------------|------|
|
|
174
|
+
| Pure Ruby | ~10 minutes | ~17K/sec |
|
|
175
|
+
| Native (2 threads) | ~5 seconds | ~2M/sec |
|
|
176
|
+
| Native (all cores) | ~2.7 seconds | **~3.7M/sec** |
|
|
177
|
+
|
|
178
|
+
## Supported Types
|
|
179
|
+
|
|
180
|
+
The native engine supports these types:
|
|
181
|
+
|
|
182
|
+
### Personal
|
|
183
|
+
- `name`, `full_name`, `first_name`, `last_name`, `title`
|
|
184
|
+
|
|
185
|
+
### Internet
|
|
186
|
+
- `email`, `username`, `password`, `url`
|
|
187
|
+
- `ip`, `ipv4`, `ipv6`, `mac_address`, `user_agent`, `domain`
|
|
188
|
+
|
|
189
|
+
### Address
|
|
190
|
+
- `city`, `country`, `country_code`, `state`
|
|
191
|
+
- `street`, `street_address`, `postal_code`, `zip_code`
|
|
192
|
+
- `latitude`, `longitude`
|
|
193
|
+
|
|
194
|
+
### Company
|
|
195
|
+
- `company`, `company_name`, `catch_phrase`, `buzzword`, `industry`
|
|
196
|
+
|
|
197
|
+
### Text
|
|
198
|
+
- `word`, `words`, `sentence`, `sentences`, `paragraph`, `paragraphs`, `text`
|
|
199
|
+
|
|
200
|
+
### Phone
|
|
201
|
+
- `phone`, `phone_number`, `cell_phone`
|
|
202
|
+
|
|
203
|
+
### Date/Time
|
|
204
|
+
- `date`, `time`, `datetime`, `timestamp`, `past_date`, `future_date`
|
|
205
|
+
|
|
206
|
+
### Identifiers
|
|
207
|
+
- `uuid`, `uuid_v4`, `uuid_v1`, `id_sequence`, `ulid`
|
|
208
|
+
|
|
209
|
+
### Primitives
|
|
210
|
+
- `number`, `integer`, `float`, `boolean`, `bool`
|
|
211
|
+
|
|
212
|
+
### Color
|
|
213
|
+
- `hex_color`, `rgb_color`
|
|
214
|
+
|
|
215
|
+
### Special
|
|
216
|
+
- `enum`, `const`, `array`
|
|
217
|
+
|
|
218
|
+
## Environment Variables
|
|
219
|
+
|
|
220
|
+
You can also configure threads via environment variable:
|
|
221
|
+
|
|
222
|
+
```bash
|
|
223
|
+
# Set before running Ruby
|
|
224
|
+
RAYON_NUM_THREADS=4 ruby my_script.rb
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
## Troubleshooting
|
|
228
|
+
|
|
229
|
+
### Native engine not available
|
|
230
|
+
|
|
231
|
+
```
|
|
232
|
+
Native extension not compiled. To enable native performance:
|
|
233
|
+
1. Install Rust: curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
|
|
234
|
+
2. Install rb_sys: gem install rb_sys
|
|
235
|
+
3. Compile extension: bundle exec rake compile
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
### Compilation errors
|
|
239
|
+
|
|
240
|
+
Make sure you have:
|
|
241
|
+
- Rust 1.70+ installed
|
|
242
|
+
- Clang/LLVM for linking
|
|
243
|
+
- rb_sys gem installed
|
|
244
|
+
|
|
245
|
+
```bash
|
|
246
|
+
# Check Rust version
|
|
247
|
+
rustc --version
|
|
248
|
+
|
|
249
|
+
# Reinstall rb_sys
|
|
250
|
+
gem install rb_sys
|
|
251
|
+
|
|
252
|
+
# Clean and recompile
|
|
253
|
+
cd fake_data_dsl
|
|
254
|
+
rm -rf ext/fake_data_dsl_native/target
|
|
255
|
+
bundle exec rake compile
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
### Performance not as expected
|
|
259
|
+
|
|
260
|
+
1. **Check thread count**: Default is 2 threads. Use `threads: 0` for max speed.
|
|
261
|
+
2. **Use file output**: `generate_to_file` is faster than `generate_many` for large datasets.
|
|
262
|
+
3. **English locale**: English uses fast pre-generated pools; other locales use full fake-rs.
|
|
263
|
+
|
|
264
|
+
## API Reference
|
|
265
|
+
|
|
266
|
+
### FakeDataDSL::NativeEngine
|
|
267
|
+
|
|
268
|
+
#### Class Methods
|
|
269
|
+
|
|
270
|
+
```ruby
|
|
271
|
+
NativeEngine.available? # Check if native extension is loaded
|
|
272
|
+
NativeEngine.version # Get extension version
|
|
273
|
+
NativeEngine.performance_info # Get performance information
|
|
274
|
+
NativeEngine.thread_count # Get current thread count
|
|
275
|
+
NativeEngine.set_threads(n) # Set thread count (call early)
|
|
276
|
+
NativeEngine.available_types # List supported types
|
|
277
|
+
NativeEngine.available_locales # List supported locales
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
#### Instance Methods
|
|
281
|
+
|
|
282
|
+
```ruby
|
|
283
|
+
engine = NativeEngine.new(schema, locale: "en", threads: 2)
|
|
284
|
+
|
|
285
|
+
engine.generate(seed: nil) # Single record
|
|
286
|
+
engine.generate_many(count, seed: nil, threads: nil) # Multiple records
|
|
287
|
+
engine.generate_to_file(count, path, seed: nil, format: "jsonl", threads: nil)
|
|
288
|
+
engine.stream(count, seed: nil) { |record| } # Stream records
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
### Schema Methods
|
|
292
|
+
|
|
293
|
+
```ruby
|
|
294
|
+
schema.generate_many(count, engine: :native, locale: "en", threads: 2)
|
|
295
|
+
schema.generate_many_native(count, seed: nil, locale: "en", threads: nil)
|
|
296
|
+
schema.generate_to_file(count, path, locale: "en", format: "jsonl", threads: nil)
|
|
297
|
+
```
|
|
298
|
+
|