Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
45626ba
Refactor enum handling through domain commands
eviltester Jun 24, 2026
db301fc
Support named enum values parsing
eviltester Jun 24, 2026
86c0256
Keep enum params as raw comma lists
eviltester Jun 24, 2026
8529bd7
Canonicalize enum aliases in schema output
eviltester Jun 24, 2026
29c9a92
Canonicalize AWD enum domain rows
eviltester Jun 24, 2026
fbb452e
Normalize declared enum rules during compile
eviltester Jun 24, 2026
77cdbd1
Anchor enum invocation detection
eviltester Jun 24, 2026
363d2d6
Parse function-shaped datatype enum args
eviltester Jun 24, 2026
ce9d0fc
Cover AWD enum token rendering
eviltester Jun 24, 2026
451de73
Remove stale matrix report generator
eviltester Jun 24, 2026
bc06cd7
Select matrix smoke scenarios semantically
eviltester Jun 24, 2026
3b9afc1
Simplify canonical enum regex
eviltester Jun 24, 2026
115da3e
Use shared enum-like rule detection
eviltester Jun 24, 2026
7d8619a
enum refactoring
eviltester Jun 24, 2026
8382b9e
Move export conversion coverage into converter suites
eviltester Jun 24, 2026
fb9e8e2
Fix enum defects from issue 228 testing
eviltester Jun 24, 2026
a3b39dd
Fix issue 228 accessibility and validation defects
eviltester Jun 24, 2026
4fc9988
Fix published command docs examples
eviltester Jun 25, 2026
cec289b
Tighten invalid schema validation
eviltester Jun 25, 2026
bf803a7
Improve UI accessibility focus behavior
eviltester Jun 25, 2026
deb85e2
Align stored schema browser selectors
eviltester Jun 25, 2026
b7857a4
Refine enum invocation syntax contract
eviltester Jun 25, 2026
2c7fd81
Support abbreviated location direction params
eviltester Jun 25, 2026
e6248da
Show schema validation errors for invalid enum text
eviltester Jun 25, 2026
a84ea14
Refine enum parsing and review coverage
eviltester Jun 25, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ name
rule

# compact pict-style alternative
status: enum(active,inactive)
status: active,inactive

