Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/auroratide/zaha
Library for building test builders
https://github.com/auroratide/zaha
builders javascript testing utility
Last synced: about 12 hours ago
JSON representation
Library for building test builders
- Host: GitHub
- URL: https://github.com/auroratide/zaha
- Owner: Auroratide
- License: mit
- Created: 2018-03-25T23:02:22.000Z (over 6 years ago)
- Default Branch: master
- Last Pushed: 2018-11-20T14:40:50.000Z (almost 6 years ago)
- Last Synced: 2024-03-23T18:45:27.831Z (8 months ago)
- Topics: builders, javascript, testing, utility
- Language: JavaScript
- Homepage:
- Size: 20.5 KB
- Stars: 0
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
# Zaha
**Zaha** is a javascript utility for generating test builders! Builders allow you to:
1. Quickly create test objects automatically populated with default fields
1. Abstract the structure of complex objects behind a fluent interface## Get Started
First, you'll want to install the library:
```
npm i -D zaha
```Then create a test builder:
```js
// room-builder.jsimport zaha, { is } from 'zaha';
export default zaha({
length: is.number(),
width: is.number(),
furniture: is.arrayOf(is.string())
});
```Then use your new builder in a test!
```js
// room.spec.jsimport RoomBuilder from './room-builder';
const room = new RoomBuilder()
.withWidth(500),
.withFurniture(['chair', 'bed'])
.build();
```## Details
**Zaha** is a function which takes as input a *schema* and outputs a *builder class*.
### Schemas
A *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.
```js
import { is } from 'zaha';const schema = {
name: is.string(),
age: is.number()
};
```**is**
You might notice that this mystical `is` object can be used to define the types of fields. `is` provides the following:
* `is(value)`: An exact value the field should be when the final object is built
* `is.string()`: A string field
* `is.datestring()`: A string which represents a date
* `is.number()`: A decimal number
* `is.int()`: An integer number
* `is.boolean()`: A boolean value
* `is.object(schema)`: Converts the schema into a basic builder; useful for nested structures
* `is.array()`: Defines an array of any type
* `is.arrayOf(builder)`: Defines an array of the provided builder type
* `is.function()`: A callable function
* `is.oneOf(values)`: Value must be exactly one of the provided values; values is an arrayThe following example shows how to use `is.object` and `is.arrayOf`:
```js
const schema = {
nested: is.object({
array: is.arrayOf(is.int()),
exact: is('This particular string')
})
};
```**Zaha Builders**
Though `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:
```js
const InnerBuilder = zaha(innerSchema);const schema = {
value: new InnerBuilder()
};
```**Custom Builders**
A *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.
```js
const randomString = {
build: () => random.string()
};const author = is.object({
name: randomString,
age: is.number()
});const schema = { author };
```### Builders
The purpose of **Zaha** is to create configurable builders. The `zaha` function converts a schema into a builder class that can be instantiated, like so:
```js
const Builder = zaha(schema);
const builder = new Builder();
```Builders define two function types:
* `with(value)`: Sets the value of the given property to the given argument
* `build()`: Emits an object with the values provided by `with`A `with` function is generated for each first-order property defined in the schema. You can chain them like so:
```js
const room = new RoomBuilder()
.withWidth(100)
.withLength(200)
.build();
```**Note on property names**
* Snake-cased property names, like `last_name`, will end up with a `with` function like `withLast_name`
* Property names which contain arbitrary symbols, like `is-admin?`, are not supported### Extending Builders
**Zaha** emits a class which can be extended. If you want to define custom methods on the builder, it's simple to do:
```js
const Base = zaha({
furniture: is.arrayOf(is.string())
});export default class RoomBuilder extends Base {
withoutFurniture() {
this.schema.furniture = is([]);
return this;
}
}
```## Example
Here is a full use-case example. Chai is being used here, but any testing framework works with **Zaha**.
```js
// room-builder.js
import zaha, { is } from 'zaha';export default zaha({
length: is.number(),
width: is.number(),
furniture: is.arrayOf(is.string())
});
``````js
import { expect } from 'chai';
import RoomBuilder from './room-builder';
import { moveAllFurniture } from './room-utils';describe('Furniture Mover', () => {
it('moves all furniture from one room into the other', () => {
const furniture = ['chair', 'table'];
const formerRoom = new RoomBuilder()
.withFurniture(furniture)
.build();
const newRoom = new RoomBuilder()
.withFurniture([])
.build();moveAllFurniture.from(formerRoom).to(newRoom);
expect(formerRoom.furniture).to.be.empty;
expect(newRoom.furniture).to.deep.equal(furniture);
});
});
```