Code Monkey home page Code Monkey logo

givens's Introduction

givens

npm GitHub Workflow Status GitHub Workflow Status MIT License

Easy test setup without side effects.

For use with jest, mocha, and jasmine. Behavior based on rspec, syntax inspired by given2


Why?

If you or your team have ruby and rspec experience, and are moving to a javascript based library, this will make the experience of writing javascript tests very similar to that of writing rspec tests.

Even if you don't come from a ruby background, givens can help you write maintainable tests quickly, while avoiding many of the side effects traditional JavaScript testing often has, such as:

  • testing different methods on the same object in multiple tests can result in cross-contamination.
  • tests can depend on order; and break when reordered.
  • Running only some tests in a single file (like via jest’s .skip or .only) can make tests behave unpredictably.

Givens, when used correctly solves all of these, dries up your tests, and might even make them more readable, while still letting you use beforeEach and afterEach.


What does it do?

when you call getGiven(), givens calls afterEach with a callback that clears the cache. Because this afterEach hook is declared first, it will run after every other afterEach in every scope.

when you call given(key, callback), givens calls the following lifecycle functions:

  • beforeAll, with a hook which pushes callback onto a stack of functions for key and makes sure there is an accessor present for key, which simply calls the topmost function on the stack and returns the result.
  • afterAll, with a hook which pops callback back off the stack of functions for key, and deletes the accessor if the stack is now empty.

Getting Started

Prerequisites

This package should work fine for any javascript or typescript project that uses jest or mocha tests. Non Node environments are untested, and may not work.

Installing

first, install from npm:

npm install --save-dev givens

or

yarn add --dev givens

global installation

import 'givens/setup';

or add to testing framework config, for example in jest:

{
  setupFilesAfterEnv: [ // this CANNOT be setupFiles
    'givens/setup.js',
  ],
}

then you can use the given keyword without importing.

local installation

in the test file, use the following import:

import getGiven from 'givens';
const given = getGiven();

or in typescript

import getGiven from 'givens';
interface myVars {
  var1: number; // the keys you intend to use
  var2: string; // and their types
}
const given = getGiven<myVars>();

Usage

When you call given(myKey, callback), givens stores the callback function you give it. When you go to retrieve the key (via given.myKey) givens will execute the most recent callback you have given for the key, and cache the value. Additionally, if you call given() inside a describe, the callback will revert to the previous one given for myKey after executing all tests in the describe, allowing you to override a given value for a set of tests. The cache is cleared after every test.

describe('basic overriding behavior', () => {
  given('var1', () => 'initial value');
  given('var2', () => {
    return 'the value is: ' + given.var1;
  });

  it('has initial value', () => {
    expect(given.var2).toEqual('the value is: initial value');
  });

  describe('with new value', () => {
    given('var1', () => 'overridden value');

    it('has overridden value', () => {
      expect(given.var2).toEqual('the value is: overridden value');
    });
  });

  it('has initial value again', () => {
    expect(given.var2).toEqual('the value is: initial value');
  });
});

