Nanoseconds Produce Minutes

    contract-decorators

    0.2.2 • Public • Published

    contract-decorators

    NPM

    Build Status Code Climate Test Coverage

    Class method decorators to ensure that class method is called with valid arguments (precondition) and/or returns expected result (postcondition).

    To get more information about preconditions and postconditions see Design by contract article on Wikipedia.

    ECMAScript decorators are currently in proposal state. Use babeljs to transpile them into executable code.

    Contents

    Installation

    Install it via npm:

    $ npm install --save contract-decorators
    

    Usage

    const contract = require('contract-decorators');
    const { precondition, postcondition } = contract;
    contract.enabled = true;
     
    const test = new class Test {
      @precondition(a => a < 9, b => b > 1)
      @postcondition(result => result % 2)
      method(a, b) {
        return a + b;
      }
    }
     
    test.method(1, 2);
    // 3
    test.method(9, 0);
    // Uncaught PreconditionError: Precondition failed. Argument #0 of method "method" must satisfy predicate "a => a < 9" but it does not: 9.
    test.method(0, 0);
    // Uncaught PreconditionError: Precondition failed. Argument #1 of method "method" must satisfy predicate "b => b > 1" but it does not: 0.
    test.method(2, 4);
    // Uncaught PostconditionError: Postcondition failed. Result of method "method" must satisfy predicate "result => result % 2" but it does not: 6.
     
    contract.enabled = false;
     
    test.method(9, 0);
    // 9
    test.method(0, 0);
    // 0
    test.method(2, 4);
    // 6

    Customization

    Custom errors

    class CustomPreconditionError extends Error {
      constructor(method, predicate, argument, index) {
        super(`Some friendly message containing name of ${method} that is called with contract violation, value of ${argument} causing the violation, its ${index} and name of ${predicate} that proves it`);
      }
    }
     
    contract.PreconditionError = CustomPreconditionError;
     
    class CustomPostconditionError extends Error {
      constructor(method, predicate, result) {
        super(`Some friendly message containing name of ${method} that returns ${result} causing contract violation and name of ${predicate} that proves it.`);
      }
    }
     
    contract.PostconditionError = CustomPostconditionError;

    Custom method/predicate name resolvers

    const customNameResolver = func => func.name;
     
    contract.methodNameResolver = customNameResolver;
    contract.predicateNameResolver = customNameResolver;

    Decorated method is always wrapped into function with the same name that method has with Contract suffix (${method.name}Contract). To avoid multiple Contract suffixes, original name of the method is stored as .originalName property of wrapper function.

    By default the following algorithms are used for method and predicate name resolution:

    • method.originalName || method.name
    • predicate.name || predicate.toString()

    Configuration

    For performance reasons contract decorators are enabled by default in development environment only (process.env === 'development'). To enable them in other environments use:

    contract.enabled = true;

    If contract decorators are disabled at the moment of decorator application, no decoration occurs and succeeding enabling won't have any effect. This behavior is intended to gain maximal performance in production.

    contract.enabled = false;
     
    const test = new class WillNotBeDecorated {
      @precondition(() => false)
      method() {
        return 'ok';
      }
    }
     
    contract.enabled = true;
     
    test.method();
    // ok

    Configuration and customization of contract decorators can be performed with one call:

    contract.configure({
      enabled: true,
      methodNameResolver: customNameResolver,
      PreconditionError: CustomPreconditionError,
      PostconditionError: CustomPostconditionError,
      predicateNameResolver: customNameResolver
    });

    License

    MIT

    Install

    npm i contract-decorators

    DownloadsWeekly Downloads

    2

    Version

    0.2.2

    License

    MIT

    Last publish

    Collaborators

    • vladen