Skip to content

roobie/cc.js

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

cc.js

Code contracts for JavaScript

Example

  function isNumeric (n) {
    return !isNaN(parseFloat(n)) && isFinite(n)
  }

  const checkedDivision = cc()
          // Check that both arguments are numeric
          .pre((num, denom) => isNumeric(num) && isNumeric(denom))
          // Check that none of the arguments are a zero
          .pre((num, denom) => num !== 0 && denom !== 0)
          // Check that the result is numeric
          .post((result) => isNumeric(result))
          // Check that the result is not a zero
          .post((result) => result !== 0)
          // We can access the arguments in a post condition as well
          .post((result, [num, denom]) => {
            return (num === denom && result === num) ||
              result !== num && result !== denom
          })
          // guaranteed to not throw when invoking the function
          // AssertionError's will still be thrown if any pre/post
          // condition is not satisfied.
          .nothrow()
          // purely informational (i.e. not checked by the library)
          .pure()
          // actual implementation
          .seal(function div (num, denom) {
            return num / denom
          })

  t.throws(() => checkedDivision(1, 0), assert.AssertionError)
  t.throws(() => checkedDivision('asd', 1), assert.AssertionError)
  t.doesNotThrow(() => checkedDivision(1, 1))
  t.equals(checkedDivision(1, 1), 1)
  t.equals(checkedDivision(10, 2), 5)
  t.equals(checkedDivision(1, 2), 0.5)
  t.equals(checkedDivision(1, 0.5), 2)
  t.equals(checkedDivision(1, -0.5), -2)
  t.equals(checkedDivision(-1, -0.5), 2)

Runtime information:

It is possible to access the configuration for an instance of cc via the getContractInfo method:

const doubleEven = cc()
  .pure()
  .nothrow()
  .pre((n) => n % 2 === 0)
  .post((r, [n]) => r > n)
  .seal((n) => n * 2)
  
doubleEven.getContractInfo()
/* =>
{ pure: true,
  nothrow: true,
  throws: [ 'AssertionError' ],
  pre: [ '(n) => n % 2 === 0' ],
  post: [ '(r, [n]) => r > n' ] }
*/