For more examples of usage for your particular setup, read through the integration tests. They are examples of how to use the library as intended (and in some cases how it's not supposed to be used).

givens's People

Contributors

dependabot[bot] avatar maboesanman avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

Forkers

maboesanman

givens's Issues

[Security] Workflow CI.yml is using vulnerable action actions/checkout

The workflow CI.yml is referencing action actions/checkout using references v1. However this reference is missing the commit a6747255bd19d7a757dbdda8c654a9f84db19839 which may contain fix to the some vulnerability.
The vulnerability fix that is missing by actions version could be related to:
(1) CVE fix
(2) upgrade of vulnerable dependency
(3) fix to secret leak and others.
Please consider to update the reference to the action.

report coverage for jest tests

report coverage to codecov for both unit and jest integration tests

This was not already done because jest does not play nice with nyc or with covering node_modules

Allow givens to take async functions and resolve correctly

The following currently gives typescript compile errors

  given("var", async () => {
    const var = await doWorkToGetVar();
    return var;
  });

Error:

 Argument of type '() => Promise<string>' is not assignable to parameter of type '() => string'

Is it possible for givens to asynchronously instantiate the lazy declarations?

Error: givens: given must be called inside a describe in

Hello, I'm working on an angular project that is using jasmine through karma,
when i try to use givens i get the error in the title.
by changing the regex that are used to evaluate the context to: /(jasmine\\.js|jasmine\/lib\/loader\.js)/ and /Env\.describe|Env\/this.describe/ respectively the test seems to work.

getContextInfo@http://localhost:9876/_karma_webpack_/vendor.js:137425:21
given@http://localhost:9876/_karma_webpack_/vendor.js:137493:46
88403/</<@http://localhost:9876/_karma_webpack_/main.js:8172:14
32600/</ZoneDelegate.prototype.invoke@http://localhost:9876/_karma_webpack_/polyfills.js:414:30
32600/</Zone.prototype.run@http://localhost:9876/_karma_webpack_/polyfills.js:174:47
wrapDescribeInZone/<@http://localhost:9876/_karma_webpack_/vendor.js:169990:33
addSpecsToSuite@http://localhost:9876/absolute/Users/vjustov/some-project/node_modules/karma-jasmine/node_modules/jasmine-core/lib/jasmine-core/jasmine.js?b9e399d056ab3608dfb7a9a60a397876081d58cd:1991:25
Env/this.describe@http://localhost:9876/absolute/Users/vjustov/some-project/node_modules/karma-jasmine/node_modules/jasmine-core/lib/jasmine-core/jasmine.js?b9e399d056ab3608dfb7a9a60a397876081d58cd:1956:22
58991/</</</jasmineEnv[methodName]@http://localhost:9876/_karma_webpack_/vendor.js:169895:42
describe@http://localhost:9876/absolute/Users/vjustov/some-project/node_modules/karma-jasmine/node_modules/jasmine-core/lib/jasmine-core/jasmine.js?b9e399d056ab3608dfb7a9a60a397876081d58cd:7727:18
88403/<@http://localhost:9876/_karma_webpack_/main.js:8170:13
32600/</ZoneDelegate.prototype.invoke@http://localhost:9876/_karma_webpack_/polyfills.js:414:30
32600/</Zone.prototype.run@http://localhost:9876/_karma_webpack_/polyfills.js:174:47
wrapDescribeInZone/<@http://localhost:9876/_karma_webpack_/vendor.js:169990:33
addSpecsToSuite@http://localhost:9876/absolute/Users/vjustov/some-project/node_modules/karma-jasmine/node_modules/jasmine-core/lib/jasmine-core/jasmine.js?b9e399d056ab3608dfb7a9a60a397876081d58cd:1991:25
Env/this.fdescribe@http://localhost:9876/absolute/Users/vjustov/some-project/node_modules/karma-jasmine/node_modules/jasmine-core/lib/jasmine-core/jasmine.js?b9e399d056ab3608dfb7a9a60a397876081d58cd:1979:22
58991/</</</jasmineEnv[methodName]@http://localhost:9876/_karma_webpack_/vendor.js:169895:42
fdescribe@http://localhost:9876/absolute/Users/vjustov/some-project/node_modules/karma-jasmine/node_modules/jasmine-core/lib/jasmine-core/jasmine.js?b9e399d056ab3608dfb7a9a60a397876081d58cd:7758:18
88403@http://localhost:9876/_karma_webpack_/main.js:8169:10
__webpack_require__@http://localhost:9876/_karma_webpack_/main.js:16424:42
webpackContext@http://localhost:9876/_karma_webpack_/main.js:16363:9
74097@http://localhost:9876/_karma_webpack_/main.js:10434:16
__webpack_require__@http://localhost:9876/_karma_webpack_/main.js:16424:42
__webpack_exports__<@http://localhost:9876/_karma_webpack_/main.js:16745:102
__webpack_require__.O@http://localhost:9876/_karma_webpack_/main.js:16463:23
@http://localhost:9876/_karma_webpack_/main.js:16746:53
@http://localhost:9876/_karma_webpack_/main.js:16748:12

I am trying to provide a greenfield sandbox to replicate the bug, but so far haven't been able

streamline makefile

makefile does a lot of duplicate building, making the install step take a very long time.
part of this fix potentially requires a newer version of make to be installed on the actions ci server.

Support forced evaluations like `let!`

This library is analogous to let in rspec, but there isn't an equivalent for let!. We are using it for cypress tests and we almost always want to eagerly evaluate our given variables (because they correspond to API calls we want to resolve before the test starts), so it would be really nice if there was a shorthand for this eager evaluation. Currently our tests looks something like

given('a', () => createSomething());
given('b', () => createSomethingElse());

beforeEach(() => {
  given.a;
  given.b;
});

it('works', () => { /* */ });

But if this library supported that behavior we could remove the beforeEach. There are a few APIs I have thought might work but I'm open to other suggestions:

// lots of different naming options here - now / eager / bang / other ideas?
given.now('a', () => createSomething());

// this one is a bit more complex to implement but I think it can be made to work with template literal types
// https://www.typescriptlang.org/docs/handbook/2/template-literal-types.html
given('!a', () => => createSomething());
// or to make it look less like a boolean operator
given('a!', () => => createSomething());

I think this is relatively easy to implement by adding a __lazy__ property to the given object (pretty much identical to the __props__ property), and pushing in true or false based on how this function is called. Then you can add a beforeEach that checks the top of the list to decide if it should access given[key]. I'm happy to submit a PR if we can agree on an API.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.