diff --git a/.vscode/launch.json b/.vscode/launch.json index 3c0c09dc..bb36bc86 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -15,7 +15,14 @@ "name": "Debug Jest Tests", "type": "node", "request": "launch", - "runtimeArgs": ["--inspect-brk", "${workspaceRoot}/node_modules/.bin/jest", "--runInBand"], + "runtimeArgs": [ + "--experimental-vm-modules", + "--inspect-brk", + "${workspaceFolder}/node_modules/jest/bin/jest.js", + "--config", + "${workspaceFolder}/jest.config.cjs", + "--runInBand" + ], "console": "integratedTerminal", "internalConsoleOptions": "neverOpen", "port": 9229 diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..13e2af26 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "jest.jestCommandLine": "node --experimental-vm-modules ./node_modules/jest/bin/jest.js --config ./jest.config.cjs", + "jestrunner.enableESM": true, + "jestrunner.jestCommand": "node --experimental-vm-modules ./node_modules/jest/bin/jest.js --config ./jest.config.cjs" +} diff --git a/docs-src/docs/040-test-data/domain/020-airline.md b/docs-src/docs/040-test-data/domain/020-airline.md index 37b2e074..68631d2a 100644 --- a/docs-src/docs/040-test-data/domain/020-airline.md +++ b/docs-src/docs/040-test-data/domain/020-airline.md @@ -40,18 +40,45 @@ Returns a random flight number. Flight numbers are always 1 to 4 digits long and - Canonical: `awd.domain.airline.flightNumber` - Faker docs: [https://fakerjs.dev/api/airline](https://fakerjs.dev/api/airline) -No parameters. +| Arg | Type | Required | Description | +| --- | --- | --- | --- | +| `length` | `number` | no | Desired flight-number length. | +| `addLeadingZeros` | `boolean` | no | Whether shorter flight numbers should be padded with leading zeros. | Examples: Shows the default airline.flightNumber call. ```txt -airline.flightNumber +airline.flightNumber() ``` Returns: `70` +Shows airline.flightNumber using length and leading-zero options. + +```txt +airline.flightNumber(length=4, addLeadingZeros=true) +``` + +Returns: `4703` + +Shows airline.flightNumber using a fixed length. + +```txt +airline.flightNumber(length=4) +``` + +Returns: `4703` + +Shows airline.flightNumber padding shorter values with leading zeros. + +```txt +airline.flightNumber(addLeadingZeros=true) +``` + +Returns: `0070` + ### `airline.iataCode` Generate an airline IATA code. @@ -66,7 +93,7 @@ Examples: Shows the default airline.airline.iataCode call. ```txt -airline.airline.iataCode +airline.iataCode ``` Returns: `FZ` @@ -85,7 +112,7 @@ Examples: Shows the default airline.airline.name call. ```txt -airline.airline.name +airline.name ``` Returns: `Flydubai` @@ -97,18 +124,37 @@ Generates a random record locator. Record locators are 6-character alphanumeric - Canonical: `awd.domain.airline.recordLocator` - Faker docs: [https://fakerjs.dev/api/airline](https://fakerjs.dev/api/airline) -No parameters. +| Arg | Type | Required | Description | +| --- | --- | --- | --- | +| `allowNumerics` | `boolean` | no | Whether numeric characters can be included. | +| `allowVisuallySimilarCharacters` | `boolean` | no | Whether visually similar characters such as I, 1, O, and 0 can be included. | Examples: Shows the default airline.recordLocator call. ```txt -airline.recordLocator +airline.recordLocator() ``` Returns: `KTAGDC` +Shows airline.recordLocator allowing numeric characters. + +```txt +airline.recordLocator(allowNumerics=true) +``` + +Returns: `ER2B64` + +Shows airline.recordLocator allowing visually similar characters. + +```txt +airline.recordLocator(allowVisuallySimilarCharacters=true) +``` + +Returns: `KSAHDC` + ### `airline.seat` Generates a random seat. @@ -160,7 +206,7 @@ Examples: Shows the default airline.airplane.iataTypeCode call. ```txt -airline.airplane.iataTypeCode +airplane.iataTypeCode ``` Returns: `74J` @@ -179,7 +225,7 @@ Examples: Shows the default airline.airplane.name call. ```txt -airline.airplane.name +airplane.name ``` Returns: `Boeing 747-400D` @@ -198,7 +244,7 @@ Examples: Shows the default airline.airport.iataCode call. ```txt -airline.airport.iataCode +airport.iataCode ``` Returns: `HRG` @@ -217,7 +263,7 @@ Examples: Shows the default airline.airport.name call. ```txt -airline.airport.name +airport.name ``` Returns: `Hurgada International Airport` diff --git a/docs-src/docs/040-test-data/domain/140-git.md b/docs-src/docs/040-test-data/domain/140-git.md index d7684f9f..3c66aead 100644 --- a/docs-src/docs/040-test-data/domain/140-git.md +++ b/docs-src/docs/040-test-data/domain/140-git.md @@ -40,18 +40,28 @@ Generates a date string for a git commit using the same format as `git log`. - Canonical: `awd.domain.git.commitDate` - Faker docs: [https://fakerjs.dev/api/git](https://fakerjs.dev/api/git) -No parameters. +| Arg | Type | Required | Description | +| --- | --- | --- | --- | +| `refDate` | `string\|date\|number` | no | The date to use as reference point for generated commit dates. | Examples: Shows the default git.commitDate call. ```txt -git.commitDate +git.commitDate() ``` Returns: `Thu Jun 18 01:55:50 2026 +0600` +Shows git.commitDate using a reference date. + +```txt +git.commitDate(refDate="2024-01-01T00:00:00.000Z") +``` + +Returns: `Sun Dec 31 10:00:30 2023 +0600` + ### `git.commitEntry` Generates a random commit entry as printed by `git log`. @@ -59,14 +69,50 @@ Generates a random commit entry as printed by `git log`. - Canonical: `awd.domain.git.commitEntry` - Faker docs: [https://fakerjs.dev/api/git](https://fakerjs.dev/api/git) -No parameters. +| Arg | Type | Required | Description | +| --- | --- | --- | --- | +| `merge` | `boolean` | no | Whether to generate a merge commit entry. | +| `eol` | `LF\|CRLF` | no | Line ending to use in the generated commit entry. | +| `refDate` | `string\|date\|number` | no | The date to use as reference point for generated commit dates. | Examples: Shows the default git.commitEntry call. ```txt -git.commitEntry +git.commitEntry() +``` + +Returns: `commit f0632478b9f4d0e9c34bf6fdd103d29fbf6fc0af\nAuthor: Ricardo Upton \nDate: Wed Jun 17 19:26:37 2026 +0300\n\n    parse auxiliary feed\n` + +Shows git.commitEntry using merge and line-ending options. + +```txt +git.commitEntry(merge=true, eol="LF") +``` + +Returns: `commit 9f0632478b9f4d0e9c34bf6fdd103d29fbf6fc0a\nMerge: fa6b29d 6620e45\nAuthor: Lindsey_Price41 \nDate: Thu Jun 18 13:36:13 2026 -0800\n\n    calculate redundant feed\n` + +Shows git.commitEntry using a reference date. + +```txt +git.commitEntry(refDate="2024-01-01T00:00:00.000Z") +``` + +Returns: `commit f0632478b9f4d0e9c34bf6fdd103d29fbf6fc0af\nAuthor: Ricardo Upton \nDate: Sun Dec 31 03:31:17 2023 +0300\n\n    parse auxiliary feed\n` + +Shows git.commitEntry forcing a merge commit entry. + +```txt +git.commitEntry(merge=true) +``` + +Returns: `commit 9f0632478b9f4d0e9c34bf6fdd103d29fbf6fc0a\nMerge: fa6b29d 6620e45\nAuthor: Lindsey_Price41 \nDate: Thu Jun 18 13:36:13 2026 -0800\n\n    calculate redundant feed\n` + +Shows git.commitEntry using LF line endings. + +```txt +git.commitEntry(eol="LF") ``` Returns: `commit f0632478b9f4d0e9c34bf6fdd103d29fbf6fc0af\nAuthor: Ricardo Upton \nDate: Wed Jun 17 19:26:37 2026 +0300\n\n    parse auxiliary feed\n` @@ -97,14 +143,24 @@ Generates a random commit sha. - Canonical: `awd.domain.git.commitSha` - Faker docs: [https://fakerjs.dev/api/git](https://fakerjs.dev/api/git) -No parameters. +| Arg | Type | Required | Description | +| --- | --- | --- | --- | +| `length` | `number` | no | The length of the generated commit SHA. | Examples: Shows the default git.commitSha call. ```txt -git.commitSha +git.commitSha() ``` Returns: `9f0632478b9f4d0e9c34bf6fdd103d29fbf6fc0a` + +Shows git.commitSha using a shorter SHA length. + +```txt +git.commitSha(length=7) +``` + +Returns: `9f06324` diff --git a/docs-src/docs/040-test-data/domain/160-image.md b/docs-src/docs/040-test-data/domain/160-image.md index db5a6808..2a2421db 100644 --- a/docs-src/docs/040-test-data/domain/160-image.md +++ b/docs-src/docs/040-test-data/domain/160-image.md @@ -59,18 +59,63 @@ Generates a random data uri containing an URL-encoded SVG image or a Base64-enco - Canonical: `awd.domain.image.dataUri` - Faker docs: [https://fakerjs.dev/api/image](https://fakerjs.dev/api/image) -No parameters. +| Arg | Type | Required | Description | +| --- | --- | --- | --- | +| `width` | `number` | no | Width of the generated image. | +| `height` | `number` | no | Height of the generated image. | +| `color` | `string` | no | Fill color for the generated SVG image. | +| `type` | `svg-uri\|svg-base64` | no | Encoding format for the generated SVG data URI. | Examples: Shows the default image.dataUri call. ```txt -image.dataUri +image.dataUri() ``` Returns: `data:image/svg+xml;charset=UTF-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20version%3D%221.1%22%20baseProfile%3D%22full%22%20width%3D%221668%22%20height%3D%222881%22%3E%3Crect%20width%3D%22100%25%22%20height%3D%22100%25%22%20fill%3D%22%23063247%22%2F%3E%3Ctext%20x%3D%22834%22%20y%3D%221440.5%22%20font-size%3D%2220%22%20alignment-baseline%3D%22middle%22%20text-anchor%3D%22middle%22%20fill%3D%22white%22%3E1668x2881%3C%2Ftext%3E%3C%2Fsvg%3E` +Shows image.dataUri using explicit image dimensions, color, and encoding type. + +```txt +image.dataUri(width=320, height=240, color="red", type="svg-base64") +``` + +Returns: `data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZlcnNpb249IjEuMSIgYmFzZVByb2ZpbGU9ImZ1bGwiIHdpZHRoPSIzMjAiIGhlaWdodD0iMjQwIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJyZWQiLz48dGV4dCB4PSIxNjAiIHk9IjEyMCIgZm9udC1zaXplPSIyMCIgYWxpZ25tZW50LWJhc2VsaW5lPSJtaWRkbGUiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZpbGw9IndoaXRlIj4zMjB4MjQwPC90ZXh0Pjwvc3ZnPg==` + +Shows image.dataUri using an explicit width. + +```txt +image.dataUri(width=320) +``` + +Returns: `data:image/svg+xml;charset=UTF-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20version%3D%221.1%22%20baseProfile%3D%22full%22%20width%3D%22320%22%20height%3D%221668%22%3E%3Crect%20width%3D%22100%25%22%20height%3D%22100%25%22%20fill%3D%22%23f06324%22%2F%3E%3Ctext%20x%3D%22160%22%20y%3D%22834%22%20font-size%3D%2220%22%20alignment-baseline%3D%22middle%22%20text-anchor%3D%22middle%22%20fill%3D%22white%22%3E320x1668%3C%2Ftext%3E%3C%2Fsvg%3E` + +Shows image.dataUri using an explicit height. + +```txt +image.dataUri(height=240) +``` + +Returns: `data:image/svg+xml;charset=UTF-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20version%3D%221.1%22%20baseProfile%3D%22full%22%20width%3D%221668%22%20height%3D%22240%22%3E%3Crect%20width%3D%22100%25%22%20height%3D%22100%25%22%20fill%3D%22%23f06324%22%2F%3E%3Ctext%20x%3D%22834%22%20y%3D%22120%22%20font-size%3D%2220%22%20alignment-baseline%3D%22middle%22%20text-anchor%3D%22middle%22%20fill%3D%22white%22%3E1668x240%3C%2Ftext%3E%3C%2Fsvg%3E` + +Shows image.dataUri using an explicit SVG fill color. + +```txt +image.dataUri(color="red") +``` + +Returns: `data:image/svg+xml;charset=UTF-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20version%3D%221.1%22%20baseProfile%3D%22full%22%20width%3D%221668%22%20height%3D%222881%22%3E%3Crect%20width%3D%22100%25%22%20height%3D%22100%25%22%20fill%3D%22red%22%2F%3E%3Ctext%20x%3D%22834%22%20y%3D%221440.5%22%20font-size%3D%2220%22%20alignment-baseline%3D%22middle%22%20text-anchor%3D%22middle%22%20fill%3D%22white%22%3E1668x2881%3C%2Ftext%3E%3C%2Fsvg%3E` + +Shows image.dataUri using Base64 SVG encoding. + +```txt +image.dataUri(type="svg-base64") +``` + +Returns: `data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZlcnNpb249IjEuMSIgYmFzZVByb2ZpbGU9ImZ1bGwiIHdpZHRoPSIxNjY4IiBoZWlnaHQ9IjI4ODEiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiMwNjMyNDciLz48dGV4dCB4PSI4MzQiIHk9IjE0NDAuNSIgZm9udC1zaXplPSIyMCIgYWxpZ25tZW50LWJhc2VsaW5lPSJtaWRkbGUiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZpbGw9IndoaXRlIj4xNjY4eDI4ODE8L3RleHQ+PC9zdmc+` + ### `image.personPortrait` Generates a random square portrait (avatar) of a person. @@ -78,18 +123,45 @@ Generates a random square portrait (avatar) of a person. - Canonical: `awd.domain.image.personPortrait` - Faker docs: [https://fakerjs.dev/api/image](https://fakerjs.dev/api/image) -No parameters. +| Arg | Type | Required | Description | +| --- | --- | --- | --- | +| `sex` | `female\|generic\|male` | no | Sex category used for the generated portrait. | +| `size` | `512\|256\|128\|64\|32` | no | Square image size in pixels. | Examples: Shows the default image.personPortrait call. ```txt -image.personPortrait +image.personPortrait() ``` Returns: `https://cdn.jsdelivr.net/gh/faker-js/assets-person-portrait/female/512/72.jpg` +Shows image.personPortrait using sex and size options. + +```txt +image.personPortrait(sex="female", size=128) +``` + +Returns: `https://cdn.jsdelivr.net/gh/faker-js/assets-person-portrait/female/128/41.jpg` + +Shows image.personPortrait using a sex category. + +```txt +image.personPortrait(sex="female") +``` + +Returns: `https://cdn.jsdelivr.net/gh/faker-js/assets-person-portrait/female/512/41.jpg` + +Shows image.personPortrait using an explicit image size. + +```txt +image.personPortrait(size=128) +``` + +Returns: `https://cdn.jsdelivr.net/gh/faker-js/assets-person-portrait/female/128/72.jpg` + ### `image.url` Generates a random image url. @@ -135,14 +207,59 @@ Generates a random image url provided via https://picsum.photos. - Canonical: `awd.domain.image.urlPicsumPhotos` - Faker docs: [https://fakerjs.dev/api/image](https://fakerjs.dev/api/image) -No parameters. +| Arg | Type | Required | Description | +| --- | --- | --- | --- | +| `width` | `number` | no | Width of the generated image URL. | +| `height` | `number` | no | Height of the generated image URL. | +| `grayscale` | `boolean` | no | Whether the generated image URL should request a grayscale image. | +| `blur` | `0\|1\|2\|3\|4\|5\|6\|7\|8\|9\|10` | no | Blur amount for the generated image URL. | Examples: Shows the default image.urlPicsumPhotos call. ```txt -image.urlPicsumPhotos +image.urlPicsumPhotos() ``` Returns: `https://picsum.photos/seed/5blox/1668/2881?grayscale&blur=3` + +Shows image.urlPicsumPhotos using dimension and filter options. + +```txt +image.urlPicsumPhotos(width=320, height=240, grayscale=true, blur=3) +``` + +Returns: `https://picsum.photos/seed/I0i95bl/320/240?grayscale&blur=3` + +Shows image.urlPicsumPhotos using an explicit width. + +```txt +image.urlPicsumPhotos(width=320) +``` + +Returns: `https://picsum.photos/seed/95blox/320/1668` + +Shows image.urlPicsumPhotos using an explicit height. + +```txt +image.urlPicsumPhotos(height=240) +``` + +Returns: `https://picsum.photos/seed/95blox/1668/240` + +Shows image.urlPicsumPhotos requesting a grayscale image. + +```txt +image.urlPicsumPhotos(grayscale=true) +``` + +Returns: `https://picsum.photos/seed/95blox/1668/2881?grayscale` + +Shows image.urlPicsumPhotos requesting a blur amount. + +```txt +image.urlPicsumPhotos(blur=3) +``` + +Returns: `https://picsum.photos/seed/95blox/1668/2881?grayscale&blur=3` diff --git a/docs-src/docs/040-test-data/domain/170-internet.md b/docs-src/docs/040-test-data/domain/170-internet.md index 17d9d71a..d8fc7df3 100644 --- a/docs-src/docs/040-test-data/domain/170-internet.md +++ b/docs-src/docs/040-test-data/domain/170-internet.md @@ -21,18 +21,45 @@ Generates a display name using the given person's name as base. - Canonical: `awd.domain.internet.displayName` - Faker docs: [https://fakerjs.dev/api/internet](https://fakerjs.dev/api/internet) -No parameters. +| Arg | Type | Required | Description | +| --- | --- | --- | --- | +| `firstName` | `string` | no | Optional first name to use as the basis for the display name. | +| `lastName` | `string` | no | Optional last name to use as the basis for the display name. | Examples: Shows the default internet.displayName call. ```txt -internet.displayName +internet.displayName() ``` Returns: `Aaliyah.Bosco` +Shows internet.displayName using firstName and lastName options. + +```txt +internet.displayName(firstName="Ada", lastName="Lovelace") +``` + +Returns: `Ada72` + +Shows internet.displayName using an explicit first name. + +```txt +internet.displayName(firstName="Ada") +``` + +Returns: `Ada14` + +Shows internet.displayName using an explicit last name. + +```txt +internet.displayName(lastName="Lovelace") +``` + +Returns: `Aaliyah14` + ### `internet.domainName` Generates a random domain name. @@ -182,18 +209,54 @@ Generates data using faker internet example email. - Canonical: `awd.domain.internet.exampleEmail` - Faker docs: [https://fakerjs.dev/api/internet](https://fakerjs.dev/api/internet) -No parameters. +| Arg | Type | Required | Description | +| --- | --- | --- | --- | +| `firstName` | `string` | no | Optional first name to use as the basis for the email address. | +| `lastName` | `string` | no | Optional last name to use as the basis for the email address. | +| `allowSpecialCharacters` | `boolean` | no | Whether special characters are allowed in the generated email address. | Examples: Shows the default internet.exampleEmail call. ```txt -internet.exampleEmail +internet.exampleEmail() +``` + +Returns: `Edwin.Dibbert@example.net` + +Shows internet.exampleEmail using firstName and lastName options. + +```txt +internet.exampleEmail(firstName="Ada", lastName="Lovelace") +``` + +Returns: `Ada_Lovelace0@example.net` + +Shows internet.exampleEmail allowing special characters. + +```txt +internet.exampleEmail(allowSpecialCharacters=true) ``` Returns: `Edwin.Dibbert@example.net` +Shows internet.exampleEmail using an explicit first name. + +```txt +internet.exampleEmail(firstName="Ada") +``` + +Returns: `Ada.Gutmann9@example.net` + +Shows internet.exampleEmail using an explicit last name. + +```txt +internet.exampleEmail(lastName="Lovelace") +``` + +Returns: `Edwin.Lovelace9@example.net` + ### `internet.httpMethod` Returns a random HTTP request method from an AnywayData-defined pool of GET, HEAD, POST, PUT, DELETE, PATCH, OPTIONS, TRACE, and CONNECT, with optional filtering for common methods and exclusions. @@ -238,18 +301,28 @@ Generates a random HTTP status code. - Canonical: `awd.domain.internet.httpStatusCode` - Faker docs: [https://fakerjs.dev/api/internet](https://fakerjs.dev/api/internet) -No parameters. +| Arg | Type | Required | Description | +| --- | --- | --- | --- | +| `types` | `array` | no | HTTP status categories to choose from. Allowed categories are informational, success, redirection, clientError, and serverError. | Examples: Shows the default internet.httpStatusCode call. ```txt -internet.httpStatusCode +internet.httpStatusCode() ``` Returns: `306` +Shows internet.httpStatusCode constrained to success status codes. + +```txt +internet.httpStatusCode(types=["success"]) +``` + +Returns: `204` + ### `internet.ip` Generates a random IPv4 or IPv6 address. diff --git a/docs-src/docs/040-test-data/domain/190-location.md b/docs-src/docs/040-test-data/domain/190-location.md index b7607a17..77b9507c 100644 --- a/docs-src/docs/040-test-data/domain/190-location.md +++ b/docs-src/docs/040-test-data/domain/190-location.md @@ -28,7 +28,7 @@ Examples: Shows the default location.language.alpha2 call. ```txt -location.language.alpha2 +language.alpha2 ``` Returns: `pa` @@ -47,7 +47,7 @@ Examples: Shows the default location.language.alpha3 call. ```txt -location.language.alpha3 +language.alpha3 ``` Returns: `pan` @@ -66,7 +66,7 @@ Examples: Shows the default location.language.name call. ```txt -location.language.name +language.name ``` Returns: `Punjabi` @@ -498,14 +498,25 @@ Generates data using faker location zip code. - Canonical: `awd.domain.location.zipCode` - Faker docs: [https://fakerjs.dev/api/location](https://fakerjs.dev/api/location) -No parameters. +| Arg | Type | Required | Description | +| --- | --- | --- | --- | +| `state` | `string` | no | State abbreviation used to constrain the generated zip code where supported by the locale. | +| `format` | `string` | no | Format pattern used for the generated zip code. | Examples: Shows the default location.zipCode call. ```txt -location.zipCode +location.zipCode() ``` Returns: `70310` + +Shows location.zipCode using a format option. + +```txt +location.zipCode(format="#####") +``` + +Returns: `47031` diff --git a/docs-src/docs/040-test-data/domain/200-lorem.md b/docs-src/docs/040-test-data/domain/200-lorem.md index 8768fd24..4817b3e3 100644 --- a/docs-src/docs/040-test-data/domain/200-lorem.md +++ b/docs-src/docs/040-test-data/domain/200-lorem.md @@ -45,7 +45,7 @@ Shows lorem.lines using min. lorem.lines(max=10, min=1) ``` -Returns: `Suppellex a cognatus arca aliquam audentia.` +Returns: `A cognatus arca aliquam audentia coniuratio crux fugit.\nStillicidium bardus utrimque acsi spargo cur.\nAqua avaritia thesaurus volo combibo stultus utor.\nAgo adflicto assentator utrimque altus curiositas vita expedita stultus comedo.\nTrucido accusamus tandem voveo tamisium cicuta testimonium amet.` Shows lorem.lines using max. @@ -61,7 +61,7 @@ Shows lorem.lines using lineCount. lorem.lines(lineCount=5) ``` -Returns: `A cognatus arca aliquam audentia coniuratio crux fugit.\nStillicidium bardus utrimque acsi spargo cur.\nAqua avaritia thesaurus volo combibo stultus utor.` +Returns: `Suppellex a cognatus arca aliquam audentia.\nCrux fugit curatio stillicidium bardus.\nAcsi spargo cur laboriosam aqua avaritia thesaurus volo combibo stultus.\nVarius ago adflicto assentator utrimque altus curiositas vita expedita stultus.\nStipes trucido accusamus tandem voveo.` Shows lorem.lines using lineCountMax. @@ -77,7 +77,7 @@ Shows lorem.lines using lineCountMin. lorem.lines(lineCountMin=5) ``` -Returns: `A cognatus arca aliquam audentia coniuratio crux fugit.\nStillicidium bardus utrimque acsi spargo cur.\nAqua avaritia thesaurus volo combibo stultus utor.` +Returns: `Suppellex a cognatus arca aliquam audentia.\nCrux fugit curatio stillicidium bardus.\nAcsi spargo cur laboriosam aqua avaritia thesaurus volo combibo stultus.\nVarius ago adflicto assentator utrimque altus curiositas vita expedita stultus.\nStipes trucido accusamus tandem voveo.` ### `lorem.paragraph` @@ -110,7 +110,7 @@ Shows lorem.paragraph using min. lorem.paragraph(max=10, min=1) ``` -Returns: `Suppellex a cognatus arca aliquam audentia.` +Returns: `A cognatus arca aliquam audentia coniuratio crux fugit. Stillicidium bardus utrimque acsi spargo cur. Aqua avaritia thesaurus volo combibo stultus utor. Ago adflicto assentator utrimque altus curiositas vita expedita stultus comedo. Trucido accusamus tandem voveo tamisium cicuta testimonium amet.` Shows lorem.paragraph using max. @@ -118,7 +118,7 @@ Shows lorem.paragraph using max. lorem.paragraph(max=5) ``` -Returns: `Suppellex a cognatus arca aliquam audentia. Crux fugit curatio stillicidium bardus. Acsi spargo cur laboriosam aqua avaritia thesaurus volo combibo stultus.` +Returns: `A cognatus arca aliquam audentia coniuratio crux fugit. Stillicidium bardus utrimque acsi spargo cur. Aqua avaritia thesaurus volo combibo stultus utor.` Shows lorem.paragraph using sentenceCount. @@ -126,7 +126,7 @@ Shows lorem.paragraph using sentenceCount. lorem.paragraph(sentenceCount=5) ``` -Returns: `Suppellex a cognatus arca aliquam audentia. Crux fugit curatio stillicidium bardus. Acsi spargo cur laboriosam aqua avaritia thesaurus volo combibo stultus.` +Returns: `Suppellex a cognatus arca aliquam audentia. Crux fugit curatio stillicidium bardus. Acsi spargo cur laboriosam aqua avaritia thesaurus volo combibo stultus. Varius ago adflicto assentator utrimque altus curiositas vita expedita stultus. Stipes trucido accusamus tandem voveo.` Shows lorem.paragraph using sentenceCountMax. @@ -134,7 +134,7 @@ Shows lorem.paragraph using sentenceCountMax. lorem.paragraph(sentenceCountMax=5) ``` -Returns: `Suppellex a cognatus arca aliquam audentia. Crux fugit curatio stillicidium bardus. Acsi spargo cur laboriosam aqua avaritia thesaurus volo combibo stultus.` +Returns: `A cognatus arca aliquam audentia coniuratio crux fugit. Stillicidium bardus utrimque acsi spargo cur. Aqua avaritia thesaurus volo combibo stultus utor.` Shows lorem.paragraph using sentenceCountMin. @@ -142,7 +142,7 @@ Shows lorem.paragraph using sentenceCountMin. lorem.paragraph(sentenceCountMin=5) ``` -Returns: `Suppellex a cognatus arca aliquam audentia. Crux fugit curatio stillicidium bardus. Acsi spargo cur laboriosam aqua avaritia thesaurus volo combibo stultus.` +Returns: `Suppellex a cognatus arca aliquam audentia. Crux fugit curatio stillicidium bardus. Acsi spargo cur laboriosam aqua avaritia thesaurus volo combibo stultus. Varius ago adflicto assentator utrimque altus curiositas vita expedita stultus. Stipes trucido accusamus tandem voveo.` ### `lorem.paragraphs` @@ -176,7 +176,7 @@ Shows lorem.paragraphs using min. lorem.paragraphs(max=10, min=1) ``` -Returns: `Suppellex a cognatus arca aliquam audentia. Crux fugit curatio stillicidium bardus. Acsi spargo cur laboriosam aqua avaritia thesaurus volo combibo stultus.` +Returns: `A cognatus arca aliquam audentia coniuratio crux fugit. Stillicidium bardus utrimque acsi spargo cur. Aqua avaritia thesaurus volo combibo stultus utor.\nAgo adflicto assentator utrimque altus curiositas vita expedita stultus comedo. Trucido accusamus tandem voveo tamisium cicuta testimonium amet. Ver claudeo civis aperio accusantium spoliatio.\nCena deprimo adnuo natus. Odit subseco ambulo cupio. Cupio admiratio facilis sonitus dolorum vinco occaecati venio.\nApud timor cubicularis asperiores. Conqueror tantillus sursum vacuus quia tantillus conscendo centum vehemens cursus. Somnus quasi amplus vir defaeco nesciunt cumque capillus venio natus.\nProvident compello et. Consuasor ver qui accendo vetus studio vulpes at approbo vicissitudo. Aedificium temeritas tego vesica sum ante accusantium acquiro.` Shows lorem.paragraphs using max. @@ -184,7 +184,7 @@ Shows lorem.paragraphs using max. lorem.paragraphs(max=5) ``` -Returns: `Suppellex a cognatus arca aliquam audentia. Crux fugit curatio stillicidium bardus. Acsi spargo cur laboriosam aqua avaritia thesaurus volo combibo stultus.5Varius ago adflicto assentator utrimque altus curiositas vita expedita stultus. Stipes trucido accusamus tandem voveo. Cicuta testimonium amet dedico ver claudeo civis aperio.5Spoliatio beneficium cena. Adnuo natus arca odit subseco ambulo. Suasoria cupio admiratio facilis sonitus dolorum.` +Returns: `A cognatus arca aliquam audentia coniuratio crux fugit. Stillicidium bardus utrimque acsi spargo cur. Aqua avaritia thesaurus volo combibo stultus utor.\nAgo adflicto assentator utrimque altus curiositas vita expedita stultus comedo. Trucido accusamus tandem voveo tamisium cicuta testimonium amet. Ver claudeo civis aperio accusantium spoliatio.\nCena deprimo adnuo natus. Odit subseco ambulo cupio. Cupio admiratio facilis sonitus dolorum vinco occaecati venio.` Shows lorem.paragraphs using paragraphCount. @@ -192,7 +192,7 @@ Shows lorem.paragraphs using paragraphCount. lorem.paragraphs(paragraphCount=5) ``` -Returns: `Suppellex a cognatus arca aliquam audentia. Crux fugit curatio stillicidium bardus. Acsi spargo cur laboriosam aqua avaritia thesaurus volo combibo stultus.\nVarius ago adflicto assentator utrimque altus curiositas vita expedita stultus. Stipes trucido accusamus tandem voveo. Cicuta testimonium amet dedico ver claudeo civis aperio.\nSpoliatio beneficium cena. Adnuo natus arca odit subseco ambulo. Suasoria cupio admiratio facilis sonitus dolorum.` +Returns: `Suppellex a cognatus arca aliquam audentia. Crux fugit curatio stillicidium bardus. Acsi spargo cur laboriosam aqua avaritia thesaurus volo combibo stultus.\nVarius ago adflicto assentator utrimque altus curiositas vita expedita stultus. Stipes trucido accusamus tandem voveo. Cicuta testimonium amet dedico ver claudeo civis aperio.\nSpoliatio beneficium cena. Adnuo natus arca odit subseco ambulo. Suasoria cupio admiratio facilis sonitus dolorum.\nOccaecati venio apto apud timor cubicularis asperiores vestigium conqueror tantillus. Vacuus quia tantillus conscendo centum vehemens cursus vobis. Quasi amplus vir defaeco nesciunt cumque capillus venio.\nAbbas provident compello et valde consuasor ver. Accendo vetus studio vulpes at approbo vicissitudo. Aedificium temeritas tego vesica sum ante accusantium acquiro.` Shows lorem.paragraphs using separator. @@ -200,7 +200,7 @@ Shows lorem.paragraphs using separator. lorem.paragraphs(separator="-") ``` -Returns: `Suppellex a cognatus arca aliquam audentia. Crux fugit curatio stillicidium bardus. Acsi spargo cur laboriosam aqua avaritia thesaurus volo combibo stultus.\nVarius ago adflicto assentator utrimque altus curiositas vita expedita stultus. Stipes trucido accusamus tandem voveo. Cicuta testimonium amet dedico ver claudeo civis aperio.\nSpoliatio beneficium cena. Adnuo natus arca odit subseco ambulo. Suasoria cupio admiratio facilis sonitus dolorum.` +Returns: `Suppellex a cognatus arca aliquam audentia. Crux fugit curatio stillicidium bardus. Acsi spargo cur laboriosam aqua avaritia thesaurus volo combibo stultus.-Varius ago adflicto assentator utrimque altus curiositas vita expedita stultus. Stipes trucido accusamus tandem voveo. Cicuta testimonium amet dedico ver claudeo civis aperio.-Spoliatio beneficium cena. Adnuo natus arca odit subseco ambulo. Suasoria cupio admiratio facilis sonitus dolorum.` Shows lorem.paragraphs using paragraphCountMax. @@ -208,7 +208,7 @@ Shows lorem.paragraphs using paragraphCountMax. lorem.paragraphs(paragraphCountMax=5) ``` -Returns: `Suppellex a cognatus arca aliquam audentia. Crux fugit curatio stillicidium bardus. Acsi spargo cur laboriosam aqua avaritia thesaurus volo combibo stultus.\nVarius ago adflicto assentator utrimque altus curiositas vita expedita stultus. Stipes trucido accusamus tandem voveo. Cicuta testimonium amet dedico ver claudeo civis aperio.\nSpoliatio beneficium cena. Adnuo natus arca odit subseco ambulo. Suasoria cupio admiratio facilis sonitus dolorum.` +Returns: `A cognatus arca aliquam audentia coniuratio crux fugit. Stillicidium bardus utrimque acsi spargo cur. Aqua avaritia thesaurus volo combibo stultus utor.\nAgo adflicto assentator utrimque altus curiositas vita expedita stultus comedo. Trucido accusamus tandem voveo tamisium cicuta testimonium amet. Ver claudeo civis aperio accusantium spoliatio.\nCena deprimo adnuo natus. Odit subseco ambulo cupio. Cupio admiratio facilis sonitus dolorum vinco occaecati venio.` Shows lorem.paragraphs using paragraphCountMin. @@ -216,7 +216,7 @@ Shows lorem.paragraphs using paragraphCountMin. lorem.paragraphs(paragraphCountMin=5) ``` -Returns: `Suppellex a cognatus arca aliquam audentia. Crux fugit curatio stillicidium bardus. Acsi spargo cur laboriosam aqua avaritia thesaurus volo combibo stultus.\nVarius ago adflicto assentator utrimque altus curiositas vita expedita stultus. Stipes trucido accusamus tandem voveo. Cicuta testimonium amet dedico ver claudeo civis aperio.\nSpoliatio beneficium cena. Adnuo natus arca odit subseco ambulo. Suasoria cupio admiratio facilis sonitus dolorum.` +Returns: `Suppellex a cognatus arca aliquam audentia. Crux fugit curatio stillicidium bardus. Acsi spargo cur laboriosam aqua avaritia thesaurus volo combibo stultus.\nVarius ago adflicto assentator utrimque altus curiositas vita expedita stultus. Stipes trucido accusamus tandem voveo. Cicuta testimonium amet dedico ver claudeo civis aperio.\nSpoliatio beneficium cena. Adnuo natus arca odit subseco ambulo. Suasoria cupio admiratio facilis sonitus dolorum.\nOccaecati venio apto apud timor cubicularis asperiores vestigium conqueror tantillus. Vacuus quia tantillus conscendo centum vehemens cursus vobis. Quasi amplus vir defaeco nesciunt cumque capillus venio.\nAbbas provident compello et valde consuasor ver. Accendo vetus studio vulpes at approbo vicissitudo. Aedificium temeritas tego vesica sum ante accusantium acquiro.` ### `lorem.sentence` @@ -249,7 +249,7 @@ Shows lorem.sentence using min. lorem.sentence(max=10, min=1) ``` -Returns: `Cur.` +Returns: `Suppellex a cognatus arca aliquam.` Shows lorem.sentence using max. @@ -257,7 +257,7 @@ Shows lorem.sentence using max. lorem.sentence(max=5) ``` -Returns: `Suppellex a cognatus arca aliquam audentia.` +Returns: `Suppellex a cognatus.` Shows lorem.sentence using wordCount. @@ -265,7 +265,7 @@ Shows lorem.sentence using wordCount. lorem.sentence(wordCount=5) ``` -Returns: `Suppellex a cognatus arca aliquam audentia.` +Returns: `Cur suppellex a cognatus arca.` Shows lorem.sentence using wordCountMax. @@ -273,7 +273,7 @@ Shows lorem.sentence using wordCountMax. lorem.sentence(wordCountMax=5) ``` -Returns: `Suppellex a cognatus arca aliquam audentia.` +Returns: `Suppellex a cognatus.` Shows lorem.sentence using wordCountMin. @@ -281,7 +281,7 @@ Shows lorem.sentence using wordCountMin. lorem.sentence(wordCountMin=5) ``` -Returns: `Suppellex a cognatus arca aliquam audentia.` +Returns: `Cur suppellex a cognatus arca.` ### `lorem.sentences` @@ -315,7 +315,7 @@ Shows lorem.sentences using min. lorem.sentences(max=10, min=1) ``` -Returns: `Suppellex a cognatus arca aliquam audentia.` +Returns: `A cognatus arca aliquam audentia coniuratio crux fugit. Stillicidium bardus utrimque acsi spargo cur. Aqua avaritia thesaurus volo combibo stultus utor. Ago adflicto assentator utrimque altus curiositas vita expedita stultus comedo. Trucido accusamus tandem voveo tamisium cicuta testimonium amet.` Shows lorem.sentences using max. @@ -323,7 +323,7 @@ Shows lorem.sentences using max. lorem.sentences(max=5) ``` -Returns: `A cognatus arca aliquam audentia coniuratio crux fugit.5Stillicidium bardus utrimque acsi spargo cur.5Aqua avaritia thesaurus volo combibo stultus utor.5Ago adflicto assentator utrimque altus curiositas vita expedita stultus comedo.` +Returns: `A cognatus arca aliquam audentia coniuratio crux fugit. Stillicidium bardus utrimque acsi spargo cur. Aqua avaritia thesaurus volo combibo stultus utor.` Shows lorem.sentences using sentenceCount. @@ -331,7 +331,7 @@ Shows lorem.sentences using sentenceCount. lorem.sentences(sentenceCount=5) ``` -Returns: `A cognatus arca aliquam audentia coniuratio crux fugit. Stillicidium bardus utrimque acsi spargo cur. Aqua avaritia thesaurus volo combibo stultus utor. Ago adflicto assentator utrimque altus curiositas vita expedita stultus comedo.` +Returns: `Suppellex a cognatus arca aliquam audentia. Crux fugit curatio stillicidium bardus. Acsi spargo cur laboriosam aqua avaritia thesaurus volo combibo stultus. Varius ago adflicto assentator utrimque altus curiositas vita expedita stultus. Stipes trucido accusamus tandem voveo.` Shows lorem.sentences using separator. @@ -339,7 +339,7 @@ Shows lorem.sentences using separator. lorem.sentences(separator="-") ``` -Returns: `A cognatus arca aliquam audentia coniuratio crux fugit. Stillicidium bardus utrimque acsi spargo cur. Aqua avaritia thesaurus volo combibo stultus utor. Ago adflicto assentator utrimque altus curiositas vita expedita stultus comedo.` +Returns: `A cognatus arca aliquam audentia coniuratio crux fugit.-Stillicidium bardus utrimque acsi spargo cur.-Aqua avaritia thesaurus volo combibo stultus utor.-Ago adflicto assentator utrimque altus curiositas vita expedita stultus comedo.` Shows lorem.sentences using sentenceCountMax. @@ -347,7 +347,7 @@ Shows lorem.sentences using sentenceCountMax. lorem.sentences(sentenceCountMax=5) ``` -Returns: `A cognatus arca aliquam audentia coniuratio crux fugit. Stillicidium bardus utrimque acsi spargo cur. Aqua avaritia thesaurus volo combibo stultus utor. Ago adflicto assentator utrimque altus curiositas vita expedita stultus comedo.` +Returns: `A cognatus arca aliquam audentia coniuratio crux fugit. Stillicidium bardus utrimque acsi spargo cur. Aqua avaritia thesaurus volo combibo stultus utor.` Shows lorem.sentences using sentenceCountMin. @@ -355,7 +355,7 @@ Shows lorem.sentences using sentenceCountMin. lorem.sentences(sentenceCountMin=5) ``` -Returns: `A cognatus arca aliquam audentia coniuratio crux fugit. Stillicidium bardus utrimque acsi spargo cur. Aqua avaritia thesaurus volo combibo stultus utor. Ago adflicto assentator utrimque altus curiositas vita expedita stultus comedo.` +Returns: `Suppellex a cognatus arca aliquam audentia. Crux fugit curatio stillicidium bardus. Acsi spargo cur laboriosam aqua avaritia thesaurus volo combibo stultus. Varius ago adflicto assentator utrimque altus curiositas vita expedita stultus. Stipes trucido accusamus tandem voveo.` ### `lorem.slug` @@ -388,7 +388,7 @@ Shows lorem.slug using min. lorem.slug(max=10, min=1) ``` -Returns: `cur` +Returns: `suppellex-a-cognatus-arca-aliquam` Shows lorem.slug using max. @@ -396,7 +396,7 @@ Shows lorem.slug using max. lorem.slug(max=5) ``` -Returns: `cur-suppellex-a` +Returns: `suppellex-a-cognatus` Shows lorem.slug using wordCount. @@ -404,7 +404,7 @@ Shows lorem.slug using wordCount. lorem.slug(wordCount=5) ``` -Returns: `cur-suppellex-a` +Returns: `cur-suppellex-a-cognatus-arca` Shows lorem.slug using wordCountMax. @@ -412,7 +412,7 @@ Shows lorem.slug using wordCountMax. lorem.slug(wordCountMax=5) ``` -Returns: `cur-suppellex-a` +Returns: `suppellex-a-cognatus` Shows lorem.slug using wordCountMin. @@ -420,7 +420,7 @@ Shows lorem.slug using wordCountMin. lorem.slug(wordCountMin=5) ``` -Returns: `cur-suppellex-a` +Returns: `cur-suppellex-a-cognatus-arca` ### `lorem.text` @@ -450,8 +450,6 @@ Generates a word of a specified length. | Arg | Type | Required | Description | | --- | --- | --- | --- | -| `min` | `number` | no | Minimum word length when generating a ranged length. | -| `max` | `number` | no | Maximum word length when generating a ranged length. | | `length` | `number` | no | Exact word length to generate. | | `strategy` | `fail\|closest\|shortest\|longest\|any-length` | no | The strategy to apply when no words with a matching length are found. Available error handling strategies: fail: Throws an error if no words with the given length are found. shortest: Returns any of the shortest words. closest: Returns any of the words closest to the given length. longest: Returns any of the longest words. any-length: Returns a word with any length. | @@ -465,22 +463,6 @@ lorem.word() Returns: `cur` -Shows lorem.word using min. - -```txt -lorem.word(max=10, min=1) -``` - -Returns: `cur` - -Shows lorem.word using max. - -```txt -lorem.word(max=5) -``` - -Returns: `cur` - Shows lorem.word using length. ```txt @@ -528,7 +510,7 @@ Shows lorem.words using min. lorem.words(max=10, min=1) ``` -Returns: `cur` +Returns: `suppellex a cognatus arca aliquam` Shows lorem.words using max. @@ -536,7 +518,7 @@ Shows lorem.words using max. lorem.words(max=5) ``` -Returns: `cur suppellex a` +Returns: `suppellex a cognatus` Shows lorem.words using wordCount. @@ -544,7 +526,7 @@ Shows lorem.words using wordCount. lorem.words(wordCount=5) ``` -Returns: `cur suppellex a` +Returns: `cur suppellex a cognatus arca` Shows lorem.words using wordCountMax. @@ -552,7 +534,7 @@ Shows lorem.words using wordCountMax. lorem.words(wordCountMax=5) ``` -Returns: `cur suppellex a` +Returns: `suppellex a cognatus` Shows lorem.words using wordCountMin. @@ -560,4 +542,4 @@ Shows lorem.words using wordCountMin. lorem.words(wordCountMin=5) ``` -Returns: `cur suppellex a` +Returns: `cur suppellex a cognatus arca` diff --git a/docs-src/docs/040-test-data/domain/220-number.md b/docs-src/docs/040-test-data/domain/220-number.md index 3f714100..0a785c57 100644 --- a/docs-src/docs/040-test-data/domain/220-number.md +++ b/docs-src/docs/040-test-data/domain/220-number.md @@ -23,7 +23,9 @@ Returns a BigInt number. | Arg | Type | Required | Description | | --- | --- | --- | --- | -| `value` | `bigint\|number\|string\|boolean` | no | Base value used for generation. Supports bigint, number, string, or boolean inputs. For range constraints use min, max, and multipleOf. | +| `min` | `integer` | no | Optional minimum bound for the generated BigInt value. | +| `max` | `integer` | no | Optional maximum bound for the generated BigInt value. | +| `multipleOf` | `integer` | no | Generated BigInt will be a multiple of the given value. | Examples: @@ -35,13 +37,29 @@ number.bigInt() Returns: `703101335462806n` -Shows number.bigInt using a boolean base value. +Shows number.bigInt using min and max bounds. ```txt -number.bigInt(value=true) +number.bigInt(min=100, max=1000) ``` -Returns: `703101335462806n` +Returns: `570n` + +Shows number.bigInt constrained to a multiple. + +```txt +number.bigInt(multipleOf=7) +``` + +Returns: `292170934823957n` + +Shows number.bigInt using an upper bound. + +```txt +number.bigInt(max=1000) +``` + +Returns: `699n` ### `number.binary` diff --git a/docs-src/docs/040-test-data/domain/230-person.md b/docs-src/docs/040-test-data/domain/230-person.md index ae3ca922..0ad3c61b 100644 --- a/docs-src/docs/040-test-data/domain/230-person.md +++ b/docs-src/docs/040-test-data/domain/230-person.md @@ -69,18 +69,54 @@ Generates a random full name. - Canonical: `awd.domain.person.fullName` - Faker docs: [https://fakerjs.dev/api/person](https://fakerjs.dev/api/person) -No parameters. +| Arg | Type | Required | Description | +| --- | --- | --- | --- | +| `firstName` | `string` | no | Optional first name to use as the basis for the full name. | +| `lastName` | `string` | no | Optional last name to use as the basis for the full name. | +| `sex` | `female\|generic\|male` | no | Sex category used for the generated full name. | Examples: Shows the default person.fullName call. ```txt -person.fullName +person.fullName() ``` Returns: `Aaliyah Corkery` +Shows person.fullName using name and sex options. + +```txt +person.fullName(firstName="Ada", lastName="Lovelace", sex="female") +``` + +Returns: `Ada Lovelace` + +Shows person.fullName using an explicit first name. + +```txt +person.fullName(firstName="Ada") +``` + +Returns: `Ada Abbott` + +Shows person.fullName using an explicit last name. + +```txt +person.fullName(lastName="Lovelace") +``` + +Returns: `Aaliyah Lovelace` + +Shows person.fullName using a sex category. + +```txt +person.fullName(sex="female") +``` + +Returns: `Monique Gutmann` + ### `person.gender` Returns a random gender. @@ -289,14 +325,24 @@ Returns a random sex type. The `SexType` is intended to be used in parameters an - Canonical: `awd.domain.person.sexType` - Faker docs: [https://fakerjs.dev/api/person](https://fakerjs.dev/api/person) -No parameters. +| Arg | Type | Required | Description | +| --- | --- | --- | --- | +| `includeGeneric` | `boolean` | no | Whether the generic sex type can be returned. | Examples: Shows the default person.sexType call. ```txt -person.sexType +person.sexType() +``` + +Returns: `female` + +Shows person.sexType excluding the generic value. + +```txt +person.sexType(includeGeneric=false) ``` Returns: `female` diff --git a/docs-src/docs/040-test-data/domain/250-science.md b/docs-src/docs/040-test-data/domain/250-science.md index 1bfe206c..56681bea 100644 --- a/docs-src/docs/040-test-data/domain/250-science.md +++ b/docs-src/docs/040-test-data/domain/250-science.md @@ -28,7 +28,7 @@ Examples: Shows the default science.chemicalElement.atomicNumber call. ```txt -science.chemicalElement.atomicNumber +chemicalElement.atomicNumber ``` Returns: `50` @@ -47,7 +47,7 @@ Examples: Shows the default science.chemicalElement.name call. ```txt -science.chemicalElement.name +chemicalElement.name ``` Returns: `Tin` @@ -66,7 +66,7 @@ Examples: Shows the default science.chemicalElement.symbol call. ```txt -science.chemicalElement.symbol +chemicalElement.symbol ``` Returns: `Sn` @@ -85,7 +85,7 @@ Examples: Shows the default science.unit.name call. ```txt -science.unit.name +unit.name ``` Returns: `watt` @@ -104,7 +104,7 @@ Examples: Shows the default science.unit.symbol call. ```txt -science.unit.symbol +unit.symbol ``` Returns: `W` diff --git a/docs-src/docs/040-test-data/domain/270-system.md b/docs-src/docs/040-test-data/domain/270-system.md index fe889729..1f169ad0 100644 --- a/docs-src/docs/040-test-data/domain/270-system.md +++ b/docs-src/docs/040-test-data/domain/270-system.md @@ -174,18 +174,28 @@ Returns a random file name with extension. - Canonical: `awd.domain.system.fileName` - Faker docs: [https://fakerjs.dev/api/system](https://fakerjs.dev/api/system) -No parameters. +| Arg | Type | Required | Description | +| --- | --- | --- | --- | +| `extensionCount` | `number` | no | How many extensions the generated file name should have. | Examples: Shows the default system.fileName call. ```txt -system.fileName +system.fileName() ``` Returns: `fog_aboard.otf` +Shows system.fileName using extensionCount. + +```txt +system.fileName(extensionCount=2) +``` + +Returns: `fog_aboard.otf.7z` + ### `system.filePath` Returns a file path. @@ -250,18 +260,45 @@ Returns a random network interface. - Canonical: `awd.domain.system.networkInterface` - Faker docs: [https://fakerjs.dev/api/system](https://fakerjs.dev/api/system) -No parameters. +| Arg | Type | Required | Description | +| --- | --- | --- | --- | +| `interfaceType` | `en\|wl\|ww` | no | Network interface type prefix. | +| `interfaceSchema` | `index\|slot\|mac\|pci` | no | Network interface naming schema. | Examples: Shows the default system.networkInterface call. ```txt -system.networkInterface +system.networkInterface() ``` Returns: `wlx042125686a3e` +Shows system.networkInterface using interface type and schema options. + +```txt +system.networkInterface(interfaceType="en", interfaceSchema="mac") +``` + +Returns: `enx6b042125686a` + +Shows system.networkInterface using an explicit interface type. + +```txt +system.networkInterface(interfaceType="en") +``` + +Returns: `ens7f3d0` + +Shows system.networkInterface using an explicit interface schema. + +```txt +system.networkInterface(interfaceSchema="mac") +``` + +Returns: `wlxb042125686a3` + ### `system.semver` Returns a semantic version. diff --git a/docs-src/docs/040-test-data/domain/290-word.md b/docs-src/docs/040-test-data/domain/290-word.md index 02e8b2db..1ad6f148 100644 --- a/docs-src/docs/040-test-data/domain/290-word.md +++ b/docs-src/docs/040-test-data/domain/290-word.md @@ -24,7 +24,6 @@ Returns a random adjective. | Arg | Type | Required | Description | | --- | --- | --- | --- | | `length` | `number` | no | Desired length of the generated value. | -| `max` | `number` | no | Maximum bound used when generating a value. | | `strategy` | `fail\|closest\|shortest\|longest\|any-length` | no | The strategy to apply when no words with a matching length are found. Available error handling strategies: fail: Throws an error if no words with the given length are found. shortest: Returns any of the shortest words. closest: Returns any of the words closest to the given length. longest: Returns any of the longest words. any-length: Returns a word with any length. | Examples: @@ -45,14 +44,6 @@ word.adjective(length=5) Returns: `major` -Shows word.adjective using max. - -```txt -word.adjective(max=5) -``` - -Returns: `inferior` - Shows word.adjective using strategy. ```txt @@ -71,7 +62,6 @@ Returns a random adverb. | Arg | Type | Required | Description | | --- | --- | --- | --- | | `length` | `number` | no | Desired length of the generated value. | -| `max` | `number` | no | Maximum bound used when generating a value. | | `strategy` | `fail\|closest\|shortest\|longest\|any-length` | no | The strategy to apply when no words with a matching length are found. Available error handling strategies: fail: Throws an error if no words with the given length are found. shortest: Returns any of the shortest words. closest: Returns any of the words closest to the given length. longest: Returns any of the longest words. any-length: Returns a word with any length. | Examples: @@ -92,14 +82,6 @@ word.adverb(length=5) Returns: `never` -Shows word.adverb using max. - -```txt -word.adverb(max=5) -``` - -Returns: `knavishly` - Shows word.adverb using strategy. ```txt @@ -118,7 +100,6 @@ Returns a random conjunction. | Arg | Type | Required | Description | | --- | --- | --- | --- | | `length` | `number` | no | Desired length of the generated value. | -| `max` | `number` | no | Maximum bound used when generating a value. | | `strategy` | `fail\|closest\|shortest\|longest\|any-length` | no | The strategy to apply when no words with a matching length are found. Available error handling strategies: fail: Throws an error if no words with the given length are found. shortest: Returns any of the shortest words. closest: Returns any of the words closest to the given length. longest: Returns any of the longest words. any-length: Returns a word with any length. | Examples: @@ -139,14 +120,6 @@ word.conjunction(length=5) Returns: `until` -Shows word.conjunction using max. - -```txt -word.conjunction(max=5) -``` - -Returns: `likewise` - Shows word.conjunction using strategy. ```txt @@ -165,7 +138,6 @@ Returns a random interjection. | Arg | Type | Required | Description | | --- | --- | --- | --- | | `length` | `number` | no | Desired length of the generated value. | -| `max` | `number` | no | Maximum bound used when generating a value. | | `strategy` | `fail\|closest\|shortest\|longest\|any-length` | no | The strategy to apply when no words with a matching length are found. Available error handling strategies: fail: Throws an error if no words with the given length are found. shortest: Returns any of the shortest words. closest: Returns any of the words closest to the given length. longest: Returns any of the longest words. any-length: Returns a word with any length. | Examples: @@ -186,14 +158,6 @@ word.interjection(length=5) Returns: `fooey` -Shows word.interjection using max. - -```txt -word.interjection(max=5) -``` - -Returns: `woot` - Shows word.interjection using strategy. ```txt @@ -212,7 +176,6 @@ Returns a random noun. | Arg | Type | Required | Description | | --- | --- | --- | --- | | `length` | `number` | no | Desired length of the generated value. | -| `max` | `number` | no | Maximum bound used when generating a value. | | `strategy` | `fail\|closest\|shortest\|longest\|any-length` | no | The strategy to apply when no words with a matching length are found. Available error handling strategies: fail: Throws an error if no words with the given length are found. shortest: Returns any of the shortest words. closest: Returns any of the words closest to the given length. longest: Returns any of the longest words. any-length: Returns a word with any length. | Examples: @@ -233,14 +196,6 @@ word.noun(length=5) Returns: `humor` -Shows word.noun using max. - -```txt -word.noun(max=5) -``` - -Returns: `heating` - Shows word.noun using strategy. ```txt @@ -259,7 +214,6 @@ Returns a random preposition. | Arg | Type | Required | Description | | --- | --- | --- | --- | | `length` | `number` | no | Desired length of the generated value. | -| `max` | `number` | no | Maximum bound used when generating a value. | | `strategy` | `fail\|closest\|shortest\|longest\|any-length` | no | The strategy to apply when no words with a matching length are found. Available error handling strategies: fail: Throws an error if no words with the given length are found. shortest: Returns any of the shortest words. closest: Returns any of the words closest to the given length. longest: Returns any of the longest words. any-length: Returns a word with any length. | Examples: @@ -280,14 +234,6 @@ word.preposition(length=5) Returns: `aside` -Shows word.preposition using max. - -```txt -word.preposition(max=5) -``` - -Returns: `except` - Shows word.preposition using strategy. ```txt @@ -306,7 +252,6 @@ Returns a random word, that can be an adjective, adverb, conjunction, interjecti | Arg | Type | Required | Description | | --- | --- | --- | --- | | `length` | `number` | no | Desired length of the generated value. | -| `max` | `number` | no | Maximum bound used when generating a value. | | `strategy` | `fail\|closest\|shortest\|longest\|any-length` | no | The strategy to apply when no words with a matching length are found. Available error handling strategies: fail: Throws an error if no words with the given length are found. shortest: Returns any of the shortest words. closest: Returns any of the words closest to the given length. longest: Returns any of the longest words. any-length: Returns a word with any length. | Examples: @@ -327,14 +272,6 @@ word.sample(length=5) Returns: `yowza` -Shows word.sample using max. - -```txt -word.sample(max=5) -``` - -Returns: `boohoo` - Shows word.sample using strategy. ```txt @@ -353,7 +290,6 @@ Returns a random verb. | Arg | Type | Required | Description | | --- | --- | --- | --- | | `length` | `number` | no | Desired length of the generated value. | -| `max` | `number` | no | Maximum bound used when generating a value. | | `strategy` | `fail\|closest\|shortest\|longest\|any-length` | no | The strategy to apply when no words with a matching length are found. Available error handling strategies: fail: Throws an error if no words with the given length are found. shortest: Returns any of the shortest words. closest: Returns any of the words closest to the given length. longest: Returns any of the longest words. any-length: Returns a word with any length. | Examples: @@ -374,14 +310,6 @@ word.verb(length=5) Returns: `mould` -Shows word.verb using max. - -```txt -word.verb(max=5) -``` - -Returns: `hunger` - Shows word.verb using strategy. ```txt @@ -400,7 +328,6 @@ Returns a random string containing some words separated by spaces. | Arg | Type | Required | Description | | --- | --- | --- | --- | | `count` | `number` | no | Number of items to generate. | -| `max` | `number` | no | Maximum bound used when generating a value. | Examples: @@ -419,11 +346,3 @@ word.words(count=5) ``` Returns: `boohoo pish tenderly above pop` - -Shows word.words using max. - -```txt -word.words(max=5) -``` - -Returns: `fog aboard` diff --git a/docs/domain-faker-param-comparison.md b/docs/domain-faker-param-comparison.md new file mode 100644 index 00000000..94b11078 --- /dev/null +++ b/docs/domain-faker-param-comparison.md @@ -0,0 +1,97 @@ +# Domain/Faker Param Comparison + +Generated by `node scripts/compare-domain-faker-params.mjs --markdown` from the installed `@faker-js/faker` declaration bundle and the domain keyword catalog. + +## Summary + +- Faker option-backed domain commands compared: 77 +- Commands with Faker option params missing from domain metadata: 0 +- Commands with domain params not present in Faker options: 0 + +## Comparison + +| Command | Faker option params | Domain params | Missing in domain | Domain-only params | +| --- | --- | --- | --- | --- | +| `airline.flightNumber` | `length`, `addLeadingZeros` | `length`, `addLeadingZeros` | none | none | +| `airline.recordLocator` | `allowNumerics`, `allowVisuallySimilarCharacters` | `allowNumerics`, `allowVisuallySimilarCharacters` | none | none | +| `airline.seat` | `aircraftType` | `aircraftType` | none | none | +| `color.cmyk` | `format` | `format` | none | none | +| `color.colorByCSSColorSpace` | `format`, `space` | `format`, `space` | none | none | +| `color.hsl` | `format`, `includeAlpha` | `format`, `includeAlpha` | none | none | +| `color.hwb` | `format` | `format` | none | none | +| `color.lab` | `format` | `format` | none | none | +| `color.lch` | `format` | `format` | none | none | +| `color.rgb` | `prefix`, `casing`, `format`, `includeAlpha` | `casing`, `format`, `includeAlpha`, `prefix` | none | none | +| `commerce.isbn` | `variant`, `separator` | `separator`, `variant` | none | none | +| `commerce.price` | `min`, `max`, `dec`, `symbol` | `dec`, `max`, `min`, `symbol` | none | none | +| `commerce.upc` | `prefix` | `prefix` | none | none | +| `datatype.boolean` | `probability` | `probability` | none | none | +| `date.month` | `abbreviated`, `context` | `abbreviated`, `context` | none | none | +| `date.weekday` | `abbreviated`, `context` | `abbreviated`, `context` | none | none | +| `finance.accountNumber` | `length` | `length` | none | none | +| `finance.amount` | `min`, `max`, `dec`, `symbol`, `autoFormat` | `autoFormat`, `dec`, `max`, `min`, `symbol` | none | none | +| `finance.bic` | `includeBranchCode` | `includeBranchCode` | none | none | +| `finance.bitcoinAddress` | `type`, `network` | `type`, `network` | none | none | +| `finance.creditCardNumber` | `issuer` | `issuer` | none | none | +| `finance.iban` | `formatted`, `countryCode` | `countryCode`, `formatted` | none | none | +| `finance.pin` | `length` | `length` | none | none | +| `git.commitDate` | `refDate` | `refDate` | none | none | +| `git.commitEntry` | `merge`, `eol`, `refDate` | `merge`, `eol`, `refDate` | none | none | +| `git.commitSha` | `length` | `length` | none | none | +| `image.dataUri` | `width`, `height`, `color`, `type` | `width`, `height`, `color`, `type` | none | none | +| `image.personPortrait` | `sex`, `size` | `sex`, `size` | none | none | +| `image.url` | `width`, `height` | `height`, `width` | none | none | +| `image.urlPicsumPhotos` | `width`, `height`, `grayscale`, `blur` | `width`, `height`, `grayscale`, `blur` | none | none | +| `internet.displayName` | `firstName`, `lastName` | `firstName`, `lastName` | none | none | +| `internet.email` | `firstName`, `lastName`, `provider`, `allowSpecialCharacters` | `allowSpecialCharacters`, `firstName`, `lastName`, `provider` | none | none | +| `internet.emoji` | `types` | `types` | none | none | +| `internet.exampleEmail` | `firstName`, `lastName`, `allowSpecialCharacters` | `firstName`, `lastName`, `allowSpecialCharacters` | none | none | +| `internet.httpStatusCode` | `types` | `types` | none | none | +| `internet.ipv4` | `cidrBlock`, `network` | `cidrBlock`, `network` | none | none | +| `internet.jwt` | `header`, `payload`, `refDate` | `header`, `payload`, `refDate` | none | none | +| `internet.mac` | `separator` | `separator` | none | none | +| `internet.password` | `length`, `memorable`, `pattern`, `prefix` | `length`, `memorable`, `pattern`, `prefix` | none | none | +| `internet.url` | `appendSlash`, `protocol` | `appendSlash`, `protocol` | none | none | +| `internet.username` | `firstName`, `lastName` | `firstName`, `lastName` | none | none | +| `location.cardinalDirection` | `abbreviated` | `abbreviated` | none | none | +| `location.countryCode` | `variant` | `variant` | none | none | +| `location.direction` | `abbreviated` | `abbreviated` | none | none | +| `location.ordinalDirection` | `abbreviated` | `abbreviated` | none | none | +| `location.state` | `abbreviated` | `abbreviated` | none | none | +| `location.streetAddress` | `useFullAddress` | `useFullAddress` | none | none | +| `location.zipCode` | `state`, `format` | `state`, `format` | none | none | +| `lorem.word` | `length`, `strategy` | `length`, `strategy` | none | none | +| `number.bigInt` | `min`, `max`, `multipleOf` | `min`, `max`, `multipleOf` | none | none | +| `number.binary` | `min`, `max` | `max`, `min` | none | none | +| `number.float` | `min`, `max`, `fractionDigits`, `multipleOf` | `fractionDigits`, `max`, `min`, `multipleOf` | none | none | +| `number.hex` | `min`, `max` | `min`, `max` | none | none | +| `number.int` | `min`, `max`, `multipleOf` | `min`, `max`, `multipleOf` | none | none | +| `number.octal` | `min`, `max` | `max`, `min` | none | none | +| `number.romanNumeral` | `min`, `max` | `min`, `max` | none | none | +| `person.fullName` | `firstName`, `lastName`, `sex` | `firstName`, `lastName`, `sex` | none | none | +| `person.sexType` | `includeGeneric` | `includeGeneric` | none | none | +| `phone.number` | `style` | `style` | none | none | +| `string.alpha` | `length`, `casing`, `exclude` | `length`, `casing`, `exclude` | none | none | +| `string.alphanumeric` | `length`, `casing`, `exclude` | `length`, `casing`, `exclude` | none | none | +| `string.binary` | `length`, `prefix` | `length`, `prefix` | none | none | +| `string.hexadecimal` | `length`, `casing`, `prefix` | `casing`, `length`, `prefix` | none | none | +| `string.numeric` | `length`, `allowLeadingZeros`, `exclude` | `length`, `allowLeadingZeros`, `exclude` | none | none | +| `string.octal` | `length`, `prefix` | `length`, `prefix` | none | none | +| `system.cron` | `includeYear`, `includeNonStandard` | `includeNonStandard`, `includeYear` | none | none | +| `system.fileName` | `extensionCount` | `extensionCount` | none | none | +| `system.networkInterface` | `interfaceType`, `interfaceSchema` | `interfaceType`, `interfaceSchema` | none | none | +| `word.adjective` | `length`, `strategy` | `length`, `strategy` | none | none | +| `word.adverb` | `length`, `strategy` | `length`, `strategy` | none | none | +| `word.conjunction` | `length`, `strategy` | `length`, `strategy` | none | none | +| `word.interjection` | `length`, `strategy` | `length`, `strategy` | none | none | +| `word.noun` | `length`, `strategy` | `length`, `strategy` | none | none | +| `word.preposition` | `length`, `strategy` | `length`, `strategy` | none | none | +| `word.sample` | `length`, `strategy` | `length`, `strategy` | none | none | +| `word.verb` | `length`, `strategy` | `length`, `strategy` | none | none | +| `word.words` | `count` | `count` | none | none | + +## Review Notes + +- `Missing in domain` must stay at `none` for every row. +- `Domain-only params` must stay at `none` for every Faker-backed domain command. + diff --git a/packages/core-ui/src/tests/interaction/matrix/schema-interaction-scenario-builder.test.js b/packages/core-ui/src/tests/interaction/matrix/schema-interaction-scenario-builder.test.js index d757b5e7..6f9203b3 100644 --- a/packages/core-ui/src/tests/interaction/matrix/schema-interaction-scenario-builder.test.js +++ b/packages/core-ui/src/tests/interaction/matrix/schema-interaction-scenario-builder.test.js @@ -16,6 +16,10 @@ import { getScenarioExecutionStatus, } from './support/schema-interaction-scenario-builder.js'; +function isScenarioArgCoverageRequired(arg) { + return arg?.usageExampleSupported !== false; +} + describe('schema interaction scenario builder', () => { test('exposes datatype.enum in domain command list with help metadata', () => { const visibleCommands = getVisibleDomainCommands({ @@ -82,9 +86,11 @@ describe('schema interaction scenario builder', () => { const bucket = byCommand.get(`domain:${command}`); expect(bucket.scenarios.length).toBeGreaterThan(0); - (metadata.args || []).forEach((arg) => { - expect(bucket.coveredArgs.has(arg.name)).toBe(true); - }); + (metadata.args || []) + .filter((arg) => isScenarioArgCoverageRequired(arg)) + .forEach((arg) => { + expect(bucket.coveredArgs.has(arg.name)).toBe(true); + }); const exampleScenarioCount = bucket.scenarios.filter((scenario) => scenario.origins.includes('example')).length; const expectedExamples = Array.isArray(getDomainKeywordByCommand(command)?.help?.usageExamples) diff --git a/packages/core/js/data_generation/domain/domainTestDataRuleValidator.js b/packages/core/js/data_generation/domain/domainTestDataRuleValidator.js index eb016acf..51987ef7 100644 --- a/packages/core/js/data_generation/domain/domainTestDataRuleValidator.js +++ b/packages/core/js/data_generation/domain/domainTestDataRuleValidator.js @@ -1,12 +1,15 @@ +import { Faker } from '@faker-js/faker'; import { parseKeywordInvocation } from '../../domain/domain-keyword-parser.js'; import { DOMAIN_KEYWORD_ALIAS_INDEX, + executeDomainKeyword, getDomainKeywordByAlias, validateDomainKeywordArgs, } from '../../domain/domain-keywords.js'; class DomainTestDataRuleValidator { - constructor() { + constructor(aFaker = null) { + this.faker = aFaker; this.validationError = ''; this.lastParsed = null; } @@ -52,6 +55,24 @@ class DomainTestDataRuleValidator { return false; } + if ( + this.faker && + keywordDefinition.delegate?.type === 'faker' && + hasFakerDelegateTarget(this.faker, keywordDefinition.delegate?.target) + ) { + const validationFaker = createIsolatedFaker(this.faker); + try { + executeDomainKeyword(recognizedKeyword, { + faker: validationFaker, + args: parsed.args, + autoIncrementState: {}, + }); + } catch (error) { + this.validationError = error?.message || 'Domain keyword failed during validation'; + return false; + } + } + return true; } @@ -64,4 +85,24 @@ class DomainTestDataRuleValidator { } } +function createIsolatedFaker(fakerInstance) { + const rawDefinitions = fakerInstance?.rawDefinitions; + const isolatedFaker = new Faker({ locale: rawDefinitions }); + isolatedFaker.seed(1); + return isolatedFaker; +} + +function hasFakerDelegateTarget(fakerInstance, target) { + const parts = String(target || '') + .split('.') + .filter((part) => part.length > 0); + let node = fakerInstance; + + for (const part of parts) { + node = node?.[part]; + } + + return typeof node === 'function'; +} + export { DomainTestDataRuleValidator }; diff --git a/packages/core/js/data_generation/testDataRulesCompiler.js b/packages/core/js/data_generation/testDataRulesCompiler.js index bac47312..91111a9c 100644 --- a/packages/core/js/data_generation/testDataRulesCompiler.js +++ b/packages/core/js/data_generation/testDataRulesCompiler.js @@ -298,7 +298,7 @@ export class TestDataRulesCompiler { const fakerValidator = new FakerTestDataRuleValidator(this.faker, this.options); const regexValidator = new RegexTestDataRuleValidator(this.RandExp); const enumValidator = new EnumTestDataRuleValidator(); - const domainValidator = new DomainTestDataRuleValidator(); + const domainValidator = new DomainTestDataRuleValidator(this.faker); this.rules.forEach((rule) => { switch (rule.type) { diff --git a/packages/core/js/domain/domain-keyword-arg-validators.js b/packages/core/js/domain/domain-keyword-arg-validators.js index 63aae6da..40fd6375 100644 --- a/packages/core/js/domain/domain-keyword-arg-validators.js +++ b/packages/core/js/domain/domain-keyword-arg-validators.js @@ -79,4 +79,54 @@ function createNumericArgRangeValidator({ }; } -export { composeArgsValidators, createNumericArgRangeValidator, createOrderedArgsValidator }; +function createIntegerArgValidator({ argName } = {}) { + return (_args = [], context = {}) => { + const argsByName = context?.argsByName || {}; + const value = argsByName[argName]; + + if (typeof value === 'undefined') { + return { ok: true }; + } + + if (typeof value !== 'number' || !Number.isFinite(value)) { + return { ok: true }; + } + + if (!Number.isInteger(value)) { + return { + ok: false, + error: `Invalid keyword arguments: argument "${argName}" must be an integer`, + }; + } + + return { ok: true }; + }; +} + +function createNonEmptyArrayArgValidator({ argName } = {}) { + return (_args = [], context = {}) => { + const argsByName = context?.argsByName || {}; + const value = argsByName[argName]; + + if (typeof value === 'undefined' || !Array.isArray(value)) { + return { ok: true }; + } + + if (value.length === 0) { + return { + ok: false, + error: `Invalid keyword arguments: argument "${argName}" must not be empty`, + }; + } + + return { ok: true }; + }; +} + +export { + composeArgsValidators, + createIntegerArgValidator, + createNonEmptyArrayArgValidator, + createNumericArgRangeValidator, + createOrderedArgsValidator, +}; diff --git a/packages/core/js/domain/domain-keywords.js b/packages/core/js/domain/domain-keywords.js index 04f9cd3f..7d3a2e6c 100644 --- a/packages/core/js/domain/domain-keywords.js +++ b/packages/core/js/domain/domain-keywords.js @@ -121,6 +121,9 @@ function buildDomainKeywordCatalog(definitions = DOMAIN_KEYWORD_DEFINITIONS) { required: arg?.required === true, optional: arg?.optional === true || arg?.required === false, variadic: arg?.variadic === true, + ...(Object.prototype.hasOwnProperty.call(arg || {}, 'usageExampleSupported') + ? { usageExampleSupported: arg.usageExampleSupported !== false } + : {}), description: String(arg?.description || '').trim(), example: String(arg?.example || '').trim(), ...(Object.prototype.hasOwnProperty.call(arg || {}, 'defaultValue') @@ -279,6 +282,7 @@ function isTypeMatch(value, typeName) { for (const item of allowed) { if (/^[+-]?\d+(\.\d+)?$/.test(item) && typeof value === 'number' && Object.is(value, Number(item))) return true; if (item === 'string' && typeof value === 'string') return true; + if (item === 'bigint' && typeof value === 'bigint') return true; if (item === 'comma-separated list' && typeof value === 'string') return true; if (item === 'integer' && typeof value === 'number' && Number.isInteger(value)) return true; if (item === 'number' && typeof value === 'number' && Number.isFinite(value)) return true; @@ -371,6 +375,67 @@ function normaliseStringUuidOptions(options) { return options; } +function buildHelpArgsByName(keyword, args = []) { + const argSchema = Array.isArray(keyword?.help?.args) ? keyword.help.args : []; + const argsByName = {}; + + for (let index = 0; index < argSchema.length; index += 1) { + const key = String(argSchema[index]?.name || '').trim(); + if (!key || typeof args[index] === 'undefined') { + continue; + } + argsByName[key] = coerceHelpArgValue(argSchema[index], args[index]); + } + + return argsByName; +} + +function createLoremCountArg(min, max) { + if (typeof min !== 'undefined' && typeof max !== 'undefined') { + return { min, max }; + } + if (typeof max !== 'undefined') { + return { min: 1, max }; + } + if (typeof min !== 'undefined') { + return min; + } + return undefined; +} + +function getLoremCountArg(keyword, argsByName = {}) { + const argNames = (Array.isArray(keyword?.help?.args) ? keyword.help.args : []) + .map((arg) => String(arg?.name || '').trim()) + .filter(Boolean); + const countName = argNames.find((argName) => /Count$/.test(argName)); + + if (countName && typeof argsByName[countName] !== 'undefined') { + return argsByName[countName]; + } + + const specificMinName = countName ? `${countName}Min` : ''; + const specificMaxName = countName ? `${countName}Max` : ''; + if ( + specificMinName && + (typeof argsByName[specificMinName] !== 'undefined' || typeof argsByName[specificMaxName] !== 'undefined') + ) { + return createLoremCountArg(argsByName[specificMinName], argsByName[specificMaxName]); + } + + return createLoremCountArg(argsByName.min, argsByName.max); +} + +function applyLoremCountArgTransform(keyword, args = []) { + const argsByName = buildHelpArgsByName(keyword, args); + const countArg = getLoremCountArg(keyword, argsByName); + + if (Object.prototype.hasOwnProperty.call(argsByName, 'separator')) { + return [countArg, argsByName.separator]; + } + + return typeof countArg === 'undefined' ? [] : [countArg]; +} + function applyFakerArgTransform(keyword, args = []) { const transformName = String(keyword?.delegate?.argTransform || '').trim(); if (!transformName) { @@ -398,6 +463,12 @@ function applyFakerArgTransform(keyword, args = []) { } return Object.keys(options).length > 0 ? [options] : []; } + if (transformName === 'loremCountFromHelpArgs') { + if (!Array.isArray(args)) { + return args; + } + return applyLoremCountArgTransform(keyword, args); + } return args; } diff --git a/packages/core/js/faker/faker-helper-keyword-definitions.js b/packages/core/js/faker/faker-helper-keyword-definitions.js index aed8925b..0960e157 100644 --- a/packages/core/js/faker/faker-helper-keyword-definitions.js +++ b/packages/core/js/faker/faker-helper-keyword-definitions.js @@ -107,6 +107,9 @@ function mapDomainKeywordHelpToFakerCommandHelp(commandHelp) { type: arg.type, description: arg.description || '', examples: Array.isArray(arg.examples) ? arg.examples : [], + ...(Object.prototype.hasOwnProperty.call(arg || {}, 'usageExampleSupported') + ? { usageExampleSupported: arg.usageExampleSupported !== false } + : {}), })) : []; const returnType = commandHelp.returnType || ''; diff --git a/packages/core/js/keywords/domain/airline/flight-number-keyword-definition.js b/packages/core/js/keywords/domain/airline/flight-number-keyword-definition.js index 0c91aab2..df25e7a0 100644 --- a/packages/core/js/keywords/domain/airline/flight-number-keyword-definition.js +++ b/packages/core/js/keywords/domain/airline/flight-number-keyword-definition.js @@ -1,10 +1,14 @@ import { validateFlightNumberValue } from '../../../command-help/command-help-validators.js'; +import { createPositiveIntegerArgsValidator } from '../shared/common-arg-validators.js'; + +const validateAirlineFlightNumberArgs = createPositiveIntegerArgsValidator(['length']); const AIRLINE_FLIGHT_NUMBER_KEYWORD_DEFINITION = { keyword: 'airline.flightNumber', delegate: { type: 'faker', target: 'airline.flightNumber', + argTransform: 'optionsFromHelpArgs', }, help: { summary: @@ -12,15 +16,46 @@ const AIRLINE_FLIGHT_NUMBER_KEYWORD_DEFINITION = { docsUrl: 'https://anywaydata.com/docs/test-data/domain/airline', fakerDocsUrl: 'https://fakerjs.dev/api/airline', validator: validateFlightNumberValue, + argsValidator: validateAirlineFlightNumberArgs, returnType: 'string', usageExamples: [ { - functionCall: 'airline.flightNumber', + functionCall: 'airline.flightNumber()', sampleReturnValue: '70', description: 'Shows the default airline.flightNumber call.', }, + { + functionCall: 'airline.flightNumber(length=4, addLeadingZeros=true)', + sampleReturnValue: '4703', + description: 'Shows airline.flightNumber using length and leading-zero options.', + }, + { + functionCall: 'airline.flightNumber(length=4)', + sampleReturnValue: '4703', + description: 'Shows airline.flightNumber using a fixed length.', + }, + { + functionCall: 'airline.flightNumber(addLeadingZeros=true)', + sampleReturnValue: '0070', + description: 'Shows airline.flightNumber padding shorter values with leading zeros.', + }, + ], + args: [ + { + name: 'length', + type: 'number', + required: false, + description: 'Desired flight-number length.', + examples: [4], + }, + { + name: 'addLeadingZeros', + type: 'boolean', + required: false, + description: 'Whether shorter flight numbers should be padded with leading zeros.', + examples: [true], + }, ], - args: [], }, }; diff --git a/packages/core/js/keywords/domain/airline/record-locator-keyword-definition.js b/packages/core/js/keywords/domain/airline/record-locator-keyword-definition.js index fb3c984a..441bedfc 100644 --- a/packages/core/js/keywords/domain/airline/record-locator-keyword-definition.js +++ b/packages/core/js/keywords/domain/airline/record-locator-keyword-definition.js @@ -5,6 +5,7 @@ const AIRLINE_RECORD_LOCATOR_KEYWORD_DEFINITION = { delegate: { type: 'faker', target: 'airline.recordLocator', + argTransform: 'optionsFromHelpArgs', }, help: { summary: 'Generates a random record locator. Record locators are 6-character alphanumeric booking references.', @@ -14,12 +15,37 @@ const AIRLINE_RECORD_LOCATOR_KEYWORD_DEFINITION = { returnType: 'string', usageExamples: [ { - functionCall: 'airline.recordLocator', + functionCall: 'airline.recordLocator()', sampleReturnValue: 'KTAGDC', description: 'Shows the default airline.recordLocator call.', }, + { + functionCall: 'airline.recordLocator(allowNumerics=true)', + sampleReturnValue: 'ER2B64', + description: 'Shows airline.recordLocator allowing numeric characters.', + }, + { + functionCall: 'airline.recordLocator(allowVisuallySimilarCharacters=true)', + sampleReturnValue: 'KSAHDC', + description: 'Shows airline.recordLocator allowing visually similar characters.', + }, + ], + args: [ + { + name: 'allowNumerics', + type: 'boolean', + required: false, + description: 'Whether numeric characters can be included.', + examples: [true], + }, + { + name: 'allowVisuallySimilarCharacters', + type: 'boolean', + required: false, + description: 'Whether visually similar characters such as I, 1, O, and 0 can be included.', + examples: [true], + }, ], - args: [], }, }; diff --git a/packages/core/js/keywords/domain/date/betweens-keyword-definition.js b/packages/core/js/keywords/domain/date/betweens-keyword-definition.js index 01c07545..cc4e1b1f 100644 --- a/packages/core/js/keywords/domain/date/betweens-keyword-definition.js +++ b/packages/core/js/keywords/domain/date/betweens-keyword-definition.js @@ -1,7 +1,11 @@ import { validateArrayValue } from '../../../command-help/command-help-validators.js'; -import { createOrderedArgsValidator } from '../../../domain/domain-keyword-arg-validators.js'; +import { composeArgsValidators, createOrderedArgsValidator } from '../../../domain/domain-keyword-arg-validators.js'; +import { createPositiveIntegerArgsValidator } from '../shared/common-arg-validators.js'; -const validateDateBetweensBounds = createOrderedArgsValidator({ lowerName: 'from', upperName: 'to' }); +const validateDateBetweensBounds = composeArgsValidators( + createPositiveIntegerArgsValidator(['count']), + createOrderedArgsValidator({ lowerName: 'from', upperName: 'to' }) +); const DATE_BETWEENS_KEYWORD_DEFINITION = { keyword: 'date.betweens', diff --git a/packages/core/js/keywords/domain/finance/account-number-keyword-definition.js b/packages/core/js/keywords/domain/finance/account-number-keyword-definition.js index 5becfc2d..b23f0dca 100644 --- a/packages/core/js/keywords/domain/finance/account-number-keyword-definition.js +++ b/packages/core/js/keywords/domain/finance/account-number-keyword-definition.js @@ -1,4 +1,7 @@ import { validateAccountNumberValue } from '../../../command-help/command-help-validators.js'; +import { createPositiveIntegerArgsValidator } from '../shared/common-arg-validators.js'; + +const validateFinanceAccountNumberArgs = createPositiveIntegerArgsValidator(['length']); const FINANCE_ACCOUNT_NUMBER_KEYWORD_DEFINITION = { keyword: 'finance.accountNumber', @@ -11,6 +14,7 @@ const FINANCE_ACCOUNT_NUMBER_KEYWORD_DEFINITION = { docsUrl: 'https://anywaydata.com/docs/test-data/domain/finance', fakerDocsUrl: 'https://fakerjs.dev/api/finance', validator: validateAccountNumberValue, + argsValidator: validateFinanceAccountNumberArgs, returnType: 'string', usageExamples: [ { diff --git a/packages/core/js/keywords/domain/finance/pin-keyword-definition.js b/packages/core/js/keywords/domain/finance/pin-keyword-definition.js index 3f12b9b1..ee97814b 100644 --- a/packages/core/js/keywords/domain/finance/pin-keyword-definition.js +++ b/packages/core/js/keywords/domain/finance/pin-keyword-definition.js @@ -1,4 +1,7 @@ import { validatePinValue } from '../../../command-help/command-help-validators.js'; +import { createPositiveIntegerArgsValidator } from '../shared/common-arg-validators.js'; + +const validateFinancePinArgs = createPositiveIntegerArgsValidator(['length']); const FINANCE_PIN_KEYWORD_DEFINITION = { keyword: 'finance.pin', @@ -11,6 +14,7 @@ const FINANCE_PIN_KEYWORD_DEFINITION = { docsUrl: 'https://anywaydata.com/docs/test-data/domain/finance', fakerDocsUrl: 'https://fakerjs.dev/api/finance', validator: validatePinValue, + argsValidator: validateFinancePinArgs, returnType: 'string', usageExamples: [ { diff --git a/packages/core/js/keywords/domain/git/commit-date-keyword-definition.js b/packages/core/js/keywords/domain/git/commit-date-keyword-definition.js index bad1ad90..7dcc7003 100644 --- a/packages/core/js/keywords/domain/git/commit-date-keyword-definition.js +++ b/packages/core/js/keywords/domain/git/commit-date-keyword-definition.js @@ -5,6 +5,7 @@ const GIT_COMMIT_DATE_KEYWORD_DEFINITION = { delegate: { type: 'faker', target: 'git.commitDate', + argTransform: 'optionsFromHelpArgs', }, help: { summary: 'Generates a date string for a git commit using the same format as `git log`.', @@ -14,12 +15,25 @@ const GIT_COMMIT_DATE_KEYWORD_DEFINITION = { returnType: 'string', usageExamples: [ { - functionCall: 'git.commitDate', + functionCall: 'git.commitDate()', sampleReturnValue: 'Thu Jun 18 01:55:50 2026 +0600', description: 'Shows the default git.commitDate call.', }, + { + functionCall: 'git.commitDate(refDate="2024-01-01T00:00:00.000Z")', + sampleReturnValue: 'Sun Dec 31 10:00:30 2023 +0600', + description: 'Shows git.commitDate using a reference date.', + }, + ], + args: [ + { + name: 'refDate', + type: 'string|date|number', + required: false, + description: 'The date to use as reference point for generated commit dates.', + examples: ['2024-01-01T00:00:00.000Z'], + }, ], - args: [], }, }; diff --git a/packages/core/js/keywords/domain/git/commit-entry-keyword-definition.js b/packages/core/js/keywords/domain/git/commit-entry-keyword-definition.js index 83969bb0..5f931899 100644 --- a/packages/core/js/keywords/domain/git/commit-entry-keyword-definition.js +++ b/packages/core/js/keywords/domain/git/commit-entry-keyword-definition.js @@ -5,6 +5,7 @@ const GIT_COMMIT_ENTRY_KEYWORD_DEFINITION = { delegate: { type: 'faker', target: 'git.commitEntry', + argTransform: 'optionsFromHelpArgs', }, help: { summary: 'Generates a random commit entry as printed by `git log`.', @@ -14,7 +15,7 @@ const GIT_COMMIT_ENTRY_KEYWORD_DEFINITION = { returnType: 'string', usageExamples: [ { - functionCall: 'git.commitEntry', + functionCall: 'git.commitEntry()', sampleReturnValue: 'commit f0632478b9f4d0e9c34bf6fdd103d29fbf6fc0af\r\n' + 'Author: Ricardo Upton \r\n' + @@ -23,8 +24,72 @@ const GIT_COMMIT_ENTRY_KEYWORD_DEFINITION = { '    parse auxiliary feed\r\n', description: 'Shows the default git.commitEntry call.', }, + { + functionCall: 'git.commitEntry(merge=true, eol="LF")', + sampleReturnValue: + 'commit 9f0632478b9f4d0e9c34bf6fdd103d29fbf6fc0a\n' + + 'Merge: fa6b29d 6620e45\n' + + 'Author: Lindsey_Price41 \n' + + 'Date: Thu Jun 18 13:36:13 2026 -0800\n' + + '\n' + + '    calculate redundant feed\n', + description: 'Shows git.commitEntry using merge and line-ending options.', + }, + { + functionCall: 'git.commitEntry(refDate="2024-01-01T00:00:00.000Z")', + sampleReturnValue: + 'commit f0632478b9f4d0e9c34bf6fdd103d29fbf6fc0af\r\n' + + 'Author: Ricardo Upton \r\n' + + 'Date: Sun Dec 31 03:31:17 2023 +0300\r\n' + + '\r\n' + + '    parse auxiliary feed\r\n', + description: 'Shows git.commitEntry using a reference date.', + }, + { + functionCall: 'git.commitEntry(merge=true)', + sampleReturnValue: + 'commit 9f0632478b9f4d0e9c34bf6fdd103d29fbf6fc0a\r\n' + + 'Merge: fa6b29d 6620e45\r\n' + + 'Author: Lindsey_Price41 \r\n' + + 'Date: Thu Jun 18 13:36:13 2026 -0800\r\n' + + '\r\n' + + '    calculate redundant feed\r\n', + description: 'Shows git.commitEntry forcing a merge commit entry.', + }, + { + functionCall: 'git.commitEntry(eol="LF")', + sampleReturnValue: + 'commit f0632478b9f4d0e9c34bf6fdd103d29fbf6fc0af\n' + + 'Author: Ricardo Upton \n' + + 'Date: Wed Jun 17 19:26:37 2026 +0300\n' + + '\n' + + '    parse auxiliary feed\n', + description: 'Shows git.commitEntry using LF line endings.', + }, + ], + args: [ + { + name: 'merge', + type: 'boolean', + required: false, + description: 'Whether to generate a merge commit entry.', + examples: [true], + }, + { + name: 'eol', + type: 'LF|CRLF', + required: false, + description: 'Line ending to use in the generated commit entry.', + examples: ['LF'], + }, + { + name: 'refDate', + type: 'string|date|number', + required: false, + description: 'The date to use as reference point for generated commit dates.', + examples: ['2024-01-01T00:00:00.000Z'], + }, ], - args: [], }, }; diff --git a/packages/core/js/keywords/domain/git/commit-sha-keyword-definition.js b/packages/core/js/keywords/domain/git/commit-sha-keyword-definition.js index 672939e4..7d55d2f2 100644 --- a/packages/core/js/keywords/domain/git/commit-sha-keyword-definition.js +++ b/packages/core/js/keywords/domain/git/commit-sha-keyword-definition.js @@ -1,25 +1,43 @@ import { validateStringValue } from '../../../command-help/command-help-validators.js'; +import { createPositiveIntegerArgsValidator } from '../shared/common-arg-validators.js'; + +const validateGitCommitShaArgs = createPositiveIntegerArgsValidator(['length']); const GIT_COMMIT_SHA_KEYWORD_DEFINITION = { keyword: 'git.commitSha', delegate: { type: 'faker', target: 'git.commitSha', + argTransform: 'optionsFromHelpArgs', }, help: { summary: 'Generates a random commit sha.', docsUrl: 'https://anywaydata.com/docs/test-data/domain/git', fakerDocsUrl: 'https://fakerjs.dev/api/git', validator: validateStringValue, + argsValidator: validateGitCommitShaArgs, returnType: 'string', usageExamples: [ { - functionCall: 'git.commitSha', + functionCall: 'git.commitSha()', sampleReturnValue: '9f0632478b9f4d0e9c34bf6fdd103d29fbf6fc0a', description: 'Shows the default git.commitSha call.', }, + { + functionCall: 'git.commitSha(length=7)', + sampleReturnValue: '9f06324', + description: 'Shows git.commitSha using a shorter SHA length.', + }, + ], + args: [ + { + name: 'length', + type: 'number', + required: false, + description: 'The length of the generated commit SHA.', + examples: [7], + }, ], - args: [], }, }; diff --git a/packages/core/js/keywords/domain/image/data-uri-keyword-definition.js b/packages/core/js/keywords/domain/image/data-uri-keyword-definition.js index fd3da1f7..a4cc4887 100644 --- a/packages/core/js/keywords/domain/image/data-uri-keyword-definition.js +++ b/packages/core/js/keywords/domain/image/data-uri-keyword-definition.js @@ -1,26 +1,90 @@ import { validateStringValue } from '../../../command-help/command-help-validators.js'; +import { createPositiveIntegerArgsValidator } from '../shared/common-arg-validators.js'; + +const validateImageDataUriArgs = createPositiveIntegerArgsValidator(['width', 'height']); const IMAGE_DATA_URI_KEYWORD_DEFINITION = { keyword: 'image.dataUri', delegate: { type: 'faker', target: 'image.dataUri', + argTransform: 'optionsFromHelpArgs', }, help: { summary: 'Generates a random data uri containing an URL-encoded SVG image or a Base64-encoded SVG image.', docsUrl: 'https://anywaydata.com/docs/test-data/domain/image', fakerDocsUrl: 'https://fakerjs.dev/api/image', validator: validateStringValue, + argsValidator: validateImageDataUriArgs, returnType: 'string', usageExamples: [ { - functionCall: 'image.dataUri', + functionCall: 'image.dataUri()', sampleReturnValue: 'data:image/svg+xml;charset=UTF-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20version%3D%221.1%22%20baseProfile%3D%22full%22%20width%3D%221668%22%20height%3D%222881%22%3E%3Crect%20width%3D%22100%25%22%20height%3D%22100%25%22%20fill%3D%22%23063247%22%2F%3E%3Ctext%20x%3D%22834%22%20y%3D%221440.5%22%20font-size%3D%2220%22%20alignment-baseline%3D%22middle%22%20text-anchor%3D%22middle%22%20fill%3D%22white%22%3E1668x2881%3C%2Ftext%3E%3C%2Fsvg%3E', description: 'Shows the default image.dataUri call.', }, + { + functionCall: 'image.dataUri(width=320, height=240, color="red", type="svg-base64")', + sampleReturnValue: + 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZlcnNpb249IjEuMSIgYmFzZVByb2ZpbGU9ImZ1bGwiIHdpZHRoPSIzMjAiIGhlaWdodD0iMjQwIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJyZWQiLz48dGV4dCB4PSIxNjAiIHk9IjEyMCIgZm9udC1zaXplPSIyMCIgYWxpZ25tZW50LWJhc2VsaW5lPSJtaWRkbGUiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZpbGw9IndoaXRlIj4zMjB4MjQwPC90ZXh0Pjwvc3ZnPg==', + description: 'Shows image.dataUri using explicit image dimensions, color, and encoding type.', + }, + { + functionCall: 'image.dataUri(width=320)', + sampleReturnValue: + 'data:image/svg+xml;charset=UTF-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20version%3D%221.1%22%20baseProfile%3D%22full%22%20width%3D%22320%22%20height%3D%221668%22%3E%3Crect%20width%3D%22100%25%22%20height%3D%22100%25%22%20fill%3D%22%23f06324%22%2F%3E%3Ctext%20x%3D%22160%22%20y%3D%22834%22%20font-size%3D%2220%22%20alignment-baseline%3D%22middle%22%20text-anchor%3D%22middle%22%20fill%3D%22white%22%3E320x1668%3C%2Ftext%3E%3C%2Fsvg%3E', + description: 'Shows image.dataUri using an explicit width.', + }, + { + functionCall: 'image.dataUri(height=240)', + sampleReturnValue: + 'data:image/svg+xml;charset=UTF-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20version%3D%221.1%22%20baseProfile%3D%22full%22%20width%3D%221668%22%20height%3D%22240%22%3E%3Crect%20width%3D%22100%25%22%20height%3D%22100%25%22%20fill%3D%22%23f06324%22%2F%3E%3Ctext%20x%3D%22834%22%20y%3D%22120%22%20font-size%3D%2220%22%20alignment-baseline%3D%22middle%22%20text-anchor%3D%22middle%22%20fill%3D%22white%22%3E1668x240%3C%2Ftext%3E%3C%2Fsvg%3E', + description: 'Shows image.dataUri using an explicit height.', + }, + { + functionCall: 'image.dataUri(color="red")', + sampleReturnValue: + 'data:image/svg+xml;charset=UTF-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20version%3D%221.1%22%20baseProfile%3D%22full%22%20width%3D%221668%22%20height%3D%222881%22%3E%3Crect%20width%3D%22100%25%22%20height%3D%22100%25%22%20fill%3D%22red%22%2F%3E%3Ctext%20x%3D%22834%22%20y%3D%221440.5%22%20font-size%3D%2220%22%20alignment-baseline%3D%22middle%22%20text-anchor%3D%22middle%22%20fill%3D%22white%22%3E1668x2881%3C%2Ftext%3E%3C%2Fsvg%3E', + description: 'Shows image.dataUri using an explicit SVG fill color.', + }, + { + functionCall: 'image.dataUri(type="svg-base64")', + sampleReturnValue: + 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZlcnNpb249IjEuMSIgYmFzZVByb2ZpbGU9ImZ1bGwiIHdpZHRoPSIxNjY4IiBoZWlnaHQ9IjI4ODEiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiMwNjMyNDciLz48dGV4dCB4PSI4MzQiIHk9IjE0NDAuNSIgZm9udC1zaXplPSIyMCIgYWxpZ25tZW50LWJhc2VsaW5lPSJtaWRkbGUiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZpbGw9IndoaXRlIj4xNjY4eDI4ODE8L3RleHQ+PC9zdmc+', + description: 'Shows image.dataUri using Base64 SVG encoding.', + }, + ], + args: [ + { + name: 'width', + type: 'number', + required: false, + description: 'Width of the generated image.', + examples: [320], + }, + { + name: 'height', + type: 'number', + required: false, + description: 'Height of the generated image.', + examples: [240], + }, + { + name: 'color', + type: 'string', + required: false, + description: 'Fill color for the generated SVG image.', + examples: ['red'], + }, + { + name: 'type', + type: 'svg-uri|svg-base64', + required: false, + description: 'Encoding format for the generated SVG data URI.', + examples: ['svg-base64'], + }, ], - args: [], }, }; diff --git a/packages/core/js/keywords/domain/image/person-portrait-keyword-definition.js b/packages/core/js/keywords/domain/image/person-portrait-keyword-definition.js index 1a43867b..a591d34e 100644 --- a/packages/core/js/keywords/domain/image/person-portrait-keyword-definition.js +++ b/packages/core/js/keywords/domain/image/person-portrait-keyword-definition.js @@ -5,6 +5,7 @@ const IMAGE_PERSON_PORTRAIT_KEYWORD_DEFINITION = { delegate: { type: 'faker', target: 'image.personPortrait', + argTransform: 'optionsFromHelpArgs', }, help: { summary: 'Generates a random square portrait (avatar) of a person.', @@ -14,12 +15,42 @@ const IMAGE_PERSON_PORTRAIT_KEYWORD_DEFINITION = { returnType: 'string', usageExamples: [ { - functionCall: 'image.personPortrait', + functionCall: 'image.personPortrait()', sampleReturnValue: 'https://cdn.jsdelivr.net/gh/faker-js/assets-person-portrait/female/512/72.jpg', description: 'Shows the default image.personPortrait call.', }, + { + functionCall: 'image.personPortrait(sex="female", size=128)', + sampleReturnValue: 'https://cdn.jsdelivr.net/gh/faker-js/assets-person-portrait/female/128/41.jpg', + description: 'Shows image.personPortrait using sex and size options.', + }, + { + functionCall: 'image.personPortrait(sex="female")', + sampleReturnValue: 'https://cdn.jsdelivr.net/gh/faker-js/assets-person-portrait/female/512/41.jpg', + description: 'Shows image.personPortrait using a sex category.', + }, + { + functionCall: 'image.personPortrait(size=128)', + sampleReturnValue: 'https://cdn.jsdelivr.net/gh/faker-js/assets-person-portrait/female/128/72.jpg', + description: 'Shows image.personPortrait using an explicit image size.', + }, + ], + args: [ + { + name: 'sex', + type: 'female|generic|male', + required: false, + description: 'Sex category used for the generated portrait.', + examples: ['female'], + }, + { + name: 'size', + type: '512|256|128|64|32', + required: false, + description: 'Square image size in pixels.', + examples: [128], + }, ], - args: [], }, }; diff --git a/packages/core/js/keywords/domain/image/url-keyword-definition.js b/packages/core/js/keywords/domain/image/url-keyword-definition.js index 70810d2f..71d58d8a 100644 --- a/packages/core/js/keywords/domain/image/url-keyword-definition.js +++ b/packages/core/js/keywords/domain/image/url-keyword-definition.js @@ -1,4 +1,7 @@ import { validateStringValue } from '../../../command-help/command-help-validators.js'; +import { createPositiveIntegerArgsValidator } from '../shared/common-arg-validators.js'; + +const validateImageUrlArgs = createPositiveIntegerArgsValidator(['height', 'width']); const IMAGE_URL_KEYWORD_DEFINITION = { keyword: 'image.url', @@ -12,6 +15,7 @@ const IMAGE_URL_KEYWORD_DEFINITION = { docsUrl: 'https://anywaydata.com/docs/test-data/domain/image', fakerDocsUrl: 'https://fakerjs.dev/api/image', validator: validateStringValue, + argsValidator: validateImageUrlArgs, returnType: 'string', usageExamples: [ { diff --git a/packages/core/js/keywords/domain/image/url-picsum-photos-keyword-definition.js b/packages/core/js/keywords/domain/image/url-picsum-photos-keyword-definition.js index 9144c887..a365fe42 100644 --- a/packages/core/js/keywords/domain/image/url-picsum-photos-keyword-definition.js +++ b/packages/core/js/keywords/domain/image/url-picsum-photos-keyword-definition.js @@ -1,25 +1,84 @@ import { validateStringValue } from '../../../command-help/command-help-validators.js'; +import { createPositiveIntegerArgsValidator } from '../shared/common-arg-validators.js'; + +const validateImageUrlPicsumPhotosArgs = createPositiveIntegerArgsValidator(['width', 'height']); const IMAGE_URL_PICSUM_PHOTOS_KEYWORD_DEFINITION = { keyword: 'image.urlPicsumPhotos', delegate: { type: 'faker', target: 'image.urlPicsumPhotos', + argTransform: 'optionsFromHelpArgs', }, help: { summary: 'Generates a random image url provided via https://picsum.photos.', docsUrl: 'https://anywaydata.com/docs/test-data/domain/image', fakerDocsUrl: 'https://fakerjs.dev/api/image', validator: validateStringValue, + argsValidator: validateImageUrlPicsumPhotosArgs, returnType: 'string', usageExamples: [ { - functionCall: 'image.urlPicsumPhotos', + functionCall: 'image.urlPicsumPhotos()', sampleReturnValue: 'https://picsum.photos/seed/5blox/1668/2881?grayscale&blur=3', description: 'Shows the default image.urlPicsumPhotos call.', }, + { + functionCall: 'image.urlPicsumPhotos(width=320, height=240, grayscale=true, blur=3)', + sampleReturnValue: 'https://picsum.photos/seed/I0i95bl/320/240?grayscale&blur=3', + description: 'Shows image.urlPicsumPhotos using dimension and filter options.', + }, + { + functionCall: 'image.urlPicsumPhotos(width=320)', + sampleReturnValue: 'https://picsum.photos/seed/95blox/320/1668', + description: 'Shows image.urlPicsumPhotos using an explicit width.', + }, + { + functionCall: 'image.urlPicsumPhotos(height=240)', + sampleReturnValue: 'https://picsum.photos/seed/95blox/1668/240', + description: 'Shows image.urlPicsumPhotos using an explicit height.', + }, + { + functionCall: 'image.urlPicsumPhotos(grayscale=true)', + sampleReturnValue: 'https://picsum.photos/seed/95blox/1668/2881?grayscale', + description: 'Shows image.urlPicsumPhotos requesting a grayscale image.', + }, + { + functionCall: 'image.urlPicsumPhotos(blur=3)', + sampleReturnValue: 'https://picsum.photos/seed/95blox/1668/2881?grayscale&blur=3', + description: 'Shows image.urlPicsumPhotos requesting a blur amount.', + }, + ], + args: [ + { + name: 'width', + type: 'number', + required: false, + description: 'Width of the generated image URL.', + examples: [320], + }, + { + name: 'height', + type: 'number', + required: false, + description: 'Height of the generated image URL.', + examples: [240], + }, + { + name: 'grayscale', + type: 'boolean', + required: false, + description: 'Whether the generated image URL should request a grayscale image.', + examples: [true], + }, + { + name: 'blur', + type: '0|1|2|3|4|5|6|7|8|9|10', + required: false, + description: 'Blur amount for the generated image URL.', + examples: [3], + }, ], - args: [], }, }; diff --git a/packages/core/js/keywords/domain/internet/display-name-keyword-definition.js b/packages/core/js/keywords/domain/internet/display-name-keyword-definition.js index 08c460ba..698f9fc1 100644 --- a/packages/core/js/keywords/domain/internet/display-name-keyword-definition.js +++ b/packages/core/js/keywords/domain/internet/display-name-keyword-definition.js @@ -5,6 +5,7 @@ const INTERNET_DISPLAY_NAME_KEYWORD_DEFINITION = { delegate: { type: 'faker', target: 'internet.displayName', + argTransform: 'optionsFromHelpArgs', }, help: { summary: "Generates a display name using the given person's name as base.", @@ -14,12 +15,42 @@ const INTERNET_DISPLAY_NAME_KEYWORD_DEFINITION = { returnType: 'string', usageExamples: [ { - functionCall: 'internet.displayName', + functionCall: 'internet.displayName()', sampleReturnValue: 'Aaliyah.Bosco', description: 'Shows the default internet.displayName call.', }, + { + functionCall: 'internet.displayName(firstName="Ada", lastName="Lovelace")', + sampleReturnValue: 'Ada72', + description: 'Shows internet.displayName using firstName and lastName options.', + }, + { + functionCall: 'internet.displayName(firstName="Ada")', + sampleReturnValue: 'Ada14', + description: 'Shows internet.displayName using an explicit first name.', + }, + { + functionCall: 'internet.displayName(lastName="Lovelace")', + sampleReturnValue: 'Aaliyah14', + description: 'Shows internet.displayName using an explicit last name.', + }, + ], + args: [ + { + name: 'firstName', + type: 'string', + required: false, + description: 'Optional first name to use as the basis for the display name.', + examples: ['Ada'], + }, + { + name: 'lastName', + type: 'string', + required: false, + description: 'Optional last name to use as the basis for the display name.', + examples: ['Lovelace'], + }, ], - args: [], }, }; diff --git a/packages/core/js/keywords/domain/internet/example-email-keyword-definition.js b/packages/core/js/keywords/domain/internet/example-email-keyword-definition.js index 6fc8c677..0bac6c8e 100644 --- a/packages/core/js/keywords/domain/internet/example-email-keyword-definition.js +++ b/packages/core/js/keywords/domain/internet/example-email-keyword-definition.js @@ -5,6 +5,7 @@ const INTERNET_EXAMPLE_EMAIL_KEYWORD_DEFINITION = { delegate: { type: 'faker', target: 'internet.exampleEmail', + argTransform: 'optionsFromHelpArgs', }, help: { summary: 'Generates data using faker internet example email.', @@ -14,12 +15,54 @@ const INTERNET_EXAMPLE_EMAIL_KEYWORD_DEFINITION = { returnType: 'string', usageExamples: [ { - functionCall: 'internet.exampleEmail', + functionCall: 'internet.exampleEmail()', sampleReturnValue: 'Edwin.Dibbert@example.net', description: 'Shows the default internet.exampleEmail call.', }, + { + functionCall: 'internet.exampleEmail(firstName="Ada", lastName="Lovelace")', + sampleReturnValue: 'Ada_Lovelace0@example.net', + description: 'Shows internet.exampleEmail using firstName and lastName options.', + }, + { + functionCall: 'internet.exampleEmail(allowSpecialCharacters=true)', + sampleReturnValue: 'Edwin.Dibbert@example.net', + description: 'Shows internet.exampleEmail allowing special characters.', + }, + { + functionCall: 'internet.exampleEmail(firstName="Ada")', + sampleReturnValue: 'Ada.Gutmann9@example.net', + description: 'Shows internet.exampleEmail using an explicit first name.', + }, + { + functionCall: 'internet.exampleEmail(lastName="Lovelace")', + sampleReturnValue: 'Edwin.Lovelace9@example.net', + description: 'Shows internet.exampleEmail using an explicit last name.', + }, + ], + args: [ + { + name: 'firstName', + type: 'string', + required: false, + description: 'Optional first name to use as the basis for the email address.', + examples: ['Ada'], + }, + { + name: 'lastName', + type: 'string', + required: false, + description: 'Optional last name to use as the basis for the email address.', + examples: ['Lovelace'], + }, + { + name: 'allowSpecialCharacters', + type: 'boolean', + required: false, + description: 'Whether special characters are allowed in the generated email address.', + examples: [true], + }, ], - args: [], }, }; diff --git a/packages/core/js/keywords/domain/internet/http-status-code-keyword-definition.js b/packages/core/js/keywords/domain/internet/http-status-code-keyword-definition.js index de5af63d..2639a8d7 100644 --- a/packages/core/js/keywords/domain/internet/http-status-code-keyword-definition.js +++ b/packages/core/js/keywords/domain/internet/http-status-code-keyword-definition.js @@ -1,25 +1,74 @@ import { validateNumberValue } from '../../../command-help/command-help-validators.js'; +import { + composeArgsValidators, + createNonEmptyArrayArgValidator, +} from '../../../domain/domain-keyword-arg-validators.js'; + +const HTTP_STATUS_CODE_TYPES = ['informational', 'success', 'redirection', 'clientError', 'serverError']; + +function validateHttpStatusCodeTypes(_args = [], context = {}) { + const types = context?.argsByName?.types; + if (typeof types === 'undefined') { + return { ok: true }; + } + if (!Array.isArray(types)) { + return { ok: true }; + } + + const invalidType = types.find((type) => !HTTP_STATUS_CODE_TYPES.includes(type)); + if (typeof invalidType !== 'undefined') { + return { + ok: false, + error: `Invalid keyword arguments: argument "types" contains unsupported value "${String( + invalidType + )}". Allowed values are ${HTTP_STATUS_CODE_TYPES.join(', ')}`, + }; + } + + return { ok: true }; +} + +const validateHttpStatusCodeArgs = composeArgsValidators( + createNonEmptyArrayArgValidator({ argName: 'types' }), + validateHttpStatusCodeTypes +); const INTERNET_HTTP_STATUS_CODE_KEYWORD_DEFINITION = { keyword: 'internet.httpStatusCode', delegate: { type: 'faker', target: 'internet.httpStatusCode', + argTransform: 'optionsFromHelpArgs', }, help: { summary: 'Generates a random HTTP status code.', docsUrl: 'https://anywaydata.com/docs/test-data/domain/internet', fakerDocsUrl: 'https://fakerjs.dev/api/internet', validator: validateNumberValue, + argsValidator: validateHttpStatusCodeArgs, returnType: 'number', usageExamples: [ { - functionCall: 'internet.httpStatusCode', + functionCall: 'internet.httpStatusCode()', sampleReturnValue: 306, description: 'Shows the default internet.httpStatusCode call.', }, + { + functionCall: 'internet.httpStatusCode(types=["success"])', + sampleReturnValue: 204, + description: 'Shows internet.httpStatusCode constrained to success status codes.', + }, + ], + args: [ + { + name: 'types', + type: 'array', + required: false, + description: + 'HTTP status categories to choose from. Allowed categories are informational, success, redirection, clientError, and serverError.', + examples: [['success']], + }, ], - args: [], }, }; diff --git a/packages/core/js/keywords/domain/internet/password-keyword-definition.js b/packages/core/js/keywords/domain/internet/password-keyword-definition.js index ccbb3a23..976ea430 100644 --- a/packages/core/js/keywords/domain/internet/password-keyword-definition.js +++ b/packages/core/js/keywords/domain/internet/password-keyword-definition.js @@ -1,4 +1,7 @@ import { validateStringValue } from '../../../command-help/command-help-validators.js'; +import { createPositiveIntegerArgsValidator } from '../shared/common-arg-validators.js'; + +const validateInternetPasswordArgs = createPositiveIntegerArgsValidator(['length']); const INTERNET_PASSWORD_KEYWORD_DEFINITION = { keyword: 'internet.password', @@ -13,6 +16,7 @@ const INTERNET_PASSWORD_KEYWORD_DEFINITION = { docsUrl: 'https://anywaydata.com/docs/test-data/domain/internet', fakerDocsUrl: 'https://fakerjs.dev/api/internet', validator: validateStringValue, + argsValidator: validateInternetPasswordArgs, returnType: 'string', usageExamples: [ { diff --git a/packages/core/js/keywords/domain/location/zip-code-keyword-definition.js b/packages/core/js/keywords/domain/location/zip-code-keyword-definition.js index fb5b1ae1..a3fade4e 100644 --- a/packages/core/js/keywords/domain/location/zip-code-keyword-definition.js +++ b/packages/core/js/keywords/domain/location/zip-code-keyword-definition.js @@ -5,6 +5,7 @@ const LOCATION_ZIP_CODE_KEYWORD_DEFINITION = { delegate: { type: 'faker', target: 'location.zipCode', + argTransform: 'optionsFromHelpArgs', }, help: { summary: 'Generates data using faker location zip code.', @@ -14,12 +15,33 @@ const LOCATION_ZIP_CODE_KEYWORD_DEFINITION = { returnType: 'string', usageExamples: [ { - functionCall: 'location.zipCode', + functionCall: 'location.zipCode()', sampleReturnValue: '70310', description: 'Shows the default location.zipCode call.', }, + { + functionCall: 'location.zipCode(format="#####")', + sampleReturnValue: '47031', + description: 'Shows location.zipCode using a format option.', + }, + ], + args: [ + { + name: 'state', + type: 'string', + required: false, + usageExampleSupported: false, + description: 'State abbreviation used to constrain the generated zip code where supported by the locale.', + examples: ['CA'], + }, + { + name: 'format', + type: 'string', + required: false, + description: 'Format pattern used for the generated zip code.', + examples: ['#####'], + }, ], - args: [], }, }; diff --git a/packages/core/js/keywords/domain/lorem/lines-keyword-definition.js b/packages/core/js/keywords/domain/lorem/lines-keyword-definition.js index 09d91fe9..e6aaafe6 100644 --- a/packages/core/js/keywords/domain/lorem/lines-keyword-definition.js +++ b/packages/core/js/keywords/domain/lorem/lines-keyword-definition.js @@ -1,16 +1,25 @@ import { validateStringValue } from '../../../command-help/command-help-validators.js'; +import { createLoremCountArgsValidator } from './lorem-arg-validators.js'; + +const validateLoremLinesArgs = createLoremCountArgsValidator({ + countName: 'lineCount', + minName: 'lineCountMin', + maxName: 'lineCountMax', +}); const LOREM_LINES_KEYWORD_DEFINITION = { keyword: 'lorem.lines', delegate: { type: 'faker', target: 'lorem.lines', + argTransform: 'loremCountFromHelpArgs', }, help: { summary: "Generates the given number lines of lorem separated by `'\\n'`.", docsUrl: 'https://anywaydata.com/docs/test-data/domain/lorem', fakerDocsUrl: 'https://fakerjs.dev/api/lorem', validator: validateStringValue, + argsValidator: validateLoremLinesArgs, returnType: 'string', usageExamples: [ { @@ -23,7 +32,12 @@ const LOREM_LINES_KEYWORD_DEFINITION = { }, { functionCall: 'lorem.lines(max=10, min=1)', - sampleReturnValue: 'Suppellex a cognatus arca aliquam audentia.', + sampleReturnValue: + 'A cognatus arca aliquam audentia coniuratio crux fugit.\n' + + 'Stillicidium bardus utrimque acsi spargo cur.\n' + + 'Aqua avaritia thesaurus volo combibo stultus utor.\n' + + 'Ago adflicto assentator utrimque altus curiositas vita expedita stultus comedo.\n' + + 'Trucido accusamus tandem voveo tamisium cicuta testimonium amet.', description: 'Shows lorem.lines using min.', }, { @@ -37,9 +51,11 @@ const LOREM_LINES_KEYWORD_DEFINITION = { { functionCall: 'lorem.lines(lineCount=5)', sampleReturnValue: - 'A cognatus arca aliquam audentia coniuratio crux fugit.\n' + - 'Stillicidium bardus utrimque acsi spargo cur.\n' + - 'Aqua avaritia thesaurus volo combibo stultus utor.', + 'Suppellex a cognatus arca aliquam audentia.\n' + + 'Crux fugit curatio stillicidium bardus.\n' + + 'Acsi spargo cur laboriosam aqua avaritia thesaurus volo combibo stultus.\n' + + 'Varius ago adflicto assentator utrimque altus curiositas vita expedita stultus.\n' + + 'Stipes trucido accusamus tandem voveo.', description: 'Shows lorem.lines using lineCount.', }, { @@ -53,9 +69,11 @@ const LOREM_LINES_KEYWORD_DEFINITION = { { functionCall: 'lorem.lines(lineCountMin=5)', sampleReturnValue: - 'A cognatus arca aliquam audentia coniuratio crux fugit.\n' + - 'Stillicidium bardus utrimque acsi spargo cur.\n' + - 'Aqua avaritia thesaurus volo combibo stultus utor.', + 'Suppellex a cognatus arca aliquam audentia.\n' + + 'Crux fugit curatio stillicidium bardus.\n' + + 'Acsi spargo cur laboriosam aqua avaritia thesaurus volo combibo stultus.\n' + + 'Varius ago adflicto assentator utrimque altus curiositas vita expedita stultus.\n' + + 'Stipes trucido accusamus tandem voveo.', description: 'Shows lorem.lines using lineCountMin.', }, ], diff --git a/packages/core/js/keywords/domain/lorem/lorem-arg-validators.js b/packages/core/js/keywords/domain/lorem/lorem-arg-validators.js new file mode 100644 index 00000000..b9c17b2a --- /dev/null +++ b/packages/core/js/keywords/domain/lorem/lorem-arg-validators.js @@ -0,0 +1,32 @@ +import { composeArgsValidators, createOrderedArgsValidator } from '../../../domain/domain-keyword-arg-validators.js'; +import { createPositiveIntegerArgsValidator } from '../shared/common-arg-validators.js'; + +function createMixedLoremCountSchemeValidator({ countName, minName, maxName }) { + return (_args = [], context = {}) => { + const argsByName = context?.argsByName || {}; + const hasGenericRange = typeof argsByName.min !== 'undefined' || typeof argsByName.max !== 'undefined'; + const hasSpecificCount = typeof argsByName[countName] !== 'undefined'; + const hasSpecificRange = typeof argsByName[minName] !== 'undefined' || typeof argsByName[maxName] !== 'undefined'; + const usedSchemeCount = [hasGenericRange, hasSpecificCount, hasSpecificRange].filter(Boolean).length; + + if (usedSchemeCount <= 1) { + return { ok: true }; + } + + return { + ok: false, + error: `Invalid keyword arguments: use only one lorem count scheme: min/max, ${countName}, or ${minName}/${maxName}`, + }; + }; +} + +function createLoremCountArgsValidator({ countName, minName, maxName }) { + return composeArgsValidators( + createPositiveIntegerArgsValidator(['min', 'max', countName, minName, maxName]), + createMixedLoremCountSchemeValidator({ countName, minName, maxName }), + createOrderedArgsValidator({ lowerName: 'min', upperName: 'max' }), + createOrderedArgsValidator({ lowerName: minName, upperName: maxName }) + ); +} + +export { createLoremCountArgsValidator }; diff --git a/packages/core/js/keywords/domain/lorem/paragraph-keyword-definition.js b/packages/core/js/keywords/domain/lorem/paragraph-keyword-definition.js index 40697f93..9d6a2300 100644 --- a/packages/core/js/keywords/domain/lorem/paragraph-keyword-definition.js +++ b/packages/core/js/keywords/domain/lorem/paragraph-keyword-definition.js @@ -1,16 +1,25 @@ import { validateStringValue } from '../../../command-help/command-help-validators.js'; +import { createLoremCountArgsValidator } from './lorem-arg-validators.js'; + +const validateLoremParagraphArgs = createLoremCountArgsValidator({ + countName: 'sentenceCount', + minName: 'sentenceCountMin', + maxName: 'sentenceCountMax', +}); const LOREM_PARAGRAPH_KEYWORD_DEFINITION = { keyword: 'lorem.paragraph', delegate: { type: 'faker', target: 'lorem.paragraph', + argTransform: 'loremCountFromHelpArgs', }, help: { summary: 'Generates a paragraph with the given number of sentences.', docsUrl: 'https://anywaydata.com/docs/test-data/domain/lorem', fakerDocsUrl: 'https://fakerjs.dev/api/lorem', validator: validateStringValue, + argsValidator: validateLoremParagraphArgs, returnType: 'string', usageExamples: [ { @@ -21,31 +30,32 @@ const LOREM_PARAGRAPH_KEYWORD_DEFINITION = { }, { functionCall: 'lorem.paragraph(max=10, min=1)', - sampleReturnValue: 'Suppellex a cognatus arca aliquam audentia.', + sampleReturnValue: + 'A cognatus arca aliquam audentia coniuratio crux fugit. Stillicidium bardus utrimque acsi spargo cur. Aqua avaritia thesaurus volo combibo stultus utor. Ago adflicto assentator utrimque altus curiositas vita expedita stultus comedo. Trucido accusamus tandem voveo tamisium cicuta testimonium amet.', description: 'Shows lorem.paragraph using min.', }, { functionCall: 'lorem.paragraph(max=5)', sampleReturnValue: - 'Suppellex a cognatus arca aliquam audentia. Crux fugit curatio stillicidium bardus. Acsi spargo cur laboriosam aqua avaritia thesaurus volo combibo stultus.', + 'A cognatus arca aliquam audentia coniuratio crux fugit. Stillicidium bardus utrimque acsi spargo cur. Aqua avaritia thesaurus volo combibo stultus utor.', description: 'Shows lorem.paragraph using max.', }, { functionCall: 'lorem.paragraph(sentenceCount=5)', sampleReturnValue: - 'Suppellex a cognatus arca aliquam audentia. Crux fugit curatio stillicidium bardus. Acsi spargo cur laboriosam aqua avaritia thesaurus volo combibo stultus.', + 'Suppellex a cognatus arca aliquam audentia. Crux fugit curatio stillicidium bardus. Acsi spargo cur laboriosam aqua avaritia thesaurus volo combibo stultus. Varius ago adflicto assentator utrimque altus curiositas vita expedita stultus. Stipes trucido accusamus tandem voveo.', description: 'Shows lorem.paragraph using sentenceCount.', }, { functionCall: 'lorem.paragraph(sentenceCountMax=5)', sampleReturnValue: - 'Suppellex a cognatus arca aliquam audentia. Crux fugit curatio stillicidium bardus. Acsi spargo cur laboriosam aqua avaritia thesaurus volo combibo stultus.', + 'A cognatus arca aliquam audentia coniuratio crux fugit. Stillicidium bardus utrimque acsi spargo cur. Aqua avaritia thesaurus volo combibo stultus utor.', description: 'Shows lorem.paragraph using sentenceCountMax.', }, { functionCall: 'lorem.paragraph(sentenceCountMin=5)', sampleReturnValue: - 'Suppellex a cognatus arca aliquam audentia. Crux fugit curatio stillicidium bardus. Acsi spargo cur laboriosam aqua avaritia thesaurus volo combibo stultus.', + 'Suppellex a cognatus arca aliquam audentia. Crux fugit curatio stillicidium bardus. Acsi spargo cur laboriosam aqua avaritia thesaurus volo combibo stultus. Varius ago adflicto assentator utrimque altus curiositas vita expedita stultus. Stipes trucido accusamus tandem voveo.', description: 'Shows lorem.paragraph using sentenceCountMin.', }, ], diff --git a/packages/core/js/keywords/domain/lorem/paragraphs-keyword-definition.js b/packages/core/js/keywords/domain/lorem/paragraphs-keyword-definition.js index e54e225d..b3588c00 100644 --- a/packages/core/js/keywords/domain/lorem/paragraphs-keyword-definition.js +++ b/packages/core/js/keywords/domain/lorem/paragraphs-keyword-definition.js @@ -1,16 +1,25 @@ import { validateStringValue } from '../../../command-help/command-help-validators.js'; +import { createLoremCountArgsValidator } from './lorem-arg-validators.js'; + +const validateLoremParagraphsArgs = createLoremCountArgsValidator({ + countName: 'paragraphCount', + minName: 'paragraphCountMin', + maxName: 'paragraphCountMax', +}); const LOREM_PARAGRAPHS_KEYWORD_DEFINITION = { keyword: 'lorem.paragraphs', delegate: { type: 'faker', target: 'lorem.paragraphs', + argTransform: 'loremCountFromHelpArgs', }, help: { summary: 'Generates the given number of paragraphs.', docsUrl: 'https://anywaydata.com/docs/test-data/domain/lorem', fakerDocsUrl: 'https://fakerjs.dev/api/lorem', validator: validateStringValue, + argsValidator: validateLoremParagraphsArgs, returnType: 'string', usageExamples: [ { @@ -24,13 +33,19 @@ const LOREM_PARAGRAPHS_KEYWORD_DEFINITION = { { functionCall: 'lorem.paragraphs(max=10, min=1)', sampleReturnValue: - 'Suppellex a cognatus arca aliquam audentia. Crux fugit curatio stillicidium bardus. Acsi spargo cur laboriosam aqua avaritia thesaurus volo combibo stultus.', + 'A cognatus arca aliquam audentia coniuratio crux fugit. Stillicidium bardus utrimque acsi spargo cur. Aqua avaritia thesaurus volo combibo stultus utor.\n' + + 'Ago adflicto assentator utrimque altus curiositas vita expedita stultus comedo. Trucido accusamus tandem voveo tamisium cicuta testimonium amet. Ver claudeo civis aperio accusantium spoliatio.\n' + + 'Cena deprimo adnuo natus. Odit subseco ambulo cupio. Cupio admiratio facilis sonitus dolorum vinco occaecati venio.\n' + + 'Apud timor cubicularis asperiores. Conqueror tantillus sursum vacuus quia tantillus conscendo centum vehemens cursus. Somnus quasi amplus vir defaeco nesciunt cumque capillus venio natus.\n' + + 'Provident compello et. Consuasor ver qui accendo vetus studio vulpes at approbo vicissitudo. Aedificium temeritas tego vesica sum ante accusantium acquiro.', description: 'Shows lorem.paragraphs using min.', }, { functionCall: 'lorem.paragraphs(max=5)', sampleReturnValue: - 'Suppellex a cognatus arca aliquam audentia. Crux fugit curatio stillicidium bardus. Acsi spargo cur laboriosam aqua avaritia thesaurus volo combibo stultus.5Varius ago adflicto assentator utrimque altus curiositas vita expedita stultus. Stipes trucido accusamus tandem voveo. Cicuta testimonium amet dedico ver claudeo civis aperio.5Spoliatio beneficium cena. Adnuo natus arca odit subseco ambulo. Suasoria cupio admiratio facilis sonitus dolorum.', + 'A cognatus arca aliquam audentia coniuratio crux fugit. Stillicidium bardus utrimque acsi spargo cur. Aqua avaritia thesaurus volo combibo stultus utor.\n' + + 'Ago adflicto assentator utrimque altus curiositas vita expedita stultus comedo. Trucido accusamus tandem voveo tamisium cicuta testimonium amet. Ver claudeo civis aperio accusantium spoliatio.\n' + + 'Cena deprimo adnuo natus. Odit subseco ambulo cupio. Cupio admiratio facilis sonitus dolorum vinco occaecati venio.', description: 'Shows lorem.paragraphs using max.', }, { @@ -38,23 +53,25 @@ const LOREM_PARAGRAPHS_KEYWORD_DEFINITION = { sampleReturnValue: 'Suppellex a cognatus arca aliquam audentia. Crux fugit curatio stillicidium bardus. Acsi spargo cur laboriosam aqua avaritia thesaurus volo combibo stultus.\n' + 'Varius ago adflicto assentator utrimque altus curiositas vita expedita stultus. Stipes trucido accusamus tandem voveo. Cicuta testimonium amet dedico ver claudeo civis aperio.\n' + - 'Spoliatio beneficium cena. Adnuo natus arca odit subseco ambulo. Suasoria cupio admiratio facilis sonitus dolorum.', + 'Spoliatio beneficium cena. Adnuo natus arca odit subseco ambulo. Suasoria cupio admiratio facilis sonitus dolorum.\n' + + 'Occaecati venio apto apud timor cubicularis asperiores vestigium conqueror tantillus. Vacuus quia tantillus conscendo centum vehemens cursus vobis. Quasi amplus vir defaeco nesciunt cumque capillus venio.\n' + + 'Abbas provident compello et valde consuasor ver. Accendo vetus studio vulpes at approbo vicissitudo. Aedificium temeritas tego vesica sum ante accusantium acquiro.', description: 'Shows lorem.paragraphs using paragraphCount.', }, { functionCall: 'lorem.paragraphs(separator="-")', sampleReturnValue: - 'Suppellex a cognatus arca aliquam audentia. Crux fugit curatio stillicidium bardus. Acsi spargo cur laboriosam aqua avaritia thesaurus volo combibo stultus.\n' + - 'Varius ago adflicto assentator utrimque altus curiositas vita expedita stultus. Stipes trucido accusamus tandem voveo. Cicuta testimonium amet dedico ver claudeo civis aperio.\n' + + 'Suppellex a cognatus arca aliquam audentia. Crux fugit curatio stillicidium bardus. Acsi spargo cur laboriosam aqua avaritia thesaurus volo combibo stultus.-' + + 'Varius ago adflicto assentator utrimque altus curiositas vita expedita stultus. Stipes trucido accusamus tandem voveo. Cicuta testimonium amet dedico ver claudeo civis aperio.-' + 'Spoliatio beneficium cena. Adnuo natus arca odit subseco ambulo. Suasoria cupio admiratio facilis sonitus dolorum.', description: 'Shows lorem.paragraphs using separator.', }, { functionCall: 'lorem.paragraphs(paragraphCountMax=5)', sampleReturnValue: - 'Suppellex a cognatus arca aliquam audentia. Crux fugit curatio stillicidium bardus. Acsi spargo cur laboriosam aqua avaritia thesaurus volo combibo stultus.\n' + - 'Varius ago adflicto assentator utrimque altus curiositas vita expedita stultus. Stipes trucido accusamus tandem voveo. Cicuta testimonium amet dedico ver claudeo civis aperio.\n' + - 'Spoliatio beneficium cena. Adnuo natus arca odit subseco ambulo. Suasoria cupio admiratio facilis sonitus dolorum.', + 'A cognatus arca aliquam audentia coniuratio crux fugit. Stillicidium bardus utrimque acsi spargo cur. Aqua avaritia thesaurus volo combibo stultus utor.\n' + + 'Ago adflicto assentator utrimque altus curiositas vita expedita stultus comedo. Trucido accusamus tandem voveo tamisium cicuta testimonium amet. Ver claudeo civis aperio accusantium spoliatio.\n' + + 'Cena deprimo adnuo natus. Odit subseco ambulo cupio. Cupio admiratio facilis sonitus dolorum vinco occaecati venio.', description: 'Shows lorem.paragraphs using paragraphCountMax.', }, { @@ -62,7 +79,9 @@ const LOREM_PARAGRAPHS_KEYWORD_DEFINITION = { sampleReturnValue: 'Suppellex a cognatus arca aliquam audentia. Crux fugit curatio stillicidium bardus. Acsi spargo cur laboriosam aqua avaritia thesaurus volo combibo stultus.\n' + 'Varius ago adflicto assentator utrimque altus curiositas vita expedita stultus. Stipes trucido accusamus tandem voveo. Cicuta testimonium amet dedico ver claudeo civis aperio.\n' + - 'Spoliatio beneficium cena. Adnuo natus arca odit subseco ambulo. Suasoria cupio admiratio facilis sonitus dolorum.', + 'Spoliatio beneficium cena. Adnuo natus arca odit subseco ambulo. Suasoria cupio admiratio facilis sonitus dolorum.\n' + + 'Occaecati venio apto apud timor cubicularis asperiores vestigium conqueror tantillus. Vacuus quia tantillus conscendo centum vehemens cursus vobis. Quasi amplus vir defaeco nesciunt cumque capillus venio.\n' + + 'Abbas provident compello et valde consuasor ver. Accendo vetus studio vulpes at approbo vicissitudo. Aedificium temeritas tego vesica sum ante accusantium acquiro.', description: 'Shows lorem.paragraphs using paragraphCountMin.', }, ], diff --git a/packages/core/js/keywords/domain/lorem/sentence-keyword-definition.js b/packages/core/js/keywords/domain/lorem/sentence-keyword-definition.js index 906872d0..e6160c75 100644 --- a/packages/core/js/keywords/domain/lorem/sentence-keyword-definition.js +++ b/packages/core/js/keywords/domain/lorem/sentence-keyword-definition.js @@ -1,16 +1,25 @@ import { validateStringValue } from '../../../command-help/command-help-validators.js'; +import { createLoremCountArgsValidator } from './lorem-arg-validators.js'; + +const validateLoremSentenceArgs = createLoremCountArgsValidator({ + countName: 'wordCount', + minName: 'wordCountMin', + maxName: 'wordCountMax', +}); const LOREM_SENTENCE_KEYWORD_DEFINITION = { keyword: 'lorem.sentence', delegate: { type: 'faker', target: 'lorem.sentence', + argTransform: 'loremCountFromHelpArgs', }, help: { summary: 'Generates a space separated list of words beginning with a capital letter and ending with a period.', docsUrl: 'https://anywaydata.com/docs/test-data/domain/lorem', fakerDocsUrl: 'https://fakerjs.dev/api/lorem', validator: validateStringValue, + argsValidator: validateLoremSentenceArgs, returnType: 'string', usageExamples: [ { @@ -20,27 +29,27 @@ const LOREM_SENTENCE_KEYWORD_DEFINITION = { }, { functionCall: 'lorem.sentence(max=10, min=1)', - sampleReturnValue: 'Cur.', + sampleReturnValue: 'Suppellex a cognatus arca aliquam.', description: 'Shows lorem.sentence using min.', }, { functionCall: 'lorem.sentence(max=5)', - sampleReturnValue: 'Suppellex a cognatus arca aliquam audentia.', + sampleReturnValue: 'Suppellex a cognatus.', description: 'Shows lorem.sentence using max.', }, { functionCall: 'lorem.sentence(wordCount=5)', - sampleReturnValue: 'Suppellex a cognatus arca aliquam audentia.', + sampleReturnValue: 'Cur suppellex a cognatus arca.', description: 'Shows lorem.sentence using wordCount.', }, { functionCall: 'lorem.sentence(wordCountMax=5)', - sampleReturnValue: 'Suppellex a cognatus arca aliquam audentia.', + sampleReturnValue: 'Suppellex a cognatus.', description: 'Shows lorem.sentence using wordCountMax.', }, { functionCall: 'lorem.sentence(wordCountMin=5)', - sampleReturnValue: 'Suppellex a cognatus arca aliquam audentia.', + sampleReturnValue: 'Cur suppellex a cognatus arca.', description: 'Shows lorem.sentence using wordCountMin.', }, ], diff --git a/packages/core/js/keywords/domain/lorem/sentences-keyword-definition.js b/packages/core/js/keywords/domain/lorem/sentences-keyword-definition.js index 6467e0e0..d781c291 100644 --- a/packages/core/js/keywords/domain/lorem/sentences-keyword-definition.js +++ b/packages/core/js/keywords/domain/lorem/sentences-keyword-definition.js @@ -1,16 +1,25 @@ import { validateStringValue } from '../../../command-help/command-help-validators.js'; +import { createLoremCountArgsValidator } from './lorem-arg-validators.js'; + +const validateLoremSentencesArgs = createLoremCountArgsValidator({ + countName: 'sentenceCount', + minName: 'sentenceCountMin', + maxName: 'sentenceCountMax', +}); const LOREM_SENTENCES_KEYWORD_DEFINITION = { keyword: 'lorem.sentences', delegate: { type: 'faker', target: 'lorem.sentences', + argTransform: 'loremCountFromHelpArgs', }, help: { summary: 'Generates the given number of sentences.', docsUrl: 'https://anywaydata.com/docs/test-data/domain/lorem', fakerDocsUrl: 'https://fakerjs.dev/api/lorem', validator: validateStringValue, + argsValidator: validateLoremSentencesArgs, returnType: 'string', usageExamples: [ { @@ -21,37 +30,38 @@ const LOREM_SENTENCES_KEYWORD_DEFINITION = { }, { functionCall: 'lorem.sentences(max=10, min=1)', - sampleReturnValue: 'Suppellex a cognatus arca aliquam audentia.', + sampleReturnValue: + 'A cognatus arca aliquam audentia coniuratio crux fugit. Stillicidium bardus utrimque acsi spargo cur. Aqua avaritia thesaurus volo combibo stultus utor. Ago adflicto assentator utrimque altus curiositas vita expedita stultus comedo. Trucido accusamus tandem voveo tamisium cicuta testimonium amet.', description: 'Shows lorem.sentences using min.', }, { functionCall: 'lorem.sentences(max=5)', sampleReturnValue: - 'A cognatus arca aliquam audentia coniuratio crux fugit.5Stillicidium bardus utrimque acsi spargo cur.5Aqua avaritia thesaurus volo combibo stultus utor.5Ago adflicto assentator utrimque altus curiositas vita expedita stultus comedo.', + 'A cognatus arca aliquam audentia coniuratio crux fugit. Stillicidium bardus utrimque acsi spargo cur. Aqua avaritia thesaurus volo combibo stultus utor.', description: 'Shows lorem.sentences using max.', }, { functionCall: 'lorem.sentences(sentenceCount=5)', sampleReturnValue: - 'A cognatus arca aliquam audentia coniuratio crux fugit. Stillicidium bardus utrimque acsi spargo cur. Aqua avaritia thesaurus volo combibo stultus utor. Ago adflicto assentator utrimque altus curiositas vita expedita stultus comedo.', + 'Suppellex a cognatus arca aliquam audentia. Crux fugit curatio stillicidium bardus. Acsi spargo cur laboriosam aqua avaritia thesaurus volo combibo stultus. Varius ago adflicto assentator utrimque altus curiositas vita expedita stultus. Stipes trucido accusamus tandem voveo.', description: 'Shows lorem.sentences using sentenceCount.', }, { functionCall: 'lorem.sentences(separator="-")', sampleReturnValue: - 'A cognatus arca aliquam audentia coniuratio crux fugit. Stillicidium bardus utrimque acsi spargo cur. Aqua avaritia thesaurus volo combibo stultus utor. Ago adflicto assentator utrimque altus curiositas vita expedita stultus comedo.', + 'A cognatus arca aliquam audentia coniuratio crux fugit.-Stillicidium bardus utrimque acsi spargo cur.-Aqua avaritia thesaurus volo combibo stultus utor.-Ago adflicto assentator utrimque altus curiositas vita expedita stultus comedo.', description: 'Shows lorem.sentences using separator.', }, { functionCall: 'lorem.sentences(sentenceCountMax=5)', sampleReturnValue: - 'A cognatus arca aliquam audentia coniuratio crux fugit. Stillicidium bardus utrimque acsi spargo cur. Aqua avaritia thesaurus volo combibo stultus utor. Ago adflicto assentator utrimque altus curiositas vita expedita stultus comedo.', + 'A cognatus arca aliquam audentia coniuratio crux fugit. Stillicidium bardus utrimque acsi spargo cur. Aqua avaritia thesaurus volo combibo stultus utor.', description: 'Shows lorem.sentences using sentenceCountMax.', }, { functionCall: 'lorem.sentences(sentenceCountMin=5)', sampleReturnValue: - 'A cognatus arca aliquam audentia coniuratio crux fugit. Stillicidium bardus utrimque acsi spargo cur. Aqua avaritia thesaurus volo combibo stultus utor. Ago adflicto assentator utrimque altus curiositas vita expedita stultus comedo.', + 'Suppellex a cognatus arca aliquam audentia. Crux fugit curatio stillicidium bardus. Acsi spargo cur laboriosam aqua avaritia thesaurus volo combibo stultus. Varius ago adflicto assentator utrimque altus curiositas vita expedita stultus. Stipes trucido accusamus tandem voveo.', description: 'Shows lorem.sentences using sentenceCountMin.', }, ], diff --git a/packages/core/js/keywords/domain/lorem/slug-keyword-definition.js b/packages/core/js/keywords/domain/lorem/slug-keyword-definition.js index 5fc275ed..3220a916 100644 --- a/packages/core/js/keywords/domain/lorem/slug-keyword-definition.js +++ b/packages/core/js/keywords/domain/lorem/slug-keyword-definition.js @@ -1,16 +1,25 @@ import { validateStringValue } from '../../../command-help/command-help-validators.js'; +import { createLoremCountArgsValidator } from './lorem-arg-validators.js'; + +const validateLoremSlugArgs = createLoremCountArgsValidator({ + countName: 'wordCount', + minName: 'wordCountMin', + maxName: 'wordCountMax', +}); const LOREM_SLUG_KEYWORD_DEFINITION = { keyword: 'lorem.slug', delegate: { type: 'faker', target: 'lorem.slug', + argTransform: 'loremCountFromHelpArgs', }, help: { summary: 'Generates a slugified text consisting of the given number of hyphen separated words.', docsUrl: 'https://anywaydata.com/docs/test-data/domain/lorem', fakerDocsUrl: 'https://fakerjs.dev/api/lorem', validator: validateStringValue, + argsValidator: validateLoremSlugArgs, returnType: 'string', usageExamples: [ { @@ -20,27 +29,27 @@ const LOREM_SLUG_KEYWORD_DEFINITION = { }, { functionCall: 'lorem.slug(max=10, min=1)', - sampleReturnValue: 'cur', + sampleReturnValue: 'suppellex-a-cognatus-arca-aliquam', description: 'Shows lorem.slug using min.', }, { functionCall: 'lorem.slug(max=5)', - sampleReturnValue: 'cur-suppellex-a', + sampleReturnValue: 'suppellex-a-cognatus', description: 'Shows lorem.slug using max.', }, { functionCall: 'lorem.slug(wordCount=5)', - sampleReturnValue: 'cur-suppellex-a', + sampleReturnValue: 'cur-suppellex-a-cognatus-arca', description: 'Shows lorem.slug using wordCount.', }, { functionCall: 'lorem.slug(wordCountMax=5)', - sampleReturnValue: 'cur-suppellex-a', + sampleReturnValue: 'suppellex-a-cognatus', description: 'Shows lorem.slug using wordCountMax.', }, { functionCall: 'lorem.slug(wordCountMin=5)', - sampleReturnValue: 'cur-suppellex-a', + sampleReturnValue: 'cur-suppellex-a-cognatus-arca', description: 'Shows lorem.slug using wordCountMin.', }, ], diff --git a/packages/core/js/keywords/domain/lorem/word-keyword-definition.js b/packages/core/js/keywords/domain/lorem/word-keyword-definition.js index e243cb92..bf81c42c 100644 --- a/packages/core/js/keywords/domain/lorem/word-keyword-definition.js +++ b/packages/core/js/keywords/domain/lorem/word-keyword-definition.js @@ -1,6 +1,8 @@ import { validateStringValue } from '../../../command-help/command-help-validators.js'; +import { createPositiveIntegerArgsValidator } from '../shared/common-arg-validators.js'; const LOREM_WORD_STRATEGY_TYPE = 'fail|closest|shortest|longest|any-length'; +const validateLoremWordArgs = createPositiveIntegerArgsValidator(['length']); const LOREM_WORD_KEYWORD_DEFINITION = { keyword: 'lorem.word', @@ -14,6 +16,7 @@ const LOREM_WORD_KEYWORD_DEFINITION = { docsUrl: 'https://anywaydata.com/docs/test-data/domain/lorem', fakerDocsUrl: 'https://fakerjs.dev/api/lorem', validator: validateStringValue, + argsValidator: validateLoremWordArgs, returnType: 'string', usageExamples: [ { @@ -21,16 +24,6 @@ const LOREM_WORD_KEYWORD_DEFINITION = { sampleReturnValue: 'cur', description: 'Shows lorem.word when optional params are omitted.', }, - { - functionCall: 'lorem.word(max=10, min=1)', - sampleReturnValue: 'cur', - description: 'Shows lorem.word using min.', - }, - { - functionCall: 'lorem.word(max=5)', - sampleReturnValue: 'cur', - description: 'Shows lorem.word using max.', - }, { functionCall: 'lorem.word(length=5)', sampleReturnValue: 'curvo', @@ -43,18 +36,6 @@ const LOREM_WORD_KEYWORD_DEFINITION = { }, ], args: [ - { - name: 'min', - type: 'number', - required: false, - description: 'Minimum word length when generating a ranged length.', - }, - { - name: 'max', - type: 'number', - required: false, - description: 'Maximum word length when generating a ranged length.', - }, { name: 'length', type: 'number', diff --git a/packages/core/js/keywords/domain/lorem/words-keyword-definition.js b/packages/core/js/keywords/domain/lorem/words-keyword-definition.js index 2f6f97c6..0ecbf264 100644 --- a/packages/core/js/keywords/domain/lorem/words-keyword-definition.js +++ b/packages/core/js/keywords/domain/lorem/words-keyword-definition.js @@ -1,16 +1,25 @@ import { validateStringValue } from '../../../command-help/command-help-validators.js'; +import { createLoremCountArgsValidator } from './lorem-arg-validators.js'; + +const validateLoremWordsArgs = createLoremCountArgsValidator({ + countName: 'wordCount', + minName: 'wordCountMin', + maxName: 'wordCountMax', +}); const LOREM_WORDS_KEYWORD_DEFINITION = { keyword: 'lorem.words', delegate: { type: 'faker', target: 'lorem.words', + argTransform: 'loremCountFromHelpArgs', }, help: { summary: 'Generates a space separated list of words.', docsUrl: 'https://anywaydata.com/docs/test-data/domain/lorem', fakerDocsUrl: 'https://fakerjs.dev/api/lorem', validator: validateStringValue, + argsValidator: validateLoremWordsArgs, returnType: 'string', usageExamples: [ { @@ -20,27 +29,27 @@ const LOREM_WORDS_KEYWORD_DEFINITION = { }, { functionCall: 'lorem.words(max=10, min=1)', - sampleReturnValue: 'cur', + sampleReturnValue: 'suppellex a cognatus arca aliquam', description: 'Shows lorem.words using min.', }, { functionCall: 'lorem.words(max=5)', - sampleReturnValue: 'cur suppellex a', + sampleReturnValue: 'suppellex a cognatus', description: 'Shows lorem.words using max.', }, { functionCall: 'lorem.words(wordCount=5)', - sampleReturnValue: 'cur suppellex a', + sampleReturnValue: 'cur suppellex a cognatus arca', description: 'Shows lorem.words using wordCount.', }, { functionCall: 'lorem.words(wordCountMax=5)', - sampleReturnValue: 'cur suppellex a', + sampleReturnValue: 'suppellex a cognatus', description: 'Shows lorem.words using wordCountMax.', }, { functionCall: 'lorem.words(wordCountMin=5)', - sampleReturnValue: 'cur suppellex a', + sampleReturnValue: 'cur suppellex a cognatus arca', description: 'Shows lorem.words using wordCountMin.', }, ], diff --git a/packages/core/js/keywords/domain/number/big-int-keyword-definition.js b/packages/core/js/keywords/domain/number/big-int-keyword-definition.js index 9aa23184..16d33e81 100644 --- a/packages/core/js/keywords/domain/number/big-int-keyword-definition.js +++ b/packages/core/js/keywords/domain/number/big-int-keyword-definition.js @@ -1,4 +1,56 @@ import { validateIntegerValue } from '../../../command-help/command-help-validators.js'; +import { + composeArgsValidators, + createOrderedArgsValidator, + createNumericArgRangeValidator, +} from '../../../domain/domain-keyword-arg-validators.js'; + +const validateBigIntBounds = composeArgsValidators( + createOrderedArgsValidator({ lowerName: 'min', upperName: 'max' }), + createNumericArgRangeValidator({ + argName: 'multipleOf', + min: 0, + inclusiveMin: false, + description: 'Invalid keyword arguments: argument "multipleOf" must be greater than 0', + }), + validateBigIntMultipleOfCanMatchRange +); + +function validateBigIntMultipleOfCanMatchRange(_args = [], context = {}) { + const argsByName = context?.argsByName || {}; + const { min, max, multipleOf } = argsByName; + + if ( + typeof min === 'undefined' || + typeof max === 'undefined' || + typeof multipleOf === 'undefined' || + typeof min !== 'number' || + typeof max !== 'number' || + typeof multipleOf !== 'number' || + !Number.isInteger(min) || + !Number.isInteger(max) || + !Number.isInteger(multipleOf) || + multipleOf <= 0 + ) { + return { ok: true }; + } + + const minValue = BigInt(min); + const maxValue = BigInt(max); + const step = BigInt(multipleOf); + const remainder = ((minValue % step) + step) % step; + const firstMultiple = remainder === 0n ? minValue : minValue + (step - remainder); + + if (firstMultiple > maxValue) { + return { + ok: false, + error: + 'Invalid keyword arguments: arguments "min", "max", and "multipleOf" do not allow any generated BigInt value', + }; + } + + return { ok: true }; +} const NUMBER_BIG_INT_KEYWORD_DEFINITION = { keyword: 'number.bigInt', @@ -12,6 +64,7 @@ const NUMBER_BIG_INT_KEYWORD_DEFINITION = { docsUrl: 'https://anywaydata.com/docs/test-data/domain/number', fakerDocsUrl: 'https://fakerjs.dev/api/number', validator: validateIntegerValue, + argsValidator: validateBigIntBounds, returnType: 'integer', usageExamples: [ { @@ -20,19 +73,42 @@ const NUMBER_BIG_INT_KEYWORD_DEFINITION = { description: 'Shows number.bigInt with all optional params omitted.', }, { - functionCall: 'number.bigInt(value=true)', - sampleReturnValue: 703101335462806n, - description: 'Shows number.bigInt using a boolean base value.', + functionCall: 'number.bigInt(min=100, max=1000)', + sampleReturnValue: 570n, + description: 'Shows number.bigInt using min and max bounds.', + }, + { + functionCall: 'number.bigInt(multipleOf=7)', + sampleReturnValue: 292170934823957n, + description: 'Shows number.bigInt constrained to a multiple.', + }, + { + functionCall: 'number.bigInt(max=1000)', + sampleReturnValue: 699n, + description: 'Shows number.bigInt using an upper bound.', }, ], args: [ { - name: 'value', - type: 'bigint|number|string|boolean', + name: 'min', + type: 'integer', + required: false, + description: 'Optional minimum bound for the generated BigInt value.', + examples: [100], + }, + { + name: 'max', + type: 'integer', + required: false, + description: 'Optional maximum bound for the generated BigInt value.', + examples: [1000], + }, + { + name: 'multipleOf', + type: 'integer', required: false, - description: - 'Base value used for generation. Supports bigint, number, string, or boolean inputs. For range constraints use min, max, and multipleOf.', - examples: [true], + description: 'Generated BigInt will be a multiple of the given value.', + examples: [7], }, ], }, diff --git a/packages/core/js/keywords/domain/person/full-name-keyword-definition.js b/packages/core/js/keywords/domain/person/full-name-keyword-definition.js index 93bfe1e2..09abd58d 100644 --- a/packages/core/js/keywords/domain/person/full-name-keyword-definition.js +++ b/packages/core/js/keywords/domain/person/full-name-keyword-definition.js @@ -5,6 +5,7 @@ const PERSON_FULL_NAME_KEYWORD_DEFINITION = { delegate: { type: 'faker', target: 'person.fullName', + argTransform: 'optionsFromHelpArgs', }, help: { summary: 'Generates a random full name.', @@ -14,12 +15,54 @@ const PERSON_FULL_NAME_KEYWORD_DEFINITION = { returnType: 'string', usageExamples: [ { - functionCall: 'person.fullName', + functionCall: 'person.fullName()', sampleReturnValue: 'Aaliyah Corkery', description: 'Shows the default person.fullName call.', }, + { + functionCall: 'person.fullName(firstName="Ada", lastName="Lovelace", sex="female")', + sampleReturnValue: 'Ada Lovelace', + description: 'Shows person.fullName using name and sex options.', + }, + { + functionCall: 'person.fullName(firstName="Ada")', + sampleReturnValue: 'Ada Abbott', + description: 'Shows person.fullName using an explicit first name.', + }, + { + functionCall: 'person.fullName(lastName="Lovelace")', + sampleReturnValue: 'Aaliyah Lovelace', + description: 'Shows person.fullName using an explicit last name.', + }, + { + functionCall: 'person.fullName(sex="female")', + sampleReturnValue: 'Monique Gutmann', + description: 'Shows person.fullName using a sex category.', + }, + ], + args: [ + { + name: 'firstName', + type: 'string', + required: false, + description: 'Optional first name to use as the basis for the full name.', + examples: ['Ada'], + }, + { + name: 'lastName', + type: 'string', + required: false, + description: 'Optional last name to use as the basis for the full name.', + examples: ['Lovelace'], + }, + { + name: 'sex', + type: 'female|generic|male', + required: false, + description: 'Sex category used for the generated full name.', + examples: ['female'], + }, ], - args: [], }, }; diff --git a/packages/core/js/keywords/domain/person/sex-type-keyword-definition.js b/packages/core/js/keywords/domain/person/sex-type-keyword-definition.js index d6aaeb96..5167068e 100644 --- a/packages/core/js/keywords/domain/person/sex-type-keyword-definition.js +++ b/packages/core/js/keywords/domain/person/sex-type-keyword-definition.js @@ -1,6 +1,6 @@ import { createStringEnumValidator } from '../../../command-help/command-help-validators.js'; -const PERSON_SEX_TYPE = 'female|male'; +const PERSON_SEX_TYPE = 'female|generic|male'; const validatePersonSexTypeValue = createStringEnumValidator(PERSON_SEX_TYPE.split('|')); @@ -9,6 +9,7 @@ const PERSON_SEX_TYPE_KEYWORD_DEFINITION = { delegate: { type: 'faker', target: 'person.sexType', + argTransform: 'optionsFromHelpArgs', }, help: { summary: 'Returns a random sex type. The `SexType` is intended to be used in parameters and conditions.', @@ -18,12 +19,25 @@ const PERSON_SEX_TYPE_KEYWORD_DEFINITION = { returnType: PERSON_SEX_TYPE, usageExamples: [ { - functionCall: 'person.sexType', + functionCall: 'person.sexType()', sampleReturnValue: 'female', description: 'Shows the default person.sexType call.', }, + { + functionCall: 'person.sexType(includeGeneric=false)', + sampleReturnValue: 'female', + description: 'Shows person.sexType excluding the generic value.', + }, + ], + args: [ + { + name: 'includeGeneric', + type: 'boolean', + required: false, + description: 'Whether the generic sex type can be returned.', + examples: [false], + }, ], - args: [], }, }; diff --git a/packages/core/js/keywords/domain/shared/common-arg-validators.js b/packages/core/js/keywords/domain/shared/common-arg-validators.js new file mode 100644 index 00000000..c945b16e --- /dev/null +++ b/packages/core/js/keywords/domain/shared/common-arg-validators.js @@ -0,0 +1,22 @@ +import { + composeArgsValidators, + createIntegerArgValidator, + createNumericArgRangeValidator, +} from '../../../domain/domain-keyword-arg-validators.js'; + +function createPositiveIntegerArgsValidator(argNames = []) { + return composeArgsValidators( + ...argNames.flatMap((argName) => [ + createIntegerArgValidator({ argName }), + createNumericArgRangeValidator({ argName, min: 0, inclusiveMin: false }), + ]) + ); +} + +const WORD_SELECTION_STRATEGY_TYPE = 'fail|closest|shortest|longest|any-length'; + +function createWordSelectionArgsValidator() { + return createPositiveIntegerArgsValidator(['length']); +} + +export { createPositiveIntegerArgsValidator, createWordSelectionArgsValidator, WORD_SELECTION_STRATEGY_TYPE }; diff --git a/packages/core/js/keywords/domain/string/alpha-keyword-definition.js b/packages/core/js/keywords/domain/string/alpha-keyword-definition.js index 12fffec6..a4692668 100644 --- a/packages/core/js/keywords/domain/string/alpha-keyword-definition.js +++ b/packages/core/js/keywords/domain/string/alpha-keyword-definition.js @@ -1,6 +1,8 @@ import { validateAlphaStringValue } from '../../../command-help/command-help-validators.js'; +import { createPositiveIntegerArgsValidator } from '../shared/common-arg-validators.js'; const STRING_CASING_TYPE = 'upper|lower|mixed'; +const validateStringAlphaArgs = createPositiveIntegerArgsValidator(['length']); const STRING_ALPHA_KEYWORD_DEFINITION = { keyword: 'string.alpha', @@ -14,6 +16,7 @@ const STRING_ALPHA_KEYWORD_DEFINITION = { docsUrl: 'https://anywaydata.com/docs/test-data/domain/string', fakerDocsUrl: 'https://fakerjs.dev/api/string', validator: validateAlphaStringValue, + argsValidator: validateStringAlphaArgs, returnType: 'string', usageExamples: [ { diff --git a/packages/core/js/keywords/domain/string/alphanumeric-keyword-definition.js b/packages/core/js/keywords/domain/string/alphanumeric-keyword-definition.js index 0315cbf6..121b3a3c 100644 --- a/packages/core/js/keywords/domain/string/alphanumeric-keyword-definition.js +++ b/packages/core/js/keywords/domain/string/alphanumeric-keyword-definition.js @@ -1,6 +1,8 @@ import { validateAlphanumericStringValue } from '../../../command-help/command-help-validators.js'; +import { createPositiveIntegerArgsValidator } from '../shared/common-arg-validators.js'; const STRING_CASING_TYPE = 'upper|lower|mixed'; +const validateStringAlphanumericArgs = createPositiveIntegerArgsValidator(['length']); const STRING_ALPHANUMERIC_KEYWORD_DEFINITION = { keyword: 'string.alphanumeric', @@ -14,6 +16,7 @@ const STRING_ALPHANUMERIC_KEYWORD_DEFINITION = { docsUrl: 'https://anywaydata.com/docs/test-data/domain/string', fakerDocsUrl: 'https://fakerjs.dev/api/string', validator: validateAlphanumericStringValue, + argsValidator: validateStringAlphanumericArgs, returnType: 'string', usageExamples: [ { diff --git a/packages/core/js/keywords/domain/string/binary-keyword-definition.js b/packages/core/js/keywords/domain/string/binary-keyword-definition.js index e97789d0..361ce09f 100644 --- a/packages/core/js/keywords/domain/string/binary-keyword-definition.js +++ b/packages/core/js/keywords/domain/string/binary-keyword-definition.js @@ -1,4 +1,7 @@ import { validateBinaryStringValue } from '../../../command-help/command-help-validators.js'; +import { createPositiveIntegerArgsValidator } from '../shared/common-arg-validators.js'; + +const validateStringBinaryArgs = createPositiveIntegerArgsValidator(['length']); const STRING_BINARY_KEYWORD_DEFINITION = { keyword: 'string.binary', @@ -12,6 +15,7 @@ const STRING_BINARY_KEYWORD_DEFINITION = { docsUrl: 'https://anywaydata.com/docs/test-data/domain/string', fakerDocsUrl: 'https://fakerjs.dev/api/string', validator: validateBinaryStringValue, + argsValidator: validateStringBinaryArgs, returnType: 'string', usageExamples: [ { diff --git a/packages/core/js/keywords/domain/string/from-characters-keyword-definition.js b/packages/core/js/keywords/domain/string/from-characters-keyword-definition.js index 0c7fa822..2e27103f 100644 --- a/packages/core/js/keywords/domain/string/from-characters-keyword-definition.js +++ b/packages/core/js/keywords/domain/string/from-characters-keyword-definition.js @@ -1,4 +1,7 @@ import { validateFromCharactersStringValue } from '../../../command-help/command-help-validators.js'; +import { createPositiveIntegerArgsValidator } from '../shared/common-arg-validators.js'; + +const validateStringFromCharactersArgs = createPositiveIntegerArgsValidator(['length']); const STRING_FROM_CHARACTERS_KEYWORD_DEFINITION = { keyword: 'string.fromCharacters', @@ -11,6 +14,7 @@ const STRING_FROM_CHARACTERS_KEYWORD_DEFINITION = { docsUrl: 'https://anywaydata.com/docs/test-data/domain/string', fakerDocsUrl: 'https://fakerjs.dev/api/string', validator: validateFromCharactersStringValue, + argsValidator: validateStringFromCharactersArgs, returnType: 'string', usageExamples: [ { diff --git a/packages/core/js/keywords/domain/string/hexadecimal-keyword-definition.js b/packages/core/js/keywords/domain/string/hexadecimal-keyword-definition.js index 99b2b516..85e4d476 100644 --- a/packages/core/js/keywords/domain/string/hexadecimal-keyword-definition.js +++ b/packages/core/js/keywords/domain/string/hexadecimal-keyword-definition.js @@ -1,6 +1,8 @@ import { validateHexadecimalStringValue } from '../../../command-help/command-help-validators.js'; +import { createPositiveIntegerArgsValidator } from '../shared/common-arg-validators.js'; const STRING_CASING_TYPE = 'upper|lower|mixed'; +const validateStringHexadecimalArgs = createPositiveIntegerArgsValidator(['length']); const STRING_HEXADECIMAL_KEYWORD_DEFINITION = { keyword: 'string.hexadecimal', @@ -14,6 +16,7 @@ const STRING_HEXADECIMAL_KEYWORD_DEFINITION = { docsUrl: 'https://anywaydata.com/docs/test-data/domain/string', fakerDocsUrl: 'https://fakerjs.dev/api/string', validator: validateHexadecimalStringValue, + argsValidator: validateStringHexadecimalArgs, returnType: 'string', usageExamples: [ { diff --git a/packages/core/js/keywords/domain/string/nanoid-keyword-definition.js b/packages/core/js/keywords/domain/string/nanoid-keyword-definition.js index 8dfc0c2a..6efbc0d8 100644 --- a/packages/core/js/keywords/domain/string/nanoid-keyword-definition.js +++ b/packages/core/js/keywords/domain/string/nanoid-keyword-definition.js @@ -1,4 +1,7 @@ import { validateNanoIdValue } from '../../../command-help/command-help-validators.js'; +import { createPositiveIntegerArgsValidator } from '../shared/common-arg-validators.js'; + +const validateStringNanoidArgs = createPositiveIntegerArgsValidator(['length']); const STRING_NANOID_KEYWORD_DEFINITION = { keyword: 'string.nanoid', @@ -11,6 +14,7 @@ const STRING_NANOID_KEYWORD_DEFINITION = { docsUrl: 'https://anywaydata.com/docs/test-data/domain/string', fakerDocsUrl: 'https://fakerjs.dev/api/string', validator: validateNanoIdValue, + argsValidator: validateStringNanoidArgs, returnType: 'string', usageExamples: [ { diff --git a/packages/core/js/keywords/domain/string/numeric-keyword-definition.js b/packages/core/js/keywords/domain/string/numeric-keyword-definition.js index 6bb02ee7..1113a0b1 100644 --- a/packages/core/js/keywords/domain/string/numeric-keyword-definition.js +++ b/packages/core/js/keywords/domain/string/numeric-keyword-definition.js @@ -1,4 +1,7 @@ import { validateNumericStringValue } from '../../../command-help/command-help-validators.js'; +import { createPositiveIntegerArgsValidator } from '../shared/common-arg-validators.js'; + +const validateStringNumericArgs = createPositiveIntegerArgsValidator(['length']); const STRING_NUMERIC_KEYWORD_DEFINITION = { keyword: 'string.numeric', @@ -12,6 +15,7 @@ const STRING_NUMERIC_KEYWORD_DEFINITION = { docsUrl: 'https://anywaydata.com/docs/test-data/domain/string', fakerDocsUrl: 'https://fakerjs.dev/api/string', validator: validateNumericStringValue, + argsValidator: validateStringNumericArgs, returnType: 'string', usageExamples: [ { diff --git a/packages/core/js/keywords/domain/string/octal-keyword-definition.js b/packages/core/js/keywords/domain/string/octal-keyword-definition.js index 45c6b0a3..64c89b26 100644 --- a/packages/core/js/keywords/domain/string/octal-keyword-definition.js +++ b/packages/core/js/keywords/domain/string/octal-keyword-definition.js @@ -1,4 +1,7 @@ import { validateOctalStringValue } from '../../../command-help/command-help-validators.js'; +import { createPositiveIntegerArgsValidator } from '../shared/common-arg-validators.js'; + +const validateStringOctalArgs = createPositiveIntegerArgsValidator(['length']); const STRING_OCTAL_KEYWORD_DEFINITION = { keyword: 'string.octal', @@ -12,6 +15,7 @@ const STRING_OCTAL_KEYWORD_DEFINITION = { docsUrl: 'https://anywaydata.com/docs/test-data/domain/string', fakerDocsUrl: 'https://fakerjs.dev/api/string', validator: validateOctalStringValue, + argsValidator: validateStringOctalArgs, returnType: 'string', usageExamples: [ { diff --git a/packages/core/js/keywords/domain/string/sample-keyword-definition.js b/packages/core/js/keywords/domain/string/sample-keyword-definition.js index 63d069a5..f9ce7fd7 100644 --- a/packages/core/js/keywords/domain/string/sample-keyword-definition.js +++ b/packages/core/js/keywords/domain/string/sample-keyword-definition.js @@ -1,4 +1,7 @@ import { validateSampleStringValue } from '../../../command-help/command-help-validators.js'; +import { createPositiveIntegerArgsValidator } from '../shared/common-arg-validators.js'; + +const validateStringSampleArgs = createPositiveIntegerArgsValidator(['length']); const STRING_SAMPLE_KEYWORD_DEFINITION = { keyword: 'string.sample', @@ -11,6 +14,7 @@ const STRING_SAMPLE_KEYWORD_DEFINITION = { docsUrl: 'https://anywaydata.com/docs/test-data/domain/string', fakerDocsUrl: 'https://fakerjs.dev/api/string', validator: validateSampleStringValue, + argsValidator: validateStringSampleArgs, returnType: 'string', usageExamples: [ { diff --git a/packages/core/js/keywords/domain/string/symbol-keyword-definition.js b/packages/core/js/keywords/domain/string/symbol-keyword-definition.js index 53f6b329..189199d4 100644 --- a/packages/core/js/keywords/domain/string/symbol-keyword-definition.js +++ b/packages/core/js/keywords/domain/string/symbol-keyword-definition.js @@ -1,4 +1,7 @@ import { validateSymbolStringValue } from '../../../command-help/command-help-validators.js'; +import { createPositiveIntegerArgsValidator } from '../shared/common-arg-validators.js'; + +const validateStringSymbolArgs = createPositiveIntegerArgsValidator(['length']); const STRING_SYMBOL_KEYWORD_DEFINITION = { keyword: 'string.symbol', @@ -12,6 +15,7 @@ const STRING_SYMBOL_KEYWORD_DEFINITION = { docsUrl: 'https://anywaydata.com/docs/test-data/domain/string', fakerDocsUrl: 'https://fakerjs.dev/api/string', validator: validateSymbolStringValue, + argsValidator: validateStringSymbolArgs, returnType: 'string', usageExamples: [ { diff --git a/packages/core/js/keywords/domain/system/file-name-keyword-definition.js b/packages/core/js/keywords/domain/system/file-name-keyword-definition.js index 45a64bdf..2d9a0bc1 100644 --- a/packages/core/js/keywords/domain/system/file-name-keyword-definition.js +++ b/packages/core/js/keywords/domain/system/file-name-keyword-definition.js @@ -1,25 +1,43 @@ import { validateStringValue } from '../../../command-help/command-help-validators.js'; +import { createPositiveIntegerArgsValidator } from '../shared/common-arg-validators.js'; + +const validateSystemFileNameArgs = createPositiveIntegerArgsValidator(['extensionCount']); const SYSTEM_FILE_NAME_KEYWORD_DEFINITION = { keyword: 'system.fileName', delegate: { type: 'faker', target: 'system.fileName', + argTransform: 'optionsFromHelpArgs', }, help: { summary: 'Returns a random file name with extension.', docsUrl: 'https://anywaydata.com/docs/test-data/domain/system', fakerDocsUrl: 'https://fakerjs.dev/api/system', validator: validateStringValue, + argsValidator: validateSystemFileNameArgs, returnType: 'string', usageExamples: [ { - functionCall: 'system.fileName', + functionCall: 'system.fileName()', sampleReturnValue: 'fog_aboard.otf', description: 'Shows the default system.fileName call.', }, + { + functionCall: 'system.fileName(extensionCount=2)', + sampleReturnValue: 'fog_aboard.otf.7z', + description: 'Shows system.fileName using extensionCount.', + }, + ], + args: [ + { + name: 'extensionCount', + type: 'number', + required: false, + description: 'How many extensions the generated file name should have.', + examples: [2], + }, ], - args: [], }, }; diff --git a/packages/core/js/keywords/domain/system/network-interface-keyword-definition.js b/packages/core/js/keywords/domain/system/network-interface-keyword-definition.js index 53362a3a..1db234ea 100644 --- a/packages/core/js/keywords/domain/system/network-interface-keyword-definition.js +++ b/packages/core/js/keywords/domain/system/network-interface-keyword-definition.js @@ -5,6 +5,7 @@ const SYSTEM_NETWORK_INTERFACE_KEYWORD_DEFINITION = { delegate: { type: 'faker', target: 'system.networkInterface', + argTransform: 'optionsFromHelpArgs', }, help: { summary: 'Returns a random network interface.', @@ -14,12 +15,42 @@ const SYSTEM_NETWORK_INTERFACE_KEYWORD_DEFINITION = { returnType: 'string', usageExamples: [ { - functionCall: 'system.networkInterface', + functionCall: 'system.networkInterface()', sampleReturnValue: 'wlx042125686a3e', description: 'Shows the default system.networkInterface call.', }, + { + functionCall: 'system.networkInterface(interfaceType="en", interfaceSchema="mac")', + sampleReturnValue: 'enx6b042125686a', + description: 'Shows system.networkInterface using interface type and schema options.', + }, + { + functionCall: 'system.networkInterface(interfaceType="en")', + sampleReturnValue: 'ens7f3d0', + description: 'Shows system.networkInterface using an explicit interface type.', + }, + { + functionCall: 'system.networkInterface(interfaceSchema="mac")', + sampleReturnValue: 'wlxb042125686a3', + description: 'Shows system.networkInterface using an explicit interface schema.', + }, + ], + args: [ + { + name: 'interfaceType', + type: 'en|wl|ww', + required: false, + description: 'Network interface type prefix.', + examples: ['en'], + }, + { + name: 'interfaceSchema', + type: 'index|slot|mac|pci', + required: false, + description: 'Network interface naming schema.', + examples: ['mac'], + }, ], - args: [], }, }; diff --git a/packages/core/js/keywords/domain/word/adjective-keyword-definition.js b/packages/core/js/keywords/domain/word/adjective-keyword-definition.js index 4aa505ee..bb9d31c9 100644 --- a/packages/core/js/keywords/domain/word/adjective-keyword-definition.js +++ b/packages/core/js/keywords/domain/word/adjective-keyword-definition.js @@ -1,6 +1,7 @@ import { validateStringValue } from '../../../command-help/command-help-validators.js'; +import { createWordSelectionArgsValidator, WORD_SELECTION_STRATEGY_TYPE } from '../shared/common-arg-validators.js'; -const WORD_SELECTION_STRATEGY_TYPE = 'fail|closest|shortest|longest|any-length'; +const validateWordSelectionArgs = createWordSelectionArgsValidator(); const WORD_ADJECTIVE_KEYWORD_DEFINITION = { keyword: 'word.adjective', @@ -14,6 +15,7 @@ const WORD_ADJECTIVE_KEYWORD_DEFINITION = { docsUrl: 'https://anywaydata.com/docs/test-data/domain/word', fakerDocsUrl: 'https://fakerjs.dev/api/word', validator: validateStringValue, + argsValidator: validateWordSelectionArgs, returnType: 'string', usageExamples: [ { @@ -26,11 +28,6 @@ const WORD_ADJECTIVE_KEYWORD_DEFINITION = { sampleReturnValue: 'major', description: 'Shows word.adjective using length.', }, - { - functionCall: 'word.adjective(max=5)', - sampleReturnValue: 'inferior', - description: 'Shows word.adjective using max.', - }, { functionCall: 'word.adjective(strategy="any-length")', sampleReturnValue: 'inferior', @@ -44,12 +41,6 @@ const WORD_ADJECTIVE_KEYWORD_DEFINITION = { required: false, description: 'Desired length of the generated value.', }, - { - name: 'max', - type: 'number', - required: false, - description: 'Maximum bound used when generating a value.', - }, { name: 'strategy', type: WORD_SELECTION_STRATEGY_TYPE, diff --git a/packages/core/js/keywords/domain/word/adverb-keyword-definition.js b/packages/core/js/keywords/domain/word/adverb-keyword-definition.js index 350f0784..e3937ed1 100644 --- a/packages/core/js/keywords/domain/word/adverb-keyword-definition.js +++ b/packages/core/js/keywords/domain/word/adverb-keyword-definition.js @@ -1,6 +1,7 @@ import { validateStringValue } from '../../../command-help/command-help-validators.js'; +import { createWordSelectionArgsValidator, WORD_SELECTION_STRATEGY_TYPE } from '../shared/common-arg-validators.js'; -const WORD_SELECTION_STRATEGY_TYPE = 'fail|closest|shortest|longest|any-length'; +const validateWordSelectionArgs = createWordSelectionArgsValidator(); const WORD_ADVERB_KEYWORD_DEFINITION = { keyword: 'word.adverb', @@ -14,6 +15,7 @@ const WORD_ADVERB_KEYWORD_DEFINITION = { docsUrl: 'https://anywaydata.com/docs/test-data/domain/word', fakerDocsUrl: 'https://fakerjs.dev/api/word', validator: validateStringValue, + argsValidator: validateWordSelectionArgs, returnType: 'string', usageExamples: [ { @@ -26,11 +28,6 @@ const WORD_ADVERB_KEYWORD_DEFINITION = { sampleReturnValue: 'never', description: 'Shows word.adverb using length.', }, - { - functionCall: 'word.adverb(max=5)', - sampleReturnValue: 'knavishly', - description: 'Shows word.adverb using max.', - }, { functionCall: 'word.adverb(strategy="any-length")', sampleReturnValue: 'knavishly', @@ -44,12 +41,6 @@ const WORD_ADVERB_KEYWORD_DEFINITION = { required: false, description: 'Desired length of the generated value.', }, - { - name: 'max', - type: 'number', - required: false, - description: 'Maximum bound used when generating a value.', - }, { name: 'strategy', type: WORD_SELECTION_STRATEGY_TYPE, diff --git a/packages/core/js/keywords/domain/word/conjunction-keyword-definition.js b/packages/core/js/keywords/domain/word/conjunction-keyword-definition.js index abe5a25b..bb20a12c 100644 --- a/packages/core/js/keywords/domain/word/conjunction-keyword-definition.js +++ b/packages/core/js/keywords/domain/word/conjunction-keyword-definition.js @@ -1,6 +1,7 @@ import { validateStringValue } from '../../../command-help/command-help-validators.js'; +import { createWordSelectionArgsValidator, WORD_SELECTION_STRATEGY_TYPE } from '../shared/common-arg-validators.js'; -const WORD_SELECTION_STRATEGY_TYPE = 'fail|closest|shortest|longest|any-length'; +const validateWordSelectionArgs = createWordSelectionArgsValidator(); const WORD_CONJUNCTION_KEYWORD_DEFINITION = { keyword: 'word.conjunction', @@ -14,6 +15,7 @@ const WORD_CONJUNCTION_KEYWORD_DEFINITION = { docsUrl: 'https://anywaydata.com/docs/test-data/domain/word', fakerDocsUrl: 'https://fakerjs.dev/api/word', validator: validateStringValue, + argsValidator: validateWordSelectionArgs, returnType: 'string', usageExamples: [ { @@ -26,11 +28,6 @@ const WORD_CONJUNCTION_KEYWORD_DEFINITION = { sampleReturnValue: 'until', description: 'Shows word.conjunction using length.', }, - { - functionCall: 'word.conjunction(max=5)', - sampleReturnValue: 'likewise', - description: 'Shows word.conjunction using max.', - }, { functionCall: 'word.conjunction(strategy="any-length")', sampleReturnValue: 'likewise', @@ -44,12 +41,6 @@ const WORD_CONJUNCTION_KEYWORD_DEFINITION = { required: false, description: 'Desired length of the generated value.', }, - { - name: 'max', - type: 'number', - required: false, - description: 'Maximum bound used when generating a value.', - }, { name: 'strategy', type: WORD_SELECTION_STRATEGY_TYPE, diff --git a/packages/core/js/keywords/domain/word/interjection-keyword-definition.js b/packages/core/js/keywords/domain/word/interjection-keyword-definition.js index c8d38511..9d5a0d9a 100644 --- a/packages/core/js/keywords/domain/word/interjection-keyword-definition.js +++ b/packages/core/js/keywords/domain/word/interjection-keyword-definition.js @@ -1,6 +1,7 @@ import { validateStringValue } from '../../../command-help/command-help-validators.js'; +import { createWordSelectionArgsValidator, WORD_SELECTION_STRATEGY_TYPE } from '../shared/common-arg-validators.js'; -const WORD_SELECTION_STRATEGY_TYPE = 'fail|closest|shortest|longest|any-length'; +const validateWordSelectionArgs = createWordSelectionArgsValidator(); const WORD_INTERJECTION_KEYWORD_DEFINITION = { keyword: 'word.interjection', @@ -14,6 +15,7 @@ const WORD_INTERJECTION_KEYWORD_DEFINITION = { docsUrl: 'https://anywaydata.com/docs/test-data/domain/word', fakerDocsUrl: 'https://fakerjs.dev/api/word', validator: validateStringValue, + argsValidator: validateWordSelectionArgs, returnType: 'string', usageExamples: [ { @@ -26,11 +28,6 @@ const WORD_INTERJECTION_KEYWORD_DEFINITION = { sampleReturnValue: 'fooey', description: 'Shows word.interjection using length.', }, - { - functionCall: 'word.interjection(max=5)', - sampleReturnValue: 'woot', - description: 'Shows word.interjection using max.', - }, { functionCall: 'word.interjection(strategy="any-length")', sampleReturnValue: 'woot', @@ -44,12 +41,6 @@ const WORD_INTERJECTION_KEYWORD_DEFINITION = { required: false, description: 'Desired length of the generated value.', }, - { - name: 'max', - type: 'number', - required: false, - description: 'Maximum bound used when generating a value.', - }, { name: 'strategy', type: WORD_SELECTION_STRATEGY_TYPE, diff --git a/packages/core/js/keywords/domain/word/noun-keyword-definition.js b/packages/core/js/keywords/domain/word/noun-keyword-definition.js index 2d2db083..9f4ca312 100644 --- a/packages/core/js/keywords/domain/word/noun-keyword-definition.js +++ b/packages/core/js/keywords/domain/word/noun-keyword-definition.js @@ -1,6 +1,7 @@ import { validateStringValue } from '../../../command-help/command-help-validators.js'; +import { createWordSelectionArgsValidator, WORD_SELECTION_STRATEGY_TYPE } from '../shared/common-arg-validators.js'; -const WORD_SELECTION_STRATEGY_TYPE = 'fail|closest|shortest|longest|any-length'; +const validateWordSelectionArgs = createWordSelectionArgsValidator(); const WORD_NOUN_KEYWORD_DEFINITION = { keyword: 'word.noun', @@ -14,6 +15,7 @@ const WORD_NOUN_KEYWORD_DEFINITION = { docsUrl: 'https://anywaydata.com/docs/test-data/domain/word', fakerDocsUrl: 'https://fakerjs.dev/api/word', validator: validateStringValue, + argsValidator: validateWordSelectionArgs, returnType: 'string', usageExamples: [ { @@ -26,11 +28,6 @@ const WORD_NOUN_KEYWORD_DEFINITION = { sampleReturnValue: 'humor', description: 'Shows word.noun using length.', }, - { - functionCall: 'word.noun(max=5)', - sampleReturnValue: 'heating', - description: 'Shows word.noun using max.', - }, { functionCall: 'word.noun(strategy="any-length")', sampleReturnValue: 'heating', @@ -44,12 +41,6 @@ const WORD_NOUN_KEYWORD_DEFINITION = { required: false, description: 'Desired length of the generated value.', }, - { - name: 'max', - type: 'number', - required: false, - description: 'Maximum bound used when generating a value.', - }, { name: 'strategy', type: WORD_SELECTION_STRATEGY_TYPE, diff --git a/packages/core/js/keywords/domain/word/preposition-keyword-definition.js b/packages/core/js/keywords/domain/word/preposition-keyword-definition.js index 2f17bc1d..6b745cbb 100644 --- a/packages/core/js/keywords/domain/word/preposition-keyword-definition.js +++ b/packages/core/js/keywords/domain/word/preposition-keyword-definition.js @@ -1,6 +1,7 @@ import { validateStringValue } from '../../../command-help/command-help-validators.js'; +import { createWordSelectionArgsValidator, WORD_SELECTION_STRATEGY_TYPE } from '../shared/common-arg-validators.js'; -const WORD_SELECTION_STRATEGY_TYPE = 'fail|closest|shortest|longest|any-length'; +const validateWordSelectionArgs = createWordSelectionArgsValidator(); const WORD_PREPOSITION_KEYWORD_DEFINITION = { keyword: 'word.preposition', @@ -14,6 +15,7 @@ const WORD_PREPOSITION_KEYWORD_DEFINITION = { docsUrl: 'https://anywaydata.com/docs/test-data/domain/word', fakerDocsUrl: 'https://fakerjs.dev/api/word', validator: validateStringValue, + argsValidator: validateWordSelectionArgs, returnType: 'string', usageExamples: [ { @@ -26,11 +28,6 @@ const WORD_PREPOSITION_KEYWORD_DEFINITION = { sampleReturnValue: 'aside', description: 'Shows word.preposition using length.', }, - { - functionCall: 'word.preposition(max=5)', - sampleReturnValue: 'except', - description: 'Shows word.preposition using max.', - }, { functionCall: 'word.preposition(strategy="any-length")', sampleReturnValue: 'except', @@ -44,12 +41,6 @@ const WORD_PREPOSITION_KEYWORD_DEFINITION = { required: false, description: 'Desired length of the generated value.', }, - { - name: 'max', - type: 'number', - required: false, - description: 'Maximum bound used when generating a value.', - }, { name: 'strategy', type: WORD_SELECTION_STRATEGY_TYPE, diff --git a/packages/core/js/keywords/domain/word/sample-keyword-definition.js b/packages/core/js/keywords/domain/word/sample-keyword-definition.js index a2d2ea2f..b4b5a07b 100644 --- a/packages/core/js/keywords/domain/word/sample-keyword-definition.js +++ b/packages/core/js/keywords/domain/word/sample-keyword-definition.js @@ -1,6 +1,7 @@ import { validateStringValue } from '../../../command-help/command-help-validators.js'; +import { createWordSelectionArgsValidator, WORD_SELECTION_STRATEGY_TYPE } from '../shared/common-arg-validators.js'; -const WORD_SELECTION_STRATEGY_TYPE = 'fail|closest|shortest|longest|any-length'; +const validateWordSelectionArgs = createWordSelectionArgsValidator(); const WORD_SAMPLE_KEYWORD_DEFINITION = { keyword: 'word.sample', @@ -15,6 +16,7 @@ const WORD_SAMPLE_KEYWORD_DEFINITION = { docsUrl: 'https://anywaydata.com/docs/test-data/domain/word', fakerDocsUrl: 'https://fakerjs.dev/api/word', validator: validateStringValue, + argsValidator: validateWordSelectionArgs, returnType: 'string', usageExamples: [ { @@ -27,11 +29,6 @@ const WORD_SAMPLE_KEYWORD_DEFINITION = { sampleReturnValue: 'yowza', description: 'Shows word.sample using length.', }, - { - functionCall: 'word.sample(max=5)', - sampleReturnValue: 'boohoo', - description: 'Shows word.sample using max.', - }, { functionCall: 'word.sample(strategy="any-length")', sampleReturnValue: 'boohoo', @@ -45,12 +42,6 @@ const WORD_SAMPLE_KEYWORD_DEFINITION = { required: false, description: 'Desired length of the generated value.', }, - { - name: 'max', - type: 'number', - required: false, - description: 'Maximum bound used when generating a value.', - }, { name: 'strategy', type: WORD_SELECTION_STRATEGY_TYPE, diff --git a/packages/core/js/keywords/domain/word/verb-keyword-definition.js b/packages/core/js/keywords/domain/word/verb-keyword-definition.js index cdaa6bba..1c27517f 100644 --- a/packages/core/js/keywords/domain/word/verb-keyword-definition.js +++ b/packages/core/js/keywords/domain/word/verb-keyword-definition.js @@ -1,6 +1,7 @@ import { validateStringValue } from '../../../command-help/command-help-validators.js'; +import { createWordSelectionArgsValidator, WORD_SELECTION_STRATEGY_TYPE } from '../shared/common-arg-validators.js'; -const WORD_SELECTION_STRATEGY_TYPE = 'fail|closest|shortest|longest|any-length'; +const validateWordSelectionArgs = createWordSelectionArgsValidator(); const WORD_VERB_KEYWORD_DEFINITION = { keyword: 'word.verb', @@ -14,6 +15,7 @@ const WORD_VERB_KEYWORD_DEFINITION = { docsUrl: 'https://anywaydata.com/docs/test-data/domain/word', fakerDocsUrl: 'https://fakerjs.dev/api/word', validator: validateStringValue, + argsValidator: validateWordSelectionArgs, returnType: 'string', usageExamples: [ { @@ -26,11 +28,6 @@ const WORD_VERB_KEYWORD_DEFINITION = { sampleReturnValue: 'mould', description: 'Shows word.verb using length.', }, - { - functionCall: 'word.verb(max=5)', - sampleReturnValue: 'hunger', - description: 'Shows word.verb using max.', - }, { functionCall: 'word.verb(strategy="any-length")', sampleReturnValue: 'hunger', @@ -44,12 +41,6 @@ const WORD_VERB_KEYWORD_DEFINITION = { required: false, description: 'Desired length of the generated value.', }, - { - name: 'max', - type: 'number', - required: false, - description: 'Maximum bound used when generating a value.', - }, { name: 'strategy', type: WORD_SELECTION_STRATEGY_TYPE, diff --git a/packages/core/js/keywords/domain/word/words-keyword-definition.js b/packages/core/js/keywords/domain/word/words-keyword-definition.js index c760b807..9ebc74cb 100644 --- a/packages/core/js/keywords/domain/word/words-keyword-definition.js +++ b/packages/core/js/keywords/domain/word/words-keyword-definition.js @@ -1,4 +1,7 @@ import { validateStringValue } from '../../../command-help/command-help-validators.js'; +import { createPositiveIntegerArgsValidator } from '../shared/common-arg-validators.js'; + +const validateWordWordsArgs = createPositiveIntegerArgsValidator(['count']); const WORD_WORDS_KEYWORD_DEFINITION = { keyword: 'word.words', @@ -12,6 +15,7 @@ const WORD_WORDS_KEYWORD_DEFINITION = { docsUrl: 'https://anywaydata.com/docs/test-data/domain/word', fakerDocsUrl: 'https://fakerjs.dev/api/word', validator: validateStringValue, + argsValidator: validateWordWordsArgs, returnType: 'string', usageExamples: [ { @@ -24,11 +28,6 @@ const WORD_WORDS_KEYWORD_DEFINITION = { sampleReturnValue: 'boohoo pish tenderly above pop', description: 'Shows word.words using count.', }, - { - functionCall: 'word.words(max=5)', - sampleReturnValue: 'fog aboard', - description: 'Shows word.words using max.', - }, ], args: [ { @@ -37,12 +36,6 @@ const WORD_WORDS_KEYWORD_DEFINITION = { required: false, description: 'Number of items to generate.', }, - { - name: 'max', - type: 'number', - required: false, - description: 'Maximum bound used when generating a value.', - }, ], }, }; diff --git a/packages/core/src/tests/command-help/command-help-examples.test-support.js b/packages/core/src/tests/command-help/command-help-examples.test-support.js index f821ce16..6962e0de 100644 --- a/packages/core/src/tests/command-help/command-help-examples.test-support.js +++ b/packages/core/src/tests/command-help/command-help-examples.test-support.js @@ -30,6 +30,10 @@ function isRequiredParam(param) { return param?.required === true || param?.optional === false; } +function isUsageExampleSupportedParam(_entry, param) { + return param?.usageExampleSupported !== false; +} + function splitTopLevelArguments(argsText = '') { const args = []; let current = ''; @@ -277,5 +281,6 @@ export { getOptionalCompanionNames, isForbiddenFakerCommand, isRequiredParam, + isUsageExampleSupportedParam, normalizeExampleValue, }; diff --git a/packages/core/src/tests/command-help/command-help-examples.test.js b/packages/core/src/tests/command-help/command-help-examples.test.js index c4d6b42e..8bd87265 100644 --- a/packages/core/src/tests/command-help/command-help-examples.test.js +++ b/packages/core/src/tests/command-help/command-help-examples.test.js @@ -4,6 +4,7 @@ import { getHelperExampleArgCount, getOptionalCompanionNames, isRequiredParam, + isUsageExampleSupportedParam, } from './command-help-examples.test-support.js'; describe('command help usage examples', () => { @@ -20,8 +21,9 @@ describe('command help usage examples', () => { test('commands expose at least one usage example per optional param, plus a zero-arg example when all params are optional', () => { const missingCoverage = commandCases .map((entry) => { - const optionalCount = entry.params.filter((param) => !isRequiredParam(param)).length; - const allParamsOptional = entry.params.length > 0 && optionalCount === entry.params.length; + const exampleSupportedParams = entry.params.filter((param) => isUsageExampleSupportedParam(entry, param)); + const optionalCount = exampleSupportedParams.filter((param) => !isRequiredParam(param)).length; + const allParamsOptional = exampleSupportedParams.length > 0 && optionalCount === exampleSupportedParams.length; const minimumExampleCount = Math.max(1, optionalCount + (allParamsOptional ? 1 : 0)); return { ...entry, @@ -100,8 +102,10 @@ describe('command help usage examples', () => { test('each optional parameter has a focused usage example and all-optional commands include a zero-arg example', () => { const failures = commandCases.flatMap((entry) => { const usageExamples = Array.isArray(entry.help?.usageExamples) ? entry.help.usageExamples : []; + const exampleSupportedParams = entry.params.filter((param) => isUsageExampleSupportedParam(entry, param)); const optionalParams = entry.params .map((param, index) => ({ ...param, index })) + .filter((param) => isUsageExampleSupportedParam(entry, param)) .filter((param) => !isRequiredParam(param)); const requiredParamNames = new Set(entry.params.filter(isRequiredParam).map((param) => param.name)); const lastRequiredIndex = entry.params.reduce( @@ -110,7 +114,7 @@ describe('command help usage examples', () => { ); const entryFailures = []; - if (entry.params.length > 0 && optionalParams.length === entry.params.length) { + if (optionalParams.length > 0 && optionalParams.length === exampleSupportedParams.length) { const hasZeroArgExample = usageExamples.some((usageExample) => { if (entry.command.startsWith('helpers.')) { return getHelperExampleArgCount(usageExample.functionCall) === 0; diff --git a/packages/core/src/tests/data_generation/keywords/domain/airline/aircraft-type-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/airline/aircraft-type-keyword-definition.test.js index 2c858b16..db035270 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/airline/aircraft-type-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/airline/aircraft-type-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('airline.aircraftType'); +defineDomainKeywordHelpContractTests('airline.aircraftType'); + +describe('airline.aircraftType parameter validation', () => { + test('executes airline.aircraftType() successfully', () => { + const parsed = parseKeywordInvocation('airline.aircraftType()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/airline/airline-iata-code-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/airline/airline-iata-code-keyword-definition.test.js index 5d18bbb8..42530826 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/airline/airline-iata-code-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/airline/airline-iata-code-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('airline.airline.iataCode'); +defineDomainKeywordHelpContractTests('airline.airline.iataCode'); + +describe('airline.airline.iataCode parameter validation', () => { + test('executes airline.airline.iataCode() successfully', () => { + const parsed = parseKeywordInvocation('airline.airline.iataCode()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/airline/airline-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/airline/airline-keyword-definition.test.js index 15c2f534..23275706 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/airline/airline-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/airline/airline-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('airline.airline'); +defineDomainKeywordHelpContractTests('airline.airline'); + +describe('airline.airline parameter validation', () => { + test('executes airline.airline() successfully', () => { + const parsed = parseKeywordInvocation('airline.airline()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/airline/airline-name-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/airline/airline-name-keyword-definition.test.js index 479cdf2e..5d4c9129 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/airline/airline-name-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/airline/airline-name-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('airline.airline.name'); +defineDomainKeywordHelpContractTests('airline.airline.name'); + +describe('airline.airline.name parameter validation', () => { + test('executes airline.airline.name() successfully', () => { + const parsed = parseKeywordInvocation('airline.airline.name()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/airline/airplane-iata-type-code-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/airline/airplane-iata-type-code-keyword-definition.test.js index f2d45998..f82d4566 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/airline/airplane-iata-type-code-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/airline/airplane-iata-type-code-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('airline.airplane.iataTypeCode'); +defineDomainKeywordHelpContractTests('airline.airplane.iataTypeCode'); + +describe('airline.airplane.iataTypeCode parameter validation', () => { + test('executes airline.airplane.iataTypeCode() successfully', () => { + const parsed = parseKeywordInvocation('airline.airplane.iataTypeCode()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/airline/airplane-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/airline/airplane-keyword-definition.test.js index b3a001f3..2626e6d9 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/airline/airplane-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/airline/airplane-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('airline.airplane'); +defineDomainKeywordHelpContractTests('airline.airplane'); + +describe('airline.airplane parameter validation', () => { + test('executes airline.airplane() successfully', () => { + const parsed = parseKeywordInvocation('airline.airplane()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/airline/airplane-name-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/airline/airplane-name-keyword-definition.test.js index e9dfd273..78bbd5ce 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/airline/airplane-name-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/airline/airplane-name-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('airline.airplane.name'); +defineDomainKeywordHelpContractTests('airline.airplane.name'); + +describe('airline.airplane.name parameter validation', () => { + test('executes airline.airplane.name() successfully', () => { + const parsed = parseKeywordInvocation('airline.airplane.name()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/airline/airport-iata-code-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/airline/airport-iata-code-keyword-definition.test.js index 7364a39c..cfec4d76 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/airline/airport-iata-code-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/airline/airport-iata-code-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('airline.airport.iataCode'); +defineDomainKeywordHelpContractTests('airline.airport.iataCode'); + +describe('airline.airport.iataCode parameter validation', () => { + test('executes airline.airport.iataCode() successfully', () => { + const parsed = parseKeywordInvocation('airline.airport.iataCode()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/airline/airport-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/airline/airport-keyword-definition.test.js index 9796ddcb..ba1a7c74 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/airline/airport-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/airline/airport-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('airline.airport'); +defineDomainKeywordHelpContractTests('airline.airport'); + +describe('airline.airport parameter validation', () => { + test('executes airline.airport() successfully', () => { + const parsed = parseKeywordInvocation('airline.airport()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/airline/airport-name-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/airline/airport-name-keyword-definition.test.js index f35643e5..b9fdcaa6 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/airline/airport-name-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/airline/airport-name-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('airline.airport.name'); +defineDomainKeywordHelpContractTests('airline.airport.name'); + +describe('airline.airport.name parameter validation', () => { + test('executes airline.airport.name() successfully', () => { + const parsed = parseKeywordInvocation('airline.airport.name()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/airline/flight-number-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/airline/flight-number-keyword-definition.test.js index f578c2b9..0d9d0345 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/airline/flight-number-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/airline/flight-number-keyword-definition.test.js @@ -1,3 +1,67 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('airline.flightNumber'); +defineDomainKeywordHelpContractTests('airline.flightNumber'); + +describe('airline.flightNumber parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('airline.flightNumber'); + const parsed = parseKeywordInvocation(`airline.flightNumber(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes airline.flightNumber(length=4, addLeadingZeros=true) successfully', () => { + const parsed = parseKeywordInvocation('airline.flightNumber(length=4, addLeadingZeros=true)'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + expect(result).toMatch(/^\d{4}$/); + }); + + test('rejects invalid length type before generation', () => { + expect(validateArgs('length={"bad":true}, addLeadingZeros=true')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be number, not object', + }); + }); + + test('rejects zero length before generation', () => { + expect(validateArgs('length=0, addLeadingZeros=true')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be greater than 0', + }); + }); + + test('rejects negative length before generation', () => { + expect(validateArgs('length=-1, addLeadingZeros=true')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be greater than 0', + }); + }); + + test('rejects fractional length before generation', () => { + expect(validateArgs('length=1.5, addLeadingZeros=true')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be an integer', + }); + }); + + test('rejects invalid addLeadingZeros type before generation', () => { + expect(validateArgs('length=4, addLeadingZeros={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "addLeadingZeros" must be boolean, not object', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/airline/record-locator-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/airline/record-locator-keyword-definition.test.js index 4e21a15f..345b9173 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/airline/record-locator-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/airline/record-locator-keyword-definition.test.js @@ -1,3 +1,59 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('airline.recordLocator'); +defineDomainKeywordHelpContractTests('airline.recordLocator'); + +describe('airline.recordLocator parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('airline.recordLocator'); + const parsed = parseKeywordInvocation(`airline.recordLocator(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes airline.recordLocator(allowNumerics=true) successfully', () => { + const parsed = parseKeywordInvocation('airline.recordLocator(allowNumerics=true)'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid allowNumerics type before generation', () => { + expect(validateArgs('allowNumerics={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "allowNumerics" must be boolean, not object', + }); + }); + + test('rejects invalid allowNumerics integer before generation', () => { + expect(validateArgs('allowNumerics=123')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "allowNumerics" must be boolean, not integer', + }); + }); + + test('rejects invalid allowVisuallySimilarCharacters type before generation', () => { + expect(validateArgs('allowNumerics=true, allowVisuallySimilarCharacters={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "allowVisuallySimilarCharacters" must be boolean, not object', + }); + }); + + test('rejects invalid allowVisuallySimilarCharacters string before generation', () => { + expect(validateArgs('allowNumerics=true, allowVisuallySimilarCharacters="true"')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "allowVisuallySimilarCharacters" must be boolean, not string', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/airline/seat-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/airline/seat-keyword-definition.test.js index 85d9215f..30922e41 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/airline/seat-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/airline/seat-keyword-definition.test.js @@ -1,3 +1,45 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('airline.seat'); +defineDomainKeywordHelpContractTests('airline.seat'); + +describe('airline.seat parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('airline.seat'); + const parsed = parseKeywordInvocation(`airline.seat(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes airline.seat(aircraftType="widebody") successfully', () => { + const parsed = parseKeywordInvocation('airline.seat(aircraftType="widebody")'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid aircraftType type before generation', () => { + expect(validateArgs('aircraftType={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "aircraftType" must be narrowbody, regional or widebody, not object', + }); + }); + + test('rejects unsupported aircraftType value before generation', () => { + expect(validateArgs('aircraftType="unknown"')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "aircraftType" must be narrowbody, regional or widebody, not string', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/animal/bear-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/animal/bear-keyword-definition.test.js index ac574b62..f2e38bae 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/animal/bear-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/animal/bear-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('animal.bear'); +defineDomainKeywordHelpContractTests('animal.bear'); + +describe('animal.bear parameter validation', () => { + test('executes animal.bear() successfully', () => { + const parsed = parseKeywordInvocation('animal.bear()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/animal/bird-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/animal/bird-keyword-definition.test.js index e2eca240..b9076726 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/animal/bird-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/animal/bird-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('animal.bird'); +defineDomainKeywordHelpContractTests('animal.bird'); + +describe('animal.bird parameter validation', () => { + test('executes animal.bird() successfully', () => { + const parsed = parseKeywordInvocation('animal.bird()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/animal/cat-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/animal/cat-keyword-definition.test.js index e16fa082..0d378887 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/animal/cat-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/animal/cat-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('animal.cat'); +defineDomainKeywordHelpContractTests('animal.cat'); + +describe('animal.cat parameter validation', () => { + test('executes animal.cat() successfully', () => { + const parsed = parseKeywordInvocation('animal.cat()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/animal/cetacean-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/animal/cetacean-keyword-definition.test.js index e2c04076..014c60bc 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/animal/cetacean-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/animal/cetacean-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('animal.cetacean'); +defineDomainKeywordHelpContractTests('animal.cetacean'); + +describe('animal.cetacean parameter validation', () => { + test('executes animal.cetacean() successfully', () => { + const parsed = parseKeywordInvocation('animal.cetacean()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/animal/cow-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/animal/cow-keyword-definition.test.js index 46b67f8c..c2d8c429 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/animal/cow-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/animal/cow-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('animal.cow'); +defineDomainKeywordHelpContractTests('animal.cow'); + +describe('animal.cow parameter validation', () => { + test('executes animal.cow() successfully', () => { + const parsed = parseKeywordInvocation('animal.cow()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/animal/crocodilia-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/animal/crocodilia-keyword-definition.test.js index 603a068f..6c41a56c 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/animal/crocodilia-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/animal/crocodilia-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('animal.crocodilia'); +defineDomainKeywordHelpContractTests('animal.crocodilia'); + +describe('animal.crocodilia parameter validation', () => { + test('executes animal.crocodilia() successfully', () => { + const parsed = parseKeywordInvocation('animal.crocodilia()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/animal/dog-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/animal/dog-keyword-definition.test.js index fc9027d7..9ce81418 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/animal/dog-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/animal/dog-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('animal.dog'); +defineDomainKeywordHelpContractTests('animal.dog'); + +describe('animal.dog parameter validation', () => { + test('executes animal.dog() successfully', () => { + const parsed = parseKeywordInvocation('animal.dog()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/animal/fish-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/animal/fish-keyword-definition.test.js index 65d83f8f..f51da4f9 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/animal/fish-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/animal/fish-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('animal.fish'); +defineDomainKeywordHelpContractTests('animal.fish'); + +describe('animal.fish parameter validation', () => { + test('executes animal.fish() successfully', () => { + const parsed = parseKeywordInvocation('animal.fish()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/animal/horse-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/animal/horse-keyword-definition.test.js index b7e87b78..4bae3a2d 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/animal/horse-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/animal/horse-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('animal.horse'); +defineDomainKeywordHelpContractTests('animal.horse'); + +describe('animal.horse parameter validation', () => { + test('executes animal.horse() successfully', () => { + const parsed = parseKeywordInvocation('animal.horse()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/animal/insect-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/animal/insect-keyword-definition.test.js index 7b0d10ec..aa2805c8 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/animal/insect-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/animal/insect-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('animal.insect'); +defineDomainKeywordHelpContractTests('animal.insect'); + +describe('animal.insect parameter validation', () => { + test('executes animal.insect() successfully', () => { + const parsed = parseKeywordInvocation('animal.insect()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/animal/lion-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/animal/lion-keyword-definition.test.js index 58d82925..d58498f3 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/animal/lion-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/animal/lion-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('animal.lion'); +defineDomainKeywordHelpContractTests('animal.lion'); + +describe('animal.lion parameter validation', () => { + test('executes animal.lion() successfully', () => { + const parsed = parseKeywordInvocation('animal.lion()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/animal/pet-name-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/animal/pet-name-keyword-definition.test.js index 8a16440b..f23ce009 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/animal/pet-name-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/animal/pet-name-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('animal.petName'); +defineDomainKeywordHelpContractTests('animal.petName'); + +describe('animal.petName parameter validation', () => { + test('executes animal.petName() successfully', () => { + const parsed = parseKeywordInvocation('animal.petName()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/animal/rabbit-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/animal/rabbit-keyword-definition.test.js index 710fa436..7187ca22 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/animal/rabbit-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/animal/rabbit-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('animal.rabbit'); +defineDomainKeywordHelpContractTests('animal.rabbit'); + +describe('animal.rabbit parameter validation', () => { + test('executes animal.rabbit() successfully', () => { + const parsed = parseKeywordInvocation('animal.rabbit()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/animal/rodent-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/animal/rodent-keyword-definition.test.js index 190b03ec..9d1bf7fe 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/animal/rodent-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/animal/rodent-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('animal.rodent'); +defineDomainKeywordHelpContractTests('animal.rodent'); + +describe('animal.rodent parameter validation', () => { + test('executes animal.rodent() successfully', () => { + const parsed = parseKeywordInvocation('animal.rodent()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/animal/snake-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/animal/snake-keyword-definition.test.js index 9e8964cb..50d38bb1 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/animal/snake-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/animal/snake-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('animal.snake'); +defineDomainKeywordHelpContractTests('animal.snake'); + +describe('animal.snake parameter validation', () => { + test('executes animal.snake() successfully', () => { + const parsed = parseKeywordInvocation('animal.snake()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/animal/type-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/animal/type-keyword-definition.test.js index f00cf080..526d6593 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/animal/type-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/animal/type-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('animal.type'); +defineDomainKeywordHelpContractTests('animal.type'); + +describe('animal.type parameter validation', () => { + test('executes animal.type() successfully', () => { + const parsed = parseKeywordInvocation('animal.type()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/autoincrement/sequence-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/autoincrement/sequence-keyword-definition.test.js index e51ebbfa..58eae8a5 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/autoincrement/sequence-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/autoincrement/sequence-keyword-definition.test.js @@ -1,3 +1,131 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('autoIncrement.sequence'); +defineDomainKeywordHelpContractTests('autoIncrement.sequence'); + +describe('autoIncrement.sequence parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('autoIncrement.sequence'); + const parsed = parseKeywordInvocation(`autoIncrement.sequence(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + function executeSequence(paramsText, autoIncrementState = {}) { + const parsed = parseKeywordInvocation(`autoIncrement.sequence(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return executeDomainKeyword(parsed.keyword, { + args: parsed.args, + autoIncrementState, + }); + } + + test('executes autoIncrement.sequence(start=10, step=5) successfully', () => { + const parsed = parseKeywordInvocation('autoIncrement.sequence(start=10, step=5)'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { args: parsed.args, autoIncrementState: {} }); + + expect(result).toBeDefined(); + expect(result).toEqual(10); + }); + + test('allows negative start values', () => { + expect(executeSequence('start=-10')).toBe(-10); + }); + + test('allows negative step values and advances by the step', () => { + const autoIncrementState = {}; + + expect(executeSequence('start=10, step=-3', autoIncrementState)).toBe(10); + expect(executeSequence('start=10, step=-3', autoIncrementState)).toBe(7); + expect(executeSequence('start=10, step=-3', autoIncrementState)).toBe(4); + expect(executeSequence('start=10, step=-3', autoIncrementState)).toBe(1); + expect(executeSequence('start=10, step=-3', autoIncrementState)).toBe(-2); + }); + + test('allows positive step values and advances by the step', () => { + const autoIncrementState = {}; + + expect(executeSequence('start=-4, step=3', autoIncrementState)).toBe(-4); + expect(executeSequence('start=-4, step=3', autoIncrementState)).toBe(-1); + expect(executeSequence('start=-4, step=3', autoIncrementState)).toBe(2); + expect(executeSequence('start=-4, step=3', autoIncrementState)).toBe(5); + expect(executeSequence('start=-4, step=3', autoIncrementState)).toBe(8); + }); + + test('applies zeropadding to the numeric value', () => { + expect(executeSequence('start=7, zeropadding=3')).toBe('007'); + }); + + test('keeps zeropadding after a prefix and before a suffix', () => { + expect(executeSequence('start=4, prefix="filename", suffix=".txt", zeropadding=4')).toBe('filename0004.txt'); + }); + + test('does not truncate values wider than zeropadding', () => { + expect(executeSequence('start=1000, zeropadding=3')).toBe('1000'); + }); + + test('keeps the minus sign outside zeropadding for negative values', () => { + expect(executeSequence('start=-7, zeropadding=2')).toBe('-07'); + }); + + test('rejects invalid start type before generation', () => { + expect(validateArgs('start={"bad":true}, step=5')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "start" must be integer, not object', + }); + }); + + test('rejects invalid step type before generation', () => { + expect(validateArgs('start=10, step={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "step" must be integer, not object', + }); + }); + + test('rejects invalid prefix type before generation', () => { + expect(validateArgs('start=10, step=5, prefix={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "prefix" must be string, not object', + }); + }); + + test('rejects invalid suffix type before generation', () => { + expect(validateArgs('start=10, step=5, suffix={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "suffix" must be string, not object', + }); + }); + + test('rejects invalid zeropadding type before generation', () => { + expect(validateArgs('start=10, step=5, zeropadding={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "zeropadding" must be integer, not object', + }); + }); + + test('rejects negative zeropadding before generation', () => { + expect(validateArgs('start=10, step=5, zeropadding=-1')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "zeropadding" must be greater than or equal to 0', + }); + }); + + test('rejects fractional zeropadding before generation', () => { + expect(validateArgs('start=10, step=5, zeropadding=1.5')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "zeropadding" must be integer, not number', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/autoincrement/timestamp-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/autoincrement/timestamp-keyword-definition.test.js index aebe1d55..93bdda6d 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/autoincrement/timestamp-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/autoincrement/timestamp-keyword-definition.test.js @@ -1,3 +1,71 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('autoIncrement.timestamp'); +defineDomainKeywordHelpContractTests('autoIncrement.timestamp'); + +describe('autoIncrement.timestamp parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('autoIncrement.timestamp'); + const parsed = parseKeywordInvocation(`autoIncrement.timestamp(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes autoIncrement.timestamp(start="2026-06-12T12:39:23Z", step=1, type="seconds") successfully', () => { + const parsed = parseKeywordInvocation( + 'autoIncrement.timestamp(start="2026-06-12T12:39:23Z", step=1, type="seconds")' + ); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { + args: parsed.args, + rowIndex: 0, + runStartedAt: new Date('2026-06-18T15:55:20.000Z'), + }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid start type before generation', () => { + expect(validateArgs('start={"bad":true}, step=1, type="seconds"')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "start" must be string or number, not object', + }); + }); + + test('rejects invalid step type before generation', () => { + expect(validateArgs('start="2026-06-12T12:39:23Z", step={"bad":true}, type="seconds"')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "step" must be number, not object', + }); + }); + + test('rejects invalid type type before generation', () => { + expect(validateArgs('start="2026-06-12T12:39:23Z", step=1, type={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "type" must be string, not object', + }); + }); + + test('rejects invalid outputFormat type before generation', () => { + expect(validateArgs('start="2026-06-12T12:39:23Z", step=1, type="seconds", outputFormat={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "outputFormat" must be string, not object', + }); + }); + + test('rejects invalid inputFormat type before generation', () => { + expect(validateArgs('start="2026-06-12T12:39:23Z", step=1, type="seconds", inputFormat={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "inputFormat" must be string, not object', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/book/author-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/book/author-keyword-definition.test.js index 7d27a144..508311b8 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/book/author-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/book/author-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('book.author'); +defineDomainKeywordHelpContractTests('book.author'); + +describe('book.author parameter validation', () => { + test('executes book.author() successfully', () => { + const parsed = parseKeywordInvocation('book.author()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/book/format-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/book/format-keyword-definition.test.js index 65db81ca..9fc5d0d3 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/book/format-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/book/format-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('book.format'); +defineDomainKeywordHelpContractTests('book.format'); + +describe('book.format parameter validation', () => { + test('executes book.format() successfully', () => { + const parsed = parseKeywordInvocation('book.format()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/book/genre-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/book/genre-keyword-definition.test.js index 8f90b285..8cd71548 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/book/genre-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/book/genre-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('book.genre'); +defineDomainKeywordHelpContractTests('book.genre'); + +describe('book.genre parameter validation', () => { + test('executes book.genre() successfully', () => { + const parsed = parseKeywordInvocation('book.genre()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/book/publisher-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/book/publisher-keyword-definition.test.js index 9dbde20e..05e6b2e7 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/book/publisher-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/book/publisher-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('book.publisher'); +defineDomainKeywordHelpContractTests('book.publisher'); + +describe('book.publisher parameter validation', () => { + test('executes book.publisher() successfully', () => { + const parsed = parseKeywordInvocation('book.publisher()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/book/series-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/book/series-keyword-definition.test.js index 0bcd7ea3..50796f2a 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/book/series-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/book/series-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('book.series'); +defineDomainKeywordHelpContractTests('book.series'); + +describe('book.series parameter validation', () => { + test('executes book.series() successfully', () => { + const parsed = parseKeywordInvocation('book.series()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/book/title-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/book/title-keyword-definition.test.js index 78c47ddb..e3fbe503 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/book/title-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/book/title-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('book.title'); +defineDomainKeywordHelpContractTests('book.title'); + +describe('book.title parameter validation', () => { + test('executes book.title() successfully', () => { + const parsed = parseKeywordInvocation('book.title()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/color/cmyk-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/color/cmyk-keyword-definition.test.js index 5004bb66..2b38b531 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/color/cmyk-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/color/cmyk-keyword-definition.test.js @@ -1,3 +1,38 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('color.cmyk'); +defineDomainKeywordHelpContractTests('color.cmyk'); + +describe('color.cmyk parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('color.cmyk'); + const parsed = parseKeywordInvocation(`color.cmyk(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes color.cmyk(format="decimal") successfully', () => { + const parsed = parseKeywordInvocation('color.cmyk(format="decimal")'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid format type before generation', () => { + expect(validateArgs('format={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "format" must be decimal, css or binary, not object', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/color/color-by-csscolor-space-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/color/color-by-csscolor-space-keyword-definition.test.js index b30be502..75079c0e 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/color/color-by-csscolor-space-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/color/color-by-csscolor-space-keyword-definition.test.js @@ -1,3 +1,46 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('color.colorByCSSColorSpace'); +defineDomainKeywordHelpContractTests('color.colorByCSSColorSpace'); + +describe('color.colorByCSSColorSpace parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('color.colorByCSSColorSpace'); + const parsed = parseKeywordInvocation(`color.colorByCSSColorSpace(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes color.colorByCSSColorSpace(format="decimal") successfully', () => { + const parsed = parseKeywordInvocation('color.colorByCSSColorSpace(format="decimal")'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid format type before generation', () => { + expect(validateArgs('format={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "format" must be decimal, css or binary, not object', + }); + }); + + test('rejects invalid space type before generation', () => { + expect(validateArgs('format="decimal", space={"bad":true}')).toEqual({ + ok: false, + error: + 'Invalid keyword arguments: argument "space" must be sRGB, display-p3, rec2020, a98-rgb or prophoto-rgb, not object', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/color/css-supported-function-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/color/css-supported-function-keyword-definition.test.js index 32b01d1f..843beefa 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/color/css-supported-function-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/color/css-supported-function-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('color.cssSupportedFunction'); +defineDomainKeywordHelpContractTests('color.cssSupportedFunction'); + +describe('color.cssSupportedFunction parameter validation', () => { + test('executes color.cssSupportedFunction() successfully', () => { + const parsed = parseKeywordInvocation('color.cssSupportedFunction()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/color/css-supported-space-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/color/css-supported-space-keyword-definition.test.js index 6e781ebb..5932ccd7 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/color/css-supported-space-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/color/css-supported-space-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('color.cssSupportedSpace'); +defineDomainKeywordHelpContractTests('color.cssSupportedSpace'); + +describe('color.cssSupportedSpace parameter validation', () => { + test('executes color.cssSupportedSpace() successfully', () => { + const parsed = parseKeywordInvocation('color.cssSupportedSpace()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/color/hsl-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/color/hsl-keyword-definition.test.js index 4475673f..59769b76 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/color/hsl-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/color/hsl-keyword-definition.test.js @@ -1,3 +1,45 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('color.hsl'); +defineDomainKeywordHelpContractTests('color.hsl'); + +describe('color.hsl parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('color.hsl'); + const parsed = parseKeywordInvocation(`color.hsl(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes color.hsl(format="css") successfully', () => { + const parsed = parseKeywordInvocation('color.hsl(format="css")'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid format type before generation', () => { + expect(validateArgs('format={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "format" must be decimal, css or binary, not object', + }); + }); + + test('rejects invalid includeAlpha type before generation', () => { + expect(validateArgs('format="css", includeAlpha={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "includeAlpha" must be boolean, not object', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/color/human-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/color/human-keyword-definition.test.js index 14f67656..5bce3bbf 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/color/human-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/color/human-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('color.human'); +defineDomainKeywordHelpContractTests('color.human'); + +describe('color.human parameter validation', () => { + test('executes color.human() successfully', () => { + const parsed = parseKeywordInvocation('color.human()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/color/hwb-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/color/hwb-keyword-definition.test.js index 34b90cea..cb3f5500 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/color/hwb-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/color/hwb-keyword-definition.test.js @@ -1,3 +1,38 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('color.hwb'); +defineDomainKeywordHelpContractTests('color.hwb'); + +describe('color.hwb parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('color.hwb'); + const parsed = parseKeywordInvocation(`color.hwb(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes color.hwb(format="decimal") successfully', () => { + const parsed = parseKeywordInvocation('color.hwb(format="decimal")'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid format type before generation', () => { + expect(validateArgs('format={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "format" must be decimal, css or binary, not object', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/color/lab-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/color/lab-keyword-definition.test.js index 92d1528a..96291a46 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/color/lab-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/color/lab-keyword-definition.test.js @@ -1,3 +1,38 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('color.lab'); +defineDomainKeywordHelpContractTests('color.lab'); + +describe('color.lab parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('color.lab'); + const parsed = parseKeywordInvocation(`color.lab(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes color.lab(format="decimal") successfully', () => { + const parsed = parseKeywordInvocation('color.lab(format="decimal")'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid format type before generation', () => { + expect(validateArgs('format={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "format" must be decimal, css or binary, not object', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/color/lch-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/color/lch-keyword-definition.test.js index 611f5db8..cbfcca1e 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/color/lch-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/color/lch-keyword-definition.test.js @@ -1,3 +1,38 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('color.lch'); +defineDomainKeywordHelpContractTests('color.lch'); + +describe('color.lch parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('color.lch'); + const parsed = parseKeywordInvocation(`color.lch(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes color.lch(format="decimal") successfully', () => { + const parsed = parseKeywordInvocation('color.lch(format="decimal")'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid format type before generation', () => { + expect(validateArgs('format={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "format" must be decimal, css or binary, not object', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/color/rgb-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/color/rgb-keyword-definition.test.js index 784f07b2..b4efd732 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/color/rgb-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/color/rgb-keyword-definition.test.js @@ -1,3 +1,59 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('color.rgb'); +defineDomainKeywordHelpContractTests('color.rgb'); + +describe('color.rgb parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('color.rgb'); + const parsed = parseKeywordInvocation(`color.rgb(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes color.rgb(casing="upper") successfully', () => { + const parsed = parseKeywordInvocation('color.rgb(casing="upper")'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid casing type before generation', () => { + expect(validateArgs('casing={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "casing" must be lower, upper or mixed, not object', + }); + }); + + test('rejects invalid format type before generation', () => { + expect(validateArgs('casing="upper", format={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "format" must be hex, decimal, css or binary, not object', + }); + }); + + test('rejects invalid includeAlpha type before generation', () => { + expect(validateArgs('casing="upper", includeAlpha={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "includeAlpha" must be boolean, not object', + }); + }); + + test('rejects invalid prefix type before generation', () => { + expect(validateArgs('casing="upper", prefix={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "prefix" must be string, not object', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/color/space-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/color/space-keyword-definition.test.js index 5e898a9f..f9a9170e 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/color/space-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/color/space-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('color.space'); +defineDomainKeywordHelpContractTests('color.space'); + +describe('color.space parameter validation', () => { + test('executes color.space() successfully', () => { + const parsed = parseKeywordInvocation('color.space()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/commerce/department-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/commerce/department-keyword-definition.test.js index 22b2ea1f..67cef0b2 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/commerce/department-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/commerce/department-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('commerce.department'); +defineDomainKeywordHelpContractTests('commerce.department'); + +describe('commerce.department parameter validation', () => { + test('executes commerce.department() successfully', () => { + const parsed = parseKeywordInvocation('commerce.department()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/commerce/isbn-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/commerce/isbn-keyword-definition.test.js index b64b8e4d..61164a7c 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/commerce/isbn-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/commerce/isbn-keyword-definition.test.js @@ -1,3 +1,45 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('commerce.isbn'); +defineDomainKeywordHelpContractTests('commerce.isbn'); + +describe('commerce.isbn parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('commerce.isbn'); + const parsed = parseKeywordInvocation(`commerce.isbn(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes commerce.isbn(separator="-") successfully', () => { + const parsed = parseKeywordInvocation('commerce.isbn(separator="-")'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid separator type before generation', () => { + expect(validateArgs('separator={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "separator" must be string, not object', + }); + }); + + test('rejects invalid variant type before generation', () => { + expect(validateArgs('separator="-", variant={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "variant" must be 10 or 13, not object', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/commerce/price-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/commerce/price-keyword-definition.test.js index 1ce12702..83c62a49 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/commerce/price-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/commerce/price-keyword-definition.test.js @@ -1,3 +1,59 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('commerce.price'); +defineDomainKeywordHelpContractTests('commerce.price'); + +describe('commerce.price parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('commerce.price'); + const parsed = parseKeywordInvocation(`commerce.price(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes commerce.price(dec=2, max=10, min=1, symbol="$") successfully', () => { + const parsed = parseKeywordInvocation('commerce.price(dec=2, max=10, min=1, symbol="$")'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid dec type before generation', () => { + expect(validateArgs('dec={"bad":true}, max=10, min=1, symbol="$"')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "dec" must be integer, not object', + }); + }); + + test('rejects invalid max type before generation', () => { + expect(validateArgs('dec=2, max={"bad":true}, min=1, symbol="$"')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "max" must be number, not object', + }); + }); + + test('rejects invalid min type before generation', () => { + expect(validateArgs('dec=2, max=10, min={"bad":true}, symbol="$"')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "min" must be number, not object', + }); + }); + + test('rejects invalid symbol type before generation', () => { + expect(validateArgs('dec=2, max=10, min=1, symbol={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "symbol" must be string, not object', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/commerce/product-adjective-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/commerce/product-adjective-keyword-definition.test.js index c21eeaa8..bc062788 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/commerce/product-adjective-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/commerce/product-adjective-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('commerce.productAdjective'); +defineDomainKeywordHelpContractTests('commerce.productAdjective'); + +describe('commerce.productAdjective parameter validation', () => { + test('executes commerce.productAdjective() successfully', () => { + const parsed = parseKeywordInvocation('commerce.productAdjective()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/commerce/product-description-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/commerce/product-description-keyword-definition.test.js index b4684024..989cecdf 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/commerce/product-description-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/commerce/product-description-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('commerce.productDescription'); +defineDomainKeywordHelpContractTests('commerce.productDescription'); + +describe('commerce.productDescription parameter validation', () => { + test('executes commerce.productDescription() successfully', () => { + const parsed = parseKeywordInvocation('commerce.productDescription()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/commerce/product-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/commerce/product-keyword-definition.test.js index 3a326cea..e98a78b1 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/commerce/product-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/commerce/product-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('commerce.product'); +defineDomainKeywordHelpContractTests('commerce.product'); + +describe('commerce.product parameter validation', () => { + test('executes commerce.product() successfully', () => { + const parsed = parseKeywordInvocation('commerce.product()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/commerce/product-material-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/commerce/product-material-keyword-definition.test.js index 4235aafb..aff61f8d 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/commerce/product-material-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/commerce/product-material-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('commerce.productMaterial'); +defineDomainKeywordHelpContractTests('commerce.productMaterial'); + +describe('commerce.productMaterial parameter validation', () => { + test('executes commerce.productMaterial() successfully', () => { + const parsed = parseKeywordInvocation('commerce.productMaterial()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/commerce/product-name-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/commerce/product-name-keyword-definition.test.js index 726ab543..aae2893c 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/commerce/product-name-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/commerce/product-name-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('commerce.productName'); +defineDomainKeywordHelpContractTests('commerce.productName'); + +describe('commerce.productName parameter validation', () => { + test('executes commerce.productName() successfully', () => { + const parsed = parseKeywordInvocation('commerce.productName()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/commerce/upc-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/commerce/upc-keyword-definition.test.js index cdd55e87..5a032973 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/commerce/upc-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/commerce/upc-keyword-definition.test.js @@ -1,3 +1,38 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('commerce.upc'); +defineDomainKeywordHelpContractTests('commerce.upc'); + +describe('commerce.upc parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('commerce.upc'); + const parsed = parseKeywordInvocation(`commerce.upc(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes commerce.upc(prefix="01234") successfully', () => { + const parsed = parseKeywordInvocation('commerce.upc(prefix="01234")'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid prefix type before generation', () => { + expect(validateArgs('prefix={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "prefix" must be string, not object', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/company/buzz-adjective-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/company/buzz-adjective-keyword-definition.test.js index 1d5ab7df..2304b95c 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/company/buzz-adjective-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/company/buzz-adjective-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('company.buzzAdjective'); +defineDomainKeywordHelpContractTests('company.buzzAdjective'); + +describe('company.buzzAdjective parameter validation', () => { + test('executes company.buzzAdjective() successfully', () => { + const parsed = parseKeywordInvocation('company.buzzAdjective()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/company/buzz-noun-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/company/buzz-noun-keyword-definition.test.js index 468dfe9b..58e583a1 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/company/buzz-noun-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/company/buzz-noun-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('company.buzzNoun'); +defineDomainKeywordHelpContractTests('company.buzzNoun'); + +describe('company.buzzNoun parameter validation', () => { + test('executes company.buzzNoun() successfully', () => { + const parsed = parseKeywordInvocation('company.buzzNoun()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/company/buzz-phrase-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/company/buzz-phrase-keyword-definition.test.js index a852d954..804b271a 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/company/buzz-phrase-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/company/buzz-phrase-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('company.buzzPhrase'); +defineDomainKeywordHelpContractTests('company.buzzPhrase'); + +describe('company.buzzPhrase parameter validation', () => { + test('executes company.buzzPhrase() successfully', () => { + const parsed = parseKeywordInvocation('company.buzzPhrase()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/company/buzz-verb-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/company/buzz-verb-keyword-definition.test.js index b7cd039b..00b523c2 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/company/buzz-verb-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/company/buzz-verb-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('company.buzzVerb'); +defineDomainKeywordHelpContractTests('company.buzzVerb'); + +describe('company.buzzVerb parameter validation', () => { + test('executes company.buzzVerb() successfully', () => { + const parsed = parseKeywordInvocation('company.buzzVerb()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/company/catch-phrase-adjective-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/company/catch-phrase-adjective-keyword-definition.test.js index 8fd4c04e..45f906c0 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/company/catch-phrase-adjective-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/company/catch-phrase-adjective-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('company.catchPhraseAdjective'); +defineDomainKeywordHelpContractTests('company.catchPhraseAdjective'); + +describe('company.catchPhraseAdjective parameter validation', () => { + test('executes company.catchPhraseAdjective() successfully', () => { + const parsed = parseKeywordInvocation('company.catchPhraseAdjective()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/company/catch-phrase-descriptor-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/company/catch-phrase-descriptor-keyword-definition.test.js index 44cbc8d0..a589ed95 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/company/catch-phrase-descriptor-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/company/catch-phrase-descriptor-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('company.catchPhraseDescriptor'); +defineDomainKeywordHelpContractTests('company.catchPhraseDescriptor'); + +describe('company.catchPhraseDescriptor parameter validation', () => { + test('executes company.catchPhraseDescriptor() successfully', () => { + const parsed = parseKeywordInvocation('company.catchPhraseDescriptor()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/company/catch-phrase-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/company/catch-phrase-keyword-definition.test.js index 0fc7e2b8..b1e7d0d9 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/company/catch-phrase-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/company/catch-phrase-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('company.catchPhrase'); +defineDomainKeywordHelpContractTests('company.catchPhrase'); + +describe('company.catchPhrase parameter validation', () => { + test('executes company.catchPhrase() successfully', () => { + const parsed = parseKeywordInvocation('company.catchPhrase()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/company/catch-phrase-noun-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/company/catch-phrase-noun-keyword-definition.test.js index 10df9f83..d5f59c45 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/company/catch-phrase-noun-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/company/catch-phrase-noun-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('company.catchPhraseNoun'); +defineDomainKeywordHelpContractTests('company.catchPhraseNoun'); + +describe('company.catchPhraseNoun parameter validation', () => { + test('executes company.catchPhraseNoun() successfully', () => { + const parsed = parseKeywordInvocation('company.catchPhraseNoun()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/company/name-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/company/name-keyword-definition.test.js index 96a8a12d..07a7a90d 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/company/name-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/company/name-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('company.name'); +defineDomainKeywordHelpContractTests('company.name'); + +describe('company.name parameter validation', () => { + test('executes company.name() successfully', () => { + const parsed = parseKeywordInvocation('company.name()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/database/collation-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/database/collation-keyword-definition.test.js index e86feb1c..7b3ec0fa 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/database/collation-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/database/collation-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('database.collation'); +defineDomainKeywordHelpContractTests('database.collation'); + +describe('database.collation parameter validation', () => { + test('executes database.collation() successfully', () => { + const parsed = parseKeywordInvocation('database.collation()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/database/column-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/database/column-keyword-definition.test.js index fb48c9fb..5b6ff6b2 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/database/column-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/database/column-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('database.column'); +defineDomainKeywordHelpContractTests('database.column'); + +describe('database.column parameter validation', () => { + test('executes database.column() successfully', () => { + const parsed = parseKeywordInvocation('database.column()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/database/engine-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/database/engine-keyword-definition.test.js index fbe2087b..5f1a31d5 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/database/engine-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/database/engine-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('database.engine'); +defineDomainKeywordHelpContractTests('database.engine'); + +describe('database.engine parameter validation', () => { + test('executes database.engine() successfully', () => { + const parsed = parseKeywordInvocation('database.engine()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/database/mongodb-object-id-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/database/mongodb-object-id-keyword-definition.test.js index 09f9a020..fa09b4fa 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/database/mongodb-object-id-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/database/mongodb-object-id-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('database.mongodbObjectId'); +defineDomainKeywordHelpContractTests('database.mongodbObjectId'); + +describe('database.mongodbObjectId parameter validation', () => { + test('executes database.mongodbObjectId() successfully', () => { + const parsed = parseKeywordInvocation('database.mongodbObjectId()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/database/type-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/database/type-keyword-definition.test.js index 38f2f9e1..b886e507 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/database/type-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/database/type-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('database.type'); +defineDomainKeywordHelpContractTests('database.type'); + +describe('database.type parameter validation', () => { + test('executes database.type() successfully', () => { + const parsed = parseKeywordInvocation('database.type()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/datatype/boolean-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/datatype/boolean-keyword-definition.test.js index d8d25909..775f4e0a 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/datatype/boolean-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/datatype/boolean-keyword-definition.test.js @@ -1,3 +1,52 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('datatype.boolean'); +defineDomainKeywordHelpContractTests('datatype.boolean'); + +describe('datatype.boolean parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('datatype.boolean'); + const parsed = parseKeywordInvocation(`datatype.boolean(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes datatype.boolean(probability=0.5) successfully', () => { + const parsed = parseKeywordInvocation('datatype.boolean(probability=0.5)'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(typeof result).toBe('boolean'); + }); + + test('rejects invalid probability type before generation', () => { + expect(validateArgs('probability={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "probability" must be number, not object', + }); + }); + + test('rejects probability above range before generation', () => { + expect(validateArgs('probability=2')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "probability" must be between 0 and 1', + }); + }); + + test('rejects probability below range before generation', () => { + expect(validateArgs('probability=-0.1')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "probability" must be between 0 and 1', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/datatype/enum-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/datatype/enum-keyword-definition.test.js new file mode 100644 index 00000000..9be7f1a7 --- /dev/null +++ b/packages/core/src/tests/data_generation/keywords/domain/datatype/enum-keyword-definition.test.js @@ -0,0 +1,65 @@ +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; + +defineDomainKeywordHelpContractTests('datatype.enum'); + +describe('datatype.enum parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('datatype.enum'); + const parsed = parseKeywordInvocation(`datatype.enum(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes datatype.enum(values=["GET","POST","PUT"]) successfully', () => { + const parsed = parseKeywordInvocation('datatype.enum(values=["GET","POST","PUT"])'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { args: parsed.args }); + + expect(['GET', 'POST', 'PUT']).toContain(result); + }); + + test('rejects missing enum values before generation', () => { + expect(validateArgs('')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "values" is required', + }); + }); + + test('rejects empty csv enum values before generation', () => { + expect(validateArgs('values=""')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "values" is required', + }); + }); + + test('rejects empty array enum values before generation', () => { + expect(validateArgs('values=[]')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "values" is required', + }); + }); + + test('rejects blank enum entries before generation', () => { + expect(validateArgs('values=["GET",""]')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: enum values cannot be empty', + }); + }); + + test('rejects invalid enum value type before generation', () => { + expect(validateArgs('values={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "values" must be comma-separated list or array, not object', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/date/anytime-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/date/anytime-keyword-definition.test.js index 5dfae387..7b4ab82f 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/date/anytime-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/date/anytime-keyword-definition.test.js @@ -1,3 +1,38 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('date.anytime'); +defineDomainKeywordHelpContractTests('date.anytime'); + +describe('date.anytime parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('date.anytime'); + const parsed = parseKeywordInvocation(`date.anytime(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes date.anytime(refDate=1577836800000) successfully', () => { + const parsed = parseKeywordInvocation('date.anytime(refDate=1577836800000)'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid refDate type before generation', () => { + expect(validateArgs('refDate={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "refDate" must be integer, not object', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/date/between-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/date/between-keyword-definition.test.js index 723594b6..eca21527 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/date/between-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/date/between-keyword-definition.test.js @@ -1,3 +1,63 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('date.between'); +defineDomainKeywordHelpContractTests('date.between'); + +describe('date.between parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('date.between'); + const parsed = parseKeywordInvocation(`date.between(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes date.between(from=1577836800000, to=1609372800000) successfully', () => { + const parsed = parseKeywordInvocation('date.between(from=1577836800000, to=1609372800000)'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects missing required from before generation', () => { + expect(validateArgs('')).toEqual({ ok: false, error: 'Invalid keyword arguments: argument "from" is required' }); + }); + + test('rejects invalid from type before generation', () => { + expect(validateArgs('from={"bad":true}, to=1609372800000')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "from" must be integer, not object', + }); + }); + + test('rejects missing required to before generation', () => { + expect(validateArgs('from=1577836800000')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "to" is required', + }); + }); + + test('rejects invalid to type before generation', () => { + expect(validateArgs('from=1577836800000, to={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "to" must be integer, not object', + }); + }); + + test('rejects from greater than to before generation', () => { + expect(validateArgs('from=10, to=1')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "from" must be less than or equal to argument "to"', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/date/betweens-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/date/betweens-keyword-definition.test.js index 29dff706..7b087c97 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/date/betweens-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/date/betweens-keyword-definition.test.js @@ -1,3 +1,94 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('date.betweens'); +defineDomainKeywordHelpContractTests('date.betweens'); + +describe('date.betweens parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('date.betweens'); + const parsed = parseKeywordInvocation(`date.betweens(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes date.betweens(from=1577836800000, to=1609372800000) successfully', () => { + const parsed = parseKeywordInvocation('date.betweens(from=1577836800000, to=1609372800000)'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid count type before generation', () => { + expect(validateArgs('count={"bad":true}, from=1577836800000, to=1609372800000')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "count" must be integer, not object', + }); + }); + + test('rejects zero count before generation', () => { + expect(validateArgs('count=0, from=1577836800000, to=1609372800000')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "count" must be greater than 0', + }); + }); + + test('rejects negative count before generation', () => { + expect(validateArgs('count=-1, from=1577836800000, to=1609372800000')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "count" must be greater than 0', + }); + }); + + test('rejects fractional count before generation', () => { + expect(validateArgs('count=1.5, from=1577836800000, to=1609372800000')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "count" must be integer, not number', + }); + }); + + test('rejects missing required from before generation', () => { + expect(validateArgs('')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "from" is required', + }); + }); + + test('rejects invalid from type before generation', () => { + expect(validateArgs('from={"bad":true}, to=1609372800000')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "from" must be integer, not object', + }); + }); + + test('rejects missing required to before generation', () => { + expect(validateArgs('from=1577836800000')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "to" is required', + }); + }); + + test('rejects invalid to type before generation', () => { + expect(validateArgs('from=1577836800000, to={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "to" must be integer, not object', + }); + }); + + test('rejects from greater than to before generation', () => { + expect(validateArgs('from=10, to=1')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "from" must be less than or equal to argument "to"', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/date/birthdate-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/date/birthdate-keyword-definition.test.js index 2c503d94..e44e92bd 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/date/birthdate-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/date/birthdate-keyword-definition.test.js @@ -1,3 +1,66 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('date.birthdate'); +defineDomainKeywordHelpContractTests('date.birthdate'); + +describe('date.birthdate parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('date.birthdate'); + const parsed = parseKeywordInvocation(`date.birthdate(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes date.birthdate(refDate=20000, max=69, min=16, mode="age") successfully', () => { + const parsed = parseKeywordInvocation('date.birthdate(refDate=20000, max=69, min=16, mode="age")'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid refDate type before generation', () => { + expect(validateArgs('refDate={"bad":true}, max=69, min=16, mode="age"')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "refDate" must be integer, not object', + }); + }); + + test('rejects invalid max type before generation', () => { + expect(validateArgs('refDate=20000, max={"bad":true}, min=16, mode="age"')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "max" must be integer, not object', + }); + }); + + test('rejects invalid min type before generation', () => { + expect(validateArgs('refDate=20000, max=69, min={"bad":true}, mode="age"')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "min" must be integer, not object', + }); + }); + + test('rejects invalid mode type before generation', () => { + expect(validateArgs('refDate=20000, max=69, min=16, mode={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "mode" must be age or year, not object', + }); + }); + + test('rejects min greater than max before generation', () => { + expect(validateArgs('refDate=20000, max=1, min=10, mode="age"')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "min" must be less than or equal to argument "max"', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/date/future-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/date/future-keyword-definition.test.js index de4f3e7b..1e16f6fa 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/date/future-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/date/future-keyword-definition.test.js @@ -1,3 +1,52 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('date.future'); +defineDomainKeywordHelpContractTests('date.future'); + +describe('date.future parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('date.future'); + const parsed = parseKeywordInvocation(`date.future(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes date.future(refDate=1577836800000) successfully', () => { + const parsed = parseKeywordInvocation('date.future(refDate=1577836800000)'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid refDate type before generation', () => { + expect(validateArgs('refDate={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "refDate" must be integer, not object', + }); + }); + + test('rejects invalid years type before generation', () => { + expect(validateArgs('refDate=1577836800000, years={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "years" must be integer, not object', + }); + }); + + test('rejects fractional years before generation', () => { + expect(validateArgs('refDate=1577836800000, years=1.5')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "years" must be integer, not number', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/date/month-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/date/month-keyword-definition.test.js index e70d6260..1c7813ab 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/date/month-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/date/month-keyword-definition.test.js @@ -1,3 +1,45 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('date.month'); +defineDomainKeywordHelpContractTests('date.month'); + +describe('date.month parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('date.month'); + const parsed = parseKeywordInvocation(`date.month(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes date.month(abbreviated=true) successfully', () => { + const parsed = parseKeywordInvocation('date.month(abbreviated=true)'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid abbreviated type before generation', () => { + expect(validateArgs('abbreviated={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "abbreviated" must be boolean, not object', + }); + }); + + test('rejects invalid context type before generation', () => { + expect(validateArgs('abbreviated=true, context={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "context" must be boolean, not object', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/date/past-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/date/past-keyword-definition.test.js index afea907f..0aa6576d 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/date/past-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/date/past-keyword-definition.test.js @@ -1,3 +1,52 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('date.past'); +defineDomainKeywordHelpContractTests('date.past'); + +describe('date.past parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('date.past'); + const parsed = parseKeywordInvocation(`date.past(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes date.past(refDate=1577836800000) successfully', () => { + const parsed = parseKeywordInvocation('date.past(refDate=1577836800000)'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid refDate type before generation', () => { + expect(validateArgs('refDate={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "refDate" must be integer, not object', + }); + }); + + test('rejects invalid years type before generation', () => { + expect(validateArgs('refDate=1577836800000, years={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "years" must be integer, not object', + }); + }); + + test('rejects fractional years before generation', () => { + expect(validateArgs('refDate=1577836800000, years=1.5')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "years" must be integer, not number', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/date/recent-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/date/recent-keyword-definition.test.js index 0baf21bd..0c908b11 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/date/recent-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/date/recent-keyword-definition.test.js @@ -1,3 +1,59 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('date.recent'); +defineDomainKeywordHelpContractTests('date.recent'); + +describe('date.recent parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('date.recent'); + const parsed = parseKeywordInvocation(`date.recent(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes date.recent(days=7) successfully', () => { + const parsed = parseKeywordInvocation('date.recent(days=7)'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid days type before generation', () => { + expect(validateArgs('days={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "days" must be integer, not object', + }); + }); + + test('rejects negative days before generation', () => { + expect(validateArgs('days=-1')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "days" must be greater than or equal to 0', + }); + }); + + test('rejects fractional days before generation', () => { + expect(validateArgs('days=1.5')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "days" must be integer, not number', + }); + }); + + test('rejects invalid refDate type before generation', () => { + expect(validateArgs('days=7, refDate={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "refDate" must be integer, not object', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/date/soon-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/date/soon-keyword-definition.test.js index 649e93ec..d453f7e7 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/date/soon-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/date/soon-keyword-definition.test.js @@ -1,3 +1,52 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('date.soon'); +defineDomainKeywordHelpContractTests('date.soon'); + +describe('date.soon parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('date.soon'); + const parsed = parseKeywordInvocation(`date.soon(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes date.soon(days=7) successfully', () => { + const parsed = parseKeywordInvocation('date.soon(days=7)'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid days type before generation', () => { + expect(validateArgs('days={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "days" must be integer, not object', + }); + }); + + test('rejects fractional days before generation', () => { + expect(validateArgs('days=1.5')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "days" must be integer, not number', + }); + }); + + test('rejects invalid refDate type before generation', () => { + expect(validateArgs('days=7, refDate={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "refDate" must be integer, not object', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/date/time-zone-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/date/time-zone-keyword-definition.test.js index 131d02b4..d3d42ba4 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/date/time-zone-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/date/time-zone-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('date.timeZone'); +defineDomainKeywordHelpContractTests('date.timeZone'); + +describe('date.timeZone parameter validation', () => { + test('executes date.timeZone() successfully', () => { + const parsed = parseKeywordInvocation('date.timeZone()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/date/weekday-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/date/weekday-keyword-definition.test.js index e7ae0339..a93c927f 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/date/weekday-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/date/weekday-keyword-definition.test.js @@ -1,3 +1,45 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('date.weekday'); +defineDomainKeywordHelpContractTests('date.weekday'); + +describe('date.weekday parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('date.weekday'); + const parsed = parseKeywordInvocation(`date.weekday(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes date.weekday(abbreviated=true) successfully', () => { + const parsed = parseKeywordInvocation('date.weekday(abbreviated=true)'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid abbreviated type before generation', () => { + expect(validateArgs('abbreviated={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "abbreviated" must be boolean, not object', + }); + }); + + test('rejects invalid context type before generation', () => { + expect(validateArgs('abbreviated=true, context={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "context" must be boolean, not object', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/define-domain-keyword-definition-tests.js b/packages/core/src/tests/data_generation/keywords/domain/define-domain-keyword-definition-tests.js deleted file mode 100644 index 2e9b2ac9..00000000 --- a/packages/core/src/tests/data_generation/keywords/domain/define-domain-keyword-definition-tests.js +++ /dev/null @@ -1,66 +0,0 @@ -import { validateCommandHelpValue } from '../../../../../js/command-help/command-help-contract.js'; -import { DOMAIN_KEYWORD_DEFINITIONS } from '../../../../../js/domain/domain-keyword-definitions.js'; -import { - buildValidationContext, - executeDomainExample, - normalizeExampleValue, -} from '../../../command-help/command-help-examples.test-support.js'; - -function getDomainKeywordDefinition(keyword) { - return DOMAIN_KEYWORD_DEFINITIONS.find((definition) => definition.keyword === keyword) || null; -} - -function defineDomainKeywordDefinitionTests(keyword) { - describe(`domain keyword definition ${keyword}`, () => { - const definition = getDomainKeywordDefinition(keyword); - - test('is registered with structured help metadata', () => { - expect(definition).toBeDefined(); - expect(definition).toEqual( - expect.objectContaining({ - keyword, - delegate: expect.objectContaining({ - type: expect.any(String), - target: expect.any(String), - }), - help: expect.objectContaining({ - summary: expect.any(String), - docsUrl: expect.any(String), - fakerDocsUrl: expect.any(String), - validator: expect.any(Function), - returnType: expect.any(String), - usageExamples: expect.any(Array), - args: expect.any(Array), - }), - }) - ); - expect(definition.help.usageExamples.length).toBeGreaterThan(0); - }); - - const usageExamples = Array.isArray(definition?.help?.usageExamples) ? definition.help.usageExamples : []; - - for (const [index, usageExample] of usageExamples.entries()) { - test(`example ${index + 1} ${usageExample.functionCall} executes, validates, and matches the seeded sample value`, () => { - const validationContext = buildValidationContext( - { - catalog: 'domain', - command: keyword, - help: definition.help, - sourceDefinition: definition, - sourceValidator: definition.help.validator, - }, - usageExample - ); - const actualValue = executeDomainExample(usageExample.functionCall); - - expect(validateCommandHelpValue(definition.help.validator, actualValue, validationContext)).toBe(true); - expect( - validateCommandHelpValue(definition.help.validator, usageExample.sampleReturnValue, validationContext) - ).toBe(true); - expect(normalizeExampleValue(actualValue)).toEqual(normalizeExampleValue(usageExample.sampleReturnValue)); - }); - } - }); -} - -export { defineDomainKeywordDefinitionTests }; diff --git a/packages/core/src/tests/data_generation/keywords/domain/define-domain-keyword-help-contract-tests.js b/packages/core/src/tests/data_generation/keywords/domain/define-domain-keyword-help-contract-tests.js new file mode 100644 index 00000000..ceca9e27 --- /dev/null +++ b/packages/core/src/tests/data_generation/keywords/domain/define-domain-keyword-help-contract-tests.js @@ -0,0 +1,76 @@ +import { validateCommandHelpValue } from '../../../../../js/command-help/command-help-contract.js'; +import { DOMAIN_KEYWORD_DEFINITIONS } from '../../../../../js/domain/domain-keyword-definitions.js'; +import { + buildValidationContext, + executeDomainExample, + normalizeExampleValue, +} from '../../../command-help/command-help-examples.test-support.js'; + +function getDomainKeywordDefinition(keyword) { + return DOMAIN_KEYWORD_DEFINITIONS.find((definition) => definition.keyword === keyword) || null; +} + +function checkKeywordIsRegisteredWithHelpMetadata(keyword, definition) { + test('is registered with structured help metadata', () => { + expect(definition).toBeDefined(); + expect(definition).toEqual( + expect.objectContaining({ + keyword, + delegate: expect.objectContaining({ + type: expect.any(String), + target: expect.any(String), + }), + help: expect.objectContaining({ + summary: expect.any(String), + docsUrl: expect.any(String), + validator: expect.any(Function), + returnType: expect.any(String), + usageExamples: expect.any(Array), + args: expect.any(Array), + }), + }) + ); + expect(definition.help.usageExamples.length).toBeGreaterThan(0); + if (definition.delegate.type === 'faker') { + expect(definition.help.fakerDocsUrl).toEqual(expect.any(String)); + expect(definition.help.fakerDocsUrl.length).toBeGreaterThan(0); + } + }); +} + +function checkKeywordUsageExamplesExecuteAndValidate(keyword, definition) { + const usageExamples = Array.isArray(definition?.help?.usageExamples) ? definition.help.usageExamples : []; + + for (const [index, usageExample] of usageExamples.entries()) { + test(`example ${index + 1} ${usageExample.functionCall} executes, validates, and matches the seeded sample value`, () => { + const validationContext = buildValidationContext( + { + catalog: 'domain', + command: keyword, + help: definition.help, + sourceDefinition: definition, + sourceValidator: definition.help.validator, + }, + usageExample + ); + const actualValue = executeDomainExample(usageExample.functionCall); + + expect(validateCommandHelpValue(definition.help.validator, actualValue, validationContext)).toBe(true); + expect( + validateCommandHelpValue(definition.help.validator, usageExample.sampleReturnValue, validationContext) + ).toBe(true); + expect(normalizeExampleValue(actualValue)).toEqual(normalizeExampleValue(usageExample.sampleReturnValue)); + }); + } +} + +function defineDomainKeywordHelpContractTests(keyword) { + describe(`domain keyword help contract ${keyword}`, () => { + const definition = getDomainKeywordDefinition(keyword); + + checkKeywordIsRegisteredWithHelpMetadata(keyword, definition); + checkKeywordUsageExamplesExecuteAndValidate(keyword, definition); + }); +} + +export { defineDomainKeywordHelpContractTests }; diff --git a/packages/core/src/tests/data_generation/keywords/domain/finance/account-name-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/finance/account-name-keyword-definition.test.js index 2e271746..82e91ad0 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/finance/account-name-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/finance/account-name-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('finance.accountName'); +defineDomainKeywordHelpContractTests('finance.accountName'); + +describe('finance.accountName parameter validation', () => { + test('executes finance.accountName() successfully', () => { + const parsed = parseKeywordInvocation('finance.accountName()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/finance/account-number-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/finance/account-number-keyword-definition.test.js index 0d168869..7c79f096 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/finance/account-number-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/finance/account-number-keyword-definition.test.js @@ -1,3 +1,59 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('finance.accountNumber'); +defineDomainKeywordHelpContractTests('finance.accountNumber'); + +describe('finance.accountNumber parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('finance.accountNumber'); + const parsed = parseKeywordInvocation(`finance.accountNumber(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes finance.accountNumber(length=5) successfully', () => { + const parsed = parseKeywordInvocation('finance.accountNumber(length=5)'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid length type before generation', () => { + expect(validateArgs('length={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be number, not object', + }); + }); + + test('rejects zero length before generation', () => { + expect(validateArgs('length=0')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be greater than 0', + }); + }); + + test('rejects negative length before generation', () => { + expect(validateArgs('length=-1')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be greater than 0', + }); + }); + + test('rejects fractional length before generation', () => { + expect(validateArgs('length=1.5')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be an integer', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/finance/amount-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/finance/amount-keyword-definition.test.js index edbd9274..78164ace 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/finance/amount-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/finance/amount-keyword-definition.test.js @@ -1,3 +1,73 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('finance.amount'); +defineDomainKeywordHelpContractTests('finance.amount'); + +describe('finance.amount parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('finance.amount'); + const parsed = parseKeywordInvocation(`finance.amount(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes finance.amount(autoFormat=true) successfully', () => { + const parsed = parseKeywordInvocation('finance.amount(autoFormat=true)'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid autoFormat type before generation', () => { + expect(validateArgs('autoFormat={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "autoFormat" must be boolean, not object', + }); + }); + + test('rejects invalid dec type before generation', () => { + expect(validateArgs('autoFormat=true, dec={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "dec" must be integer, not object', + }); + }); + + test('rejects invalid max type before generation', () => { + expect(validateArgs('autoFormat=true, max={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "max" must be number, not object', + }); + }); + + test('rejects invalid min type before generation', () => { + expect(validateArgs('autoFormat=true, min={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "min" must be number, not object', + }); + }); + + test('rejects invalid symbol type before generation', () => { + expect(validateArgs('autoFormat=true, symbol={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "symbol" must be string, not object', + }); + }); + + test('rejects min greater than max before generation', () => { + expect(validateArgs('autoFormat=true, max=1, min=10')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "min" must be less than or equal to argument "max"', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/finance/bic-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/finance/bic-keyword-definition.test.js index 1de160ca..280d8470 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/finance/bic-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/finance/bic-keyword-definition.test.js @@ -1,3 +1,38 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('finance.bic'); +defineDomainKeywordHelpContractTests('finance.bic'); + +describe('finance.bic parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('finance.bic'); + const parsed = parseKeywordInvocation(`finance.bic(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes finance.bic(includeBranchCode=true) successfully', () => { + const parsed = parseKeywordInvocation('finance.bic(includeBranchCode=true)'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid includeBranchCode type before generation', () => { + expect(validateArgs('includeBranchCode={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "includeBranchCode" must be boolean, not object', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/finance/bitcoin-address-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/finance/bitcoin-address-keyword-definition.test.js index 7afdc30a..d2ffbb7c 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/finance/bitcoin-address-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/finance/bitcoin-address-keyword-definition.test.js @@ -1,3 +1,45 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('finance.bitcoinAddress'); +defineDomainKeywordHelpContractTests('finance.bitcoinAddress'); + +describe('finance.bitcoinAddress parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('finance.bitcoinAddress'); + const parsed = parseKeywordInvocation(`finance.bitcoinAddress(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes finance.bitcoinAddress(type="bech32") successfully', () => { + const parsed = parseKeywordInvocation('finance.bitcoinAddress(type="bech32")'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid type type before generation', () => { + expect(validateArgs('type={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "type" must be legacy, segwit, bech32 or taproot, not object', + }); + }); + + test('rejects invalid network type before generation', () => { + expect(validateArgs('type="bech32", network={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "network" must be mainnet or testnet, not object', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/finance/credit-card-cvv-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/finance/credit-card-cvv-keyword-definition.test.js index b981c9d6..287c4db9 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/finance/credit-card-cvv-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/finance/credit-card-cvv-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('finance.creditCardCVV'); +defineDomainKeywordHelpContractTests('finance.creditCardCVV'); + +describe('finance.creditCardCVV parameter validation', () => { + test('executes finance.creditCardCVV() successfully', () => { + const parsed = parseKeywordInvocation('finance.creditCardCVV()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/finance/credit-card-issuer-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/finance/credit-card-issuer-keyword-definition.test.js index e285f531..51191cd2 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/finance/credit-card-issuer-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/finance/credit-card-issuer-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('finance.creditCardIssuer'); +defineDomainKeywordHelpContractTests('finance.creditCardIssuer'); + +describe('finance.creditCardIssuer parameter validation', () => { + test('executes finance.creditCardIssuer() successfully', () => { + const parsed = parseKeywordInvocation('finance.creditCardIssuer()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/finance/credit-card-number-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/finance/credit-card-number-keyword-definition.test.js index c69d378e..eb058550 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/finance/credit-card-number-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/finance/credit-card-number-keyword-definition.test.js @@ -1,3 +1,38 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('finance.creditCardNumber'); +defineDomainKeywordHelpContractTests('finance.creditCardNumber'); + +describe('finance.creditCardNumber parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('finance.creditCardNumber'); + const parsed = parseKeywordInvocation(`finance.creditCardNumber(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes finance.creditCardNumber(issuer="Visa") successfully', () => { + const parsed = parseKeywordInvocation('finance.creditCardNumber(issuer="Visa")'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid issuer type before generation', () => { + expect(validateArgs('issuer={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "issuer" must be string, not object', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/finance/currency-code-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/finance/currency-code-keyword-definition.test.js index bc6e9730..15620de4 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/finance/currency-code-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/finance/currency-code-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('finance.currencyCode'); +defineDomainKeywordHelpContractTests('finance.currencyCode'); + +describe('finance.currencyCode parameter validation', () => { + test('executes finance.currencyCode() successfully', () => { + const parsed = parseKeywordInvocation('finance.currencyCode()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/finance/currency-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/finance/currency-keyword-definition.test.js index e9bc2739..200a7545 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/finance/currency-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/finance/currency-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('finance.currency'); +defineDomainKeywordHelpContractTests('finance.currency'); + +describe('finance.currency parameter validation', () => { + test('executes finance.currency() successfully', () => { + const parsed = parseKeywordInvocation('finance.currency()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/finance/currency-name-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/finance/currency-name-keyword-definition.test.js index 978cb5bb..7ab7b98d 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/finance/currency-name-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/finance/currency-name-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('finance.currencyName'); +defineDomainKeywordHelpContractTests('finance.currencyName'); + +describe('finance.currencyName parameter validation', () => { + test('executes finance.currencyName() successfully', () => { + const parsed = parseKeywordInvocation('finance.currencyName()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/finance/currency-numeric-code-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/finance/currency-numeric-code-keyword-definition.test.js index 41f33625..af6b140a 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/finance/currency-numeric-code-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/finance/currency-numeric-code-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('finance.currencyNumericCode'); +defineDomainKeywordHelpContractTests('finance.currencyNumericCode'); + +describe('finance.currencyNumericCode parameter validation', () => { + test('executes finance.currencyNumericCode() successfully', () => { + const parsed = parseKeywordInvocation('finance.currencyNumericCode()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/finance/currency-symbol-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/finance/currency-symbol-keyword-definition.test.js index c9441f97..5270cd01 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/finance/currency-symbol-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/finance/currency-symbol-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('finance.currencySymbol'); +defineDomainKeywordHelpContractTests('finance.currencySymbol'); + +describe('finance.currencySymbol parameter validation', () => { + test('executes finance.currencySymbol() successfully', () => { + const parsed = parseKeywordInvocation('finance.currencySymbol()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/finance/ethereum-address-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/finance/ethereum-address-keyword-definition.test.js index 9e0e6fcd..24368865 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/finance/ethereum-address-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/finance/ethereum-address-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('finance.ethereumAddress'); +defineDomainKeywordHelpContractTests('finance.ethereumAddress'); + +describe('finance.ethereumAddress parameter validation', () => { + test('executes finance.ethereumAddress() successfully', () => { + const parsed = parseKeywordInvocation('finance.ethereumAddress()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/finance/iban-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/finance/iban-keyword-definition.test.js index 30ab9e19..57634aba 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/finance/iban-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/finance/iban-keyword-definition.test.js @@ -1,3 +1,45 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('finance.iban'); +defineDomainKeywordHelpContractTests('finance.iban'); + +describe('finance.iban parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('finance.iban'); + const parsed = parseKeywordInvocation(`finance.iban(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes finance.iban(countryCode="GB") successfully', () => { + const parsed = parseKeywordInvocation('finance.iban(countryCode="GB")'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid countryCode type before generation', () => { + expect(validateArgs('countryCode={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "countryCode" must be string, not object', + }); + }); + + test('rejects invalid formatted type before generation', () => { + expect(validateArgs('countryCode="GB", formatted={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "formatted" must be boolean, not object', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/finance/litecoin-address-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/finance/litecoin-address-keyword-definition.test.js index 154a03ea..ff6f31ee 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/finance/litecoin-address-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/finance/litecoin-address-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('finance.litecoinAddress'); +defineDomainKeywordHelpContractTests('finance.litecoinAddress'); + +describe('finance.litecoinAddress parameter validation', () => { + test('executes finance.litecoinAddress() successfully', () => { + const parsed = parseKeywordInvocation('finance.litecoinAddress()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/finance/pin-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/finance/pin-keyword-definition.test.js index 058766b0..fc2493d4 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/finance/pin-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/finance/pin-keyword-definition.test.js @@ -1,3 +1,59 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('finance.pin'); +defineDomainKeywordHelpContractTests('finance.pin'); + +describe('finance.pin parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('finance.pin'); + const parsed = parseKeywordInvocation(`finance.pin(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes finance.pin(length=5) successfully', () => { + const parsed = parseKeywordInvocation('finance.pin(length=5)'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid length type before generation', () => { + expect(validateArgs('length={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be number, not object', + }); + }); + + test('rejects zero length before generation', () => { + expect(validateArgs('length=0')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be greater than 0', + }); + }); + + test('rejects negative length before generation', () => { + expect(validateArgs('length=-1')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be greater than 0', + }); + }); + + test('rejects fractional length before generation', () => { + expect(validateArgs('length=1.5')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be an integer', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/finance/routing-number-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/finance/routing-number-keyword-definition.test.js index a608cfe2..57e5980f 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/finance/routing-number-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/finance/routing-number-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('finance.routingNumber'); +defineDomainKeywordHelpContractTests('finance.routingNumber'); + +describe('finance.routingNumber parameter validation', () => { + test('executes finance.routingNumber() successfully', () => { + const parsed = parseKeywordInvocation('finance.routingNumber()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/finance/transaction-description-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/finance/transaction-description-keyword-definition.test.js index 339b57e3..d30e45a2 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/finance/transaction-description-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/finance/transaction-description-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('finance.transactionDescription'); +defineDomainKeywordHelpContractTests('finance.transactionDescription'); + +describe('finance.transactionDescription parameter validation', () => { + test('executes finance.transactionDescription() successfully', () => { + const parsed = parseKeywordInvocation('finance.transactionDescription()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/finance/transaction-type-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/finance/transaction-type-keyword-definition.test.js index eecc40b2..184ce947 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/finance/transaction-type-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/finance/transaction-type-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('finance.transactionType'); +defineDomainKeywordHelpContractTests('finance.transactionType'); + +describe('finance.transactionType parameter validation', () => { + test('executes finance.transactionType() successfully', () => { + const parsed = parseKeywordInvocation('finance.transactionType()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/food/adjective-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/food/adjective-keyword-definition.test.js index a1e78960..ef6d32dd 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/food/adjective-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/food/adjective-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('food.adjective'); +defineDomainKeywordHelpContractTests('food.adjective'); + +describe('food.adjective parameter validation', () => { + test('executes food.adjective() successfully', () => { + const parsed = parseKeywordInvocation('food.adjective()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/food/description-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/food/description-keyword-definition.test.js index 15258075..b03f02d8 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/food/description-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/food/description-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('food.description'); +defineDomainKeywordHelpContractTests('food.description'); + +describe('food.description parameter validation', () => { + test('executes food.description() successfully', () => { + const parsed = parseKeywordInvocation('food.description()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/food/dish-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/food/dish-keyword-definition.test.js index b995f82d..a4bb1226 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/food/dish-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/food/dish-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('food.dish'); +defineDomainKeywordHelpContractTests('food.dish'); + +describe('food.dish parameter validation', () => { + test('executes food.dish() successfully', () => { + const parsed = parseKeywordInvocation('food.dish()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/food/ethnic-category-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/food/ethnic-category-keyword-definition.test.js index b2a61d4c..28dc0b14 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/food/ethnic-category-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/food/ethnic-category-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('food.ethnicCategory'); +defineDomainKeywordHelpContractTests('food.ethnicCategory'); + +describe('food.ethnicCategory parameter validation', () => { + test('executes food.ethnicCategory() successfully', () => { + const parsed = parseKeywordInvocation('food.ethnicCategory()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/food/fruit-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/food/fruit-keyword-definition.test.js index 11676e3c..85818f3f 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/food/fruit-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/food/fruit-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('food.fruit'); +defineDomainKeywordHelpContractTests('food.fruit'); + +describe('food.fruit parameter validation', () => { + test('executes food.fruit() successfully', () => { + const parsed = parseKeywordInvocation('food.fruit()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/food/ingredient-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/food/ingredient-keyword-definition.test.js index 60996712..73dc4c59 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/food/ingredient-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/food/ingredient-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('food.ingredient'); +defineDomainKeywordHelpContractTests('food.ingredient'); + +describe('food.ingredient parameter validation', () => { + test('executes food.ingredient() successfully', () => { + const parsed = parseKeywordInvocation('food.ingredient()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/food/meat-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/food/meat-keyword-definition.test.js index 88a62faa..8f5e685b 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/food/meat-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/food/meat-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('food.meat'); +defineDomainKeywordHelpContractTests('food.meat'); + +describe('food.meat parameter validation', () => { + test('executes food.meat() successfully', () => { + const parsed = parseKeywordInvocation('food.meat()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/food/spice-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/food/spice-keyword-definition.test.js index 3787ac7d..25831cab 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/food/spice-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/food/spice-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('food.spice'); +defineDomainKeywordHelpContractTests('food.spice'); + +describe('food.spice parameter validation', () => { + test('executes food.spice() successfully', () => { + const parsed = parseKeywordInvocation('food.spice()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/food/vegetable-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/food/vegetable-keyword-definition.test.js index 4e1f3701..8584d436 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/food/vegetable-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/food/vegetable-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('food.vegetable'); +defineDomainKeywordHelpContractTests('food.vegetable'); + +describe('food.vegetable parameter validation', () => { + test('executes food.vegetable() successfully', () => { + const parsed = parseKeywordInvocation('food.vegetable()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/git/branch-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/git/branch-keyword-definition.test.js index 2307b620..4cb90fa9 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/git/branch-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/git/branch-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('git.branch'); +defineDomainKeywordHelpContractTests('git.branch'); + +describe('git.branch parameter validation', () => { + test('executes git.branch() successfully', () => { + const parsed = parseKeywordInvocation('git.branch()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/git/commit-date-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/git/commit-date-keyword-definition.test.js index 7c3f4832..cbee2c9a 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/git/commit-date-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/git/commit-date-keyword-definition.test.js @@ -1,3 +1,38 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('git.commitDate'); +defineDomainKeywordHelpContractTests('git.commitDate'); + +describe('git.commitDate parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('git.commitDate'); + const parsed = parseKeywordInvocation(`git.commitDate(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes git.commitDate(refDate="2024-01-01T00:00:00.000Z") successfully', () => { + const parsed = parseKeywordInvocation('git.commitDate(refDate="2024-01-01T00:00:00.000Z")'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid refDate type before generation', () => { + expect(validateArgs('refDate={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "refDate" must be string, date or number, not object', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/git/commit-entry-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/git/commit-entry-keyword-definition.test.js index 19ba62eb..74624761 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/git/commit-entry-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/git/commit-entry-keyword-definition.test.js @@ -1,3 +1,52 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('git.commitEntry'); +defineDomainKeywordHelpContractTests('git.commitEntry'); + +describe('git.commitEntry parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('git.commitEntry'); + const parsed = parseKeywordInvocation(`git.commitEntry(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes git.commitEntry(merge=true, eol="LF") successfully', () => { + const parsed = parseKeywordInvocation('git.commitEntry(merge=true, eol="LF")'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid merge type before generation', () => { + expect(validateArgs('merge={"bad":true}, eol="LF"')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "merge" must be boolean, not object', + }); + }); + + test('rejects invalid eol type before generation', () => { + expect(validateArgs('merge=true, eol={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "eol" must be LF or CRLF, not object', + }); + }); + + test('rejects invalid refDate type before generation', () => { + expect(validateArgs('merge=true, eol="LF", refDate={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "refDate" must be string, date or number, not object', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/git/commit-message-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/git/commit-message-keyword-definition.test.js index 09bc437a..d74c8982 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/git/commit-message-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/git/commit-message-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('git.commitMessage'); +defineDomainKeywordHelpContractTests('git.commitMessage'); + +describe('git.commitMessage parameter validation', () => { + test('executes git.commitMessage() successfully', () => { + const parsed = parseKeywordInvocation('git.commitMessage()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/git/commit-sha-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/git/commit-sha-keyword-definition.test.js index 82efcb87..a98dbebb 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/git/commit-sha-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/git/commit-sha-keyword-definition.test.js @@ -1,3 +1,59 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('git.commitSha'); +defineDomainKeywordHelpContractTests('git.commitSha'); + +describe('git.commitSha parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('git.commitSha'); + const parsed = parseKeywordInvocation(`git.commitSha(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes git.commitSha(length=7) successfully', () => { + const parsed = parseKeywordInvocation('git.commitSha(length=7)'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid length type before generation', () => { + expect(validateArgs('length={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be number, not object', + }); + }); + + test('rejects zero length before generation', () => { + expect(validateArgs('length=0')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be greater than 0', + }); + }); + + test('rejects negative length before generation', () => { + expect(validateArgs('length=-1')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be greater than 0', + }); + }); + + test('rejects fractional length before generation', () => { + expect(validateArgs('length=1.5')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be an integer', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/hacker/abbreviation-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/hacker/abbreviation-keyword-definition.test.js index b2c303e2..b267eee2 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/hacker/abbreviation-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/hacker/abbreviation-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('hacker.abbreviation'); +defineDomainKeywordHelpContractTests('hacker.abbreviation'); + +describe('hacker.abbreviation parameter validation', () => { + test('executes hacker.abbreviation() successfully', () => { + const parsed = parseKeywordInvocation('hacker.abbreviation()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/hacker/adjective-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/hacker/adjective-keyword-definition.test.js index b0eb49e9..09614fad 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/hacker/adjective-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/hacker/adjective-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('hacker.adjective'); +defineDomainKeywordHelpContractTests('hacker.adjective'); + +describe('hacker.adjective parameter validation', () => { + test('executes hacker.adjective() successfully', () => { + const parsed = parseKeywordInvocation('hacker.adjective()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/hacker/ingverb-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/hacker/ingverb-keyword-definition.test.js index bc30023d..128a0bfb 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/hacker/ingverb-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/hacker/ingverb-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('hacker.ingverb'); +defineDomainKeywordHelpContractTests('hacker.ingverb'); + +describe('hacker.ingverb parameter validation', () => { + test('executes hacker.ingverb() successfully', () => { + const parsed = parseKeywordInvocation('hacker.ingverb()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/hacker/noun-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/hacker/noun-keyword-definition.test.js index 42ab5f38..b8903ad0 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/hacker/noun-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/hacker/noun-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('hacker.noun'); +defineDomainKeywordHelpContractTests('hacker.noun'); + +describe('hacker.noun parameter validation', () => { + test('executes hacker.noun() successfully', () => { + const parsed = parseKeywordInvocation('hacker.noun()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/hacker/phrase-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/hacker/phrase-keyword-definition.test.js index 333b0c8d..7b9f91df 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/hacker/phrase-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/hacker/phrase-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('hacker.phrase'); +defineDomainKeywordHelpContractTests('hacker.phrase'); + +describe('hacker.phrase parameter validation', () => { + test('executes hacker.phrase() successfully', () => { + const parsed = parseKeywordInvocation('hacker.phrase()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/hacker/verb-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/hacker/verb-keyword-definition.test.js index 1eb28fe4..60f2bdb7 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/hacker/verb-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/hacker/verb-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('hacker.verb'); +defineDomainKeywordHelpContractTests('hacker.verb'); + +describe('hacker.verb parameter validation', () => { + test('executes hacker.verb() successfully', () => { + const parsed = parseKeywordInvocation('hacker.verb()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/image/avatar-git-hub-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/image/avatar-git-hub-keyword-definition.test.js index 7f4490c2..71466091 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/image/avatar-git-hub-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/image/avatar-git-hub-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('image.avatarGitHub'); +defineDomainKeywordHelpContractTests('image.avatarGitHub'); + +describe('image.avatarGitHub parameter validation', () => { + test('executes image.avatarGitHub() successfully', () => { + const parsed = parseKeywordInvocation('image.avatarGitHub()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/image/avatar-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/image/avatar-keyword-definition.test.js index bd3755fa..0afd2d10 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/image/avatar-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/image/avatar-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('image.avatar'); +defineDomainKeywordHelpContractTests('image.avatar'); + +describe('image.avatar parameter validation', () => { + test('executes image.avatar() successfully', () => { + const parsed = parseKeywordInvocation('image.avatar()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/image/data-uri-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/image/data-uri-keyword-definition.test.js index c226cd54..4fab61fd 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/image/data-uri-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/image/data-uri-keyword-definition.test.js @@ -1,3 +1,101 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('image.dataUri'); +defineDomainKeywordHelpContractTests('image.dataUri'); + +describe('image.dataUri parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('image.dataUri'); + const parsed = parseKeywordInvocation(`image.dataUri(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes image.dataUri(width=320, height=240, color="red", type="svg-base64") successfully', () => { + const parsed = parseKeywordInvocation('image.dataUri(width=320, height=240, color="red", type="svg-base64")'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid width type before generation', () => { + expect(validateArgs('width={"bad":true}, height=240, color="red", type="svg-base64"')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "width" must be number, not object', + }); + }); + + test('rejects zero width before generation', () => { + expect(validateArgs('width=0, height=240, color="red", type="svg-base64"')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "width" must be greater than 0', + }); + }); + + test('rejects negative width before generation', () => { + expect(validateArgs('width=-1, height=240, color="red", type="svg-base64"')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "width" must be greater than 0', + }); + }); + + test('rejects fractional width before generation', () => { + expect(validateArgs('width=1.5, height=240, color="red", type="svg-base64"')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "width" must be an integer', + }); + }); + + test('rejects invalid height type before generation', () => { + expect(validateArgs('width=320, height={"bad":true}, color="red", type="svg-base64"')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "height" must be number, not object', + }); + }); + + test('rejects zero height before generation', () => { + expect(validateArgs('width=320, height=0, color="red", type="svg-base64"')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "height" must be greater than 0', + }); + }); + + test('rejects negative height before generation', () => { + expect(validateArgs('width=320, height=-1, color="red", type="svg-base64"')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "height" must be greater than 0', + }); + }); + + test('rejects fractional height before generation', () => { + expect(validateArgs('width=320, height=1.5, color="red", type="svg-base64"')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "height" must be an integer', + }); + }); + + test('rejects invalid color type before generation', () => { + expect(validateArgs('width=320, height=240, color={"bad":true}, type="svg-base64"')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "color" must be string, not object', + }); + }); + + test('rejects invalid type type before generation', () => { + expect(validateArgs('width=320, height=240, color="red", type={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "type" must be svg-uri or svg-base64, not object', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/image/person-portrait-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/image/person-portrait-keyword-definition.test.js index afb1136e..39571d18 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/image/person-portrait-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/image/person-portrait-keyword-definition.test.js @@ -1,3 +1,45 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('image.personPortrait'); +defineDomainKeywordHelpContractTests('image.personPortrait'); + +describe('image.personPortrait parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('image.personPortrait'); + const parsed = parseKeywordInvocation(`image.personPortrait(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes image.personPortrait(sex="female", size=128) successfully', () => { + const parsed = parseKeywordInvocation('image.personPortrait(sex="female", size=128)'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid sex type before generation', () => { + expect(validateArgs('sex={"bad":true}, size=128')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "sex" must be female, generic or male, not object', + }); + }); + + test('rejects invalid size type before generation', () => { + expect(validateArgs('sex="female", size={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "size" must be 512, 256, 128, 64 or 32, not object', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/image/url-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/image/url-keyword-definition.test.js index 889f7c5d..730df09e 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/image/url-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/image/url-keyword-definition.test.js @@ -1,3 +1,87 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('image.url'); +defineDomainKeywordHelpContractTests('image.url'); + +describe('image.url parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('image.url'); + const parsed = parseKeywordInvocation(`image.url(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes image.url(height=1) successfully', () => { + const parsed = parseKeywordInvocation('image.url(height=1)'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid height type before generation', () => { + expect(validateArgs('height={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "height" must be number, not object', + }); + }); + + test('rejects zero height before generation', () => { + expect(validateArgs('height=0')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "height" must be greater than 0', + }); + }); + + test('rejects negative height before generation', () => { + expect(validateArgs('height=-1')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "height" must be greater than 0', + }); + }); + + test('rejects fractional height before generation', () => { + expect(validateArgs('height=1.5')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "height" must be an integer', + }); + }); + + test('rejects invalid width type before generation', () => { + expect(validateArgs('height=1, width={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "width" must be number, not object', + }); + }); + + test('rejects zero width before generation', () => { + expect(validateArgs('height=1, width=0')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "width" must be greater than 0', + }); + }); + + test('rejects negative width before generation', () => { + expect(validateArgs('height=1, width=-1')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "width" must be greater than 0', + }); + }); + + test('rejects fractional width before generation', () => { + expect(validateArgs('height=1, width=1.5')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "width" must be an integer', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/image/url-picsum-photos-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/image/url-picsum-photos-keyword-definition.test.js index 6a09571f..d56373a0 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/image/url-picsum-photos-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/image/url-picsum-photos-keyword-definition.test.js @@ -1,3 +1,101 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('image.urlPicsumPhotos'); +defineDomainKeywordHelpContractTests('image.urlPicsumPhotos'); + +describe('image.urlPicsumPhotos parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('image.urlPicsumPhotos'); + const parsed = parseKeywordInvocation(`image.urlPicsumPhotos(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes image.urlPicsumPhotos(width=320, height=240, grayscale=true, blur=3) successfully', () => { + const parsed = parseKeywordInvocation('image.urlPicsumPhotos(width=320, height=240, grayscale=true, blur=3)'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid width type before generation', () => { + expect(validateArgs('width={"bad":true}, height=240, grayscale=true, blur=3')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "width" must be number, not object', + }); + }); + + test('rejects zero width before generation', () => { + expect(validateArgs('width=0, height=240, grayscale=true, blur=3')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "width" must be greater than 0', + }); + }); + + test('rejects negative width before generation', () => { + expect(validateArgs('width=-1, height=240, grayscale=true, blur=3')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "width" must be greater than 0', + }); + }); + + test('rejects fractional width before generation', () => { + expect(validateArgs('width=1.5, height=240, grayscale=true, blur=3')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "width" must be an integer', + }); + }); + + test('rejects invalid height type before generation', () => { + expect(validateArgs('width=320, height={"bad":true}, grayscale=true, blur=3')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "height" must be number, not object', + }); + }); + + test('rejects zero height before generation', () => { + expect(validateArgs('width=320, height=0, grayscale=true, blur=3')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "height" must be greater than 0', + }); + }); + + test('rejects negative height before generation', () => { + expect(validateArgs('width=320, height=-1, grayscale=true, blur=3')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "height" must be greater than 0', + }); + }); + + test('rejects fractional height before generation', () => { + expect(validateArgs('width=320, height=1.5, grayscale=true, blur=3')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "height" must be an integer', + }); + }); + + test('rejects invalid grayscale type before generation', () => { + expect(validateArgs('width=320, height=240, grayscale={"bad":true}, blur=3')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "grayscale" must be boolean, not object', + }); + }); + + test('rejects invalid blur type before generation', () => { + expect(validateArgs('width=320, height=240, grayscale=true, blur={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "blur" must be 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 or 10, not object', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/internet/display-name-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/internet/display-name-keyword-definition.test.js index 7f5de422..b1df5a00 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/internet/display-name-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/internet/display-name-keyword-definition.test.js @@ -1,3 +1,45 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('internet.displayName'); +defineDomainKeywordHelpContractTests('internet.displayName'); + +describe('internet.displayName parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('internet.displayName'); + const parsed = parseKeywordInvocation(`internet.displayName(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes internet.displayName(firstName="Ada", lastName="Lovelace") successfully', () => { + const parsed = parseKeywordInvocation('internet.displayName(firstName="Ada", lastName="Lovelace")'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid firstName type before generation', () => { + expect(validateArgs('firstName={"bad":true}, lastName="Lovelace"')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "firstName" must be string, not object', + }); + }); + + test('rejects invalid lastName type before generation', () => { + expect(validateArgs('firstName="Ada", lastName={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "lastName" must be string, not object', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/internet/domain-name-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/internet/domain-name-keyword-definition.test.js index 7d3586ab..ec3afa3a 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/internet/domain-name-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/internet/domain-name-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('internet.domainName'); +defineDomainKeywordHelpContractTests('internet.domainName'); + +describe('internet.domainName parameter validation', () => { + test('executes internet.domainName() successfully', () => { + const parsed = parseKeywordInvocation('internet.domainName()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/internet/domain-suffix-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/internet/domain-suffix-keyword-definition.test.js index 503255e7..b4ffa73e 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/internet/domain-suffix-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/internet/domain-suffix-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('internet.domainSuffix'); +defineDomainKeywordHelpContractTests('internet.domainSuffix'); + +describe('internet.domainSuffix parameter validation', () => { + test('executes internet.domainSuffix() successfully', () => { + const parsed = parseKeywordInvocation('internet.domainSuffix()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/internet/domain-word-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/internet/domain-word-keyword-definition.test.js index 05cb5ece..fbec2624 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/internet/domain-word-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/internet/domain-word-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('internet.domainWord'); +defineDomainKeywordHelpContractTests('internet.domainWord'); + +describe('internet.domainWord parameter validation', () => { + test('executes internet.domainWord() successfully', () => { + const parsed = parseKeywordInvocation('internet.domainWord()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/internet/email-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/internet/email-keyword-definition.test.js index 9445c75d..364f2dc4 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/internet/email-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/internet/email-keyword-definition.test.js @@ -1,3 +1,59 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('internet.email'); +defineDomainKeywordHelpContractTests('internet.email'); + +describe('internet.email parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('internet.email'); + const parsed = parseKeywordInvocation(`internet.email(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes internet.email(allowSpecialCharacters=true) successfully', () => { + const parsed = parseKeywordInvocation('internet.email(allowSpecialCharacters=true)'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid allowSpecialCharacters type before generation', () => { + expect(validateArgs('allowSpecialCharacters={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "allowSpecialCharacters" must be boolean, not object', + }); + }); + + test('rejects invalid firstName type before generation', () => { + expect(validateArgs('allowSpecialCharacters=true, firstName={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "firstName" must be string, not object', + }); + }); + + test('rejects invalid lastName type before generation', () => { + expect(validateArgs('allowSpecialCharacters=true, lastName={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "lastName" must be string, not object', + }); + }); + + test('rejects invalid provider type before generation', () => { + expect(validateArgs('allowSpecialCharacters=true, provider={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "provider" must be string, not object', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/internet/emoji-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/internet/emoji-keyword-definition.test.js index 40aef37a..a49975bc 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/internet/emoji-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/internet/emoji-keyword-definition.test.js @@ -1,3 +1,38 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('internet.emoji'); +defineDomainKeywordHelpContractTests('internet.emoji'); + +describe('internet.emoji parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('internet.emoji'); + const parsed = parseKeywordInvocation(`internet.emoji(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes internet.emoji(types=["food"]) successfully', () => { + const parsed = parseKeywordInvocation('internet.emoji(types=["food"])'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid types type before generation', () => { + expect(validateArgs('types={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "types" must be array, not object', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/internet/example-email-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/internet/example-email-keyword-definition.test.js index a04b365c..2a1f2695 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/internet/example-email-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/internet/example-email-keyword-definition.test.js @@ -1,3 +1,52 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('internet.exampleEmail'); +defineDomainKeywordHelpContractTests('internet.exampleEmail'); + +describe('internet.exampleEmail parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('internet.exampleEmail'); + const parsed = parseKeywordInvocation(`internet.exampleEmail(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes internet.exampleEmail(firstName="Ada", lastName="Lovelace") successfully', () => { + const parsed = parseKeywordInvocation('internet.exampleEmail(firstName="Ada", lastName="Lovelace")'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid firstName type before generation', () => { + expect(validateArgs('firstName={"bad":true}, lastName="Lovelace"')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "firstName" must be string, not object', + }); + }); + + test('rejects invalid lastName type before generation', () => { + expect(validateArgs('firstName="Ada", lastName={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "lastName" must be string, not object', + }); + }); + + test('rejects invalid allowSpecialCharacters type before generation', () => { + expect(validateArgs('firstName="Ada", lastName="Lovelace", allowSpecialCharacters={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "allowSpecialCharacters" must be boolean, not object', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/internet/http-method-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/internet/http-method-keyword-definition.test.js index 1f18eddd..4c9b8bf4 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/internet/http-method-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/internet/http-method-keyword-definition.test.js @@ -1,3 +1,45 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('internet.httpMethod'); +defineDomainKeywordHelpContractTests('internet.httpMethod'); + +describe('internet.httpMethod parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('internet.httpMethod'); + const parsed = parseKeywordInvocation(`internet.httpMethod(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes internet.httpMethod(commonOnly=true) successfully', () => { + const parsed = parseKeywordInvocation('internet.httpMethod(commonOnly=true)'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid commonOnly type before generation', () => { + expect(validateArgs('commonOnly={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "commonOnly" must be boolean, not object', + }); + }); + + test('rejects invalid excludes type before generation', () => { + expect(validateArgs('commonOnly=true, excludes={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "excludes" must be string, not object', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/internet/http-status-code-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/internet/http-status-code-keyword-definition.test.js index a20fb96b..64285c34 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/internet/http-status-code-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/internet/http-status-code-keyword-definition.test.js @@ -1,3 +1,53 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('internet.httpStatusCode'); +defineDomainKeywordHelpContractTests('internet.httpStatusCode'); + +describe('internet.httpStatusCode parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('internet.httpStatusCode'); + const parsed = parseKeywordInvocation(`internet.httpStatusCode(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes internet.httpStatusCode(types=["success"]) successfully', () => { + const parsed = parseKeywordInvocation('internet.httpStatusCode(types=["success"])'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(typeof result).toBe('number'); + }); + + test('rejects invalid types type before generation', () => { + expect(validateArgs('types={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "types" must be array, not object', + }); + }); + + test('rejects empty types before generation', () => { + expect(validateArgs('types=[]')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "types" must not be empty', + }); + }); + + test('rejects unsupported types before generation', () => { + expect(validateArgs('types=["unsupported-value"]')).toEqual({ + ok: false, + error: + 'Invalid keyword arguments: argument "types" contains unsupported value "unsupported-value". Allowed values are informational, success, redirection, clientError, serverError', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/internet/ip-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/internet/ip-keyword-definition.test.js index fd6bed88..428e7a67 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/internet/ip-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/internet/ip-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('internet.ip'); +defineDomainKeywordHelpContractTests('internet.ip'); + +describe('internet.ip parameter validation', () => { + test('executes internet.ip() successfully', () => { + const parsed = parseKeywordInvocation('internet.ip()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/internet/ipv4-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/internet/ipv4-keyword-definition.test.js index 28f3ec4c..423b0f82 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/internet/ipv4-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/internet/ipv4-keyword-definition.test.js @@ -1,3 +1,46 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('internet.ipv4'); +defineDomainKeywordHelpContractTests('internet.ipv4'); + +describe('internet.ipv4 parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('internet.ipv4'); + const parsed = parseKeywordInvocation(`internet.ipv4(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes internet.ipv4(cidrBlock="192.168.0.0/24") successfully', () => { + const parsed = parseKeywordInvocation('internet.ipv4(cidrBlock="192.168.0.0/24")'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid cidrBlock type before generation', () => { + expect(validateArgs('cidrBlock={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "cidrBlock" must be string, not object', + }); + }); + + test('rejects invalid network type before generation', () => { + expect(validateArgs('cidrBlock="192.168.0.0/24", network={"bad":true}')).toEqual({ + ok: false, + error: + 'Invalid keyword arguments: argument "network" must be any, loopback, private-a, private-b, private-c, test-net-1, test-net-2, test-net-3, link-local or multicast, not object', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/internet/ipv6-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/internet/ipv6-keyword-definition.test.js index b4311be9..b9681692 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/internet/ipv6-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/internet/ipv6-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('internet.ipv6'); +defineDomainKeywordHelpContractTests('internet.ipv6'); + +describe('internet.ipv6 parameter validation', () => { + test('executes internet.ipv6() successfully', () => { + const parsed = parseKeywordInvocation('internet.ipv6()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/internet/jwt-algorithm-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/internet/jwt-algorithm-keyword-definition.test.js index 5f557f2a..0e7d5184 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/internet/jwt-algorithm-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/internet/jwt-algorithm-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('internet.jwtAlgorithm'); +defineDomainKeywordHelpContractTests('internet.jwtAlgorithm'); + +describe('internet.jwtAlgorithm parameter validation', () => { + test('executes internet.jwtAlgorithm() successfully', () => { + const parsed = parseKeywordInvocation('internet.jwtAlgorithm()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/internet/jwt-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/internet/jwt-keyword-definition.test.js index 3f4eac4d..8297dd6d 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/internet/jwt-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/internet/jwt-keyword-definition.test.js @@ -1,3 +1,52 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('internet.jwt'); +defineDomainKeywordHelpContractTests('internet.jwt'); + +describe('internet.jwt parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('internet.jwt'); + const parsed = parseKeywordInvocation(`internet.jwt(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes internet.jwt(header={"value":"sample"}) successfully', () => { + const parsed = parseKeywordInvocation('internet.jwt(header={"value":"sample"})'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid header type before generation', () => { + expect(validateArgs('header=["bad"]')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "header" must be object, not array', + }); + }); + + test('rejects invalid payload type before generation', () => { + expect(validateArgs('header={"value":"sample"}, payload=["bad"]')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "payload" must be object, not array', + }); + }); + + test('rejects invalid refDate type before generation', () => { + expect(validateArgs('header={"value":"sample"}, refDate={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "refDate" must be number, not object', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/internet/mac-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/internet/mac-keyword-definition.test.js index c10d7db6..ef2d6d64 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/internet/mac-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/internet/mac-keyword-definition.test.js @@ -1,3 +1,38 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('internet.mac'); +defineDomainKeywordHelpContractTests('internet.mac'); + +describe('internet.mac parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('internet.mac'); + const parsed = parseKeywordInvocation(`internet.mac(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes internet.mac(separator="-") successfully', () => { + const parsed = parseKeywordInvocation('internet.mac(separator="-")'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid separator type before generation', () => { + expect(validateArgs('separator={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "separator" must be ":", "-" or "", not object', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/internet/password-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/internet/password-keyword-definition.test.js index 751b9d5a..aee81113 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/internet/password-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/internet/password-keyword-definition.test.js @@ -1,3 +1,80 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('internet.password'); +defineDomainKeywordHelpContractTests('internet.password'); + +describe('internet.password parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('internet.password'); + const parsed = parseKeywordInvocation(`internet.password(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes internet.password(length=12) successfully', () => { + const parsed = parseKeywordInvocation('internet.password(length=12)'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid length type before generation', () => { + expect(validateArgs('length={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be integer, not object', + }); + }); + + test('rejects zero length before generation', () => { + expect(validateArgs('length=0')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be greater than 0', + }); + }); + + test('rejects negative length before generation', () => { + expect(validateArgs('length=-1')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be greater than 0', + }); + }); + + test('rejects fractional length before generation', () => { + expect(validateArgs('length=1.5')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be integer, not number', + }); + }); + + test('rejects invalid memorable type before generation', () => { + expect(validateArgs('length=12, memorable={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "memorable" must be boolean, not object', + }); + }); + + test('rejects invalid pattern type before generation', () => { + expect(validateArgs('length=12, pattern={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "pattern" must be regexp, not object', + }); + }); + + test('rejects invalid prefix type before generation', () => { + expect(validateArgs('length=12, prefix={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "prefix" must be string, not object', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/internet/port-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/internet/port-keyword-definition.test.js index 4bb988e4..fc75c9d3 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/internet/port-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/internet/port-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('internet.port'); +defineDomainKeywordHelpContractTests('internet.port'); + +describe('internet.port parameter validation', () => { + test('executes internet.port() successfully', () => { + const parsed = parseKeywordInvocation('internet.port()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(typeof result).toBe('number'); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/internet/protocol-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/internet/protocol-keyword-definition.test.js index f18a7d2c..4cbd88df 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/internet/protocol-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/internet/protocol-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('internet.protocol'); +defineDomainKeywordHelpContractTests('internet.protocol'); + +describe('internet.protocol parameter validation', () => { + test('executes internet.protocol() successfully', () => { + const parsed = parseKeywordInvocation('internet.protocol()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/internet/url-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/internet/url-keyword-definition.test.js index df9ac55a..e896f7a5 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/internet/url-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/internet/url-keyword-definition.test.js @@ -1,3 +1,45 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('internet.url'); +defineDomainKeywordHelpContractTests('internet.url'); + +describe('internet.url parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('internet.url'); + const parsed = parseKeywordInvocation(`internet.url(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes internet.url(appendSlash=true) successfully', () => { + const parsed = parseKeywordInvocation('internet.url(appendSlash=true)'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid appendSlash type before generation', () => { + expect(validateArgs('appendSlash={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "appendSlash" must be boolean, not object', + }); + }); + + test('rejects invalid protocol type before generation', () => { + expect(validateArgs('appendSlash=true, protocol={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "protocol" must be http or https, not object', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/internet/user-agent-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/internet/user-agent-keyword-definition.test.js index 1779a492..9d92b2b3 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/internet/user-agent-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/internet/user-agent-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('internet.userAgent'); +defineDomainKeywordHelpContractTests('internet.userAgent'); + +describe('internet.userAgent parameter validation', () => { + test('executes internet.userAgent() successfully', () => { + const parsed = parseKeywordInvocation('internet.userAgent()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/internet/username-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/internet/username-keyword-definition.test.js index 0be227cc..6caae464 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/internet/username-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/internet/username-keyword-definition.test.js @@ -1,3 +1,45 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('internet.username'); +defineDomainKeywordHelpContractTests('internet.username'); + +describe('internet.username parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('internet.username'); + const parsed = parseKeywordInvocation(`internet.username(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes internet.username(firstName="Ada") successfully', () => { + const parsed = parseKeywordInvocation('internet.username(firstName="Ada")'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid firstName type before generation', () => { + expect(validateArgs('firstName={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "firstName" must be string, not object', + }); + }); + + test('rejects invalid lastName type before generation', () => { + expect(validateArgs('firstName="Ada", lastName={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "lastName" must be string, not object', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/literal/value-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/literal/value-keyword-definition.test.js index e0792b63..a297c33e 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/literal/value-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/literal/value-keyword-definition.test.js @@ -1,3 +1,37 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('literal.value'); +defineDomainKeywordHelpContractTests('literal.value'); + +describe('literal.value parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('literal.value'); + const parsed = parseKeywordInvocation(`literal.value(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes literal.value(value="Pending") successfully', () => { + const parsed = parseKeywordInvocation('literal.value(value="Pending")'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { args: parsed.args }); + + expect(result).toBe('Pending'); + }); + + test('rejects invalid value type before generation', () => { + expect(validateArgs('value={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "value" must be string, number or boolean, not object', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/location/building-number-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/location/building-number-keyword-definition.test.js index 5871be47..f7ccff96 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/location/building-number-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/location/building-number-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('location.buildingNumber'); +defineDomainKeywordHelpContractTests('location.buildingNumber'); + +describe('location.buildingNumber parameter validation', () => { + test('executes location.buildingNumber() successfully', () => { + const parsed = parseKeywordInvocation('location.buildingNumber()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/location/cardinal-direction-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/location/cardinal-direction-keyword-definition.test.js index 172d9147..2cf894c5 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/location/cardinal-direction-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/location/cardinal-direction-keyword-definition.test.js @@ -1,3 +1,38 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('location.cardinalDirection'); +defineDomainKeywordHelpContractTests('location.cardinalDirection'); + +describe('location.cardinalDirection parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('location.cardinalDirection'); + const parsed = parseKeywordInvocation(`location.cardinalDirection(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes location.cardinalDirection(abbreviated=true) successfully', () => { + const parsed = parseKeywordInvocation('location.cardinalDirection(abbreviated=true)'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid abbreviated type before generation', () => { + expect(validateArgs('abbreviated={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "abbreviated" must be boolean, not object', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/location/city-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/location/city-keyword-definition.test.js index 4a421c55..f4fb5b80 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/location/city-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/location/city-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('location.city'); +defineDomainKeywordHelpContractTests('location.city'); + +describe('location.city parameter validation', () => { + test('executes location.city() successfully', () => { + const parsed = parseKeywordInvocation('location.city()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/location/continent-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/location/continent-keyword-definition.test.js index 19ba2317..f750ef28 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/location/continent-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/location/continent-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('location.continent'); +defineDomainKeywordHelpContractTests('location.continent'); + +describe('location.continent parameter validation', () => { + test('executes location.continent() successfully', () => { + const parsed = parseKeywordInvocation('location.continent()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/location/country-code-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/location/country-code-keyword-definition.test.js index 65f0d3b8..f7fac5bf 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/location/country-code-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/location/country-code-keyword-definition.test.js @@ -1,3 +1,38 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('location.countryCode'); +defineDomainKeywordHelpContractTests('location.countryCode'); + +describe('location.countryCode parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('location.countryCode'); + const parsed = parseKeywordInvocation(`location.countryCode(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes location.countryCode(variant="alpha-3") successfully', () => { + const parsed = parseKeywordInvocation('location.countryCode(variant="alpha-3")'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid variant type before generation', () => { + expect(validateArgs('variant={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "variant" must be alpha-2, alpha-3 or numeric, not object', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/location/country-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/location/country-keyword-definition.test.js index fb8c5610..05d78091 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/location/country-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/location/country-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('location.country'); +defineDomainKeywordHelpContractTests('location.country'); + +describe('location.country parameter validation', () => { + test('executes location.country() successfully', () => { + const parsed = parseKeywordInvocation('location.country()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/location/county-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/location/county-keyword-definition.test.js index 591bfde1..58f96859 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/location/county-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/location/county-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('location.county'); +defineDomainKeywordHelpContractTests('location.county'); + +describe('location.county parameter validation', () => { + test('executes location.county() successfully', () => { + const parsed = parseKeywordInvocation('location.county()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/location/direction-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/location/direction-keyword-definition.test.js index 44c1c3aa..461575fb 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/location/direction-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/location/direction-keyword-definition.test.js @@ -1,3 +1,38 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('location.direction'); +defineDomainKeywordHelpContractTests('location.direction'); + +describe('location.direction parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('location.direction'); + const parsed = parseKeywordInvocation(`location.direction(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes location.direction(abbreviated=true) successfully', () => { + const parsed = parseKeywordInvocation('location.direction(abbreviated=true)'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid abbreviated type before generation', () => { + expect(validateArgs('abbreviated={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "abbreviated" must be boolean, not object', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/location/language-alpha2-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/location/language-alpha2-keyword-definition.test.js index fe9c7a7b..d58aae7e 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/location/language-alpha2-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/location/language-alpha2-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('location.language.alpha2'); +defineDomainKeywordHelpContractTests('location.language.alpha2'); + +describe('location.language.alpha2 parameter validation', () => { + test('executes location.language.alpha2() successfully', () => { + const parsed = parseKeywordInvocation('location.language.alpha2()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/location/language-alpha3-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/location/language-alpha3-keyword-definition.test.js index 0b4c1176..1ebf112f 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/location/language-alpha3-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/location/language-alpha3-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('location.language.alpha3'); +defineDomainKeywordHelpContractTests('location.language.alpha3'); + +describe('location.language.alpha3 parameter validation', () => { + test('executes location.language.alpha3() successfully', () => { + const parsed = parseKeywordInvocation('location.language.alpha3()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/location/language-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/location/language-keyword-definition.test.js index 2648b668..1fbe2e67 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/location/language-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/location/language-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('location.language'); +defineDomainKeywordHelpContractTests('location.language'); + +describe('location.language parameter validation', () => { + test('executes location.language() successfully', () => { + const parsed = parseKeywordInvocation('location.language()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/location/language-name-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/location/language-name-keyword-definition.test.js index de4dfc5c..7029a0d3 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/location/language-name-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/location/language-name-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('location.language.name'); +defineDomainKeywordHelpContractTests('location.language.name'); + +describe('location.language.name parameter validation', () => { + test('executes location.language.name() successfully', () => { + const parsed = parseKeywordInvocation('location.language.name()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/location/latitude-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/location/latitude-keyword-definition.test.js index 1bacca33..3a0f4826 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/location/latitude-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/location/latitude-keyword-definition.test.js @@ -1,3 +1,59 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('location.latitude'); +defineDomainKeywordHelpContractTests('location.latitude'); + +describe('location.latitude parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('location.latitude'); + const parsed = parseKeywordInvocation(`location.latitude(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes location.latitude(max=10, min=1) successfully', () => { + const parsed = parseKeywordInvocation('location.latitude(max=10, min=1)'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(typeof result).toBe('number'); + }); + + test('rejects invalid min type before generation', () => { + expect(validateArgs('min={"bad":true}, max=10')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "min" must be number, not object', + }); + }); + + test('rejects invalid max type before generation', () => { + expect(validateArgs('min=1, max={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "max" must be number, not object', + }); + }); + + test('rejects invalid precision type before generation', () => { + expect(validateArgs('min=1, max=10, precision={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "precision" must be number, not object', + }); + }); + + test('rejects min greater than max before generation', () => { + expect(validateArgs('min=10, max=1')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "min" must be less than or equal to argument "max"', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/location/longitude-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/location/longitude-keyword-definition.test.js index ebab3ffe..508bb502 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/location/longitude-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/location/longitude-keyword-definition.test.js @@ -1,3 +1,59 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('location.longitude'); +defineDomainKeywordHelpContractTests('location.longitude'); + +describe('location.longitude parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('location.longitude'); + const parsed = parseKeywordInvocation(`location.longitude(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes location.longitude(max=10, min=1) successfully', () => { + const parsed = parseKeywordInvocation('location.longitude(max=10, min=1)'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(typeof result).toBe('number'); + }); + + test('rejects invalid min type before generation', () => { + expect(validateArgs('min={"bad":true}, max=10')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "min" must be number, not object', + }); + }); + + test('rejects invalid max type before generation', () => { + expect(validateArgs('min=1, max={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "max" must be number, not object', + }); + }); + + test('rejects invalid precision type before generation', () => { + expect(validateArgs('min=1, max=10, precision={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "precision" must be number, not object', + }); + }); + + test('rejects min greater than max before generation', () => { + expect(validateArgs('min=10, max=1')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "min" must be less than or equal to argument "max"', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/location/nearby-gpscoordinate-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/location/nearby-gpscoordinate-keyword-definition.test.js index 725d9ca9..3e368b6f 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/location/nearby-gpscoordinate-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/location/nearby-gpscoordinate-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('location.nearbyGPSCoordinate'); +defineDomainKeywordHelpContractTests('location.nearbyGPSCoordinate'); + +describe('location.nearbyGPSCoordinate parameter validation', () => { + test('executes location.nearbyGPSCoordinate() successfully', () => { + const parsed = parseKeywordInvocation('location.nearbyGPSCoordinate()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/location/ordinal-direction-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/location/ordinal-direction-keyword-definition.test.js index c8346858..71179fb6 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/location/ordinal-direction-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/location/ordinal-direction-keyword-definition.test.js @@ -1,3 +1,38 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('location.ordinalDirection'); +defineDomainKeywordHelpContractTests('location.ordinalDirection'); + +describe('location.ordinalDirection parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('location.ordinalDirection'); + const parsed = parseKeywordInvocation(`location.ordinalDirection(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes location.ordinalDirection(abbreviated=true) successfully', () => { + const parsed = parseKeywordInvocation('location.ordinalDirection(abbreviated=true)'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid abbreviated type before generation', () => { + expect(validateArgs('abbreviated={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "abbreviated" must be boolean, not object', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/location/secondary-address-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/location/secondary-address-keyword-definition.test.js index 3ec811d4..bf082920 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/location/secondary-address-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/location/secondary-address-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('location.secondaryAddress'); +defineDomainKeywordHelpContractTests('location.secondaryAddress'); + +describe('location.secondaryAddress parameter validation', () => { + test('executes location.secondaryAddress() successfully', () => { + const parsed = parseKeywordInvocation('location.secondaryAddress()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/location/state-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/location/state-keyword-definition.test.js index 9049a230..e11de8e1 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/location/state-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/location/state-keyword-definition.test.js @@ -1,3 +1,38 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('location.state'); +defineDomainKeywordHelpContractTests('location.state'); + +describe('location.state parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('location.state'); + const parsed = parseKeywordInvocation(`location.state(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes location.state(abbreviated=true) successfully', () => { + const parsed = parseKeywordInvocation('location.state(abbreviated=true)'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid abbreviated type before generation', () => { + expect(validateArgs('abbreviated={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "abbreviated" must be boolean, not object', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/location/street-address-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/location/street-address-keyword-definition.test.js index b51e9347..c1123ced 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/location/street-address-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/location/street-address-keyword-definition.test.js @@ -1,3 +1,38 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('location.streetAddress'); +defineDomainKeywordHelpContractTests('location.streetAddress'); + +describe('location.streetAddress parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('location.streetAddress'); + const parsed = parseKeywordInvocation(`location.streetAddress(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes location.streetAddress(useFullAddress=true) successfully', () => { + const parsed = parseKeywordInvocation('location.streetAddress(useFullAddress=true)'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid useFullAddress type before generation', () => { + expect(validateArgs('useFullAddress={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "useFullAddress" must be boolean, not object', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/location/street-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/location/street-keyword-definition.test.js index 31494de1..c0db82e5 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/location/street-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/location/street-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('location.street'); +defineDomainKeywordHelpContractTests('location.street'); + +describe('location.street parameter validation', () => { + test('executes location.street() successfully', () => { + const parsed = parseKeywordInvocation('location.street()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/location/time-zone-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/location/time-zone-keyword-definition.test.js index 6d848475..cdd8b2ca 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/location/time-zone-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/location/time-zone-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('location.timeZone'); +defineDomainKeywordHelpContractTests('location.timeZone'); + +describe('location.timeZone parameter validation', () => { + test('executes location.timeZone() successfully', () => { + const parsed = parseKeywordInvocation('location.timeZone()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/location/zip-code-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/location/zip-code-keyword-definition.test.js index b16037ff..4b809da0 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/location/zip-code-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/location/zip-code-keyword-definition.test.js @@ -1,3 +1,45 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('location.zipCode'); +defineDomainKeywordHelpContractTests('location.zipCode'); + +describe('location.zipCode parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('location.zipCode'); + const parsed = parseKeywordInvocation(`location.zipCode(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes location.zipCode(format="#####") successfully', () => { + const parsed = parseKeywordInvocation('location.zipCode(format="#####")'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid state type before generation', () => { + expect(validateArgs('state={"bad":true}, format="#####"')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "state" must be string, not object', + }); + }); + + test('rejects invalid format type before generation', () => { + expect(validateArgs('format={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "format" must be string, not object', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/lorem/lines-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/lorem/lines-keyword-definition.test.js index 7708a4a4..484e9079 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/lorem/lines-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/lorem/lines-keyword-definition.test.js @@ -1,3 +1,101 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('lorem.lines'); +defineDomainKeywordHelpContractTests('lorem.lines'); + +describe('lorem.lines parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('lorem.lines'); + const parsed = parseKeywordInvocation(`lorem.lines(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes lorem.lines(max=10, min=1) successfully', () => { + const parsed = parseKeywordInvocation('lorem.lines(max=10, min=1)'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid min type before generation', () => { + expect(validateArgs('min={"bad":true}, max=10')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "min" must be number, not object', + }); + }); + + test('rejects invalid max type before generation', () => { + expect(validateArgs('min=1, max={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "max" must be number, not object', + }); + }); + + test('rejects invalid lineCount type before generation', () => { + expect(validateArgs('lineCount={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "lineCount" must be number, not object', + }); + }); + + test('rejects zero lineCount before generation', () => { + expect(validateArgs('lineCount=0')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "lineCount" must be greater than 0', + }); + }); + + test('rejects negative lineCount before generation', () => { + expect(validateArgs('lineCount=-1')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "lineCount" must be greater than 0', + }); + }); + + test('rejects fractional lineCount before generation', () => { + expect(validateArgs('lineCount=1.5')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "lineCount" must be an integer', + }); + }); + + test('rejects invalid lineCountMax type before generation', () => { + expect(validateArgs('lineCountMax={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "lineCountMax" must be number, not object', + }); + }); + + test('rejects invalid lineCountMin type before generation', () => { + expect(validateArgs('lineCountMin={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "lineCountMin" must be number, not object', + }); + }); + + test('rejects min greater than max before generation', () => { + expect(validateArgs('min=10, max=1')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "min" must be less than or equal to argument "max"', + }); + }); + + test('rejects lineCountMin greater than lineCountMax before generation', () => { + expect(validateArgs('lineCountMax=1, lineCountMin=10')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "lineCountMin" must be less than or equal to argument "lineCountMax"', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/lorem/paragraph-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/lorem/paragraph-keyword-definition.test.js index 786bf781..93ea8847 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/lorem/paragraph-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/lorem/paragraph-keyword-definition.test.js @@ -1,3 +1,102 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('lorem.paragraph'); +defineDomainKeywordHelpContractTests('lorem.paragraph'); + +describe('lorem.paragraph parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('lorem.paragraph'); + const parsed = parseKeywordInvocation(`lorem.paragraph(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes lorem.paragraph(max=10, min=1) successfully', () => { + const parsed = parseKeywordInvocation('lorem.paragraph(max=10, min=1)'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid min type before generation', () => { + expect(validateArgs('min={"bad":true}, max=10')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "min" must be number, not object', + }); + }); + + test('rejects invalid max type before generation', () => { + expect(validateArgs('min=1, max={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "max" must be number, not object', + }); + }); + + test('rejects invalid sentenceCount type before generation', () => { + expect(validateArgs('sentenceCount={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "sentenceCount" must be number, not object', + }); + }); + + test('rejects zero sentenceCount before generation', () => { + expect(validateArgs('sentenceCount=0')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "sentenceCount" must be greater than 0', + }); + }); + + test('rejects negative sentenceCount before generation', () => { + expect(validateArgs('sentenceCount=-1')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "sentenceCount" must be greater than 0', + }); + }); + + test('rejects fractional sentenceCount before generation', () => { + expect(validateArgs('sentenceCount=1.5')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "sentenceCount" must be an integer', + }); + }); + + test('rejects invalid sentenceCountMax type before generation', () => { + expect(validateArgs('sentenceCountMax={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "sentenceCountMax" must be number, not object', + }); + }); + + test('rejects invalid sentenceCountMin type before generation', () => { + expect(validateArgs('sentenceCountMin={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "sentenceCountMin" must be number, not object', + }); + }); + + test('rejects min greater than max before generation', () => { + expect(validateArgs('min=10, max=1')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "min" must be less than or equal to argument "max"', + }); + }); + + test('rejects sentenceCountMin greater than sentenceCountMax before generation', () => { + expect(validateArgs('sentenceCountMax=1, sentenceCountMin=10')).toEqual({ + ok: false, + error: + 'Invalid keyword arguments: argument "sentenceCountMin" must be less than or equal to argument "sentenceCountMax"', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/lorem/paragraphs-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/lorem/paragraphs-keyword-definition.test.js index dae174bf..0343991b 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/lorem/paragraphs-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/lorem/paragraphs-keyword-definition.test.js @@ -1,3 +1,109 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('lorem.paragraphs'); +defineDomainKeywordHelpContractTests('lorem.paragraphs'); + +describe('lorem.paragraphs parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('lorem.paragraphs'); + const parsed = parseKeywordInvocation(`lorem.paragraphs(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes lorem.paragraphs(max=10, min=1) successfully', () => { + const parsed = parseKeywordInvocation('lorem.paragraphs(max=10, min=1)'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid min type before generation', () => { + expect(validateArgs('min={"bad":true}, max=10')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "min" must be number, not object', + }); + }); + + test('rejects invalid max type before generation', () => { + expect(validateArgs('min=1, max={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "max" must be number, not object', + }); + }); + + test('rejects invalid paragraphCount type before generation', () => { + expect(validateArgs('paragraphCount={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "paragraphCount" must be number, not object', + }); + }); + + test('rejects zero paragraphCount before generation', () => { + expect(validateArgs('paragraphCount=0')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "paragraphCount" must be greater than 0', + }); + }); + + test('rejects negative paragraphCount before generation', () => { + expect(validateArgs('paragraphCount=-1')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "paragraphCount" must be greater than 0', + }); + }); + + test('rejects fractional paragraphCount before generation', () => { + expect(validateArgs('paragraphCount=1.5')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "paragraphCount" must be an integer', + }); + }); + + test('rejects invalid separator type before generation', () => { + expect(validateArgs('min=1, max=10, separator={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "separator" must be string, not object', + }); + }); + + test('rejects invalid paragraphCountMax type before generation', () => { + expect(validateArgs('paragraphCountMax={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "paragraphCountMax" must be number, not object', + }); + }); + + test('rejects invalid paragraphCountMin type before generation', () => { + expect(validateArgs('paragraphCountMin={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "paragraphCountMin" must be number, not object', + }); + }); + + test('rejects min greater than max before generation', () => { + expect(validateArgs('min=10, max=1')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "min" must be less than or equal to argument "max"', + }); + }); + + test('rejects paragraphCountMin greater than paragraphCountMax before generation', () => { + expect(validateArgs('paragraphCountMax=1, paragraphCountMin=10')).toEqual({ + ok: false, + error: + 'Invalid keyword arguments: argument "paragraphCountMin" must be less than or equal to argument "paragraphCountMax"', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/lorem/sentence-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/lorem/sentence-keyword-definition.test.js index 7cff40db..aada56b6 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/lorem/sentence-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/lorem/sentence-keyword-definition.test.js @@ -1,3 +1,117 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('lorem.sentence'); +defineDomainKeywordHelpContractTests('lorem.sentence'); + +describe('lorem.sentence parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('lorem.sentence'); + const parsed = parseKeywordInvocation(`lorem.sentence(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes lorem.sentence(max=10, min=1) successfully', () => { + const parsed = parseKeywordInvocation('lorem.sentence(max=10, min=1)'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid min type before generation', () => { + expect(validateArgs('min={"bad":true}, max=10')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "min" must be number, not object', + }); + }); + + test('rejects invalid max type before generation', () => { + expect(validateArgs('min=1, max={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "max" must be number, not object', + }); + }); + + test('rejects invalid wordCount type before generation', () => { + expect(validateArgs('wordCount={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "wordCount" must be number, not object', + }); + }); + + test('rejects zero wordCount before generation', () => { + expect(validateArgs('wordCount=0')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "wordCount" must be greater than 0', + }); + }); + + test('rejects negative wordCount before generation', () => { + expect(validateArgs('wordCount=-1')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "wordCount" must be greater than 0', + }); + }); + + test('rejects fractional wordCount before generation', () => { + expect(validateArgs('wordCount=1.5')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "wordCount" must be an integer', + }); + }); + + test('rejects invalid wordCountMax type before generation', () => { + expect(validateArgs('wordCountMax={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "wordCountMax" must be number, not object', + }); + }); + + test('rejects invalid wordCountMin type before generation', () => { + expect(validateArgs('wordCountMin={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "wordCountMin" must be number, not object', + }); + }); + + test('rejects min greater than max before generation', () => { + expect(validateArgs('min=10, max=1')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "min" must be less than or equal to argument "max"', + }); + }); + + test('rejects mixed generic range and specific count before generation', () => { + expect(validateArgs('min=1, max=10, wordCount=5')).toEqual({ + ok: false, + error: + 'Invalid keyword arguments: use only one lorem count scheme: min/max, wordCount, or wordCountMin/wordCountMax', + }); + }); + + test('rejects mixed generic range and specific count range before generation', () => { + expect(validateArgs('min=1, max=10, wordCountMin=2, wordCountMax=5')).toEqual({ + ok: false, + error: + 'Invalid keyword arguments: use only one lorem count scheme: min/max, wordCount, or wordCountMin/wordCountMax', + }); + }); + + test('rejects wordCountMin greater than wordCountMax before generation', () => { + expect(validateArgs('wordCountMax=1, wordCountMin=10')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "wordCountMin" must be less than or equal to argument "wordCountMax"', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/lorem/sentences-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/lorem/sentences-keyword-definition.test.js index 3fe8fa9d..7b27cb2f 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/lorem/sentences-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/lorem/sentences-keyword-definition.test.js @@ -1,3 +1,109 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('lorem.sentences'); +defineDomainKeywordHelpContractTests('lorem.sentences'); + +describe('lorem.sentences parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('lorem.sentences'); + const parsed = parseKeywordInvocation(`lorem.sentences(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes lorem.sentences(max=10, min=1) successfully', () => { + const parsed = parseKeywordInvocation('lorem.sentences(max=10, min=1)'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid min type before generation', () => { + expect(validateArgs('min={"bad":true}, max=10')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "min" must be number, not object', + }); + }); + + test('rejects invalid max type before generation', () => { + expect(validateArgs('min=1, max={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "max" must be number, not object', + }); + }); + + test('rejects invalid sentenceCount type before generation', () => { + expect(validateArgs('sentenceCount={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "sentenceCount" must be number, not object', + }); + }); + + test('rejects zero sentenceCount before generation', () => { + expect(validateArgs('sentenceCount=0')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "sentenceCount" must be greater than 0', + }); + }); + + test('rejects negative sentenceCount before generation', () => { + expect(validateArgs('sentenceCount=-1')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "sentenceCount" must be greater than 0', + }); + }); + + test('rejects fractional sentenceCount before generation', () => { + expect(validateArgs('sentenceCount=1.5')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "sentenceCount" must be an integer', + }); + }); + + test('rejects invalid separator type before generation', () => { + expect(validateArgs('min=1, max=10, separator={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "separator" must be string, not object', + }); + }); + + test('rejects invalid sentenceCountMax type before generation', () => { + expect(validateArgs('sentenceCountMax={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "sentenceCountMax" must be number, not object', + }); + }); + + test('rejects invalid sentenceCountMin type before generation', () => { + expect(validateArgs('sentenceCountMin={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "sentenceCountMin" must be number, not object', + }); + }); + + test('rejects min greater than max before generation', () => { + expect(validateArgs('min=10, max=1')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "min" must be less than or equal to argument "max"', + }); + }); + + test('rejects sentenceCountMin greater than sentenceCountMax before generation', () => { + expect(validateArgs('sentenceCountMax=1, sentenceCountMin=10')).toEqual({ + ok: false, + error: + 'Invalid keyword arguments: argument "sentenceCountMin" must be less than or equal to argument "sentenceCountMax"', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/lorem/slug-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/lorem/slug-keyword-definition.test.js index 7ddab8bb..3a847eea 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/lorem/slug-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/lorem/slug-keyword-definition.test.js @@ -1,3 +1,101 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('lorem.slug'); +defineDomainKeywordHelpContractTests('lorem.slug'); + +describe('lorem.slug parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('lorem.slug'); + const parsed = parseKeywordInvocation(`lorem.slug(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes lorem.slug(max=10, min=1) successfully', () => { + const parsed = parseKeywordInvocation('lorem.slug(max=10, min=1)'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid min type before generation', () => { + expect(validateArgs('min={"bad":true}, max=10')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "min" must be number, not object', + }); + }); + + test('rejects invalid max type before generation', () => { + expect(validateArgs('min=1, max={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "max" must be number, not object', + }); + }); + + test('rejects invalid wordCount type before generation', () => { + expect(validateArgs('wordCount={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "wordCount" must be number, not object', + }); + }); + + test('rejects zero wordCount before generation', () => { + expect(validateArgs('wordCount=0')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "wordCount" must be greater than 0', + }); + }); + + test('rejects negative wordCount before generation', () => { + expect(validateArgs('wordCount=-1')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "wordCount" must be greater than 0', + }); + }); + + test('rejects fractional wordCount before generation', () => { + expect(validateArgs('wordCount=1.5')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "wordCount" must be an integer', + }); + }); + + test('rejects invalid wordCountMax type before generation', () => { + expect(validateArgs('wordCountMax={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "wordCountMax" must be number, not object', + }); + }); + + test('rejects invalid wordCountMin type before generation', () => { + expect(validateArgs('wordCountMin={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "wordCountMin" must be number, not object', + }); + }); + + test('rejects min greater than max before generation', () => { + expect(validateArgs('min=10, max=1')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "min" must be less than or equal to argument "max"', + }); + }); + + test('rejects wordCountMin greater than wordCountMax before generation', () => { + expect(validateArgs('wordCountMax=1, wordCountMin=10')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "wordCountMin" must be less than or equal to argument "wordCountMax"', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/lorem/text-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/lorem/text-keyword-definition.test.js index 04061643..182433ff 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/lorem/text-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/lorem/text-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('lorem.text'); +defineDomainKeywordHelpContractTests('lorem.text'); + +describe('lorem.text parameter validation', () => { + test('executes lorem.text() successfully', () => { + const parsed = parseKeywordInvocation('lorem.text()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/lorem/word-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/lorem/word-keyword-definition.test.js index 107b0226..031ec754 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/lorem/word-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/lorem/word-keyword-definition.test.js @@ -1,3 +1,67 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('lorem.word'); +defineDomainKeywordHelpContractTests('lorem.word'); + +describe('lorem.word parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('lorem.word'); + const parsed = parseKeywordInvocation(`lorem.word(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes lorem.word(length=5) successfully', () => { + const parsed = parseKeywordInvocation('lorem.word(length=5)'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid length type before generation', () => { + expect(validateArgs('length={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be number, not object', + }); + }); + + test('rejects zero length before generation', () => { + expect(validateArgs('length=0')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be greater than 0', + }); + }); + + test('rejects negative length before generation', () => { + expect(validateArgs('length=-1')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be greater than 0', + }); + }); + + test('rejects fractional length before generation', () => { + expect(validateArgs('length=1.5')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be an integer', + }); + }); + + test('rejects invalid strategy type before generation', () => { + expect(validateArgs('length=5, strategy={"bad":true}')).toEqual({ + ok: false, + error: + 'Invalid keyword arguments: argument "strategy" must be fail, closest, shortest, longest or any-length, not object', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/lorem/words-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/lorem/words-keyword-definition.test.js index fad53213..069a5b78 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/lorem/words-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/lorem/words-keyword-definition.test.js @@ -1,3 +1,101 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('lorem.words'); +defineDomainKeywordHelpContractTests('lorem.words'); + +describe('lorem.words parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('lorem.words'); + const parsed = parseKeywordInvocation(`lorem.words(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes lorem.words(max=10, min=1) successfully', () => { + const parsed = parseKeywordInvocation('lorem.words(max=10, min=1)'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid min type before generation', () => { + expect(validateArgs('min={"bad":true}, max=10')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "min" must be number, not object', + }); + }); + + test('rejects invalid max type before generation', () => { + expect(validateArgs('min=1, max={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "max" must be number, not object', + }); + }); + + test('rejects invalid wordCount type before generation', () => { + expect(validateArgs('wordCount={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "wordCount" must be number, not object', + }); + }); + + test('rejects zero wordCount before generation', () => { + expect(validateArgs('wordCount=0')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "wordCount" must be greater than 0', + }); + }); + + test('rejects negative wordCount before generation', () => { + expect(validateArgs('wordCount=-1')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "wordCount" must be greater than 0', + }); + }); + + test('rejects fractional wordCount before generation', () => { + expect(validateArgs('wordCount=1.5')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "wordCount" must be an integer', + }); + }); + + test('rejects invalid wordCountMax type before generation', () => { + expect(validateArgs('wordCountMax={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "wordCountMax" must be number, not object', + }); + }); + + test('rejects invalid wordCountMin type before generation', () => { + expect(validateArgs('wordCountMin={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "wordCountMin" must be number, not object', + }); + }); + + test('rejects min greater than max before generation', () => { + expect(validateArgs('min=10, max=1')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "min" must be less than or equal to argument "max"', + }); + }); + + test('rejects wordCountMin greater than wordCountMax before generation', () => { + expect(validateArgs('wordCountMax=1, wordCountMin=10')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "wordCountMin" must be less than or equal to argument "wordCountMax"', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/music/album-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/music/album-keyword-definition.test.js index 3394aac1..ef23995e 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/music/album-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/music/album-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('music.album'); +defineDomainKeywordHelpContractTests('music.album'); + +describe('music.album parameter validation', () => { + test('executes music.album() successfully', () => { + const parsed = parseKeywordInvocation('music.album()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/music/artist-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/music/artist-keyword-definition.test.js index ba15b3ba..778d4e79 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/music/artist-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/music/artist-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('music.artist'); +defineDomainKeywordHelpContractTests('music.artist'); + +describe('music.artist parameter validation', () => { + test('executes music.artist() successfully', () => { + const parsed = parseKeywordInvocation('music.artist()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/music/genre-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/music/genre-keyword-definition.test.js index d58cc746..d9a84a52 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/music/genre-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/music/genre-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('music.genre'); +defineDomainKeywordHelpContractTests('music.genre'); + +describe('music.genre parameter validation', () => { + test('executes music.genre() successfully', () => { + const parsed = parseKeywordInvocation('music.genre()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/music/song-name-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/music/song-name-keyword-definition.test.js index 5018c5ce..cc24c59c 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/music/song-name-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/music/song-name-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('music.songName'); +defineDomainKeywordHelpContractTests('music.songName'); + +describe('music.songName parameter validation', () => { + test('executes music.songName() successfully', () => { + const parsed = parseKeywordInvocation('music.songName()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/number/big-int-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/number/big-int-keyword-definition.test.js index 6bef1932..5d71e5e4 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/number/big-int-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/number/big-int-keyword-definition.test.js @@ -1,3 +1,80 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('number.bigInt'); +defineDomainKeywordHelpContractTests('number.bigInt'); + +describe('number.bigInt parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('number.bigInt'); + const parsed = parseKeywordInvocation(`number.bigInt(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes number.bigInt(min=100, max=1000) successfully', () => { + const parsed = parseKeywordInvocation('number.bigInt(min=100, max=1000)'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid min type before generation', () => { + expect(validateArgs('min={"bad":true}, max=1000')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "min" must be integer, not object', + }); + }); + + test('rejects invalid max type before generation', () => { + expect(validateArgs('min=100, max={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "max" must be integer, not object', + }); + }); + + test('rejects invalid multipleOf type before generation', () => { + expect(validateArgs('min=100, max=1000, multipleOf={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "multipleOf" must be integer, not object', + }); + }); + + test('rejects zero multipleOf before generation', () => { + expect(validateArgs('min=100, max=1000, multipleOf=0')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "multipleOf" must be greater than 0', + }); + }); + + test('rejects negative multipleOf before generation', () => { + expect(validateArgs('min=100, max=1000, multipleOf=-1')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "multipleOf" must be greater than 0', + }); + }); + + test('rejects fractional multipleOf before generation', () => { + expect(validateArgs('min=100, max=1000, multipleOf=1.5')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "multipleOf" must be integer, not number', + }); + }); + + test('rejects min greater than max before generation', () => { + expect(validateArgs('min=10, max=1')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "min" must be less than or equal to argument "max"', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/number/binary-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/number/binary-keyword-definition.test.js index b81bb3a8..1dcbfe2e 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/number/binary-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/number/binary-keyword-definition.test.js @@ -1,3 +1,52 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('number.binary'); +defineDomainKeywordHelpContractTests('number.binary'); + +describe('number.binary parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('number.binary'); + const parsed = parseKeywordInvocation(`number.binary(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes number.binary(max=5) successfully', () => { + const parsed = parseKeywordInvocation('number.binary(max=5)'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid max type before generation', () => { + expect(validateArgs('max={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "max" must be number, not object', + }); + }); + + test('rejects invalid min type before generation', () => { + expect(validateArgs('max=5, min={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "min" must be number, not object', + }); + }); + + test('rejects min greater than max before generation', () => { + expect(validateArgs('max=1, min=10')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "min" must be less than or equal to argument "max"', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/number/float-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/number/float-keyword-definition.test.js index 200efcd8..a3c5e9b1 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/number/float-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/number/float-keyword-definition.test.js @@ -1,3 +1,66 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('number.float'); +defineDomainKeywordHelpContractTests('number.float'); + +describe('number.float parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('number.float'); + const parsed = parseKeywordInvocation(`number.float(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes number.float(fractionDigits=2) successfully', () => { + const parsed = parseKeywordInvocation('number.float(fractionDigits=2)'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(typeof result).toBe('number'); + }); + + test('rejects invalid fractionDigits type before generation', () => { + expect(validateArgs('fractionDigits={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "fractionDigits" must be integer, not object', + }); + }); + + test('rejects invalid max type before generation', () => { + expect(validateArgs('fractionDigits=2, max={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "max" must be number, not object', + }); + }); + + test('rejects invalid min type before generation', () => { + expect(validateArgs('fractionDigits=2, min={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "min" must be number, not object', + }); + }); + + test('rejects invalid multipleOf type before generation', () => { + expect(validateArgs('fractionDigits=2, multipleOf={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "multipleOf" must be number, not object', + }); + }); + + test('rejects min greater than max before generation', () => { + expect(validateArgs('fractionDigits=2, max=1, min=10')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "min" must be less than or equal to argument "max"', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/number/hex-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/number/hex-keyword-definition.test.js index 999a7390..96e4c1b0 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/number/hex-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/number/hex-keyword-definition.test.js @@ -1,3 +1,52 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('number.hex'); +defineDomainKeywordHelpContractTests('number.hex'); + +describe('number.hex parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('number.hex'); + const parsed = parseKeywordInvocation(`number.hex(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes number.hex(max=10, min=1) successfully', () => { + const parsed = parseKeywordInvocation('number.hex(max=10, min=1)'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid min type before generation', () => { + expect(validateArgs('min={"bad":true}, max=10')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "min" must be number, not object', + }); + }); + + test('rejects invalid max type before generation', () => { + expect(validateArgs('min=1, max={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "max" must be number, not object', + }); + }); + + test('rejects min greater than max before generation', () => { + expect(validateArgs('min=10, max=1')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "min" must be less than or equal to argument "max"', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/number/int-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/number/int-keyword-definition.test.js index d8234afd..ccc27f28 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/number/int-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/number/int-keyword-definition.test.js @@ -1,3 +1,73 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('number.int'); +defineDomainKeywordHelpContractTests('number.int'); + +describe('number.int parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('number.int'); + const parsed = parseKeywordInvocation(`number.int(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes number.int(max=10, min=1) successfully', () => { + const parsed = parseKeywordInvocation('number.int(max=10, min=1)'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(typeof result).toBe('number'); + }); + + test('rejects invalid min type before generation', () => { + expect(validateArgs('min={"bad":true}, max=10')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "min" must be number, not object', + }); + }); + + test('rejects invalid max type before generation', () => { + expect(validateArgs('min=1, max={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "max" must be number, not object', + }); + }); + + test('rejects invalid multipleOf type before generation', () => { + expect(validateArgs('min=1, max=10, multipleOf={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "multipleOf" must be number, not object', + }); + }); + + test('rejects zero multipleOf before generation', () => { + expect(validateArgs('min=1, max=10, multipleOf=0')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "multipleOf" must be greater than 0', + }); + }); + + test('rejects negative multipleOf before generation', () => { + expect(validateArgs('min=1, max=10, multipleOf=-1')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "multipleOf" must be greater than 0', + }); + }); + + test('rejects min greater than max before generation', () => { + expect(validateArgs('min=10, max=1')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "min" must be less than or equal to argument "max"', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/number/octal-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/number/octal-keyword-definition.test.js index 15a9043c..1298de73 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/number/octal-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/number/octal-keyword-definition.test.js @@ -1,3 +1,52 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('number.octal'); +defineDomainKeywordHelpContractTests('number.octal'); + +describe('number.octal parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('number.octal'); + const parsed = parseKeywordInvocation(`number.octal(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes number.octal(max=5) successfully', () => { + const parsed = parseKeywordInvocation('number.octal(max=5)'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid max type before generation', () => { + expect(validateArgs('max={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "max" must be number, not object', + }); + }); + + test('rejects invalid min type before generation', () => { + expect(validateArgs('max=5, min={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "min" must be number, not object', + }); + }); + + test('rejects min greater than max before generation', () => { + expect(validateArgs('max=1, min=10')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "min" must be less than or equal to argument "max"', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/number/roman-numeral-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/number/roman-numeral-keyword-definition.test.js index 83fe1943..bd6bf207 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/number/roman-numeral-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/number/roman-numeral-keyword-definition.test.js @@ -1,3 +1,52 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('number.romanNumeral'); +defineDomainKeywordHelpContractTests('number.romanNumeral'); + +describe('number.romanNumeral parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('number.romanNumeral'); + const parsed = parseKeywordInvocation(`number.romanNumeral(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes number.romanNumeral(max=10, min=1) successfully', () => { + const parsed = parseKeywordInvocation('number.romanNumeral(max=10, min=1)'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid min type before generation', () => { + expect(validateArgs('min={"bad":true}, max=10')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "min" must be number, not object', + }); + }); + + test('rejects invalid max type before generation', () => { + expect(validateArgs('min=1, max={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "max" must be number, not object', + }); + }); + + test('rejects min greater than max before generation', () => { + expect(validateArgs('min=10, max=1')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "min" must be less than or equal to argument "max"', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/person/bio-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/person/bio-keyword-definition.test.js index 9184c07c..25be20da 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/person/bio-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/person/bio-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('person.bio'); +defineDomainKeywordHelpContractTests('person.bio'); + +describe('person.bio parameter validation', () => { + test('executes person.bio() successfully', () => { + const parsed = parseKeywordInvocation('person.bio()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/person/first-name-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/person/first-name-keyword-definition.test.js index d97f14a6..072dc004 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/person/first-name-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/person/first-name-keyword-definition.test.js @@ -1,3 +1,38 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('person.firstName'); +defineDomainKeywordHelpContractTests('person.firstName'); + +describe('person.firstName parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('person.firstName'); + const parsed = parseKeywordInvocation(`person.firstName(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes person.firstName(sex="female") successfully', () => { + const parsed = parseKeywordInvocation('person.firstName(sex="female")'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid sex type before generation', () => { + expect(validateArgs('sex={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "sex" must be female or male, not object', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/person/full-name-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/person/full-name-keyword-definition.test.js index ce566efe..ca7cfde7 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/person/full-name-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/person/full-name-keyword-definition.test.js @@ -1,3 +1,52 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('person.fullName'); +defineDomainKeywordHelpContractTests('person.fullName'); + +describe('person.fullName parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('person.fullName'); + const parsed = parseKeywordInvocation(`person.fullName(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes person.fullName(firstName="Ada", lastName="Lovelace", sex="female") successfully', () => { + const parsed = parseKeywordInvocation('person.fullName(firstName="Ada", lastName="Lovelace", sex="female")'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid firstName type before generation', () => { + expect(validateArgs('firstName={"bad":true}, lastName="Lovelace", sex="female"')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "firstName" must be string, not object', + }); + }); + + test('rejects invalid lastName type before generation', () => { + expect(validateArgs('firstName="Ada", lastName={"bad":true}, sex="female"')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "lastName" must be string, not object', + }); + }); + + test('rejects invalid sex type before generation', () => { + expect(validateArgs('firstName="Ada", lastName="Lovelace", sex={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "sex" must be female, generic or male, not object', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/person/gender-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/person/gender-keyword-definition.test.js index a2260e61..067fd39a 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/person/gender-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/person/gender-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('person.gender'); +defineDomainKeywordHelpContractTests('person.gender'); + +describe('person.gender parameter validation', () => { + test('executes person.gender() successfully', () => { + const parsed = parseKeywordInvocation('person.gender()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/person/job-area-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/person/job-area-keyword-definition.test.js index ae8f9c55..6459e9c9 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/person/job-area-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/person/job-area-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('person.jobArea'); +defineDomainKeywordHelpContractTests('person.jobArea'); + +describe('person.jobArea parameter validation', () => { + test('executes person.jobArea() successfully', () => { + const parsed = parseKeywordInvocation('person.jobArea()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/person/job-descriptor-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/person/job-descriptor-keyword-definition.test.js index e41a961c..4b390eff 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/person/job-descriptor-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/person/job-descriptor-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('person.jobDescriptor'); +defineDomainKeywordHelpContractTests('person.jobDescriptor'); + +describe('person.jobDescriptor parameter validation', () => { + test('executes person.jobDescriptor() successfully', () => { + const parsed = parseKeywordInvocation('person.jobDescriptor()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/person/job-title-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/person/job-title-keyword-definition.test.js index 944ffb54..09d669c1 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/person/job-title-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/person/job-title-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('person.jobTitle'); +defineDomainKeywordHelpContractTests('person.jobTitle'); + +describe('person.jobTitle parameter validation', () => { + test('executes person.jobTitle() successfully', () => { + const parsed = parseKeywordInvocation('person.jobTitle()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/person/job-type-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/person/job-type-keyword-definition.test.js index 522f363b..944f73c2 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/person/job-type-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/person/job-type-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('person.jobType'); +defineDomainKeywordHelpContractTests('person.jobType'); + +describe('person.jobType parameter validation', () => { + test('executes person.jobType() successfully', () => { + const parsed = parseKeywordInvocation('person.jobType()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/person/last-name-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/person/last-name-keyword-definition.test.js index f782f0e8..af67675e 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/person/last-name-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/person/last-name-keyword-definition.test.js @@ -1,3 +1,38 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('person.lastName'); +defineDomainKeywordHelpContractTests('person.lastName'); + +describe('person.lastName parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('person.lastName'); + const parsed = parseKeywordInvocation(`person.lastName(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes person.lastName(sex="female") successfully', () => { + const parsed = parseKeywordInvocation('person.lastName(sex="female")'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid sex type before generation', () => { + expect(validateArgs('sex={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "sex" must be female or male, not object', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/person/middle-name-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/person/middle-name-keyword-definition.test.js index de4efdd6..b0b3d4c9 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/person/middle-name-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/person/middle-name-keyword-definition.test.js @@ -1,3 +1,38 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('person.middleName'); +defineDomainKeywordHelpContractTests('person.middleName'); + +describe('person.middleName parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('person.middleName'); + const parsed = parseKeywordInvocation(`person.middleName(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes person.middleName(sex="female") successfully', () => { + const parsed = parseKeywordInvocation('person.middleName(sex="female")'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid sex type before generation', () => { + expect(validateArgs('sex={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "sex" must be female or male, not object', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/person/prefix-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/person/prefix-keyword-definition.test.js index 7a750b13..cf486962 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/person/prefix-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/person/prefix-keyword-definition.test.js @@ -1,3 +1,38 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('person.prefix'); +defineDomainKeywordHelpContractTests('person.prefix'); + +describe('person.prefix parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('person.prefix'); + const parsed = parseKeywordInvocation(`person.prefix(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes person.prefix(sex="female") successfully', () => { + const parsed = parseKeywordInvocation('person.prefix(sex="female")'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid sex type before generation', () => { + expect(validateArgs('sex={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "sex" must be female or male, not object', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/person/sex-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/person/sex-keyword-definition.test.js index e9f5a6c5..f9cda893 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/person/sex-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/person/sex-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('person.sex'); +defineDomainKeywordHelpContractTests('person.sex'); + +describe('person.sex parameter validation', () => { + test('executes person.sex() successfully', () => { + const parsed = parseKeywordInvocation('person.sex()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/person/sex-type-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/person/sex-type-keyword-definition.test.js index 428c9943..0b5ddb65 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/person/sex-type-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/person/sex-type-keyword-definition.test.js @@ -1,3 +1,38 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('person.sexType'); +defineDomainKeywordHelpContractTests('person.sexType'); + +describe('person.sexType parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('person.sexType'); + const parsed = parseKeywordInvocation(`person.sexType(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes person.sexType(includeGeneric=false) successfully', () => { + const parsed = parseKeywordInvocation('person.sexType(includeGeneric=false)'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid includeGeneric type before generation', () => { + expect(validateArgs('includeGeneric={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "includeGeneric" must be boolean, not object', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/person/suffix-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/person/suffix-keyword-definition.test.js index 99fd4f8c..c9e95a3f 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/person/suffix-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/person/suffix-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('person.suffix'); +defineDomainKeywordHelpContractTests('person.suffix'); + +describe('person.suffix parameter validation', () => { + test('executes person.suffix() successfully', () => { + const parsed = parseKeywordInvocation('person.suffix()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/person/zodiac-sign-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/person/zodiac-sign-keyword-definition.test.js index f3a6b138..a9753e43 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/person/zodiac-sign-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/person/zodiac-sign-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('person.zodiacSign'); +defineDomainKeywordHelpContractTests('person.zodiacSign'); + +describe('person.zodiacSign parameter validation', () => { + test('executes person.zodiacSign() successfully', () => { + const parsed = parseKeywordInvocation('person.zodiacSign()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/phone/imei-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/phone/imei-keyword-definition.test.js index 34fc69f8..bc10a411 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/phone/imei-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/phone/imei-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('phone.imei'); +defineDomainKeywordHelpContractTests('phone.imei'); + +describe('phone.imei parameter validation', () => { + test('executes phone.imei() successfully', () => { + const parsed = parseKeywordInvocation('phone.imei()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/phone/number-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/phone/number-keyword-definition.test.js index bc2c4d27..e60cb5b2 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/phone/number-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/phone/number-keyword-definition.test.js @@ -1,3 +1,38 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('phone.number'); +defineDomainKeywordHelpContractTests('phone.number'); + +describe('phone.number parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('phone.number'); + const parsed = parseKeywordInvocation(`phone.number(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes phone.number(style="international") successfully', () => { + const parsed = parseKeywordInvocation('phone.number(style="international")'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid style type before generation', () => { + expect(validateArgs('style={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "style" must be human, national or international, not object', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/science/chemical-element-atomic-number-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/science/chemical-element-atomic-number-keyword-definition.test.js index ca6972b7..f5b85d64 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/science/chemical-element-atomic-number-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/science/chemical-element-atomic-number-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('science.chemicalElement.atomicNumber'); +defineDomainKeywordHelpContractTests('science.chemicalElement.atomicNumber'); + +describe('science.chemicalElement.atomicNumber parameter validation', () => { + test('executes science.chemicalElement.atomicNumber() successfully', () => { + const parsed = parseKeywordInvocation('science.chemicalElement.atomicNumber()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(typeof result).toBe('number'); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/science/chemical-element-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/science/chemical-element-keyword-definition.test.js index 82bad503..5bda8c6f 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/science/chemical-element-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/science/chemical-element-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('science.chemicalElement'); +defineDomainKeywordHelpContractTests('science.chemicalElement'); + +describe('science.chemicalElement parameter validation', () => { + test('executes science.chemicalElement() successfully', () => { + const parsed = parseKeywordInvocation('science.chemicalElement()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/science/chemical-element-name-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/science/chemical-element-name-keyword-definition.test.js index e5e193d8..e01f5e07 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/science/chemical-element-name-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/science/chemical-element-name-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('science.chemicalElement.name'); +defineDomainKeywordHelpContractTests('science.chemicalElement.name'); + +describe('science.chemicalElement.name parameter validation', () => { + test('executes science.chemicalElement.name() successfully', () => { + const parsed = parseKeywordInvocation('science.chemicalElement.name()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/science/chemical-element-symbol-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/science/chemical-element-symbol-keyword-definition.test.js index 6810cc01..83aa83a2 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/science/chemical-element-symbol-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/science/chemical-element-symbol-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('science.chemicalElement.symbol'); +defineDomainKeywordHelpContractTests('science.chemicalElement.symbol'); + +describe('science.chemicalElement.symbol parameter validation', () => { + test('executes science.chemicalElement.symbol() successfully', () => { + const parsed = parseKeywordInvocation('science.chemicalElement.symbol()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/science/unit-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/science/unit-keyword-definition.test.js index c135b3d7..c28be44c 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/science/unit-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/science/unit-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('science.unit'); +defineDomainKeywordHelpContractTests('science.unit'); + +describe('science.unit parameter validation', () => { + test('executes science.unit() successfully', () => { + const parsed = parseKeywordInvocation('science.unit()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/science/unit-name-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/science/unit-name-keyword-definition.test.js index 46916b14..91d3466d 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/science/unit-name-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/science/unit-name-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('science.unit.name'); +defineDomainKeywordHelpContractTests('science.unit.name'); + +describe('science.unit.name parameter validation', () => { + test('executes science.unit.name() successfully', () => { + const parsed = parseKeywordInvocation('science.unit.name()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/science/unit-symbol-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/science/unit-symbol-keyword-definition.test.js index 4e1ff707..d08ecd4b 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/science/unit-symbol-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/science/unit-symbol-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('science.unit.symbol'); +defineDomainKeywordHelpContractTests('science.unit.symbol'); + +describe('science.unit.symbol parameter validation', () => { + test('executes science.unit.symbol() successfully', () => { + const parsed = parseKeywordInvocation('science.unit.symbol()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/string/alpha-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/string/alpha-keyword-definition.test.js index d00d733d..84b76bf4 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/string/alpha-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/string/alpha-keyword-definition.test.js @@ -1,3 +1,73 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('string.alpha'); +defineDomainKeywordHelpContractTests('string.alpha'); + +describe('string.alpha parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('string.alpha'); + const parsed = parseKeywordInvocation(`string.alpha(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes string.alpha(length=5) successfully', () => { + const parsed = parseKeywordInvocation('string.alpha(length=5)'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid length type before generation', () => { + expect(validateArgs('length={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be number, not object', + }); + }); + + test('rejects zero length before generation', () => { + expect(validateArgs('length=0')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be greater than 0', + }); + }); + + test('rejects negative length before generation', () => { + expect(validateArgs('length=-1')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be greater than 0', + }); + }); + + test('rejects fractional length before generation', () => { + expect(validateArgs('length=1.5')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be an integer', + }); + }); + + test('rejects invalid casing type before generation', () => { + expect(validateArgs('length=5, casing={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "casing" must be upper, lower or mixed, not object', + }); + }); + + test('rejects invalid exclude type before generation', () => { + expect(validateArgs('length=5, exclude={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "exclude" must be array, not object', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/string/alphanumeric-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/string/alphanumeric-keyword-definition.test.js index 51581587..382d2c2e 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/string/alphanumeric-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/string/alphanumeric-keyword-definition.test.js @@ -1,3 +1,73 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('string.alphanumeric'); +defineDomainKeywordHelpContractTests('string.alphanumeric'); + +describe('string.alphanumeric parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('string.alphanumeric'); + const parsed = parseKeywordInvocation(`string.alphanumeric(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes string.alphanumeric(length=5) successfully', () => { + const parsed = parseKeywordInvocation('string.alphanumeric(length=5)'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid length type before generation', () => { + expect(validateArgs('length={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be number, not object', + }); + }); + + test('rejects zero length before generation', () => { + expect(validateArgs('length=0')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be greater than 0', + }); + }); + + test('rejects negative length before generation', () => { + expect(validateArgs('length=-1')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be greater than 0', + }); + }); + + test('rejects fractional length before generation', () => { + expect(validateArgs('length=1.5')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be an integer', + }); + }); + + test('rejects invalid casing type before generation', () => { + expect(validateArgs('length=5, casing={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "casing" must be upper, lower or mixed, not object', + }); + }); + + test('rejects invalid exclude type before generation', () => { + expect(validateArgs('length=5, exclude={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "exclude" must be array, not object', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/string/binary-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/string/binary-keyword-definition.test.js index e01799b8..6099f202 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/string/binary-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/string/binary-keyword-definition.test.js @@ -1,3 +1,66 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('string.binary'); +defineDomainKeywordHelpContractTests('string.binary'); + +describe('string.binary parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('string.binary'); + const parsed = parseKeywordInvocation(`string.binary(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes string.binary(length=5) successfully', () => { + const parsed = parseKeywordInvocation('string.binary(length=5)'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid length type before generation', () => { + expect(validateArgs('length={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be number, not object', + }); + }); + + test('rejects zero length before generation', () => { + expect(validateArgs('length=0')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be greater than 0', + }); + }); + + test('rejects negative length before generation', () => { + expect(validateArgs('length=-1')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be greater than 0', + }); + }); + + test('rejects fractional length before generation', () => { + expect(validateArgs('length=1.5')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be an integer', + }); + }); + + test('rejects invalid prefix type before generation', () => { + expect(validateArgs('length=5, prefix={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "prefix" must be string, not object', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/string/counter-string-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/string/counter-string-keyword-definition.test.js index be78db76..4065fbd7 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/string/counter-string-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/string/counter-string-keyword-definition.test.js @@ -1,3 +1,51 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('string.counterString'); +defineDomainKeywordHelpContractTests('string.counterString'); + +describe('string.counterString parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('string.counterString'); + const parsed = parseKeywordInvocation(`string.counterString(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes string.counterString(min=15) successfully', () => { + const parsed = parseKeywordInvocation('string.counterString(min=15)'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid min type before generation', () => { + expect(validateArgs('min={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "min" must be integer, not object', + }); + }); + + test('rejects invalid max type before generation', () => { + expect(validateArgs('min=15, max={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "max" must be integer, not object', + }); + }); + + test('rejects invalid delimiter type before generation', () => { + expect(validateArgs('min=15, delimiter={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "delimiter" must be string, not object', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/string/from-characters-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/string/from-characters-keyword-definition.test.js index 7d1db135..c0eca513 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/string/from-characters-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/string/from-characters-keyword-definition.test.js @@ -1,3 +1,73 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('string.fromCharacters'); +defineDomainKeywordHelpContractTests('string.fromCharacters'); + +describe('string.fromCharacters parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('string.fromCharacters'); + const parsed = parseKeywordInvocation(`string.fromCharacters(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes string.fromCharacters(characters="ABC123") successfully', () => { + const parsed = parseKeywordInvocation('string.fromCharacters(characters="ABC123")'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects missing required characters before generation', () => { + expect(validateArgs('')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "characters" is required', + }); + }); + + test('rejects invalid characters type before generation', () => { + expect(validateArgs('characters={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "characters" must be string or array, not object', + }); + }); + + test('rejects invalid length type before generation', () => { + expect(validateArgs('characters="ABC123", length={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be integer, not object', + }); + }); + + test('rejects zero length before generation', () => { + expect(validateArgs('characters="ABC123", length=0')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be greater than 0', + }); + }); + + test('rejects negative length before generation', () => { + expect(validateArgs('characters="ABC123", length=-1')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be greater than 0', + }); + }); + + test('rejects fractional length before generation', () => { + expect(validateArgs('characters="ABC123", length=1.5')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be integer, not number', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/string/hexadecimal-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/string/hexadecimal-keyword-definition.test.js index acb9fef2..00233d44 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/string/hexadecimal-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/string/hexadecimal-keyword-definition.test.js @@ -1,3 +1,73 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('string.hexadecimal'); +defineDomainKeywordHelpContractTests('string.hexadecimal'); + +describe('string.hexadecimal parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('string.hexadecimal'); + const parsed = parseKeywordInvocation(`string.hexadecimal(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes string.hexadecimal(casing="upper") successfully', () => { + const parsed = parseKeywordInvocation('string.hexadecimal(casing="upper")'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid casing type before generation', () => { + expect(validateArgs('casing={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "casing" must be upper, lower or mixed, not object', + }); + }); + + test('rejects invalid length type before generation', () => { + expect(validateArgs('casing="upper", length={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be number, not object', + }); + }); + + test('rejects zero length before generation', () => { + expect(validateArgs('casing="upper", length=0')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be greater than 0', + }); + }); + + test('rejects negative length before generation', () => { + expect(validateArgs('casing="upper", length=-1')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be greater than 0', + }); + }); + + test('rejects fractional length before generation', () => { + expect(validateArgs('casing="upper", length=1.5')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be an integer', + }); + }); + + test('rejects invalid prefix type before generation', () => { + expect(validateArgs('casing="upper", prefix={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "prefix" must be string, not object', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/string/nanoid-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/string/nanoid-keyword-definition.test.js index 4bb3cac5..5c3fa27b 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/string/nanoid-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/string/nanoid-keyword-definition.test.js @@ -1,3 +1,59 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('string.nanoid'); +defineDomainKeywordHelpContractTests('string.nanoid'); + +describe('string.nanoid parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('string.nanoid'); + const parsed = parseKeywordInvocation(`string.nanoid(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes string.nanoid(length=5) successfully', () => { + const parsed = parseKeywordInvocation('string.nanoid(length=5)'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid length type before generation', () => { + expect(validateArgs('length={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be number, not object', + }); + }); + + test('rejects zero length before generation', () => { + expect(validateArgs('length=0')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be greater than 0', + }); + }); + + test('rejects negative length before generation', () => { + expect(validateArgs('length=-1')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be greater than 0', + }); + }); + + test('rejects fractional length before generation', () => { + expect(validateArgs('length=1.5')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be an integer', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/string/numeric-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/string/numeric-keyword-definition.test.js index 3e4e5999..8a4248e6 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/string/numeric-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/string/numeric-keyword-definition.test.js @@ -1,3 +1,73 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('string.numeric'); +defineDomainKeywordHelpContractTests('string.numeric'); + +describe('string.numeric parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('string.numeric'); + const parsed = parseKeywordInvocation(`string.numeric(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes string.numeric(length=5) successfully', () => { + const parsed = parseKeywordInvocation('string.numeric(length=5)'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid length type before generation', () => { + expect(validateArgs('length={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be number, not object', + }); + }); + + test('rejects zero length before generation', () => { + expect(validateArgs('length=0')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be greater than 0', + }); + }); + + test('rejects negative length before generation', () => { + expect(validateArgs('length=-1')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be greater than 0', + }); + }); + + test('rejects fractional length before generation', () => { + expect(validateArgs('length=1.5')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be an integer', + }); + }); + + test('rejects invalid allowLeadingZeros type before generation', () => { + expect(validateArgs('length=5, allowLeadingZeros={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "allowLeadingZeros" must be boolean, not object', + }); + }); + + test('rejects invalid exclude type before generation', () => { + expect(validateArgs('length=5, exclude={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "exclude" must be array, not object', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/string/octal-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/string/octal-keyword-definition.test.js index 635e985c..382f0ce5 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/string/octal-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/string/octal-keyword-definition.test.js @@ -1,3 +1,66 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('string.octal'); +defineDomainKeywordHelpContractTests('string.octal'); + +describe('string.octal parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('string.octal'); + const parsed = parseKeywordInvocation(`string.octal(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes string.octal(length=5) successfully', () => { + const parsed = parseKeywordInvocation('string.octal(length=5)'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid length type before generation', () => { + expect(validateArgs('length={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be number, not object', + }); + }); + + test('rejects zero length before generation', () => { + expect(validateArgs('length=0')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be greater than 0', + }); + }); + + test('rejects negative length before generation', () => { + expect(validateArgs('length=-1')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be greater than 0', + }); + }); + + test('rejects fractional length before generation', () => { + expect(validateArgs('length=1.5')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be an integer', + }); + }); + + test('rejects invalid prefix type before generation', () => { + expect(validateArgs('length=5, prefix={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "prefix" must be string, not object', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/string/sample-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/string/sample-keyword-definition.test.js index 2c4b50e9..29747170 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/string/sample-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/string/sample-keyword-definition.test.js @@ -1,3 +1,59 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('string.sample'); +defineDomainKeywordHelpContractTests('string.sample'); + +describe('string.sample parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('string.sample'); + const parsed = parseKeywordInvocation(`string.sample(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes string.sample(length=5) successfully', () => { + const parsed = parseKeywordInvocation('string.sample(length=5)'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid length type before generation', () => { + expect(validateArgs('length={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be number, not object', + }); + }); + + test('rejects zero length before generation', () => { + expect(validateArgs('length=0')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be greater than 0', + }); + }); + + test('rejects negative length before generation', () => { + expect(validateArgs('length=-1')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be greater than 0', + }); + }); + + test('rejects fractional length before generation', () => { + expect(validateArgs('length=1.5')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be an integer', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/string/symbol-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/string/symbol-keyword-definition.test.js index 47381ce8..74b6596f 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/string/symbol-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/string/symbol-keyword-definition.test.js @@ -1,3 +1,59 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('string.symbol'); +defineDomainKeywordHelpContractTests('string.symbol'); + +describe('string.symbol parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('string.symbol'); + const parsed = parseKeywordInvocation(`string.symbol(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes string.symbol(length=5) successfully', () => { + const parsed = parseKeywordInvocation('string.symbol(length=5)'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid length type before generation', () => { + expect(validateArgs('length={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be number, not object', + }); + }); + + test('rejects zero length before generation', () => { + expect(validateArgs('length=0')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be greater than 0', + }); + }); + + test('rejects negative length before generation', () => { + expect(validateArgs('length=-1')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be greater than 0', + }); + }); + + test('rejects fractional length before generation', () => { + expect(validateArgs('length=1.5')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be an integer', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/string/ulid-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/string/ulid-keyword-definition.test.js index 75117f46..51811753 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/string/ulid-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/string/ulid-keyword-definition.test.js @@ -1,3 +1,38 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('string.ulid'); +defineDomainKeywordHelpContractTests('string.ulid'); + +describe('string.ulid parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('string.ulid'); + const parsed = parseKeywordInvocation(`string.ulid(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes string.ulid(refDate=1718755200000) successfully', () => { + const parsed = parseKeywordInvocation('string.ulid(refDate=1718755200000)'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid refDate type before generation', () => { + expect(validateArgs('refDate={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "refDate" must be number, not object', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/string/uuid-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/string/uuid-keyword-definition.test.js index f6bc7a92..9d8d7975 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/string/uuid-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/string/uuid-keyword-definition.test.js @@ -1,3 +1,45 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('string.uuid'); +defineDomainKeywordHelpContractTests('string.uuid'); + +describe('string.uuid parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('string.uuid'); + const parsed = parseKeywordInvocation(`string.uuid(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes string.uuid(version=7) successfully', () => { + const parsed = parseKeywordInvocation('string.uuid(version=7)'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid version type before generation', () => { + expect(validateArgs('version={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "version" must be 4 or 7, not object', + }); + }); + + test('rejects invalid refDate type before generation', () => { + expect(validateArgs('version=7, refDate={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "refDate" must be string, number or date, not object', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/system/common-file-ext-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/system/common-file-ext-keyword-definition.test.js index f763dcd5..f95f8930 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/system/common-file-ext-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/system/common-file-ext-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('system.commonFileExt'); +defineDomainKeywordHelpContractTests('system.commonFileExt'); + +describe('system.commonFileExt parameter validation', () => { + test('executes system.commonFileExt() successfully', () => { + const parsed = parseKeywordInvocation('system.commonFileExt()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/system/common-file-name-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/system/common-file-name-keyword-definition.test.js index aab1bd1a..0ad4fb83 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/system/common-file-name-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/system/common-file-name-keyword-definition.test.js @@ -1,3 +1,38 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('system.commonFileName'); +defineDomainKeywordHelpContractTests('system.commonFileName'); + +describe('system.commonFileName parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('system.commonFileName'); + const parsed = parseKeywordInvocation(`system.commonFileName(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes system.commonFileName(extension="txt") successfully', () => { + const parsed = parseKeywordInvocation('system.commonFileName(extension="txt")'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid extension type before generation', () => { + expect(validateArgs('extension={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "extension" must be string, not object', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/system/common-file-type-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/system/common-file-type-keyword-definition.test.js index 40f089fe..01933a1d 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/system/common-file-type-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/system/common-file-type-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('system.commonFileType'); +defineDomainKeywordHelpContractTests('system.commonFileType'); + +describe('system.commonFileType parameter validation', () => { + test('executes system.commonFileType() successfully', () => { + const parsed = parseKeywordInvocation('system.commonFileType()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/system/cron-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/system/cron-keyword-definition.test.js index 05b2a142..9cdf0754 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/system/cron-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/system/cron-keyword-definition.test.js @@ -1,3 +1,45 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('system.cron'); +defineDomainKeywordHelpContractTests('system.cron'); + +describe('system.cron parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('system.cron'); + const parsed = parseKeywordInvocation(`system.cron(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes system.cron(includeNonStandard=true) successfully', () => { + const parsed = parseKeywordInvocation('system.cron(includeNonStandard=true)'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid includeNonStandard type before generation', () => { + expect(validateArgs('includeNonStandard={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "includeNonStandard" must be boolean, not object', + }); + }); + + test('rejects invalid includeYear type before generation', () => { + expect(validateArgs('includeNonStandard=true, includeYear={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "includeYear" must be boolean, not object', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/system/directory-path-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/system/directory-path-keyword-definition.test.js index 5013fd93..4b88d3e9 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/system/directory-path-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/system/directory-path-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('system.directoryPath'); +defineDomainKeywordHelpContractTests('system.directoryPath'); + +describe('system.directoryPath parameter validation', () => { + test('executes system.directoryPath() successfully', () => { + const parsed = parseKeywordInvocation('system.directoryPath()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/system/file-ext-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/system/file-ext-keyword-definition.test.js index b9bfff17..b288c324 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/system/file-ext-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/system/file-ext-keyword-definition.test.js @@ -1,3 +1,38 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('system.fileExt'); +defineDomainKeywordHelpContractTests('system.fileExt'); + +describe('system.fileExt parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('system.fileExt'); + const parsed = parseKeywordInvocation(`system.fileExt(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes system.fileExt(mimeType="image/png") successfully', () => { + const parsed = parseKeywordInvocation('system.fileExt(mimeType="image/png")'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid mimeType type before generation', () => { + expect(validateArgs('mimeType={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "mimeType" must be string, not object', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/system/file-name-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/system/file-name-keyword-definition.test.js index 86d8512c..df8bfbef 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/system/file-name-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/system/file-name-keyword-definition.test.js @@ -1,3 +1,60 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('system.fileName'); +defineDomainKeywordHelpContractTests('system.fileName'); + +describe('system.fileName parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('system.fileName'); + const parsed = parseKeywordInvocation(`system.fileName(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes system.fileName(extensionCount=1) successfully', () => { + const parsed = parseKeywordInvocation('system.fileName(extensionCount=1)'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + expect(result.split('.')).toHaveLength(2); + }); + + test('rejects invalid extensionCount type before generation', () => { + expect(validateArgs('extensionCount={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "extensionCount" must be number, not object', + }); + }); + + test('rejects zero extensionCount before generation', () => { + expect(validateArgs('extensionCount=0')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "extensionCount" must be greater than 0', + }); + }); + + test('rejects negative extensionCount before generation', () => { + expect(validateArgs('extensionCount=-1')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "extensionCount" must be greater than 0', + }); + }); + + test('rejects fractional extensionCount before generation', () => { + expect(validateArgs('extensionCount=1.5')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "extensionCount" must be an integer', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/system/file-path-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/system/file-path-keyword-definition.test.js index 90ae99b7..cfb2b56e 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/system/file-path-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/system/file-path-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('system.filePath'); +defineDomainKeywordHelpContractTests('system.filePath'); + +describe('system.filePath parameter validation', () => { + test('executes system.filePath() successfully', () => { + const parsed = parseKeywordInvocation('system.filePath()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/system/file-type-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/system/file-type-keyword-definition.test.js index 6e3b0c8c..80c05475 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/system/file-type-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/system/file-type-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('system.fileType'); +defineDomainKeywordHelpContractTests('system.fileType'); + +describe('system.fileType parameter validation', () => { + test('executes system.fileType() successfully', () => { + const parsed = parseKeywordInvocation('system.fileType()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/system/mime-type-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/system/mime-type-keyword-definition.test.js index abf0448f..1ad619aa 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/system/mime-type-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/system/mime-type-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('system.mimeType'); +defineDomainKeywordHelpContractTests('system.mimeType'); + +describe('system.mimeType parameter validation', () => { + test('executes system.mimeType() successfully', () => { + const parsed = parseKeywordInvocation('system.mimeType()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/system/network-interface-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/system/network-interface-keyword-definition.test.js index e12b4ecc..ab3dc9f1 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/system/network-interface-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/system/network-interface-keyword-definition.test.js @@ -1,3 +1,45 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('system.networkInterface'); +defineDomainKeywordHelpContractTests('system.networkInterface'); + +describe('system.networkInterface parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('system.networkInterface'); + const parsed = parseKeywordInvocation(`system.networkInterface(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes system.networkInterface(interfaceType="en", interfaceSchema="mac") successfully', () => { + const parsed = parseKeywordInvocation('system.networkInterface(interfaceType="en", interfaceSchema="mac")'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid interfaceType type before generation', () => { + expect(validateArgs('interfaceType={"bad":true}, interfaceSchema="mac"')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "interfaceType" must be en, wl or ww, not object', + }); + }); + + test('rejects invalid interfaceSchema type before generation', () => { + expect(validateArgs('interfaceType="en", interfaceSchema={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "interfaceSchema" must be index, slot, mac or pci, not object', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/system/semver-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/system/semver-keyword-definition.test.js index 6b20db24..b18e4cdf 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/system/semver-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/system/semver-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('system.semver'); +defineDomainKeywordHelpContractTests('system.semver'); + +describe('system.semver parameter validation', () => { + test('executes system.semver() successfully', () => { + const parsed = parseKeywordInvocation('system.semver()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/vehicle/bicycle-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/vehicle/bicycle-keyword-definition.test.js index c0890881..1e0ab438 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/vehicle/bicycle-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/vehicle/bicycle-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('vehicle.bicycle'); +defineDomainKeywordHelpContractTests('vehicle.bicycle'); + +describe('vehicle.bicycle parameter validation', () => { + test('executes vehicle.bicycle() successfully', () => { + const parsed = parseKeywordInvocation('vehicle.bicycle()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/vehicle/color-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/vehicle/color-keyword-definition.test.js index d062164e..6ca61d17 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/vehicle/color-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/vehicle/color-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('vehicle.color'); +defineDomainKeywordHelpContractTests('vehicle.color'); + +describe('vehicle.color parameter validation', () => { + test('executes vehicle.color() successfully', () => { + const parsed = parseKeywordInvocation('vehicle.color()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/vehicle/fuel-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/vehicle/fuel-keyword-definition.test.js index 2a3425ae..cc211d29 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/vehicle/fuel-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/vehicle/fuel-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('vehicle.fuel'); +defineDomainKeywordHelpContractTests('vehicle.fuel'); + +describe('vehicle.fuel parameter validation', () => { + test('executes vehicle.fuel() successfully', () => { + const parsed = parseKeywordInvocation('vehicle.fuel()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/vehicle/manufacturer-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/vehicle/manufacturer-keyword-definition.test.js index 0d19784a..fd1de879 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/vehicle/manufacturer-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/vehicle/manufacturer-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('vehicle.manufacturer'); +defineDomainKeywordHelpContractTests('vehicle.manufacturer'); + +describe('vehicle.manufacturer parameter validation', () => { + test('executes vehicle.manufacturer() successfully', () => { + const parsed = parseKeywordInvocation('vehicle.manufacturer()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/vehicle/model-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/vehicle/model-keyword-definition.test.js index 355c7756..bec1b999 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/vehicle/model-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/vehicle/model-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('vehicle.model'); +defineDomainKeywordHelpContractTests('vehicle.model'); + +describe('vehicle.model parameter validation', () => { + test('executes vehicle.model() successfully', () => { + const parsed = parseKeywordInvocation('vehicle.model()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/vehicle/type-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/vehicle/type-keyword-definition.test.js index 2f3ed7f8..573fe03e 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/vehicle/type-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/vehicle/type-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('vehicle.type'); +defineDomainKeywordHelpContractTests('vehicle.type'); + +describe('vehicle.type parameter validation', () => { + test('executes vehicle.type() successfully', () => { + const parsed = parseKeywordInvocation('vehicle.type()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/vehicle/vehicle-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/vehicle/vehicle-keyword-definition.test.js index 08592f10..b0a592ad 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/vehicle/vehicle-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/vehicle/vehicle-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('vehicle.vehicle'); +defineDomainKeywordHelpContractTests('vehicle.vehicle'); + +describe('vehicle.vehicle parameter validation', () => { + test('executes vehicle.vehicle() successfully', () => { + const parsed = parseKeywordInvocation('vehicle.vehicle()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/vehicle/vin-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/vehicle/vin-keyword-definition.test.js index 649b1b56..c91ffcf3 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/vehicle/vin-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/vehicle/vin-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('vehicle.vin'); +defineDomainKeywordHelpContractTests('vehicle.vin'); + +describe('vehicle.vin parameter validation', () => { + test('executes vehicle.vin() successfully', () => { + const parsed = parseKeywordInvocation('vehicle.vin()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/vehicle/vrm-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/vehicle/vrm-keyword-definition.test.js index cf7333c7..1adedd82 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/vehicle/vrm-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/vehicle/vrm-keyword-definition.test.js @@ -1,3 +1,18 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { executeDomainKeyword } from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('vehicle.vrm'); +defineDomainKeywordHelpContractTests('vehicle.vrm'); + +describe('vehicle.vrm parameter validation', () => { + test('executes vehicle.vrm() successfully', () => { + const parsed = parseKeywordInvocation('vehicle.vrm()'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/word/adjective-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/word/adjective-keyword-definition.test.js index aa179c9f..a18b6e3d 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/word/adjective-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/word/adjective-keyword-definition.test.js @@ -1,3 +1,67 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('word.adjective'); +defineDomainKeywordHelpContractTests('word.adjective'); + +describe('word.adjective parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('word.adjective'); + const parsed = parseKeywordInvocation(`word.adjective(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes word.adjective(length=5) successfully', () => { + const parsed = parseKeywordInvocation('word.adjective(length=5)'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid length type before generation', () => { + expect(validateArgs('length={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be number, not object', + }); + }); + + test('rejects zero length before generation', () => { + expect(validateArgs('length=0')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be greater than 0', + }); + }); + + test('rejects negative length before generation', () => { + expect(validateArgs('length=-1')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be greater than 0', + }); + }); + + test('rejects fractional length before generation', () => { + expect(validateArgs('length=1.5')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be an integer', + }); + }); + + test('rejects invalid strategy type before generation', () => { + expect(validateArgs('length=5, strategy={"bad":true}')).toEqual({ + ok: false, + error: + 'Invalid keyword arguments: argument "strategy" must be fail, closest, shortest, longest or any-length, not object', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/word/adverb-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/word/adverb-keyword-definition.test.js index 2e98dff9..bb84353e 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/word/adverb-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/word/adverb-keyword-definition.test.js @@ -1,3 +1,67 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('word.adverb'); +defineDomainKeywordHelpContractTests('word.adverb'); + +describe('word.adverb parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('word.adverb'); + const parsed = parseKeywordInvocation(`word.adverb(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes word.adverb(length=5) successfully', () => { + const parsed = parseKeywordInvocation('word.adverb(length=5)'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid length type before generation', () => { + expect(validateArgs('length={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be number, not object', + }); + }); + + test('rejects zero length before generation', () => { + expect(validateArgs('length=0')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be greater than 0', + }); + }); + + test('rejects negative length before generation', () => { + expect(validateArgs('length=-1')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be greater than 0', + }); + }); + + test('rejects fractional length before generation', () => { + expect(validateArgs('length=1.5')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be an integer', + }); + }); + + test('rejects invalid strategy type before generation', () => { + expect(validateArgs('length=5, strategy={"bad":true}')).toEqual({ + ok: false, + error: + 'Invalid keyword arguments: argument "strategy" must be fail, closest, shortest, longest or any-length, not object', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/word/conjunction-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/word/conjunction-keyword-definition.test.js index d7b5ec95..b43c854b 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/word/conjunction-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/word/conjunction-keyword-definition.test.js @@ -1,3 +1,67 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('word.conjunction'); +defineDomainKeywordHelpContractTests('word.conjunction'); + +describe('word.conjunction parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('word.conjunction'); + const parsed = parseKeywordInvocation(`word.conjunction(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes word.conjunction(length=5) successfully', () => { + const parsed = parseKeywordInvocation('word.conjunction(length=5)'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid length type before generation', () => { + expect(validateArgs('length={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be number, not object', + }); + }); + + test('rejects zero length before generation', () => { + expect(validateArgs('length=0')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be greater than 0', + }); + }); + + test('rejects negative length before generation', () => { + expect(validateArgs('length=-1')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be greater than 0', + }); + }); + + test('rejects fractional length before generation', () => { + expect(validateArgs('length=1.5')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be an integer', + }); + }); + + test('rejects invalid strategy type before generation', () => { + expect(validateArgs('length=5, strategy={"bad":true}')).toEqual({ + ok: false, + error: + 'Invalid keyword arguments: argument "strategy" must be fail, closest, shortest, longest or any-length, not object', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/word/interjection-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/word/interjection-keyword-definition.test.js index 25d49077..622c423e 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/word/interjection-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/word/interjection-keyword-definition.test.js @@ -1,3 +1,67 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('word.interjection'); +defineDomainKeywordHelpContractTests('word.interjection'); + +describe('word.interjection parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('word.interjection'); + const parsed = parseKeywordInvocation(`word.interjection(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes word.interjection(length=5) successfully', () => { + const parsed = parseKeywordInvocation('word.interjection(length=5)'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid length type before generation', () => { + expect(validateArgs('length={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be number, not object', + }); + }); + + test('rejects zero length before generation', () => { + expect(validateArgs('length=0')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be greater than 0', + }); + }); + + test('rejects negative length before generation', () => { + expect(validateArgs('length=-1')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be greater than 0', + }); + }); + + test('rejects fractional length before generation', () => { + expect(validateArgs('length=1.5')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be an integer', + }); + }); + + test('rejects invalid strategy type before generation', () => { + expect(validateArgs('length=5, strategy={"bad":true}')).toEqual({ + ok: false, + error: + 'Invalid keyword arguments: argument "strategy" must be fail, closest, shortest, longest or any-length, not object', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/word/noun-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/word/noun-keyword-definition.test.js index 3f22be7a..dde9404d 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/word/noun-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/word/noun-keyword-definition.test.js @@ -1,3 +1,67 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('word.noun'); +defineDomainKeywordHelpContractTests('word.noun'); + +describe('word.noun parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('word.noun'); + const parsed = parseKeywordInvocation(`word.noun(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes word.noun(length=5) successfully', () => { + const parsed = parseKeywordInvocation('word.noun(length=5)'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid length type before generation', () => { + expect(validateArgs('length={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be number, not object', + }); + }); + + test('rejects zero length before generation', () => { + expect(validateArgs('length=0')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be greater than 0', + }); + }); + + test('rejects negative length before generation', () => { + expect(validateArgs('length=-1')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be greater than 0', + }); + }); + + test('rejects fractional length before generation', () => { + expect(validateArgs('length=1.5')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be an integer', + }); + }); + + test('rejects invalid strategy type before generation', () => { + expect(validateArgs('length=5, strategy={"bad":true}')).toEqual({ + ok: false, + error: + 'Invalid keyword arguments: argument "strategy" must be fail, closest, shortest, longest or any-length, not object', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/word/preposition-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/word/preposition-keyword-definition.test.js index 240d025d..b8d74899 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/word/preposition-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/word/preposition-keyword-definition.test.js @@ -1,3 +1,67 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('word.preposition'); +defineDomainKeywordHelpContractTests('word.preposition'); + +describe('word.preposition parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('word.preposition'); + const parsed = parseKeywordInvocation(`word.preposition(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes word.preposition(length=5) successfully', () => { + const parsed = parseKeywordInvocation('word.preposition(length=5)'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid length type before generation', () => { + expect(validateArgs('length={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be number, not object', + }); + }); + + test('rejects zero length before generation', () => { + expect(validateArgs('length=0')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be greater than 0', + }); + }); + + test('rejects negative length before generation', () => { + expect(validateArgs('length=-1')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be greater than 0', + }); + }); + + test('rejects fractional length before generation', () => { + expect(validateArgs('length=1.5')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be an integer', + }); + }); + + test('rejects invalid strategy type before generation', () => { + expect(validateArgs('length=5, strategy={"bad":true}')).toEqual({ + ok: false, + error: + 'Invalid keyword arguments: argument "strategy" must be fail, closest, shortest, longest or any-length, not object', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/word/sample-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/word/sample-keyword-definition.test.js index c4b92c16..53b0e5e3 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/word/sample-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/word/sample-keyword-definition.test.js @@ -1,3 +1,67 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('word.sample'); +defineDomainKeywordHelpContractTests('word.sample'); + +describe('word.sample parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('word.sample'); + const parsed = parseKeywordInvocation(`word.sample(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes word.sample(length=5) successfully', () => { + const parsed = parseKeywordInvocation('word.sample(length=5)'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid length type before generation', () => { + expect(validateArgs('length={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be number, not object', + }); + }); + + test('rejects zero length before generation', () => { + expect(validateArgs('length=0')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be greater than 0', + }); + }); + + test('rejects negative length before generation', () => { + expect(validateArgs('length=-1')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be greater than 0', + }); + }); + + test('rejects fractional length before generation', () => { + expect(validateArgs('length=1.5')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be an integer', + }); + }); + + test('rejects invalid strategy type before generation', () => { + expect(validateArgs('length=5, strategy={"bad":true}')).toEqual({ + ok: false, + error: + 'Invalid keyword arguments: argument "strategy" must be fail, closest, shortest, longest or any-length, not object', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/word/verb-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/word/verb-keyword-definition.test.js index d0c571b4..285ab054 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/word/verb-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/word/verb-keyword-definition.test.js @@ -1,3 +1,67 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('word.verb'); +defineDomainKeywordHelpContractTests('word.verb'); + +describe('word.verb parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('word.verb'); + const parsed = parseKeywordInvocation(`word.verb(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes word.verb(length=5) successfully', () => { + const parsed = parseKeywordInvocation('word.verb(length=5)'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid length type before generation', () => { + expect(validateArgs('length={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be number, not object', + }); + }); + + test('rejects zero length before generation', () => { + expect(validateArgs('length=0')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be greater than 0', + }); + }); + + test('rejects negative length before generation', () => { + expect(validateArgs('length=-1')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be greater than 0', + }); + }); + + test('rejects fractional length before generation', () => { + expect(validateArgs('length=1.5')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "length" must be an integer', + }); + }); + + test('rejects invalid strategy type before generation', () => { + expect(validateArgs('length=5, strategy={"bad":true}')).toEqual({ + ok: false, + error: + 'Invalid keyword arguments: argument "strategy" must be fail, closest, shortest, longest or any-length, not object', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/keywords/domain/word/words-keyword-definition.test.js b/packages/core/src/tests/data_generation/keywords/domain/word/words-keyword-definition.test.js index 34c05929..79c71b07 100644 --- a/packages/core/src/tests/data_generation/keywords/domain/word/words-keyword-definition.test.js +++ b/packages/core/src/tests/data_generation/keywords/domain/word/words-keyword-definition.test.js @@ -1,3 +1,59 @@ -import { defineDomainKeywordDefinitionTests } from '../define-domain-keyword-definition-tests.js'; +import { faker } from '@faker-js/faker'; +import { defineDomainKeywordHelpContractTests } from '../define-domain-keyword-help-contract-tests.js'; +import { + executeDomainKeyword, + getDomainKeywordByAlias, + validateDomainKeywordArgs, +} from '../../../../../../js/domain/domain-keywords.js'; +import { parseKeywordInvocation } from '../../../../../../js/domain/domain-keyword-parser.js'; -defineDomainKeywordDefinitionTests('word.words'); +defineDomainKeywordHelpContractTests('word.words'); + +describe('word.words parameter validation', () => { + function validateArgs(paramsText) { + const keyword = getDomainKeywordByAlias('word.words'); + const parsed = parseKeywordInvocation(`word.words(${paramsText})`); + + expect(parsed.errors).toEqual([]); + + return validateDomainKeywordArgs(keyword, parsed.args); + } + + test('executes word.words(count=5) successfully', () => { + const parsed = parseKeywordInvocation('word.words(count=5)'); + + expect(parsed.errors).toEqual([]); + + const result = executeDomainKeyword(parsed.keyword, { faker, args: parsed.args }); + + expect(result).toBeDefined(); + }); + + test('rejects invalid count type before generation', () => { + expect(validateArgs('count={"bad":true}')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "count" must be number, not object', + }); + }); + + test('rejects zero count before generation', () => { + expect(validateArgs('count=0')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "count" must be greater than 0', + }); + }); + + test('rejects negative count before generation', () => { + expect(validateArgs('count=-1')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "count" must be greater than 0', + }); + }); + + test('rejects fractional count before generation', () => { + expect(validateArgs('count=1.5')).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "count" must be an integer', + }); + }); +}); diff --git a/packages/core/src/tests/data_generation/unit/domain/domain-doc-generator-output.test.js b/packages/core/src/tests/data_generation/unit/domain/domain-doc-generator-output.test.js index 28e0bd0c..c2f701cd 100644 --- a/packages/core/src/tests/data_generation/unit/domain/domain-doc-generator-output.test.js +++ b/packages/core/src/tests/data_generation/unit/domain/domain-doc-generator-output.test.js @@ -164,6 +164,10 @@ describe('domain docs generator output', () => { expect(airlineDoc).not.toContain('### `airline.airplane`'); expect(airlineDoc).toContain('### `airplane.name`'); expect(airlineDoc).toContain('### `airplane.iataTypeCode`'); + expect(airlineDoc).toContain('### `airline.iataCode`'); + expect(airlineDoc).toContain('```txt\nairline.iataCode\n```'); + expect(airlineDoc).not.toContain('```txt\nairline.airline.iataCode\n```'); + expect(airlineDoc).not.toContain('```txt\nawd.domain.airline.airline.iataCode\n```'); expect(financeDoc).not.toContain('### `finance.currency`'); expect(financeDoc).toContain('### `finance.currencyCode`'); diff --git a/packages/core/src/tests/data_generation/unit/domain/domain-faker-param-comparison.test.js b/packages/core/src/tests/data_generation/unit/domain/domain-faker-param-comparison.test.js new file mode 100644 index 00000000..7d744e96 --- /dev/null +++ b/packages/core/src/tests/data_generation/unit/domain/domain-faker-param-comparison.test.js @@ -0,0 +1,84 @@ +import { pathToFileURL } from 'node:url'; +import path from 'node:path'; + +async function loadComparisonScript() { + const scriptPath = path.resolve(process.cwd(), 'scripts/compare-domain-faker-params.mjs'); + return import(pathToFileURL(scriptPath).href); +} + +describe('domain faker option param comparison', () => { + test('documents every Faker top-level options object param in domain metadata', async () => { + const { getFakerOptionParamComparison } = await loadComparisonScript(); + const comparison = getFakerOptionParamComparison(); + + expect(comparison.filter((row) => row.missingInDomain.length > 0)).toEqual([]); + }); + + test('does not expose domain params that Faker does not implement', async () => { + const { getFakerOptionParamComparison } = await loadComparisonScript(); + const comparison = getFakerOptionParamComparison(); + + expect(comparison.filter((row) => row.domainOnlyParams.length > 0)).toEqual([]); + }); + + test('check failures include params missing in either direction', async () => { + const { hasParamComparisonFailures } = await loadComparisonScript(); + + expect( + hasParamComparisonFailures([ + { + missingInDomain: [], + domainOnlyParams: ['legacyOnly'], + }, + ]) + ).toBe(true); + expect( + hasParamComparisonFailures([ + { + missingInDomain: ['fakerOnly'], + domainOnlyParams: [], + }, + ]) + ).toBe(true); + expect( + hasParamComparisonFailures([ + { + missingInDomain: [], + domainOnlyParams: [], + }, + ]) + ).toBe(false); + }); + + test('merges option params from overloaded Faker method declarations', async () => { + const { extractFakerOptionMethods } = await loadComparisonScript(); + const modules = extractFakerOptionMethods(` + declare class ExampleModule { + sample(options?: { first?: string; shared?: boolean }): string; + sample(options?: { second?: number; shared?: boolean }): string; + sample(value?: string): string; + } + `); + + expect(modules.get('example').get('sample')).toEqual( + expect.objectContaining({ + optionParams: ['first', 'shared', 'second'], + signatures: ['{ first?: string; shared?: boolean }', '{ second?: number; shared?: boolean }'], + }) + ); + }); + + test('number.bigInt exposes Faker range params instead of the old value placeholder', async () => { + const { getFakerOptionParamComparison } = await loadComparisonScript(); + const comparison = getFakerOptionParamComparison(); + const bigIntRow = comparison.find((row) => row.keyword === 'number.bigInt'); + + expect(bigIntRow).toEqual( + expect.objectContaining({ + fakerOptionParams: ['min', 'max', 'multipleOf'], + domainParams: ['min', 'max', 'multipleOf'], + missingInDomain: [], + }) + ); + }); +}); diff --git a/packages/core/src/tests/data_generation/unit/domain/domain-keyword-params-usage.test.js b/packages/core/src/tests/data_generation/unit/domain/domain-keyword-params-usage.test.js index b60cc86a..58ecd469 100644 --- a/packages/core/src/tests/data_generation/unit/domain/domain-keyword-params-usage.test.js +++ b/packages/core/src/tests/data_generation/unit/domain/domain-keyword-params-usage.test.js @@ -1,6 +1,7 @@ import { DOMAIN_KEYWORDS, executeDomainKeyword } from '../../../../../js/domain/domain-keywords.js'; import { faker } from '@faker-js/faker'; import { assertDomainKeywordResult } from './domain-result-assertions.test-helper.js'; +import { sampleValueForKeywordArg, sampleValueForType } from './domain-keyword-sample-values.test-helper.js'; function setDeepMethod(root, target, fn) { const parts = String(target || '') @@ -47,118 +48,6 @@ function createResultForPath(resultPath) { return root; } -function sampleValueForType(type) { - const allowed = String(type || '') - .split('|') - .map((entry) => entry.trim()); - const numericLiterals = allowed.filter((entry) => /^[+-]?\d+(\.\d+)?$/.test(entry)).map((entry) => Number(entry)); - const stringLiterals = allowed - .filter( - (entry) => - !['string', 'integer', 'number', 'date', 'regexp', 'boolean', 'array', 'object'].includes(entry) && - !/^[+-]?\d+(\.\d+)?$/.test(entry) - ) - .map((entry) => - (entry.startsWith('"') && entry.endsWith('"')) || (entry.startsWith("'") && entry.endsWith("'")) - ? entry.slice(1, -1) - : entry - ); - - if (numericLiterals.length === allowed.length && numericLiterals.length > 0) { - return numericLiterals[0]; - } - if (stringLiterals.length > 0) return stringLiterals[0]; - - if (allowed.includes('integer')) { - return 7; - } - if (allowed.includes('number')) { - return 7; - } - if (allowed.includes('regexp')) { - return '[A-Z]'; - } - if (allowed.includes('boolean')) { - return true; - } - if (allowed.includes('array')) { - return ['a', 'b']; - } - if (allowed.includes('object')) { - return { key: 'value' }; - } - return 'sample'; -} - -function sampleValueForKeywordArg(keywordName, argName, typeName) { - const key = `${keywordName}.${argName}`; - const type = String(typeName || ''); - - if (key === 'date.between.from' || key === 'date.betweens.from') - return new Date('2020-01-01T00:00:00.000Z').getTime(); - if (key === 'date.between.to' || key === 'date.betweens.to') return new Date('2020-12-31T00:00:00.000Z').getTime(); - if (key === 'date.betweens.count') return 3; - if (key === 'date.birthdate.min') return 18; - if (key === 'date.birthdate.max') return 65; - if (key === 'date.birthdate.mode') return 'age'; - if (key === 'datatype.boolean.probability') return 0.5; - - if (key === 'location.latitude.min' || key === 'location.longitude.min') return -10; - if (key === 'location.latitude.max' || key === 'location.longitude.max') return 10; - if (key === 'location.latitude.precision' || key === 'location.longitude.precision') return 2; - - if (key === 'number.int.min') return 1; - if (key === 'number.int.max') return 10; - if (key === 'number.int.multipleOf') return 1; - - if (key === 'commerce.price.dec') return 2; - if (key === 'commerce.price.min') return 10; - if (key === 'commerce.price.max') return 100; - if (key === 'finance.iban.countryCode') return 'GB'; - - if (key === 'airline.seat.aircraftType') return 'narrowbody'; - if (key === 'internet.emoji.types') return ['smiley']; - if (key === 'internet.jwt.header') return { alg: 'HS256', typ: 'JWT' }; - if (key === 'internet.jwt.payload') return { iss: 'Acme' }; - if (key === 'internet.ipv4.cidrBlock') return '192.168.0.0/24'; - if (key === 'internet.ipv4.network') return 'private-a'; - if (key === 'finance.bitcoinAddress.network') return 'testnet'; - if (key === 'internet.password.pattern') return '[A-Za-z0-9]'; - if (key === 'phone.number.style') return 'human'; - if (key === 'string.alpha.casing') return 'lower'; - if (key === 'color.rgb.format') return 'hex'; - if (key === 'color.cmyk.format') return 'css'; - if (key === 'color.hsl.format') return 'css'; - if (key === 'color.hwb.format') return 'css'; - if (key === 'color.lab.format') return 'css'; - if (key === 'color.lch.format') return 'css'; - - if (argName === 'min') return 1; - if (argName === 'max') return 10; - if (argName === 'count') return 3; - if (argName === 'length') return 5; - if (argName === 'lengthMin') return 3; - if (argName === 'lengthMax') return 6; - if (argName === 'precision') return 2; - if (argName === 'dec') return 2; - if (argName === 'multipleOf') return 1; - if (key === 'commerce.upc.prefix') return '01234'; - if (argName === 'prefix') return 'pre'; - if (argName === 'symbol') return '$'; - if (argName === 'version') return 7; - if (argName === 'refDate') return Date.now(); - if (argName === 'from') return Date.now() - 86400000; - if (argName === 'to') return Date.now() + 86400000; - if (argName === 'exclude') return ['x', 'y']; - - if (type.includes('integer')) return 7; - if (type.includes('number')) return 7; - if (type.includes('regexp')) return '[A-Z]'; - if (type.includes('boolean')) return true; - if (type.includes('array')) return ['a', 'b']; - return sampleValueForType(type); -} - function buildValidArgs(keyword) { const args = new Array(keyword.help.args.length).fill(undefined); for (let index = 0; index < keyword.help.args.length; index += 1) { @@ -194,16 +83,27 @@ function applyKeywordExecutionDefaults(keyword, args) { return args; } +function expectedLoremCountArgs(argName, sample) { + if (argName === 'separator') { + return [undefined, sample]; + } + if (argName === 'max' || /CountMax$/.test(argName)) { + return [{ min: 1, max: sample }]; + } + if (argName === 'min' || /CountMin$/.test(argName) || /Count$/.test(argName)) { + return [sample]; + } + return []; +} + function expectsRuntimeRejection(keywordName, argName) { void keywordName; void argName; return false; } -function shouldSkipRuntimeExecution(keywordName, argName) { - void keywordName; - void argName; - return false; +function shouldSkipRuntimeExecution(argSpec) { + return argSpec?.usageExampleSupported === false; } describe('domain keyword parameter usage', () => { @@ -238,6 +138,8 @@ describe('domain keyword parameter usage', () => { expect(receivedArgs[0]).toEqual( expect.objectContaining({ [argSpec.name]: expectedDelegatedArgValue(argSpec, sample) }) ); + } else if (keyword.delegate.argTransform === 'loremCountFromHelpArgs') { + expect(receivedArgs).toEqual(expectedLoremCountArgs(argSpec.name, sample)); } else { expect(receivedArgs[argIndex]).toEqual(sample); } @@ -247,7 +149,7 @@ describe('domain keyword parameter usage', () => { const args = applyKeywordExecutionDefaults(keyword, buildValidArgs(keyword)); args[argIndex] = sampleValueForKeywordArg(keyword.keyword, argSpec.name, argSpec.type); - if (shouldSkipRuntimeExecution(keyword.keyword, argSpec.name)) { + if (shouldSkipRuntimeExecution(argSpec)) { return; } diff --git a/packages/core/src/tests/data_generation/unit/domain/domain-keyword-parser.test.js b/packages/core/src/tests/data_generation/unit/domain/domain-keyword-parser.test.js index bd467068..315fdc87 100644 --- a/packages/core/src/tests/data_generation/unit/domain/domain-keyword-parser.test.js +++ b/packages/core/src/tests/data_generation/unit/domain/domain-keyword-parser.test.js @@ -88,11 +88,11 @@ describe('domain keyword parser', () => { expect(parsedKeyword.errors).toEqual([]); }); - test('parses lorem.word(min=2, max=67) as a valid domain invocation', () => { + test('rejects lorem.word params that Faker does not implement', () => { const parsedKeyword = parseKeywordInvocation('lorem.word(min=2, max=67)'); expect(parsedKeyword.keyword).toBe('lorem.word'); - expect(parsedKeyword.args).toEqual([2, 67]); - expect(parsedKeyword.errors).toEqual([]); + expect(parsedKeyword.args).toEqual([]); + expect(parsedKeyword.errors).toEqual(['Invalid keyword arguments: unknown named argument "min"']); }); test('parses named args with broader spacing combinations', () => { diff --git a/packages/core/src/tests/data_generation/unit/domain/domain-keyword-sample-values.test-helper.js b/packages/core/src/tests/data_generation/unit/domain/domain-keyword-sample-values.test-helper.js new file mode 100644 index 00000000..2a21564e --- /dev/null +++ b/packages/core/src/tests/data_generation/unit/domain/domain-keyword-sample-values.test-helper.js @@ -0,0 +1,153 @@ +const BUILT_IN_TYPE_TOKENS = new Set([ + 'bigint', + 'string', + 'integer', + 'number', + 'date', + 'regexp', + 'boolean', + 'array', + 'object', +]); + +function splitTypeTokens(typeName) { + return String(typeName || '') + .split('|') + .map((entry) => entry.trim()) + .filter(Boolean); +} + +function unquoteLiteralToken(value) { + if ((value.startsWith('"') && value.endsWith('"')) || (value.startsWith("'") && value.endsWith("'"))) { + return value.slice(1, -1); + } + return value; +} + +function getStringLiteralTypeSamples(types) { + return types + .filter((entry) => !BUILT_IN_TYPE_TOKENS.has(entry) && !/^[+-]?\d+(\.\d+)?$/.test(entry)) + .map(unquoteLiteralToken); +} + +function sampleValueForType(typeName, { arraySample = ['x', 'y'] } = {}) { + const types = splitTypeTokens(typeName); + const numericLiterals = types.filter((entry) => /^[+-]?\d+(\.\d+)?$/.test(entry)).map((entry) => Number(entry)); + const stringLiterals = getStringLiteralTypeSamples(types); + + if (numericLiterals.length === types.length && numericLiterals.length > 0) { + return numericLiterals[0]; + } + if (stringLiterals.length > 0) return stringLiterals[0]; + + if (types.includes('bigint')) return 7; + if (types.includes('integer')) return 7; + if (types.includes('number')) return 7; + if (types.includes('regexp')) return '[A-Z]'; + if (types.includes('boolean')) return true; + if (types.includes('array')) return arraySample; + if (types.includes('object')) return { key: 'value' }; + return 'sample'; +} + +function sampleValueForKeywordArg(keywordName, argName, typeName) { + const key = `${keywordName}.${argName}`; + const type = String(typeName || ''); + + if (key === 'date.between.from' || key === 'date.betweens.from') return 1577836800000; + if (key === 'date.between.to' || key === 'date.betweens.to') return 1609372800000; + if (key === 'date.betweens.count') return 3; + if (key === 'date.birthdate.min') return 18; + if (key === 'date.birthdate.max') return 65; + if (key === 'date.birthdate.mode') return 'age'; + if (key === 'datatype.boolean.probability') return 0.5; + if (key === 'airline.flightNumber.length') return 4; + if (key === 'image.dataUri.type') return 'svg-base64'; + if (key === 'internet.httpStatusCode.types') return ['success']; + if (key === 'location.zipCode.state') return 'CA'; + if (key === 'location.zipCode.format') return '#####'; + if (key === 'system.networkInterface.interfaceType') return 'en'; + if (key === 'system.networkInterface.interfaceSchema') return 'mac'; + if (key === 'location.latitude.min' || key === 'location.longitude.min') return -10; + if (key === 'location.latitude.max' || key === 'location.longitude.max') return 10; + if (key === 'location.latitude.precision' || key === 'location.longitude.precision') return 2; + if (key === 'number.int.min' || key === 'number.bigInt.min') return 1; + if (key === 'number.int.max' || key === 'number.bigInt.max') return 10; + if (key === 'number.int.multipleOf' || key === 'number.bigInt.multipleOf') return 1; + if (key === 'commerce.price.dec') return 2; + if (key === 'commerce.price.min') return 10; + if (key === 'commerce.price.max') return 100; + if (key === 'finance.iban.countryCode') return 'GB'; + if (key === 'airline.seat.aircraftType') return 'narrowbody'; + if (key === 'internet.emoji.types') return ['smiley']; + if (key === 'internet.jwt.header') return { alg: 'HS256', typ: 'JWT' }; + if (key === 'internet.jwt.payload') return { iss: 'Acme' }; + if (key === 'internet.ipv4.cidrBlock') return '192.168.0.0/24'; + if (key === 'internet.ipv4.network') return 'private-a'; + if (key === 'finance.bitcoinAddress.network') return 'testnet'; + if (key === 'internet.password.pattern') return '[A-Za-z0-9]'; + if (key === 'phone.number.style') return 'human'; + if (key === 'string.alpha.casing') return 'lower'; + if (key === 'color.rgb.format') return 'hex'; + if (key === 'color.cmyk.format') return 'css'; + if (key === 'color.hsl.format') return 'css'; + if (key === 'color.hwb.format') return 'css'; + if (key === 'color.lab.format') return 'css'; + if (key === 'color.lch.format') return 'css'; + + if (argName === 'from') return 1577836800000; + if (argName === 'to') return 1580428800000; + if (argName === 'refDate') return 1716110400000; + if (argName === 'version') return 7; + if (argName === 'count') return 3; + if (argName === 'min') return 1; + if (argName === 'max') return 10; + if (argName === 'length') return 8; + if (argName === 'lengthMin') return 3; + if (argName === 'lengthMax') return 6; + if (argName === 'precision') return 2; + if (argName === 'dec') return 2; + if (argName === 'multipleOf') return 1; + if (key === 'commerce.upc.prefix') return '01234'; + if (argName === 'prefix') return 'pre'; + if (argName === 'symbol') return '$'; + if (argName === 'separator') return '-'; + if (argName === 'protocol') return 'https'; + if (argName === 'countryCode') return 'GB'; + if (argName === 'mimeType') return 'image/png'; + if (argName === 'cidrBlock') return '192.168.0.0/24'; + if (argName === 'types') return ['smiley']; + if (argName === 'header') return { alg: 'HS256', typ: 'JWT' }; + if (argName === 'payload') return { iss: 'Acme' }; + if (argName === 'pattern') return '[A-Z]'; + if (argName === 'mode') return 'age'; + if (argName === 'strategy') return 'any-length'; + if (argName === 'sex') return 'female'; + if (argName === 'style') return 'human'; + if (argName === 'exclude') return ['x', 'y']; + + if (type.includes('integer')) return 7; + if (type.includes('number')) return 7; + if (type.includes('regexp')) return '[A-Z]'; + if (type.includes('boolean')) return true; + if (type.includes('array')) return ['x', 'y']; + return sampleValueForType(type); +} + +function valueToInvocationLiteral(value) { + if (typeof value === 'string') { + return JSON.stringify(value); + } + if (typeof value === 'number' || typeof value === 'boolean') { + return String(value); + } + if (Array.isArray(value)) { + return JSON.stringify(value); + } + if (value && typeof value === 'object') { + return JSON.stringify(value); + } + throw new Error(`Unsupported invocation literal value: ${String(value)}`); +} + +export { sampleValueForKeywordArg, sampleValueForType, valueToInvocationLiteral }; diff --git a/packages/core/src/tests/data_generation/unit/domain/domain-param-invocation-coverage.test-helper.js b/packages/core/src/tests/data_generation/unit/domain/domain-param-invocation-coverage.test-helper.js index b7726e7f..a2737f7f 100644 --- a/packages/core/src/tests/data_generation/unit/domain/domain-param-invocation-coverage.test-helper.js +++ b/packages/core/src/tests/data_generation/unit/domain/domain-param-invocation-coverage.test-helper.js @@ -1,5 +1,6 @@ import { DOMAIN_KEYWORDS, executeDomainKeyword } from '../../../../../js/domain/domain-keywords.js'; import { parseKeywordInvocation } from '../../../../../js/domain/domain-keyword-parser.js'; +import { sampleValueForKeywordArg, valueToInvocationLiteral } from './domain-keyword-sample-values.test-helper.js'; function setDeepMethod(root, target, fn) { const parts = String(target || '') @@ -16,90 +17,6 @@ function setDeepMethod(root, target, fn) { node[parts[parts.length - 1]] = fn; } -function sampleValueForType(typeName) { - const types = String(typeName || '') - .split('|') - .map((entry) => entry.trim()); - const stringLiterals = types - .filter( - (entry) => - !['string', 'integer', 'number', 'date', 'regexp', 'boolean', 'array', 'object'].includes(entry) && - !/^[+-]?\d+(\.\d+)?$/.test(entry) - ) - .map((entry) => - (entry.startsWith('"') && entry.endsWith('"')) || (entry.startsWith("'") && entry.endsWith("'")) - ? entry.slice(1, -1) - : entry - ); - - if (types.includes('number') || types.includes('integer')) { - return 7; - } - if (stringLiterals.length > 0) { - return stringLiterals[0]; - } - if (types.includes('regexp')) { - return '[A-Z]'; - } - if (types.includes('boolean')) { - return true; - } - if (types.includes('array')) { - return ['x', 'y']; - } - if (types.includes('object')) { - return { key: 'value' }; - } - return 'sample'; -} - -function sampleValueForKeywordArg(keywordName, argName, typeName) { - const key = `${keywordName}.${argName}`; - if (argName === 'from') return 1577836800000; - if (argName === 'to') return 1580428800000; - if (argName === 'refDate') return 1716110400000; - if (argName === 'version') return 7; - if (argName === 'count') return 3; - if (argName === 'min') return 1; - if (argName === 'max') return 10; - if (argName === 'length') return 8; - if (argName === 'precision') return 2; - if (argName === 'multipleOf') return 1; - if (argName === 'separator') return '-'; - if (argName === 'protocol') return 'https'; - if (argName === 'countryCode') return 'GB'; - if (argName === 'mimeType') return 'image/png'; - if (key === 'internet.ipv4.network') return 'private-a'; - if (key === 'finance.bitcoinAddress.network') return 'testnet'; - if (argName === 'cidrBlock') return '192.168.0.0/24'; - if (argName === 'types') return ['smiley']; - if (argName === 'header') return { alg: 'HS256', typ: 'JWT' }; - if (argName === 'payload') return { iss: 'Acme' }; - if (argName === 'pattern') return '[A-Z]'; - if (argName === 'mode') return 'age'; - if (argName === 'strategy') return 'any-length'; - if (argName === 'sex') return 'female'; - if (argName === 'style') return 'human'; - - return sampleValueForType(typeName); -} - -function valueToInvocationLiteral(value) { - if (typeof value === 'string') { - return JSON.stringify(value); - } - if (typeof value === 'number' || typeof value === 'boolean') { - return String(value); - } - if (Array.isArray(value)) { - return JSON.stringify(value); - } - if (value && typeof value === 'object') { - return JSON.stringify(value); - } - throw new Error(`Unsupported literal type for invocation: ${typeof value}`); -} - function addDomainParamInvocationCoverageTests(domainName) { const keywords = DOMAIN_KEYWORDS.filter( (keyword) => diff --git a/packages/core/src/tests/data_generation/unit/domain/domain-test-data-rule-validator.test.js b/packages/core/src/tests/data_generation/unit/domain/domain-test-data-rule-validator.test.js index 53683f37..356e9e70 100644 --- a/packages/core/src/tests/data_generation/unit/domain/domain-test-data-rule-validator.test.js +++ b/packages/core/src/tests/data_generation/unit/domain/domain-test-data-rule-validator.test.js @@ -1,3 +1,4 @@ +import { Faker, faker } from '@faker-js/faker'; import { DomainTestDataRuleValidator } from '../../../../../js/data_generation/domain/domainTestDataRuleValidator.js'; describe('DomainTestDataRuleValidator', () => { @@ -74,4 +75,45 @@ describe('DomainTestDataRuleValidator', () => { }) ); }); + + test('accepts syntactically valid domain commands without dry-run execution when no faker is supplied', () => { + const validator = new DomainTestDataRuleValidator(); + + const isValid = validator.validate({ ruleSpec: 'word.adjective(length=999, strategy="fail")' }); + + expect(isValid).toBe(true); + }); + + test('rejects domain commands that would throw during generation when faker is supplied', () => { + const validator = new DomainTestDataRuleValidator(faker); + + const isValid = validator.validate({ ruleSpec: 'word.adjective(length=999, strategy="fail")' }); + + expect(isValid).toBe(false); + expect(validator.getValidationError()).toContain('No words found that match the given length.'); + }); + + test('does not advance supplied faker while validating faker-backed domain commands', () => { + const seed = 12345; + const controlFaker = new Faker({ locale: faker.rawDefinitions }); + controlFaker.seed(seed); + faker.seed(seed); + const validator = new DomainTestDataRuleValidator(faker); + + const isValid = validator.validate({ ruleSpec: 'person.firstName()' }); + + expect(isValid).toBe(true); + expect(faker.person.firstName()).toBe(controlFaker.person.firstName()); + }); + + test('rejects unsatisfiable BigInt params before generation', () => { + const validator = new DomainTestDataRuleValidator(faker); + + const isValid = validator.validate({ ruleSpec: 'number.bigInt(min=1, max=5, multipleOf=10)' }); + + expect(isValid).toBe(false); + expect(validator.getValidationError()).toBe( + 'Invalid keyword arguments: arguments "min", "max", and "multipleOf" do not allow any generated BigInt value' + ); + }); }); diff --git a/packages/core/src/tests/data_generation/unit/domain/domainKeywords.test.js b/packages/core/src/tests/data_generation/unit/domain/domainKeywords.test.js index e8ad3ac1..daa3bcd6 100644 --- a/packages/core/src/tests/data_generation/unit/domain/domainKeywords.test.js +++ b/packages/core/src/tests/data_generation/unit/domain/domainKeywords.test.js @@ -17,6 +17,7 @@ import { getFakerCommandHelp, } from '../../../../../js/faker/faker-helper-keyword-definitions.js'; import { FAKER_HELPER_KEYWORD_DEFINITIONS } from '../../../../../js/faker/faker-helper-keyword-definitions.js'; +import { sampleValueForKeywordArg, valueToInvocationLiteral } from './domain-keyword-sample-values.test-helper.js'; describe('domain keyword catalog', () => { test('registers canonical awd.domain keywords for faker commands', () => { @@ -421,6 +422,46 @@ describe('domain keyword delegation', () => { }); expect(result).toBe('should-run'); }); + + test('passes lorem wordCount to faker using the positional count argument', () => { + const callArgs = []; + const fakeFaker = { + lorem: { + words: (...receivedArgs) => { + callArgs.push(receivedArgs); + return 'one two three four five'; + }, + }, + }; + + const result = executeDomainKeyword('lorem.words', { + faker: fakeFaker, + args: [undefined, undefined, 5], + }); + + expect(result).toBe('one two three four five'); + expect(callArgs).toEqual([[5]]); + }); + + test('passes lorem separator after transformed count argument', () => { + const callArgs = []; + const fakeFaker = { + lorem: { + sentences: (...receivedArgs) => { + callArgs.push(receivedArgs); + return 'One.-Two.'; + }, + }, + }; + + const result = executeDomainKeyword('lorem.sentences', { + faker: fakeFaker, + args: [undefined, undefined, 2, '-', undefined, undefined], + }); + + expect(result).toBe('One.-Two.'); + expect(callArgs).toEqual([[2, '-']]); + }); }); describe('domain keyword arg validation', () => { @@ -448,6 +489,68 @@ describe('domain keyword arg validation', () => { }); }); + test('rejects unsupported internet.httpStatusCode types before generation', () => { + const keyword = getDomainKeywordByAlias('internet.httpStatusCode'); + const result = validateDomainKeywordArgs(keyword, [['success', 'redirect']]); + + expect(result).toEqual({ + ok: false, + error: + 'Invalid keyword arguments: argument "types" contains unsupported value "redirect". Allowed values are informational, success, redirection, clientError, serverError', + }); + }); + + test('rejects empty internet.httpStatusCode type arrays before generation', () => { + const keyword = getDomainKeywordByAlias('internet.httpStatusCode'); + const result = validateDomainKeywordArgs(keyword, [[]]); + + expect(result).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "types" must not be empty', + }); + }); + + test.each([ + ['git.commitSha', [0], 'length'], + ['word.words', [0], 'count'], + ['lorem.word', [0], 'length'], + ['string.alpha', [0], 'length'], + ['finance.accountNumber', [0], 'length'], + ['date.betweens', [0, 1577836800000, 1609372800000], 'count'], + ])('rejects zero %s size/count parameters before generation', (keywordName, args, argName) => { + const keyword = getDomainKeywordByAlias(keywordName); + const result = validateDomainKeywordArgs(keyword, args); + + expect(result).toEqual({ + ok: false, + error: `Invalid keyword arguments: argument "${argName}" must be greater than 0`, + }); + }); + + test.each([ + ['image.dataUri', [10, -1], 'height'], + ['image.urlPicsumPhotos', [-1, 10], 'width'], + ['image.url', [-1, 10], 'height'], + ])('rejects negative image dimension parameters before generation', (keywordName, args, argName) => { + const keyword = getDomainKeywordByAlias(keywordName); + const result = validateDomainKeywordArgs(keyword, args); + + expect(result).toEqual({ + ok: false, + error: `Invalid keyword arguments: argument "${argName}" must be greater than 0`, + }); + }); + + test('rejects reversed lorem count bounds before generation', () => { + const keyword = getDomainKeywordByAlias('lorem.words'); + const result = validateDomainKeywordArgs(keyword, [undefined, undefined, undefined, 3, 5]); + + expect(result).toEqual({ + ok: false, + error: 'Invalid keyword arguments: argument "wordCountMin" must be less than or equal to argument "wordCountMax"', + }); + }); + test('treats comma-separated list metadata as string-compatible for datatype.enum', () => { const keyword = getDomainKeywordByAlias('datatype.enum'); const result = validateDomainKeywordArgs(keyword, ['active,inactive,pending']); @@ -554,37 +657,6 @@ function setDeepMethod(root, target, fn) { node[parts[parts.length - 1]] = fn; } -function sampleValueForType(type) { - const allowed = String(type || '') - .split('|') - .map((entry) => entry.trim()); - const numericLiterals = allowed.filter((entry) => /^[+-]?\d+(\.\d+)?$/.test(entry)).map((entry) => Number(entry)); - const stringLiterals = allowed - .filter( - (entry) => - !['string', 'integer', 'number', 'date', 'regexp', 'boolean', 'array', 'object'].includes(entry) && - !/^[+-]?\d+(\.\d+)?$/.test(entry) - ) - .map((entry) => - (entry.startsWith('"') && entry.endsWith('"')) || (entry.startsWith("'") && entry.endsWith("'")) - ? entry.slice(1, -1) - : entry - ); - - if (numericLiterals.length === allowed.length && numericLiterals.length > 0) { - return numericLiterals[0]; - } - if (stringLiterals.length > 0) return stringLiterals[0]; - - if (allowed.includes('integer')) return 7; - if (allowed.includes('number')) return 7; - if (allowed.includes('regexp')) return '[A-Z]'; - if (allowed.includes('boolean')) return true; - if (allowed.includes('array')) return ['x', 'y']; - if (allowed.includes('object')) return { key: 'value' }; - return 'sample'; -} - function normalizeExampleValue(value) { if (typeof value === 'bigint') { return { @@ -612,22 +684,6 @@ function serializeExampleValue(value) { return JSON.stringify(normalizeExampleValue(value)); } -function valueToInvocationLiteral(value) { - if (typeof value === 'string') { - return JSON.stringify(value); - } - if (typeof value === 'number' || typeof value === 'boolean') { - return String(value); - } - if (Array.isArray(value)) { - return JSON.stringify(value); - } - if (value && typeof value === 'object') { - return JSON.stringify(value); - } - throw new Error(`Unsupported invocation literal value: ${String(value)}`); -} - function inferTypeFromExampleLiteral(example) { if (example === null || typeof example === 'undefined') { return { type: 'unknown', confidence: 'low' }; @@ -677,7 +733,10 @@ describe('faker keyword invocation styles', () => { for (const keyword of fakerKeywordsWithArgs) { test(`${keyword.keyword} supports equivalent positional and named argument invocation`, () => { - const sampleArgs = keyword.help.args.map((arg) => sampleValueForType(arg.type)); + const argsForInvocation = keyword.keyword.startsWith('lorem.') + ? keyword.help.args.filter((arg) => ['min', 'max'].includes(arg.name)) + : keyword.help.args; + const sampleArgs = argsForInvocation.map((arg) => sampleValueForKeywordArg(keyword.keyword, arg.name, arg.type)); if (keyword.keyword === 'datatype.boolean') { sampleArgs[0] = 0.5; } @@ -686,7 +745,7 @@ describe('faker keyword invocation styles', () => { } const positionalInvocation = `${keyword.keyword}(${sampleArgs.map(valueToInvocationLiteral).join(', ')})`; - const namedInvocation = `${keyword.keyword}(${keyword.help.args + const namedInvocation = `${keyword.keyword}(${argsForInvocation .map((arg, index) => `${arg.name}=${valueToInvocationLiteral(sampleArgs[index])}`) .join(', ')})`; diff --git a/scripts/compare-domain-faker-params.mjs b/scripts/compare-domain-faker-params.mjs new file mode 100644 index 00000000..1c4397a8 --- /dev/null +++ b/scripts/compare-domain-faker-params.mjs @@ -0,0 +1,267 @@ +import fs from 'node:fs'; +import path from 'node:path'; +import { createRequire } from 'node:module'; +import { fileURLToPath } from 'node:url'; +import { DOMAIN_KEYWORDS } from '../packages/core/js/domain/domain-keywords.js'; + +const require = createRequire(import.meta.url); + +function findMatching(source, openIndex, openChar, closeChar) { + let depth = 0; + for (let index = openIndex; index < source.length; index += 1) { + if (source[index] === openChar) { + depth += 1; + } + if (source[index] === closeChar) { + depth -= 1; + if (depth === 0) { + return index; + } + } + } + return -1; +} + +function getTopLevelObjectKeys(objectBody) { + const keys = []; + let depth = 0; + let tokenStart = 0; + const normalizedBody = objectBody.replace(/\/\*[\s\S]*?\*\//g, ' '); + + for (let index = 0; index <= normalizedBody.length; index += 1) { + const character = normalizedBody[index] || ';'; + if (character === '{' || character === '(' || character === '[' || character === '<') { + depth += 1; + } + if (character === '}' || character === ')' || character === ']' || character === '>') { + depth = Math.max(0, depth - 1); + } + if ((character === ';' || character === ',') && depth === 0) { + const segment = normalizedBody.slice(tokenStart, index).trim(); + const match = segment.match(/^([A-Za-z_$][\w$]*)\??\s*:/); + if (match) { + keys.push(match[1]); + } + tokenStart = index + 1; + } + } + + return [...new Set(keys)]; +} + +function getObjectOptionKeys(optionsSignature) { + const keys = []; + for (let index = 0; index < optionsSignature.length; index += 1) { + if (optionsSignature[index] !== '{') { + continue; + } + const objectEnd = findMatching(optionsSignature, index, '{', '}'); + if (objectEnd < 0) { + continue; + } + keys.push(...getTopLevelObjectKeys(optionsSignature.slice(index + 1, objectEnd))); + index = objectEnd; + } + return [...new Set(keys)]; +} + +function getFakerDeclarationPath() { + const packageJsonPath = require.resolve('@faker-js/faker/package.json'); + const packageRoot = path.dirname(packageJsonPath); + const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8')); + const typesEntry = packageJson.exports?.['.']?.default?.types || packageJson.types; + + if (!typesEntry) { + throw new Error('Unable to resolve Faker declaration entry from package exports.'); + } + + const typesEntryPath = path.join(packageRoot, typesEntry); + const typesEntryText = fs.readFileSync(typesEntryPath, 'utf8'); + const bundleMatch = typesEntryText.match(/\bfrom\s+['"]\.\/([^'"]+\.js)['"]/); + + if (bundleMatch) { + const bundlePath = path.join(path.dirname(typesEntryPath), bundleMatch[1].replace(/\.js$/u, '.d.ts')); + if (fs.existsSync(bundlePath)) { + return bundlePath; + } + } + + if (typesEntryText.includes('declare class')) { + return typesEntryPath; + } + + throw new Error('Unable to find Faker declaration bundle with module method signatures.'); +} + +function mergeMethodOverload(method, optionsSignature) { + const signatures = [...(method?.signatures || []), optionsSignature]; + const optionParams = [...new Set([...(method?.optionParams || []), ...getObjectOptionKeys(optionsSignature)])]; + + return { + signature: signatures.join(' | '), + signatures, + optionParams, + }; +} + +function extractFakerOptionMethods(declarationText) { + const modules = new Map(); + const classRegex = /declare class (\w+)Module\b/g; + let classMatch = classRegex.exec(declarationText); + + while (classMatch) { + const className = classMatch[1]; + const classOpen = declarationText.indexOf('{', classMatch.index); + if (classOpen < 0) { + classRegex.lastIndex = classMatch.index + classMatch[0].length; + classMatch = classRegex.exec(declarationText); + continue; + } + const classClose = findMatching(declarationText, classOpen, '{', '}'); + if (classClose < 0) { + classRegex.lastIndex = classMatch.index + classMatch[0].length; + classMatch = classRegex.exec(declarationText); + continue; + } + + const body = declarationText.slice(classOpen + 1, classClose); + const methods = new Map(); + const methodStartRegex = /^\s*(\w+)\s*(?:<[^\n;]+>)?\s*\(/gm; + let methodMatch = methodStartRegex.exec(body); + + while (methodMatch) { + const methodName = methodMatch[1]; + const paramsOpen = body.indexOf('(', methodMatch.index); + const paramsClose = findMatching(body, paramsOpen, '(', ')'); + if (paramsClose < 0) { + methodMatch = methodStartRegex.exec(body); + continue; + } + + const paramsText = body + .slice(paramsOpen + 1, paramsClose) + .replace(/\s+/g, ' ') + .trim(); + const optionsIndex = paramsText.indexOf('options?:'); + if (optionsIndex < 0) { + methodMatch = methodStartRegex.exec(body); + continue; + } + + const optionsSignature = paramsText.slice(optionsIndex + 'options?:'.length).trim(); + methods.set(methodName, mergeMethodOverload(methods.get(methodName), optionsSignature)); + methodMatch = methodStartRegex.exec(body); + } + + const moduleName = className.charAt(0).toLowerCase() + className.slice(1); + modules.set(moduleName, methods); + classRegex.lastIndex = classClose + 1; + classMatch = classRegex.exec(declarationText); + } + + return modules; +} + +function getFakerOptionParamComparison({ declarationPath = getFakerDeclarationPath() } = {}) { + const declarationText = fs.readFileSync(declarationPath, 'utf8'); + const fakerMethods = extractFakerOptionMethods(declarationText); + + return DOMAIN_KEYWORDS.filter((keyword) => keyword.delegate?.type === 'faker') + .map((keyword) => { + const [moduleName, methodName] = String(keyword.delegate.target || '').split('.'); + const method = fakerMethods.get(moduleName)?.get(methodName); + if (!method || method.optionParams.length === 0) { + return null; + } + + const domainParams = (keyword.help?.args || []) + .map((arg) => String(arg?.name || '').trim()) + .filter((name) => name.length > 0); + const domainParamSet = new Set(domainParams); + const fakerParamSet = new Set(method.optionParams); + + return { + keyword: keyword.keyword, + fakerTarget: keyword.delegate.target, + fakerOptionParams: method.optionParams, + domainParams, + missingInDomain: method.optionParams.filter((param) => !domainParamSet.has(param)), + domainOnlyParams: domainParams.filter((param) => !fakerParamSet.has(param)), + fakerOptionsSignature: method.signature, + }; + }) + .filter(Boolean) + .sort((left, right) => left.keyword.localeCompare(right.keyword)); +} + +function formatList(values) { + return values.length > 0 ? values.map((value) => `\`${value}\``).join(', ') : 'none'; +} + +function formatMarkdownComparisonReport(rows = getFakerOptionParamComparison()) { + const missingRows = rows.filter((row) => row.missingInDomain.length > 0); + const domainOnlyRows = rows.filter((row) => row.domainOnlyParams.length > 0); + + const lines = [ + '# Domain/Faker Param Comparison', + '', + 'Generated by `node scripts/compare-domain-faker-params.mjs --markdown` from the installed `@faker-js/faker` declaration bundle and the domain keyword catalog.', + '', + '## Summary', + '', + `- Faker option-backed domain commands compared: ${rows.length}`, + `- Commands with Faker option params missing from domain metadata: ${missingRows.length}`, + `- Commands with domain params not present in Faker options: ${domainOnlyRows.length}`, + '', + '## Comparison', + '', + '| Command | Faker option params | Domain params | Missing in domain | Domain-only params |', + '| --- | --- | --- | --- | --- |', + ]; + + for (const row of rows) { + lines.push( + `| \`${row.keyword}\` | ${formatList(row.fakerOptionParams)} | ${formatList(row.domainParams)} | ${formatList(row.missingInDomain)} | ${formatList(row.domainOnlyParams)} |` + ); + } + + lines.push(''); + lines.push('## Review Notes'); + lines.push(''); + lines.push('- `Missing in domain` must stay at `none` for every row.'); + lines.push('- `Domain-only params` must stay at `none` for every Faker-backed domain command.'); + lines.push(''); + + return `${lines.join('\n')}\n`; +} + +function hasParamComparisonFailures(rows = []) { + return rows.some((row) => row.missingInDomain.length > 0 || row.domainOnlyParams.length > 0); +} + +function runCli() { + const args = process.argv.slice(2); + const rows = getFakerOptionParamComparison(); + + if (args.includes('--markdown')) { + process.stdout.write(formatMarkdownComparisonReport(rows)); + } else { + process.stdout.write(`${JSON.stringify(rows, null, 2)}\n`); + } + + if (args.includes('--check') && hasParamComparisonFailures(rows)) { + process.exitCode = 1; + } +} + +const isCli = fileURLToPath(import.meta.url) === path.resolve(process.argv[1] || ''); +if (isCli) { + runCli(); +} + +export { + extractFakerOptionMethods, + formatMarkdownComparisonReport, + getFakerOptionParamComparison, + hasParamComparisonFailures, +}; diff --git a/scripts/generate-domain-docs.mjs b/scripts/generate-domain-docs.mjs index 84fd8250..dd0009a8 100644 --- a/scripts/generate-domain-docs.mjs +++ b/scripts/generate-domain-docs.mjs @@ -138,10 +138,27 @@ function escapeMarkdownTableCell(value) { return escapeMdxText(normalized.replaceAll('\n', '
')).replaceAll('|', '\\|'); } +function toDisplayFunctionCall(functionCall, entry) { + const call = String(functionCall || '').trim(); + const keyword = String(entry?.keyword || '').trim(); + const displayCommand = String(entry?.displayCommand || keyword).trim(); + if (!call || !keyword || !displayCommand || displayCommand === keyword) { + return call; + } + + const prefixes = [`awd.domain.${keyword}`, `domain.${keyword}`, keyword]; + const matchedPrefix = prefixes.find((prefix) => call === prefix || call.startsWith(`${prefix}(`)); + if (!matchedPrefix) { + return call; + } + + return `${displayCommand}${call.slice(matchedPrefix.length)}`; +} + function getDefinitionUsageExamples(entry) { return (Array.isArray(entry?.help?.usageExamples) ? entry.help.usageExamples : []) .map((usageExample) => { - const functionCall = String(usageExample?.functionCall || '').trim(); + const functionCall = toDisplayFunctionCall(usageExample?.functionCall, entry); if (!functionCall) { return null; }