IF [name] = "Bob" THEN [status] = "active" ENDIF
```
Expand Down
2 changes: 1 addition & 1 deletion apps/api/src/fromschema.route.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ test('/v1/generate/fromschema accepts comments and blank lines in schema text',
const response = await fetch(url('/v1/generate/fromschema?rowCount=2&outputFormat=json'), {
method: 'POST',
headers: { 'content-type': 'text/plain' },
body: '# skip me\n\nPriority\nenum(high,medium,low)\n\n# and me\nStatus\nenum(active,inactive,pending)',
body: '# skip me\n\nPriority\nhigh,medium,low\n\n# and me\nStatus\nactive,inactive,pending',
});

expect(response.status).toBe(200);
Expand Down
2 changes: 1 addition & 1 deletion apps/cli/src/tests/run-cli.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ test('generates deterministic pairwise output in buffered mode', async () => {

test('supports comments and blank lines in input schema', async () => {
const platform = makePlatform({
textSpec: '# comment\n\nPriority\nenum(high,medium,low)\n\nStatus\nenum(active,inactive,pending)',
textSpec: '# comment\n\nPriority\nhigh,medium,low\n\nStatus\nactive,inactive,pending',
});
const code = await runCliCommand({
platform,
Expand Down
2 changes: 1 addition & 1 deletion apps/mcp/src/mcp.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ test('MCP server accepts comments and blank lines in textSpec', () => {
params: {
name: 'generate_data_from_spec',
arguments: {
textSpec: '# comment\n\nPriority\nenum(high,medium,low)\nStatus\nenum(active,inactive,pending)',
textSpec: '# comment\n\nPriority\nhigh,medium,low\nStatus\nactive,inactive,pending',
rowCount: 1,
outputFormat: 'json',
},
Expand Down
4 changes: 2 additions & 2 deletions apps/web/src/stories/generator-page.stories.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { createGeneratorPageComponent } from '../../../../packages/core-ui/js/gu
import { createGeneratorPageShellComponent } from '../../../../packages/core-ui/js/gui_components/generator/page/create-generator-page-shell-component.js';
import { GENERATOR_DEFAULT_EXAMPLE_SCHEMA_TEXT } from '../../../../packages/core-ui/js/gui_components/shared/test-data/schema/schema-examples.js';
import { validateSchemaRows as validateSharedSchemaRows } from '../../../../packages/core-ui/js/gui_components/shared/test-data/schema/schema-editor-core.js';
import { getKnownFakerCommandsAlphabetical } from '../../../../packages/core-ui/js/gui_components/shared/faker-commands.js';
import { getAllowedFakerCommandsAlphabetical } from '../../../../packages/core-ui/js/gui_components/shared/faker-commands.js';
import { getKnownDomainCommandsAlphabetical } from '../../../../packages/core-ui/js/gui_components/shared/domain-commands.js';
import { buildSchemaModeHelpHtml } from '../../../../packages/core-ui/js/gui_components/shared/test-data/help/schema-mode-help-builder.js';
import { createGeneratorSchemaDefinitionSupport } from '../../../../packages/core-ui/js/gui_components/generator/schema-support/create-generator-schema-definition-support.js';
Expand Down Expand Up @@ -50,7 +50,7 @@ function getSchemaHelpText(rootElement) {

function createGeneratorSchemaStoryProps(ids = {}) {
let rowCounter = 1;
const fakerCommands = getKnownFakerCommandsAlphabetical().filter(
const fakerCommands = getAllowedFakerCommandsAlphabetical().filter(
(command) => command !== 'RegEx' && command.startsWith('helpers.')
);
const domainCommands = getKnownDomainCommandsAlphabetical();
Expand Down
4 changes: 2 additions & 2 deletions apps/web/src/stories/generator-schema-panel.stories.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@ import {
} from '@anywaydata/core/data_generation/schema-rules-adapter.js';
import { createSchemaPanelComponent } from '../../../../packages/core-ui/js/gui_components/shared/schema-panel/index.js';
import { validateSchemaRows as validateSharedSchemaRows } from '../../../../packages/core-ui/js/gui_components/shared/test-data/schema/schema-editor-core.js';
import { getKnownFakerCommandsAlphabetical } from '../../../../packages/core-ui/js/gui_components/shared/faker-commands.js';
import { getAllowedFakerCommandsAlphabetical } from '../../../../packages/core-ui/js/gui_components/shared/faker-commands.js';
import { getKnownDomainCommandsAlphabetical } from '../../../../packages/core-ui/js/gui_components/shared/domain-commands.js';
import { buildSchemaModeHelpHtml } from '../../../../packages/core-ui/js/gui_components/shared/test-data/help/schema-mode-help-builder.js';
import { createGeneratorSchemaDefinitionSupport } from '../../../../packages/core-ui/js/gui_components/generator/schema-support/create-generator-schema-definition-support.js';
import { GENERATOR_DEFAULT_EXAMPLE_SCHEMA_TEXT } from '../../../../packages/core-ui/js/gui_components/shared/test-data/schema/schema-examples.js';

function createGeneratorSchemaStoryProps() {
let rowCounter = 1;
const fakerCommands = getKnownFakerCommandsAlphabetical().filter(
const fakerCommands = getAllowedFakerCommandsAlphabetical().filter(
(command) => command !== 'RegEx' && command.startsWith('helpers.')
);
const domainCommands = getKnownDomainCommandsAlphabetical();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ export const Default = {
},
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
const downloadButton = canvas.getByRole('button', { name: /\.csv Download/i });
const downloadButton = canvas.getByRole('button', { name: 'Download file' });
await expect(downloadButton).toBeEnabled();
await userEvent.click(downloadButton);
await expect(canvas.getByText('action:download')).toBeVisible();
Expand All @@ -101,7 +101,7 @@ export const Busy = {
},
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
await expect(canvas.getByRole('button', { name: /\.csv Download/i })).toBeDisabled();
await expect(canvas.getByRole('button', { name: 'Download file' })).toBeDisabled();
await expect(canvas.getByText('Generating export text...')).toBeVisible();
},
};
Expand Down
4 changes: 2 additions & 2 deletions apps/web/src/stories/import-export-toolbar.stories.js
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ export const Default = {
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
const helpButtons = canvas.getAllByRole('button', { name: 'Show help' });
const downloadButton = canvas.getByRole('button', { name: /\.csv Download/i });
const downloadButton = canvas.getByRole('button', { name: 'Download file' });

await expect(helpButtons).toHaveLength(2);
await expect(helpButtons[0]).toHaveAttribute('data-help', 'import-export-import');
Expand Down Expand Up @@ -259,7 +259,7 @@ export const BusyAndStatus = {
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
await expect(canvas.getByRole('button', { name: 'Import From Clipboard' })).toBeDisabled();
await expect(canvas.getByRole('button', { name: /\.csv Download/i })).toBeDisabled();
await expect(canvas.getByRole('button', { name: 'Download file' })).toBeDisabled();
await expect(canvas.getByText('Importing full data into grid...')).toBeVisible();
await expect(canvas.getByText('Generating export text...')).toBeVisible();
},
Expand Down
10 changes: 5 additions & 5 deletions apps/web/src/stories/shared-schema-definition.stories.js
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,7 @@ export const SampleSchema = {
export const ValidationError = {
render: renderSharedSchemaDefinitionStory,
args: {
initialText: 'Status\nenum(active,inactive)',
initialText: 'Status\nactive,inactive',
showErrors: true,
startInTextMode: false,
},
Expand Down Expand Up @@ -335,7 +335,7 @@ export const ValidationError = {
export const TextMode = {
render: renderSharedSchemaDefinitionStory,
args: {
initialText: 'Status\nenum(active,inactive,pending)',
initialText: 'Status\nactive,inactive,pending',
showErrors: true,
startInTextMode: true,
},
Expand All @@ -351,7 +351,7 @@ export const TextMode = {
expectTextModeVisible(canvasElement);
const textArea = within(canvasElement).getByRole('textbox', { name: /schema text/i });
await expect(textArea.value).toContain('Status');
await expect(textArea.value).toContain('enum(active,inactive,pending)');
await expect(textArea.value).toContain('active,inactive,pending');
const helpIcon = canvasElement.querySelector('[data-role="schema-mode-help"]');
await userEvent.hover(helpIcon);
await expectSchemaHelpContent(helpIcon, { helpHeadingText: 'Edit as Schema' });
Expand All @@ -363,9 +363,9 @@ export const ConstrainedTextMode = {
render: renderSharedSchemaDefinitionStory,
args: {
initialText: `Priority
enum(high,low)
enum("high","low")
Status
enum(open,closed)
enum("open","closed")
IF [Priority] = "high" THEN [Status] = "open" ENDIF`,
showErrors: true,
startInTextMode: true,
Expand Down
6 changes: 3 additions & 3 deletions apps/web/src/stories/stored-schemas-manager.stories.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ function createInMemoryStorageState(args) {
{
id: 'last-1',
name: 'last used - 2026-06-16T10:05:00.000Z',
schemaText: 'Status\nenum(active,inactive)',
schemaText: 'Status\nactive,inactive',
updatedAt: '2026-06-16T10:05:00.000Z',
},
]
Expand All @@ -26,7 +26,7 @@ function createInMemoryStorageState(args) {
{
id: 'saved-1',
name: 'Regression Smoke',
schemaText: 'Browser\nenum(chrome,firefox)',
schemaText: 'Browser\nchrome,firefox',
updatedAt: '2026-06-16T10:06:00.000Z',
},
]
Expand Down Expand Up @@ -203,7 +203,7 @@ export const DraftAndHistory = {
const canvas = within(canvasElement);
await userEvent.click(canvas.getByText('Managed Stored Schemas (0)'));
await userEvent.selectOptions(canvas.getByLabelText('Last Used'), 'last-1');
await userEvent.click(canvas.getByRole('button', { name: /^load$/i }));
await userEvent.click(canvas.getByRole('button', { name: /load last used schema/i }));
await expect(canvas.getByText(/Loaded last used/i)).toBeVisible();
},
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@ class TestDataPanelComponent {
this.storedSchemasSummary = this.panelRoot.getByText(/Managed Stored Schemas/);
this.storedSchemasSaveAsButton = this.panelRoot.getByRole('button', { name: 'Save Schema As' });
this.storedSchemasRecoverDraftButton = this.panelRoot.getByRole('button', { name: 'Recover Draft' });
this.storedSchemasLastUsedSelect = this.panelRoot.getByLabel('Last Used');
this.storedSchemasLoadLastUsedButton = this.panelRoot.getByRole('button', { name: /^Load$/ });
this.storedSchemasLastUsedSelect = this.panelRoot.getByRole('combobox', { name: 'Last Used' });
this.storedSchemasLoadLastUsedButton = this.panelRoot.getByRole('button', { name: 'Load last used schema' });
this.storedSchemasLoadSavedButton = this.panelRoot.getByRole('button', { name: 'Load Saved Schema' });
this.storedSchemasDialog = page.getByRole('dialog', { name: 'Saved Schemas' });
this.schemaGrid = this.schemaEditor.rowsContainer;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ test.describe('7. Test Data Generation', () => {
await expect.poll(async () => appPage.testDataPanel.getSchemaRowCount()).toBe(2);
await expect
.poll(async () => appPage.testDataPanel.getSchemaText())
.toContain('Status\nenum(active,pending,inactive)');
.toContain('Status\nenum("active","pending","inactive")');
await expect(await appPage.testDataPanel.getSchemaCell(0, 'columnName')).toBe('Status');
await expect(await appPage.testDataPanel.getSchemaCell(1, 'columnName')).toBe('Priority');
expectNoPageErrors(pageErrors);
Expand All @@ -51,7 +51,7 @@ test.describe('7. Test Data Generation', () => {
await appPage.testDataPanel.submitGridToEnumSchemaLimit(2);
await appPage.testDataPanel.confirmDialog.confirm({ confirmLabel: /truncate schema/i });

await expect.poll(async () => appPage.testDataPanel.getSchemaText()).toContain('Status\nenum(active,pending)');
await expect.poll(async () => appPage.testDataPanel.getSchemaText()).toContain('Status\nenum("active","pending")');
await expect.poll(async () => appPage.testDataPanel.getSchemaText()).not.toContain('inactive');
expectNoPageErrors(pageErrors);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ test.describe('7. Test Data Generation', () => {
await appPage.testDataPanel.expectExpanded();

await appPage.testDataPanel.setSchemaText(
'Browser\nenum(chrome,firefox,safari)\n\nPlan\nenum(free,pro,enterprise)\n\nFixed\nliteral(CONSTANT)'
'Browser\nchrome,firefox,safari\n\nPlan\nfree,pro,enterprise\n\nFixed\nliteral(CONSTANT)'
);

const initialRowCount = await appPage.gridEditor.renderer.countRows();
Expand All @@ -29,7 +29,7 @@ test.describe('7. Test Data Generation', () => {
await appPage.testDataPanel.expectExpanded();

await appPage.testDataPanel.setSchemaText(
'Browser\nenum(chrome,firefox,safari)\n\nPlan\nenum(free,pro,enterprise)\n\nFixed\nliteral(CONSTANT)\n\nCode\n[A-Z]{2}[0-9]{2}\n\nEnabled\ndatatype.boolean'
'Browser\nchrome,firefox,safari\n\nPlan\nfree,pro,enterprise\n\nFixed\nliteral(CONSTANT)\n\nCode\n[A-Z]{2}[0-9]{2}\n\nEnabled\ndatatype.boolean'
);

await appPage.testDataPanel.clickGeneratePairwise();
Expand Down Expand Up @@ -86,7 +86,7 @@ test.describe('7. Test Data Generation', () => {
await appPage.testDataPanel.expectExpanded();

await appPage.testDataPanel.setSchemaText(
'Browser\nenum(chrome,firefox,safari)\n\nPlan\nenum(free,pro,enterprise)\n\nRegion\nenum(amer,emea,apac)\n\nFixed\nliteral(CONSTANT)'
'Browser\nchrome,firefox,safari\n\nPlan\nfree,pro,enterprise\n\nRegion\namer,emea,apac\n\nFixed\nliteral(CONSTANT)'
);

await appPage.testDataPanel.openGenerateCombinationsDialog();
Expand Down Expand Up @@ -127,7 +127,7 @@ test.describe('7. Test Data Generation', () => {
await appPage.testDataPanel.expectExpanded();

await appPage.testDataPanel.setSchemaText(
'A\nenum(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11)\n\nB\nenum(b1,b2,b3,b4,b5,b6,b7,b8,b9,b10,b11)\n\nC\nenum(c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11)\n\nD\nenum(d1,d2,d3,d4,d5,d6,d7,d8,d9,d10,d11)'
'A\na1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11\n\nB\nb1,b2,b3,b4,b5,b6,b7,b8,b9,b10,b11\n\nC\nc1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11\n\nD\nd1,d2,d3,d4,d5,d6,d7,d8,d9,d10,d11'
);

const initialRowCount = await appPage.gridEditor.renderer.countRows();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ test.describe('Test Data Schema File Load Save', () => {
await appPage.testDataPanel.loadSchemaFile({
name: 'schema.txt',
mimeType: 'text/plain',
buffer: Buffer.from('Loaded Name\nliteral(Ada)\nLoaded Status\nenum(active,inactive)'),
buffer: Buffer.from('Loaded Name\nliteral(Ada)\nLoaded Status\nactive,inactive'),
});

await expect.poll(async () => appPage.testDataPanel.getSchemaText()).toContain('Loaded Name');
Expand Down
Loading