### GeneratorFaker setup example Source: https://github.com/xhubio/nanook-table/blob/master/docs/api/data-generator.md Complete example of setting up GeneratorFaker with a registry and logger. The createDefaultGeneratorRegistry() factory function in the processor module creates a registry with GeneratorFaker already registered. ```typescript import { GeneratorFaker, DataGeneratorRegistry, LoggerMemory } from 'nanook-table' const logger = new LoggerMemory() const registry = new DataGeneratorRegistry() const faker = new GeneratorFaker({ logger, serviceRegistry: registry }) registry.registerGenerator('GeneratorFaker', faker) ``` -------------------------------- ### Full TestcaseProcessor setup and execution Source: https://github.com/xhubio/nanook-table/blob/master/docs/api/processor.md Complete example of setting up and running the TestcaseProcessor. Creates a memory logger, loads test cases from an Excel file, and processes them. The processor's tables are assigned from the file processor's tables before calling process(). ```typescript import { LoggerMemory, TestcaseProcessor, createDefaultFileProcessor, createDefaultGeneratorRegistry, createDefaultWriter } from 'nanook-table' const logger = new LoggerMemory() logger.writeConsole = true // Set up components const fileProcessor = await createDefaultFileProcessor(logger) const registry = createDefaultGeneratorRegistry() const writer = createDefaultWriter(logger) // Load and process await fileProcessor.load('resources/tests.xlsx') const processor = new TestcaseProcessor({ logger, generatorRegistry: registry, writer }) processor.tables = fileProcessor.tables await processor.process() ``` -------------------------------- ### Quick Start: Process XLSX tables with @xhubio/nanook-table Source: https://github.com/xhubio/nanook-table/blob/master/README.md Quick start example: loads an XLSX file, registers the Faker generator, defines a custom writer that writes one JSON file per test case, and processes the tables. The registry starts empty, so every generator used by tables must be registered. ```typescript import path from 'node:path' import fs from 'node:fs/promises' import { LoggerMemory, TestcaseProcessor, createDefaultFileProcessor, DataGeneratorRegistry, GeneratorFaker, type InterfaceWriter } from '@xhubio/nanook-table' async function main() { const logger = new LoggerMemory() logger.writeConsole = true const fileProcessor = createDefaultFileProcessor(logger) // the registry starts empty: register every generator your tables call (gen::faker:...) const generatorRegistry = new DataGeneratorRegistry() generatorRegistry.registerGenerator( 'faker', new GeneratorFaker({ generatorRegistry, name: 'faker', logger }) ) await fileProcessor.load([path.join('resources', 'tests.xlsx')]) const tables: Record = {} for (const table of fileProcessor.tables) { tables[table.tableName] = table } // one JSON file per test case; see "Writing a Custom Writer" below const writer: InterfaceWriter = { logger, async before() { await fs.mkdir('tdg', { recursive: true }) }, async write(tc) { await fs.writeFile(path.join('tdg', `${tc.tableName}.${tc.name}.json`), JSON.stringify(tc, null, 2)) }, async after() {} } const processor = new TestcaseProcessor({ logger, generatorRegistry, writer: [writer], tables }) await processor.process() } main() ``` -------------------------------- ### Install @xhubio/nanook-table with npm Source: https://github.com/xhubio/nanook-table/blob/master/README.md Install the @xhubio/nanook-table package. Requires Node.js >= 22. ```bash npm install @xhubio/nanook-table ``` -------------------------------- ### Install nanook-table package Source: https://github.com/xhubio/nanook-table/blob/master/docs/README.md Install the nanook-table package using npm. ```bash npm install nanook-table ``` -------------------------------- ### Check server start time and recent commits Source: https://github.com/xhubio/nanook-table/blob/master/docs/articles/2026-08-15_notes_ai-nanook-playwright.md Run at the start of a measurement session to check whether the running server is stale. The first command shows the server's start time; the second lists commits since that timestamp. If the second command prints anything, the process must be restarted before trusting any findings. ```bash ps -eo lstart,command | grep '' git log --since="" --oneline ``` -------------------------------- ### Install and use skill as Claude Code plugin Source: https://github.com/xhubio/nanook-table/blob/master/README.md Install and use the create-equivalence-class-table skill as a Claude Code plugin. Run these commands in Claude Code (CLI, desktop, web, IDE) to add the plugin, install it, and invoke the skill with a prompt. ```text /plugin marketplace add xhubio/nanook-table /plugin install nanook@nanook /nanook:create-equivalence-class-table Login form with email and password ``` -------------------------------- ### Expected Output Directory Structure Source: https://github.com/xhubio/nanook-table/blob/master/docs/tutorials/create-writer.md Shows the expected directory structure after running the example, with per-test-case files from the default and CSV writers. ```text tdg/ TC1/ testcaseData.json (from the default writer) person.csv (from the CSV writer) TC2/ testcaseData.json person.csv TC3/ testcaseData.json person.csv TC4/ testcaseData.json person.csv ``` -------------------------------- ### Custom Writer Example Source: https://github.com/xhubio/nanook-table/blob/master/docs/api/processor.md Example of implementing a custom writer by extending InterfaceWriter and overriding the before, write, and after methods. ```APIDOC ## Custom Writer Example ### Description Example of a custom writer that logs test case data to the console. ### Code ```typescript import { InterfaceWriter } from 'nanook-table' import type { TestcaseData } from 'nanook-table' class ConsoleWriter extends InterfaceWriter { async before(): Promise { console.log('--- Start of test data ---') } async write(testcaseData: TestcaseData): Promise { const name = testcaseData.name console.log(`Test case: ${name}`) console.log(JSON.stringify(testcaseData.data, null, 2)) } async after(): Promise { console.log('--- End of test data ---') } } ``` ``` -------------------------------- ### Creating a Custom Generator Source: https://github.com/xhubio/nanook-table/blob/master/docs/api/data-generator.md Example of creating and registering a custom generator. ```APIDOC ## Creating a Custom Generator ### Description Example of creating and registering a custom generator by extending `DataGeneratorBase`. ### Steps 1. Extend `DataGeneratorBase` and override `_doGenerate`. 2. Instantiate the generator with a logger and service registry. 3. Register the generator with a `DataGeneratorRegistry`. ### Example ```typescript import { DataGeneratorBase, DataGeneratorRegistry, LoggerMemory } from 'nanook-table' import type { GeneratorDirective, TestcaseData } from 'nanook-table' class GeneratorCounter extends DataGeneratorBase { private counter = 0 async _doGenerate( instanceId: string, testcase: TestcaseData, generatorDirective: GeneratorDirective ): Promise { this.counter += 1 return this.counter } } // Register the generator const logger = new LoggerMemory() const registry = new DataGeneratorRegistry() const counter = new GeneratorCounter({ logger, serviceRegistry: registry }) registry.registerGenerator('counter', counter) ``` ``` -------------------------------- ### Build and Development Commands Source: https://github.com/xhubio/nanook-table/blob/master/AGENTS.md Common npm commands for installing dependencies, building, testing, linting, formatting, and type checking. CI uses the full `npm test` pipeline. ```bash npm install # install dependencies npm run build # tsc -p tsconfig.build.json npm test # format + lint + build + vitest with coverage npm run lint # eslint only npm run format # prettier --write npm run format:check # prettier --check (CI) npm run typecheck # tsc --noEmit (type check without emitting) ``` -------------------------------- ### Example of nested data object Source: https://github.com/xhubio/nanook-table/blob/master/docs/tutorials/create-writer.md Shows an example of the data property structure with a table name, instance ID, and field values. ```json { "Sheet1": { "a9dad54a-...": { "first name": "Alice", "last name": "Garcia", "email": "Alice.Garcia@example.com" } } } ``` -------------------------------- ### async before(): Promise Source: https://github.com/xhubio/nanook-table/blob/master/docs/api/processor.md Called once before the processor starts generating test cases. Use this for initialization tasks such as creating output directories or opening connections. ```APIDOC ## async before(): Promise ### Description Called once before the processor starts generating test cases. Use this for initialization (creating output directories, opening database connections, writing file headers, etc.). ### Method `async before(): Promise` ### Parameters None. ### Returns `Promise` - Resolves when initialization is complete. ``` -------------------------------- ### Instance ID reuse example Source: https://github.com/xhubio/nanook-table/blob/master/docs/guide/directives.md Two reference directives sharing the same instance ID and pointing to the same test case reuse the same generated instance. ```text ref:1:PersonTable:email:tc2 <- Creates instance of PersonTable:tc2, returns email ref:1:PersonTable:name:tc2 <- Reuses the same instance, returns name ``` -------------------------------- ### Sample CSV Output for TC1 Source: https://github.com/xhubio/nanook-table/blob/master/docs/tutorials/create-writer.md Example CSV output for test case TC1, showing the header row and a single data row. ```csv first name,last name,email Alice,Garcia,Alice.Garcia@example.com ``` -------------------------------- ### Basic generator directive example Source: https://github.com/xhubio/nanook-table/blob/master/docs/guide/directives.md Basic generator directive example. Calls the generator registered as 'PersonGenerator' with parameter 'firstName' and no explicit instance ID, so a new UUID is assigned automatically. ```text gen::PersonGenerator:firstName ``` -------------------------------- ### Basic reference example Source: https://github.com/xhubio/nanook-table/blob/master/docs/guide/directives.md References test case tc1 in table PersonTable, extracts the email field, and stores the referenced instance under ID 1. ```text ref:1:PersonTable:email:tc1 ``` -------------------------------- ### Example usage of LoggerMemory Source: https://github.com/xhubio/nanook-table/blob/master/docs/api/logger.md Shows how to import LoggerMemory, enable console output, log messages at different levels, access stored entries, and check for errors. ```typescript import { LoggerMemory } from 'nanook-table' const logger = new LoggerMemory() logger.writeConsole = true await logger.info('Starting generation') await logger.debug('Processing sheet: LoginTests') await logger.warning('Empty test case column found') // Access stored entries for (const entry of logger.entries.warning) { console.log(`Warning at ${entry.time}: ${entry.message}`) } // Check for errors after processing if (logger.entries.error.length > 0) { console.log(`${logger.entries.error.length} errors occurred`) } ``` -------------------------------- ### Load an XLSX file and list sheet names Source: https://github.com/xhubio/nanook-table/blob/master/docs/api/file-processor.md Creates an ImporterXlsx instance, loads a file, and retrieves the sheet names. The comment shows the expected output for the example file. ```typescript const importer = new ImporterXlsx() await importer.loadFile('tests.xlsx') const sheets = importer.sheetNames() // ['LoginTests', 'RegistrationTests', 'PaymentMatrix'] ``` -------------------------------- ### Instance ID without reuse example Source: https://github.com/xhubio/nanook-table/blob/master/docs/guide/directives.md Without matching instance IDs, each reference creates a new independent instance, potentially with different data. ```text ref::PersonTable:email:tc2 <- Instance A of PersonTable:tc2 ref::PersonTable:name:tc2 <- Instance B of PersonTable:tc2 (different data!) ``` -------------------------------- ### Refine rule for reversed date ranges in quote-backend Source: https://github.com/xhubio/nanook-table/blob/master/docs/articles/2026-08-15_notes_ai-nanook-playwright.md A refinement rule on line items that rejects reversed date ranges (e.g., service period ending before it starts). The comment translates to "from the 20th to the 5th is not a time period". This is the single place that checks reversed date ranges across four modules. ```ts // „vom 20. bis zum 5. ``` -------------------------------- ### Get generator switches with createGeneratorSwitches() Source: https://github.com/xhubio/nanook-table/blob/master/docs/api/model.md Calls createGeneratorSwitches() to get a list of generator names that should be skipped for this test case. The comment shows an example result where 'generatorPassword' is switched off. ```typescript const switches = testcase.createGeneratorSwitches() // ['generatorPassword'] -- this generator will be skipped ``` -------------------------------- ### Initialize the project with npm Source: https://github.com/xhubio/nanook-table/blob/master/docs/tutorials/setup-data-generation.md Initializes a new TypeScript project for the data generation tutorial. Creates the required directory structure and installs nanook-table along with TypeScript and Node type definitions. ```bash mkdir demo-tdg cd demo-tdg mkdir resources mkdir tdg mkdir src npm init -y npm install nanook-table npm install -D typescript @types/node ``` -------------------------------- ### Custom writer example Source: https://github.com/xhubio/nanook-table/blob/master/docs/api/processor.md Example of a custom writer that extends InterfaceWriter. It logs the start and end of test data and prints each test case's name and data as JSON. ```typescript import { InterfaceWriter } from 'nanook-table' import type { TestcaseData } from 'nanook-table' class ConsoleWriter extends InterfaceWriter { async before(): Promise { console.log('--- Start of test data ---') } async write(testcaseData: TestcaseData): Promise { const name = testcaseData.name console.log(`Test case: ${name}`) console.log(JSON.stringify(testcaseData.data, null, 2)) } async after(): Promise { console.log('--- End of test data ---') } } ``` -------------------------------- ### Minimal TestcaseProcessor pipeline setup Source: https://github.com/xhubio/nanook-table/blob/master/docs/guide/overview.md Sets up a FileProcessor with XLSX importer and parsers for decision, matrix, and specification tables, loads spreadsheet files, registers a Faker data generator, and runs the TestcaseProcessor with a custom writer. ```typescript import { FileProcessor, ImporterXlsx, ParserDecision, ParserMatrix, ParserSpecification, TestcaseProcessor, DataGeneratorRegistry, GeneratorFaker } from 'nanook-table' // 1. Set up the file processor with importer and parsers const fileProcessor = new FileProcessor() fileProcessor.registerImporter('xlsx', new ImporterXlsx()) fileProcessor.registerParser('', new ParserDecision()) fileProcessor.registerParser('', new ParserMatrix()) fileProcessor.registerParser('', new ParserSpecification()) // 2. Load spreadsheet files await fileProcessor.load(['tests.xlsx', 'more-tests.xlsx']) // 3. Set up the data generator registry const registry = new DataGeneratorRegistry() registry.registerGenerator('faker', new GeneratorFaker()) // 4. Set up the processor with generators and writers const processor = new TestcaseProcessor({ tables: {}, generatorRegistry: registry, writer: [myWriter] }) // 5. Add tables and run processor.addTables(fileProcessor.tables) await processor.process() ``` -------------------------------- ### StaticDirective value examples Source: https://github.com/xhubio/nanook-table/blob/master/docs/guide/directives.md Shows static values that are copied as-is into the test case data object. Values not starting with 'gen:' or 'ref:' are treated as static. ```text hello@example.com <- Static email value 42 <- Static number (as string) true <- Static boolean (as string) some arbitrary text <- Any text ``` -------------------------------- ### Get tags with createTags() Source: https://github.com/xhubio/nanook-table/blob/master/docs/api/model.md Calls createTags() to retrieve the test case's tags, which come from TagSection rows and are used for filtering. The comment shows an example result array. ```typescript const tags = testcase.createTags() // ['smoke', 'regression', 'login'] ``` -------------------------------- ### Run project commands (build, test, lint, format, typecheck, single test) Source: https://github.com/xhubio/nanook-table/blob/master/CLAUDE.md Quick reference for common development commands in the nanook-table project. Use `npm run build` to compile with tsc, `npm test` to run the full pipeline (format, lint, build, and vitest with coverage), and `npx vitest run` to execute a single test file. ```bash npm run build # tsc -p tsconfig.build.json npm test # format + lint + build + vitest with coverage npm run lint # eslint only npm run format # prettier only npm run typecheck # tsc --noEmit npx vitest run tests/path/to/file.test.ts # single test ``` -------------------------------- ### SimpleArrayFilterProcessor usage example Source: https://github.com/xhubio/nanook-table/blob/master/docs/api/processor.md Example usage of SimpleArrayFilterProcessor. Creates an include filter with delimiter ',' and demonstrates matching and non-matching cases with expected boolean returns. ```typescript import { SimpleArrayFilterProcessor } from 'nanook-table' const filter = new SimpleArrayFilterProcessor('include', ',') // Expression "smoke,regression" matches test case with tag "smoke" filter.filter(['smoke', 'login'], 'smoke,regression') // Returns: true // No match filter.filter(['payment'], 'smoke,regression') // Returns: false ``` -------------------------------- ### Initialize and Run TestcaseProcessor Source: https://github.com/xhubio/nanook-table/blob/master/docs/guide/overview.md Creates a TestcaseProcessor with an empty tables object, a generator registry, and a writer array, then adds the tables from the FileProcessor and processes them. The processor drives the entire generation pipeline. ```typescript import { TestcaseProcessor, DataGeneratorRegistry } from 'nanook-table' const processor = new TestcaseProcessor({ tables: {}, generatorRegistry: registry, writer: [myWriter] }) processor.addTables(fileProcessor.tables) await processor.process() ``` -------------------------------- ### Development commands for nanook-table Source: https://github.com/xhubio/nanook-table/blob/master/README.md Run these commands in the project root to install dependencies, compile TypeScript, run tests with vitest, lint with eslint, format with prettier, and type-check without emitting. ```bash npm install # install dependencies npm run build # compile TypeScript npm test # run tests (vitest) npm run lint # run eslint npm run format # run prettier npm run typecheck # type-check without emitting ``` -------------------------------- ### Get a generator by name Source: https://github.com/xhubio/nanook-table/blob/master/docs/api/data-generator.md Retrieves a generator by name. Throws an error if no generator with that name exists. ```typescript const faker = registry.getGenerator('GeneratorFaker') ```