{"id":18578429,"url":"https://github.com/auroratide/zaha","last_synced_at":"2025-08-12T16:07:05.410Z","repository":{"id":57405121,"uuid":"126747863","full_name":"Auroratide/zaha","owner":"Auroratide","description":"Library for building test builders","archived":false,"fork":false,"pushed_at":"2018-11-20T14:40:50.000Z","size":21,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-07-08T07:53:17.222Z","etag":null,"topics":["builders","javascript","testing","utility"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Auroratide.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-03-25T23:02:22.000Z","updated_at":"2018-11-20T14:40:52.000Z","dependencies_parsed_at":"2022-09-16T08:40:34.426Z","dependency_job_id":null,"html_url":"https://github.com/Auroratide/zaha","commit_stats":null,"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/Auroratide/zaha","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Auroratide%2Fzaha","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Auroratide%2Fzaha/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Auroratide%2Fzaha/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Auroratide%2Fzaha/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Auroratide","download_url":"https://codeload.github.com/Auroratide/zaha/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Auroratide%2Fzaha/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":270091686,"owners_count":24525249,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-12T02:00:09.011Z","response_time":80,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["builders","javascript","testing","utility"],"created_at":"2024-11-06T23:35:26.976Z","updated_at":"2025-08-12T16:07:05.361Z","avatar_url":"https://github.com/Auroratide.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Zaha\n\n**Zaha** is a javascript utility for generating test builders!  Builders allow you to:\n\n1. Quickly create test objects automatically populated with default fields\n1. Abstract the structure of complex objects behind a fluent interface\n\n## Get Started\n\nFirst, you'll want to install the library:\n\n```\nnpm i -D zaha\n```\n\nThen create a test builder:\n\n```js\n// room-builder.js\n\nimport zaha, { is } from 'zaha';\n\nexport default zaha({\n  length: is.number(),\n  width: is.number(),\n  furniture: is.arrayOf(is.string())\n});\n```\n\nThen use your new builder in a test!\n\n```js\n// room.spec.js\n\nimport RoomBuilder from './room-builder';\n\nconst room = new RoomBuilder()\n  .withWidth(500),\n  .withFurniture(['chair', 'bed'])\n  .build();\n```\n\n## Details\n\n**Zaha** is a function which takes as input a *schema* and outputs a *builder class*.\n\n### Schemas\n\nA *schema* is an object whose fields are all *builders*.  It defines what fields you want your eventually build object to contain.  The following example of a schema defines an object with a string and numeric field, for instance.\n\n```js\nimport { is } from 'zaha';\n\nconst schema = {\n  name: is.string(),\n  age: is.number()\n};\n```\n\n**is**\n\nYou might notice that this mystical `is` object can be used to define the types of fields.  `is` provides the following:\n\n* `is(value)`: An exact value the field should be when the final object is built\n* `is.string()`: A string field\n* `is.datestring()`: A string which represents a date\n* `is.number()`: A decimal number\n* `is.int()`: An integer number\n* `is.boolean()`: A boolean value\n* `is.object(schema)`: Converts the schema into a basic builder; useful for nested structures\n* `is.array()`: Defines an array of any type\n* `is.arrayOf(builder)`: Defines an array of the provided builder type\n* `is.function()`: A callable function\n* `is.oneOf(values)`: Value must be exactly one of the provided values; values is an array\n\nThe following example shows how to use `is.object` and `is.arrayOf`:\n\n```js\nconst schema = {\n  nested: is.object({\n    array: is.arrayOf(is.int()),\n    exact: is('This particular string')\n  })\n};\n```\n\n**Zaha Builders**\n\nThough `is` is useful, in reality these fields can take any *builder*.  A *builder* object is simply an object which has the `build()` method defined on it.  This means you can pass in builders created by **Zaha** into the schema:\n\n```js\nconst InnerBuilder = zaha(innerSchema);\n\nconst schema = {\n  value: new InnerBuilder()\n};\n```\n\n**Custom Builders**\n\nA *builder* is any object which has `build()` defined on it.  This means you can make your own collection of domain-specific basic builders that you can pass to a **Zaha** schema.\n\n```js\nconst randomString = {\n  build: () =\u003e random.string()\n};\n\nconst author = is.object({\n  name: randomString,\n  age: is.number()\n});\n\nconst schema = { author };\n```\n\n### Builders\n\nThe purpose of **Zaha** is to create configurable builders.  The `zaha` function converts a schema into a builder class that can be instantiated, like so:\n\n```js\nconst Builder = zaha(schema);\nconst builder = new Builder();\n```\n\nBuilders define two function types:\n\n* `with\u003cPropertyName\u003e(value)`: Sets the value of the given property to the given argument\n* `build()`: Emits an object with the values provided by `with`\n\nA `with` function is generated for each first-order property defined in the schema.  You can chain them like so:\n\n```js\nconst room = new RoomBuilder()\n  .withWidth(100)\n  .withLength(200)\n  .build();\n```\n\n**Note on property names**\n\n* Snake-cased property names, like `last_name`, will end up with a `with` function like `withLast_name`\n* Property names which contain arbitrary symbols, like `is-admin?`, are not supported\n\n### Extending Builders\n\n**Zaha** emits a class which can be extended.  If you want to define custom methods on the builder, it's simple to do:\n\n```js\nconst Base = zaha({\n  furniture: is.arrayOf(is.string())\n});\n\nexport default class RoomBuilder extends Base {\n  withoutFurniture() {\n    this.schema.furniture = is([]);\n    return this;\n  }\n}\n```\n\n## Example\n\nHere is a full use-case example.  Chai is being used here, but any testing framework works with **Zaha**.\n\n```js\n// room-builder.js\nimport zaha, { is } from 'zaha';\n\nexport default zaha({\n  length: is.number(),\n  width: is.number(),\n  furniture: is.arrayOf(is.string())\n});\n```\n\n```js\nimport { expect } from 'chai';\nimport RoomBuilder from './room-builder';\nimport { moveAllFurniture } from './room-utils';\n\ndescribe('Furniture Mover', () =\u003e {\n  it('moves all furniture from one room into the other', () =\u003e {\n    const furniture = ['chair', 'table'];\n    const formerRoom = new RoomBuilder()\n      .withFurniture(furniture)\n      .build();\n    const newRoom = new RoomBuilder()\n      .withFurniture([])\n      .build();\n\n    moveAllFurniture.from(formerRoom).to(newRoom);\n\n    expect(formerRoom.furniture).to.be.empty;\n    expect(newRoom.furniture).to.deep.equal(furniture);\n  });\n});\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fauroratide%2Fzaha","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fauroratide%2Fzaha","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fauroratide%2Fzaha/lists"}