Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

merging

  • Loading branch information...
commit 882dd289e799dd4b8ed414b22bd35116e416dbd3 2 parents 8a23ca2 + 0877d82
@Raynos authored
Showing with 414 additions and 263 deletions.
  1. +74 −67 docs/contract.html
  2. +1 −1  package.json
  3. +87 −70 src/contract.js
  4. +252 −125 test/contract-test.js
View
141 docs/contract.html
@@ -1,75 +1,82 @@
-<!DOCTYPE html> <html> <head> <title>contract.js</title> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <link rel="stylesheet" media="all" href="docco.css" /> </head> <body> <div id="container"> <div id="background"></div> <table cellpadding="0" cellspacing="0"> <thead> <tr> <th class="docs"> <h1> contract.js </h1> </th> <th class="code"> </th> </tr> </thead> <tbody> <tr id="section-1"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-1">&#182;</a> </div> <h1><a href="https://github.com/Raynos/contract">Github Repo</a></h1>
-
-<p>The contract object.</p> </td> <td class="code"> <div class="highlight"><pre><span class="kd">var</span> <span class="nx">Contract</span> <span class="o">=</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-2"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-2">&#182;</a> </div> <p>A method that generates a function which will wrap the function and
-call the pre condition with (arg1, arg2, ...)</p> </td> <td class="code"> <div class="highlight"><pre> <span class="s2">&quot;_constructPre&quot;</span><span class="o">:</span> <span class="kd">function</span> <span class="nx">_constructPre</span><span class="p">(</span><span class="nx">f</span><span class="p">,</span> <span class="nx">pre</span><span class="p">)</span> <span class="p">{</span>
- <span class="k">return</span> <span class="kd">function</span> <span class="nx">_wrapped</span><span class="p">()</span> <span class="p">{</span>
- <span class="nx">pre</span><span class="p">.</span><span class="nx">apply</span><span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="nx">arguments</span><span class="p">);</span>
- <span class="k">return</span> <span class="nx">f</span><span class="p">.</span><span class="nx">apply</span><span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="nx">arguments</span><span class="p">);</span>
- <span class="p">};</span>
- <span class="p">},</span></pre></div> </td> </tr> <tr id="section-3"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-3">&#182;</a> </div> <p>handle multiple APIs. Pass the function &amp; pre conditions into constructPre</p> </td> <td class="code"> <div class="highlight"><pre> <span class="s2">&quot;pre&quot;</span><span class="o">:</span> <span class="kd">function</span> <span class="nx">_pre</span><span class="p">(</span><span class="nx">pre</span><span class="p">,</span> <span class="nx">f</span><span class="p">)</span> <span class="p">{</span>
- <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">_handleMultipleAPIs</span><span class="p">(</span><span class="nx">f</span><span class="p">,</span> <span class="nx">pre</span><span class="p">,</span> <span class="s2">&quot;_constructPre&quot;</span><span class="p">);</span>
- <span class="p">},</span></pre></div> </td> </tr> <tr id="section-4"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-4">&#182;</a> </div> <p>A method that generates a function which will wrap the function and
-call the post condition with (ret, arg1, arg2, ...)</p> </td> <td class="code"> <div class="highlight"><pre> <span class="s2">&quot;_constructPost&quot;</span><span class="o">:</span> <span class="kd">function</span> <span class="nx">_constructPost</span><span class="p">(</span><span class="nx">f</span><span class="p">,</span> <span class="nx">post</span><span class="p">)</span> <span class="p">{</span>
- <span class="k">return</span> <span class="kd">function</span> <span class="nx">_wrapped</span><span class="p">()</span> <span class="p">{</span>
- <span class="kd">var</span> <span class="nx">arr</span> <span class="o">=</span> <span class="p">[</span><span class="nx">f</span><span class="p">.</span><span class="nx">apply</span><span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="nx">arguments</span><span class="p">)];</span>
- <span class="nx">post</span><span class="p">.</span><span class="nx">apply</span><span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="nx">arr</span><span class="p">.</span><span class="nx">concat</span><span class="p">.</span><span class="nx">apply</span><span class="p">(</span><span class="nx">arr</span><span class="p">,</span> <span class="nx">arguments</span><span class="p">));</span>
- <span class="k">return</span> <span class="nx">arr</span><span class="p">[</span><span class="mi">0</span><span class="p">];</span>
- <span class="p">}</span>
- <span class="p">},</span></pre></div> </td> </tr> <tr id="section-5"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-5">&#182;</a> </div> <p>Handle multiple APIs. Either this was wrapped <code>construct(f).pre(pre)</code> or
+<!DOCTYPE html> <html> <head> <title>contract.js</title> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <link rel="stylesheet" media="all" href="docco.css" /> </head> <body> <div id="container"> <div id="background"></div> <table cellpadding="0" cellspacing="0"> <thead> <tr> <th class="docs"> <h1> contract.js </h1> </th> <th class="code"> </th> </tr> </thead> <tbody> <tr id="section-1"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-1">&#182;</a> </div> <h1><a href="https://github.com/Raynos/contract">Github Repo</a></h1> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-2"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-2">&#182;</a> </div> <p>A method that generates a function which will wrap the function <code>f</code> and
+call the pre condition with (arg1, arg2, ...)</p> </td> <td class="code"> <div class="highlight"><pre><span class="kd">var</span> <span class="nx">constructPre</span> <span class="o">=</span> <span class="kd">function</span> <span class="nx">_constructPre</span><span class="p">(</span><span class="nx">f</span><span class="p">,</span> <span class="nx">pre</span><span class="p">)</span> <span class="p">{</span>
+ <span class="k">return</span> <span class="kd">function</span> <span class="nx">_wrapped</span><span class="p">()</span> <span class="p">{</span>
+ <span class="nx">pre</span><span class="p">.</span><span class="nx">apply</span><span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="nx">arguments</span><span class="p">);</span>
+ <span class="k">return</span> <span class="nx">f</span><span class="p">.</span><span class="nx">apply</span><span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="nx">arguments</span><span class="p">);</span>
+ <span class="p">};</span>
+<span class="p">};</span></pre></div> </td> </tr> <tr id="section-3"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-3">&#182;</a> </div> <p>A method that generates a function which will wrap the function and
+call the post condition with (ret, arg1, arg2, ...)</p> </td> <td class="code"> <div class="highlight"><pre><span class="kd">var</span> <span class="nx">constructPost</span> <span class="o">=</span> <span class="kd">function</span> <span class="nx">_constructPost</span><span class="p">(</span><span class="nx">f</span><span class="p">,</span> <span class="nx">post</span><span class="p">)</span> <span class="p">{</span>
+ <span class="k">return</span> <span class="kd">function</span> <span class="nx">_wrapped</span><span class="p">()</span> <span class="p">{</span>
+ <span class="kd">var</span> <span class="nx">arr</span> <span class="o">=</span> <span class="p">[</span><span class="nx">f</span><span class="p">.</span><span class="nx">apply</span><span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="nx">arguments</span><span class="p">)];</span>
+ <span class="nx">post</span><span class="p">.</span><span class="nx">apply</span><span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="nx">arr</span><span class="p">.</span><span class="nx">concat</span><span class="p">.</span><span class="nx">apply</span><span class="p">(</span><span class="nx">arr</span><span class="p">,</span> <span class="nx">arguments</span><span class="p">));</span>
+ <span class="k">return</span> <span class="nx">arr</span><span class="p">[</span><span class="mi">0</span><span class="p">];</span>
+ <span class="p">};</span>
+<span class="p">};</span></pre></div> </td> </tr> <tr id="section-4"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-4">&#182;</a> </div> <p>A method that generates a function which will wrap the function <code>f</code> and
+call the invariant with (before, arg1, arg2, ...)</p> </td> <td class="code"> <div class="highlight"><pre><span class="kd">var</span> <span class="nx">constructInvariant</span> <span class="o">=</span> <span class="kd">function</span> <span class="nx">_constructInvariant</span><span class="p">(</span><span class="nx">f</span><span class="p">,</span> <span class="nx">invariant</span><span class="p">)</span> <span class="p">{</span>
+ <span class="k">return</span> <span class="kd">function</span> <span class="nx">_wrapped</span><span class="p">()</span> <span class="p">{</span>
+ <span class="kd">var</span> <span class="nx">before</span> <span class="o">=</span> <span class="nx">JSON</span><span class="p">.</span><span class="nx">parse</span><span class="p">(</span><span class="nx">JSON</span><span class="p">.</span><span class="nx">stringify</span><span class="p">(</span><span class="k">this</span><span class="p">));</span>
+ <span class="kd">var</span> <span class="nx">ret</span> <span class="o">=</span> <span class="nx">f</span><span class="p">.</span><span class="nx">apply</span><span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="nx">arguments</span><span class="p">);</span>
+ <span class="kd">var</span> <span class="nx">arr</span> <span class="o">=</span> <span class="p">[</span><span class="nx">before</span><span class="p">];</span>
+ <span class="nx">invariant</span><span class="p">.</span><span class="nx">apply</span><span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="nx">arr</span><span class="p">.</span><span class="nx">concat</span><span class="p">.</span><span class="nx">apply</span><span class="p">(</span><span class="nx">arr</span><span class="p">,</span> <span class="nx">arguments</span><span class="p">));</span>
+ <span class="k">return</span> <span class="nx">ret</span><span class="p">;</span>
+ <span class="p">};</span>
+<span class="p">}</span></pre></div> </td> </tr> <tr id="section-5"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-5">&#182;</a> </div> <p>Handle multiple APIs. Either this was wrapped <code>construct(f).pre(pre)</code> or
This was called from the function prototype <code>f.pre(pre)</code> or this was
-called from the Construct object <code>Construct.pre(pre, f)</code> </p> </td> <td class="code"> <div class="highlight"><pre> <span class="s2">&quot;_handleMultipleAPIs&quot;</span><span class="o">:</span> <span class="kd">function</span> <span class="nx">_handleMultipleAPIs</span><span class="p">(</span><span class="nx">f</span><span class="p">,</span> <span class="nx">obj</span><span class="p">,</span> <span class="nx">method</span><span class="p">)</span> <span class="p">{</span>
- <span class="k">if</span> <span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">_wrapped</span><span class="p">)</span> <span class="p">{</span>
- <span class="nx">f</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">_wrapped</span><span class="p">;</span>
- <span class="k">this</span><span class="p">.</span><span class="nx">_wrapped</span> <span class="o">=</span> <span class="k">this</span><span class="p">[</span><span class="nx">method</span><span class="p">](</span><span class="nx">f</span><span class="p">,</span> <span class="nx">obj</span><span class="p">);</span>
- <span class="k">return</span> <span class="k">this</span><span class="p">;</span>
- <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">arguments</span><span class="p">.</span><span class="nx">length</span> <span class="o">===</span> <span class="mi">1</span><span class="p">)</span> <span class="p">{</span>
- <span class="nx">f</span> <span class="o">=</span> <span class="k">this</span><span class="p">;</span>
- <span class="k">return</span> <span class="k">this</span><span class="p">[</span><span class="nx">method</span><span class="p">](</span><span class="nx">f</span><span class="p">,</span> <span class="nx">obj</span><span class="p">);</span>
- <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
- <span class="k">return</span> <span class="k">this</span><span class="p">[</span><span class="nx">method</span><span class="p">](</span><span class="nx">f</span><span class="p">,</span> <span class="nx">obj</span><span class="p">);</span>
- <span class="p">}</span>
- <span class="p">},</span></pre></div> </td> </tr> <tr id="section-6"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-6">&#182;</a> </div> <p>handle multiple APIs. Pass the function &amp; post condition into constructPost</p> </td> <td class="code"> <div class="highlight"><pre> <span class="s2">&quot;post&quot;</span><span class="o">:</span> <span class="kd">function</span> <span class="nx">_post</span><span class="p">(</span><span class="nx">post</span><span class="p">,</span> <span class="nx">f</span><span class="p">)</span> <span class="p">{</span>
- <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">_handleMultipleAPIs</span><span class="p">(</span><span class="nx">f</span><span class="p">,</span> <span class="nx">post</span><span class="p">,</span> <span class="s2">&quot;_constructPost&quot;</span><span class="p">);</span>
- <span class="p">},</span></pre></div> </td> </tr> <tr id="section-7"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-7">&#182;</a> </div> <p>un-implemented TODO</p> </td> <td class="code"> <div class="highlight"><pre> <span class="s2">&quot;invariant&quot;</span><span class="o">:</span> <span class="kd">function</span> <span class="nx">_invariant</span><span class="p">()</span> <span class="p">{</span>
-
- <span class="p">},</span></pre></div> </td> </tr> <tr id="section-8"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-8">&#182;</a> </div> <p>unwrap the Constructo object</p> </td> <td class="code"> <div class="highlight"><pre> <span class="s2">&quot;valueOf&quot;</span><span class="o">:</span> <span class="kd">function</span> <span class="nx">_valueOf</span><span class="p">()</span> <span class="p">{</span>
- <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">_wrapped</span><span class="p">;</span>
- <span class="p">}</span>
-<span class="p">};</span></pre></div> </td> </tr> <tr id="section-9"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-9">&#182;</a> </div> <p>defaults object. By default inject into Function.prototype</p> </td> <td class="code"> <div class="highlight"><pre><span class="kd">var</span> <span class="nx">defaults</span> <span class="o">=</span> <span class="p">{</span>
- <span class="nx">natives</span><span class="o">:</span> <span class="kc">true</span>
-<span class="p">};</span></pre></div> </td> </tr> <tr id="section-10"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-10">&#182;</a> </div> <p>ContractFactory generates a new Contract based on the passed function <code>f</code></p> </td> <td class="code"> <div class="highlight"><pre><span class="kd">var</span> <span class="nx">ContractFactory</span> <span class="o">=</span> <span class="kd">function</span> <span class="nx">_create</span><span class="p">(</span><span class="nx">f</span><span class="p">)</span> <span class="p">{</span>
- <span class="kd">var</span> <span class="nx">c</span> <span class="o">=</span> <span class="nb">Object</span><span class="p">.</span><span class="nx">create</span><span class="p">(</span><span class="nx">Contract</span><span class="p">);</span>
- <span class="nx">c</span><span class="p">.</span><span class="nx">_wrapped</span> <span class="o">=</span> <span class="nx">f</span><span class="p">;</span>
- <span class="k">return</span> <span class="nx">c</span><span class="p">;</span>
-<span class="p">}</span></pre></div> </td> </tr> <tr id="section-11"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-11">&#182;</a> </div> <p>contract = require("constract");
+called from the Construct object <code>Construct.pre(pre, f)</code> </p> </td> <td class="code"> <div class="highlight"><pre><span class="kd">var</span> <span class="nx">handleMultipleAPIs</span> <span class="o">=</span> <span class="kd">function</span> <span class="nx">_handleMultipleAPIs</span><span class="p">(</span><span class="nx">obj</span><span class="p">,</span> <span class="nx">method</span><span class="p">,</span> <span class="nx">f</span><span class="p">)</span> <span class="p">{</span>
+ <span class="k">if</span> <span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">_wrapped</span><span class="p">)</span> <span class="p">{</span>
+ <span class="nx">f</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">_wrapped</span><span class="p">;</span>
+ <span class="k">this</span><span class="p">.</span><span class="nx">_wrapped</span> <span class="o">=</span> <span class="nx">method</span><span class="p">(</span><span class="nx">f</span><span class="p">,</span> <span class="nx">obj</span><span class="p">);</span>
+ <span class="k">return</span> <span class="k">this</span><span class="p">;</span>
+ <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">f</span> <span class="o">===</span> <span class="kc">undefined</span><span class="p">)</span> <span class="p">{</span>
+ <span class="nx">f</span> <span class="o">=</span> <span class="k">this</span><span class="p">;</span>
+ <span class="k">return</span> <span class="nx">method</span><span class="p">(</span><span class="nx">f</span><span class="p">,</span> <span class="nx">obj</span><span class="p">);</span>
+ <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
+ <span class="k">return</span> <span class="nx">method</span><span class="p">(</span><span class="nx">f</span><span class="p">,</span> <span class="nx">obj</span><span class="p">);</span>
+ <span class="p">}</span>
+<span class="p">};</span></pre></div> </td> </tr> <tr id="section-6"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-6">&#182;</a> </div> <p>The contract object.</p> </td> <td class="code"> <div class="highlight"><pre><span class="kd">var</span> <span class="nx">Contract</span> <span class="o">=</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-7"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-7">&#182;</a> </div> <p>handle multiple APIs. Pass the function &amp; pre conditions into constructPre</p> </td> <td class="code"> <div class="highlight"><pre> <span class="s2">&quot;pre&quot;</span><span class="o">:</span> <span class="kd">function</span> <span class="nx">_pre</span><span class="p">(</span><span class="nx">pre</span><span class="p">,</span> <span class="nx">f</span><span class="p">)</span> <span class="p">{</span>
+ <span class="k">return</span> <span class="nx">handleMultipleAPIs</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="nx">pre</span><span class="p">,</span> <span class="nx">constructPre</span><span class="p">,</span> <span class="nx">f</span><span class="p">);</span>
+ <span class="p">},</span></pre></div> </td> </tr> <tr id="section-8"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-8">&#182;</a> </div> <p>handle multiple APIs. Pass the function &amp; post condition into constructPost</p> </td> <td class="code"> <div class="highlight"><pre> <span class="s2">&quot;post&quot;</span><span class="o">:</span> <span class="kd">function</span> <span class="nx">_post</span><span class="p">(</span><span class="nx">post</span><span class="p">,</span> <span class="nx">f</span><span class="p">)</span> <span class="p">{</span>
+ <span class="k">return</span> <span class="nx">handleMultipleAPIs</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="nx">post</span><span class="p">,</span> <span class="nx">constructPost</span><span class="p">,</span> <span class="nx">f</span><span class="p">);</span>
+ <span class="p">},</span></pre></div> </td> </tr> <tr id="section-9"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-9">&#182;</a> </div> <p>handle multiple APIs. Pass the function &amp; invariant condition into constructInvariant</p> </td> <td class="code"> <div class="highlight"><pre> <span class="s2">&quot;invariant&quot;</span><span class="o">:</span> <span class="kd">function</span> <span class="nx">_invariant</span><span class="p">(</span><span class="nx">invariant</span><span class="p">,</span> <span class="nx">f</span><span class="p">)</span> <span class="p">{</span>
+ <span class="k">return</span> <span class="nx">handleMultipleAPIs</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="nx">invariant</span><span class="p">,</span> <span class="nx">constructInvariant</span><span class="p">,</span> <span class="nx">f</span><span class="p">);</span>
+ <span class="p">},</span></pre></div> </td> </tr> <tr id="section-10"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-10">&#182;</a> </div> <p>unwrap the Constract object</p> </td> <td class="code"> <div class="highlight"><pre> <span class="s2">&quot;valueOf&quot;</span><span class="o">:</span> <span class="kd">function</span> <span class="nx">_valueOf</span><span class="p">()</span> <span class="p">{</span>
+ <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">_wrapped</span><span class="p">;</span>
+ <span class="p">}</span>
+<span class="p">};</span></pre></div> </td> </tr> <tr id="section-11"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-11">&#182;</a> </div> <p>defaults object. By default inject into Function.prototype</p> </td> <td class="code"> <div class="highlight"><pre><span class="kd">var</span> <span class="nx">defaults</span> <span class="o">=</span> <span class="p">{</span>
+ <span class="nx">natives</span><span class="o">:</span> <span class="kc">true</span>
+<span class="p">};</span></pre></div> </td> </tr> <tr id="section-12"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-12">&#182;</a> </div> <p>ContractFactory generates a new Contract based on the passed function <code>f</code></p> </td> <td class="code"> <div class="highlight"><pre><span class="kd">var</span> <span class="nx">ContractFactory</span> <span class="o">=</span> <span class="kd">function</span> <span class="nx">_create</span><span class="p">(</span><span class="nx">f</span><span class="p">)</span> <span class="p">{</span>
+ <span class="kd">var</span> <span class="nx">c</span> <span class="o">=</span> <span class="nb">Object</span><span class="p">.</span><span class="nx">create</span><span class="p">(</span><span class="nx">Contract</span><span class="p">);</span>
+ <span class="nx">c</span><span class="p">.</span><span class="nx">_wrapped</span> <span class="o">=</span> <span class="nx">f</span><span class="p">;</span>
+ <span class="k">return</span> <span class="nx">c</span><span class="p">;</span>
+<span class="p">}</span></pre></div> </td> </tr> <tr id="section-13"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-13">&#182;</a> </div> <p>contract = require("constract");
Sets up the contract object basedon the options.
If <code>natives === true</code> inject the methods into Function.prototype.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nx">module</span><span class="p">.</span><span class="nx">exports</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">options</span><span class="p">)</span> <span class="p">{</span>
- <span class="nb">Object</span><span class="p">.</span><span class="nx">keys</span><span class="p">(</span><span class="nx">defaults</span><span class="p">).</span><span class="nx">forEach</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">key</span><span class="p">)</span> <span class="p">{</span>
- <span class="k">if</span> <span class="p">(</span><span class="nx">options</span> <span class="o">&amp;&amp;</span> <span class="nx">options</span><span class="p">[</span><span class="nx">key</span><span class="p">])</span> <span class="p">{</span>
- <span class="nx">defaults</span><span class="p">[</span><span class="nx">key</span><span class="p">]</span> <span class="o">=</span> <span class="nx">options</span><span class="p">[</span><span class="nx">key</span><span class="p">];</span>
- <span class="p">}</span>
- <span class="p">});</span>
+ <span class="nb">Object</span><span class="p">.</span><span class="nx">keys</span><span class="p">(</span><span class="nx">defaults</span><span class="p">).</span><span class="nx">forEach</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">key</span><span class="p">)</span> <span class="p">{</span>
+ <span class="k">if</span> <span class="p">(</span><span class="nx">options</span> <span class="o">&amp;&amp;</span> <span class="nx">options</span><span class="p">[</span><span class="nx">key</span><span class="p">])</span> <span class="p">{</span>
+ <span class="nx">defaults</span><span class="p">[</span><span class="nx">key</span><span class="p">]</span> <span class="o">=</span> <span class="nx">options</span><span class="p">[</span><span class="nx">key</span><span class="p">];</span>
+ <span class="p">}</span>
+ <span class="p">});</span>
- <span class="k">if</span> <span class="p">(</span><span class="nx">defaults</span><span class="p">.</span><span class="nx">natives</span><span class="p">)</span> <span class="p">{</span>
- <span class="nx">defineProperties</span><span class="p">(</span><span class="nb">Function</span><span class="p">.</span><span class="nx">prototype</span><span class="p">)</span>
- <span class="p">}</span>
+ <span class="k">if</span> <span class="p">(</span><span class="nx">defaults</span><span class="p">.</span><span class="nx">natives</span><span class="p">)</span> <span class="p">{</span>
+ <span class="nx">defineProperties</span><span class="p">(</span><span class="nb">Function</span><span class="p">.</span><span class="nx">prototype</span><span class="p">)</span>
+ <span class="p">}</span>
- <span class="k">return</span> <span class="nx">ContractFactory</span><span class="p">;</span>
-<span class="p">};</span></pre></div> </td> </tr> <tr id="section-12"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-12">&#182;</a> </div> <p>define the properties on <code>ContractFactory</code></p> </td> <td class="code"> <div class="highlight"><pre><span class="nx">defineProperties</span><span class="p">(</span><span class="nx">ContractFactory</span><span class="p">);</span></pre></div> </td> </tr> <tr id="section-13"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-13">&#182;</a> </div> <p>Define the pre, post &amp; invariant objects onto an object.</p> </td> <td class="code"> <div class="highlight"><pre><span class="kd">function</span> <span class="nx">defineProperties</span><span class="p">(</span><span class="nx">obj</span><span class="p">)</span> <span class="p">{</span>
- <span class="nb">Object</span><span class="p">.</span><span class="nx">defineProperties</span><span class="p">(</span><span class="nx">obj</span><span class="p">,</span> <span class="p">{</span>
- <span class="s2">&quot;pre&quot;</span><span class="o">:</span> <span class="p">{</span>
- <span class="nx">value</span><span class="o">:</span> <span class="nx">Contract</span><span class="p">.</span><span class="nx">pre</span><span class="p">,</span>
- <span class="nx">configurable</span><span class="o">:</span> <span class="kc">true</span>
- <span class="p">},</span>
- <span class="s2">&quot;post&quot;</span><span class="o">:</span> <span class="p">{</span>
- <span class="nx">value</span><span class="o">:</span> <span class="nx">Contract</span><span class="p">.</span><span class="nx">post</span><span class="p">,</span>
- <span class="nx">configurable</span><span class="o">:</span> <span class="kc">true</span>
- <span class="p">},</span>
- <span class="s2">&quot;invariant&quot;</span><span class="o">:</span> <span class="p">{</span>
- <span class="nx">value</span><span class="o">:</span> <span class="nx">Contract</span><span class="p">.</span><span class="nx">invariant</span><span class="p">,</span>
- <span class="nx">configurable</span><span class="o">:</span> <span class="kc">true</span>
- <span class="p">}</span>
- <span class="p">});</span>
+ <span class="k">return</span> <span class="nx">ContractFactory</span><span class="p">;</span>
+<span class="p">};</span></pre></div> </td> </tr> <tr id="section-14"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-14">&#182;</a> </div> <p>define the properties on <code>ContractFactory</code></p> </td> <td class="code"> <div class="highlight"><pre><span class="nx">defineProperties</span><span class="p">(</span><span class="nx">ContractFactory</span><span class="p">);</span></pre></div> </td> </tr> <tr id="section-15"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-15">&#182;</a> </div> <p>Define the pre, post &amp; invariant objects onto an object.</p> </td> <td class="code"> <div class="highlight"><pre><span class="kd">function</span> <span class="nx">defineProperties</span><span class="p">(</span><span class="nx">obj</span><span class="p">)</span> <span class="p">{</span>
+ <span class="nb">Object</span><span class="p">.</span><span class="nx">defineProperties</span><span class="p">(</span><span class="nx">obj</span><span class="p">,</span> <span class="p">{</span>
+ <span class="s2">&quot;pre&quot;</span><span class="o">:</span> <span class="p">{</span>
+ <span class="nx">value</span><span class="o">:</span> <span class="nx">Contract</span><span class="p">.</span><span class="nx">pre</span><span class="p">,</span>
+ <span class="nx">configurable</span><span class="o">:</span> <span class="kc">true</span>
+ <span class="p">},</span>
+ <span class="s2">&quot;post&quot;</span><span class="o">:</span> <span class="p">{</span>
+ <span class="nx">value</span><span class="o">:</span> <span class="nx">Contract</span><span class="p">.</span><span class="nx">post</span><span class="p">,</span>
+ <span class="nx">configurable</span><span class="o">:</span> <span class="kc">true</span>
+ <span class="p">},</span>
+ <span class="s2">&quot;invariant&quot;</span><span class="o">:</span> <span class="p">{</span>
+ <span class="nx">value</span><span class="o">:</span> <span class="nx">Contract</span><span class="p">.</span><span class="nx">invariant</span><span class="p">,</span>
+ <span class="nx">configurable</span><span class="o">:</span> <span class="kc">true</span>
+ <span class="p">}</span>
+ <span class="p">});</span>
<span class="p">}</span>
</pre></div> </td> </tr> </tbody> </table> </div> </body> </html>
View
2  package.json
@@ -1,7 +1,7 @@
{
"name": "contract",
"description": "A design by contract library",
- "version": "0.1.1",
+ "version": "0.1.2",
"author": "Raynos <raynos2@gmail.com>",
"contributors": [
{ "name": "Raynos", "email": "raynos2@gmail.com", "url":"http://raynos.org" }
View
157 src/contract.js
@@ -1,83 +1,100 @@
// # [Github Repo](https://github.com/Raynos/contract)
+
+// A method that generates a function which will wrap the function `f` and
+// call the pre condition with (arg1, arg2, ...)
+var constructPre = function _constructPre(f, pre) {
+ return function _wrapped() {
+ pre.apply(this, arguments);
+ return f.apply(this, arguments);
+ };
+};
+
+
+// A method that generates a function which will wrap the function and
+// call the post condition with (ret, arg1, arg2, ...)
+var constructPost = function _constructPost(f, post) {
+ return function _wrapped() {
+ var arr = [f.apply(this, arguments)];
+ post.apply(this, arr.concat.apply(arr, arguments));
+ return arr[0];
+ };
+};
+
+// A method that generates a function which will wrap the function `f` and
+// call the invariant with (before, arg1, arg2, ...)
+var constructInvariant = function _constructInvariant(f, invariant) {
+ return function _wrapped() {
+ var before = JSON.parse(JSON.stringify(this));
+ var ret = f.apply(this, arguments);
+ var arr = [before];
+ invariant.apply(this, arr.concat.apply(arr, arguments));
+ return ret;
+ };
+}
+
+// Handle multiple APIs. Either this was wrapped `construct(f).pre(pre)` or
+// This was called from the function prototype `f.pre(pre)` or this was
+// called from the Construct object `Construct.pre(pre, f)`
+var handleMultipleAPIs = function _handleMultipleAPIs(obj, method, f) {
+ if (this._wrapped) {
+ f = this._wrapped;
+ this._wrapped = method(f, obj);
+ return this;
+ } else if (f === undefined) {
+ f = this;
+ return method(f, obj);
+ } else {
+ return method(f, obj);
+ }
+};
+
// The contract object.
var Contract = {
- // A method that generates a function which will wrap the function and
- // call the pre condition with (arg1, arg2, ...)
- "_constructPre": function _constructPre(f, pre) {
- return function _wrapped() {
- pre.apply(this, arguments);
- return f.apply(this, arguments);
- };
- },
// handle multiple APIs. Pass the function & pre conditions into constructPre
"pre": function _pre(pre, f) {
- return this._handleMultipleAPIs(f, pre, "_constructPre");
- },
- // A method that generates a function which will wrap the function and
- // call the post condition with (ret, arg1, arg2, ...)
- "_constructPost": function _constructPost(f, post) {
- return function _wrapped() {
- var arr = [f.apply(this, arguments)];
- post.apply(this, arr.concat.apply(arr, arguments));
- return arr[0];
- }
- },
- // Handle multiple APIs. Either this was wrapped `construct(f).pre(pre)` or
- // This was called from the function prototype `f.pre(pre)` or this was
- // called from the Construct object `Construct.pre(pre, f)`
- "_handleMultipleAPIs": function _handleMultipleAPIs(f, obj, method) {
- if (this._wrapped) {
- f = this._wrapped;
- this._wrapped = this[method](f, obj);
- return this;
- } else if (arguments.length === 1) {
- f = this;
- return this[method](f, obj);
- } else {
- return this[method](f, obj);
- }
+ return handleMultipleAPIs.call(this, pre, constructPre, f);
},
// handle multiple APIs. Pass the function & post condition into constructPost
"post": function _post(post, f) {
- return this._handleMultipleAPIs(f, post, "_constructPost");
+ return handleMultipleAPIs.call(this, post, constructPost, f);
+ },
+ // handle multiple APIs. Pass the function & invariant condition into constructInvariant
+ "invariant": function _invariant(invariant, f) {
+ return handleMultipleAPIs.call(this, invariant, constructInvariant, f);
},
- // un-implemented TODO
- "invariant": function _invariant() {
-
- },
- // unwrap the Constructo object
- "valueOf": function _valueOf() {
- return this._wrapped;
- }
+ // unwrap the Constract object
+ "valueOf": function _valueOf() {
+ return this._wrapped;
+ }
};
// defaults object. By default inject into Function.prototype
-var defaults = {
- natives: true
+var defaults = {
+ natives: true
};
// ContractFactory generates a new Contract based on the passed function `f`
var ContractFactory = function _create(f) {
- var c = Object.create(Contract);
- c._wrapped = f;
- return c;
+ var c = Object.create(Contract);
+ c._wrapped = f;
+ return c;
}
// contract = require("constract");
// Sets up the contract object basedon the options.
// If `natives === true` inject the methods into Function.prototype.
module.exports = function(options) {
- Object.keys(defaults).forEach(function(key) {
- if (options && options[key]) {
- defaults[key] = options[key];
- }
- });
+ Object.keys(defaults).forEach(function(key) {
+ if (options && options[key]) {
+ defaults[key] = options[key];
+ }
+ });
- if (defaults.natives) {
- defineProperties(Function.prototype)
- }
+ if (defaults.natives) {
+ defineProperties(Function.prototype)
+ }
- return ContractFactory;
+ return ContractFactory;
};
// define the properties on `ContractFactory`
@@ -85,18 +102,18 @@ defineProperties(ContractFactory);
// Define the pre, post & invariant objects onto an object.
function defineProperties(obj) {
- Object.defineProperties(obj, {
- "pre": {
- value: Contract.pre,
- configurable: true
- },
- "post": {
- value: Contract.post,
- configurable: true
- },
- "invariant": {
- value: Contract.invariant,
- configurable: true
- }
- });
+ Object.defineProperties(obj, {
+ "pre": {
+ value: Contract.pre,
+ configurable: true
+ },
+ "post": {
+ value: Contract.post,
+ configurable: true
+ },
+ "invariant": {
+ value: Contract.invariant,
+ configurable: true
+ }
+ });
}
View
377 test/contract-test.js
@@ -1,145 +1,272 @@
var is = require("vows-is"),
- _should = is.should,
- EventEmitter = require("events").EventEmitter.prototype;
-
-var ev = function() { return Object.create(EventEmitter); };
+ _should = is.should,
+ EventEmitter = require("events").EventEmitter.prototype;
var contract = require("../src/contract.js")();
is.partial("contains pre", function _partial(context) {
- return context
- .context("contains pre which")
- .topic.is(function(c) { return c.pre; })
- .vow.it.should.be.a("function")
- .parent();
+ return context
+ .context("contains pre which")
+ .topic.is(function(c) { return c.pre; })
+ .vow.it.should.be.a("function")
+ .parent();
});
is.partial("contains post", function _partial(context) {
- return context
- .context("contains post which")
- .topic.is(function(c) { return c.post; })
- .vow.it.should.be.a("function")
- .parent();
+ return context
+ .context("contains post which")
+ .topic.is(function(c) { return c.post; })
+ .vow.it.should.be.a("function")
+ .parent();
});
is.partial("contains invariant", function _partial(context) {
- return context
- .context("contains invariant which")
- .topic.is(function(c) { return c.invariant; })
- .vow.it.should.be.a("function")
- .parent();
+ return context
+ .context("contains invariant which")
+ .topic.is(function(c) { return c.invariant; })
+ .vow.it.should.be.a("function")
+ .parent();
+});
+
+is.partial("pre", function _partial(context) {
+ return context
+ .vow.it.should.be.a("function")
+ .context("when called (1)")
+ .topic.is.an.invocation(1)
+ .vow.it.should.error
+ .vow.it.should.have
+ .property("message", "expected undefined to exist")
+ .parent()
+ .context("when called (1,2)")
+ .topic.is.an.invocation(1,2)
+ .vow.it.should.error
+ .vow.it.should.have
+ .property("message", "expected 2 to be a string")
+ .parent()
+ .context("when called (1, 'foo')")
+ .topic.is.an.invocation(1, 'foo')
+ .vow.it.should.error
+ .vow.it.should.have
+ .property("message", "expected 1 to be above 5")
+ .parent()
+ .context("when called (6, 'foo')")
+ .topic.is.an.invocation(6, 'foo')
+ .vow.it.should.not.error
+ .vow.it.should.equal(6)
+ .batch();
+});
+
+is.partial("post", function _partial(context) {
+ return context
+ .vow.it.should.be.a("function")
+ .context("when called (5, 6)")
+ .topic.is.an.invocation(5, 6)
+ .vow.it.should.error
+ .vow.it.should.have
+ .property("message", "expected 5 to equal 6")
+ .parent()
+ .context("when called (5, 5)")
+ .topic.is.an.invocation(5, 5)
+ .vow.it.should.not.error
+ .vow.it.should.equal(5)
+ .batch();
+});
+
+is.partial("invariant", function _invariant(context) {
+ return context
+ .vow.it.should.be.a("function")
+ .context("when called ('foobar')")
+ .topic.is.an.invocation("foobar")
+ .vow.it.should.error
+ .vow.it.should.have
+ .property("message", "expected 50 to equal 42")
+ .parent()
+ .context("when called ('foo')")
+ .topic.is.an.invocation("foo")
+ .vow.it.should.not.error
+ .vow.it.should.equal(42)
+ .batch();
});
var suite = is.suite("contract").batch()
-
- .context("the contract function")
- .topic.is(function() { return contract; })
- .vow.it.should.be.a("function")
- .partial("contains pre")
- .partial("contains post")
- .partial("contains invariant")
- .context("when called returns an object which")
- .topic.is(function(c) { return c(function() { }); })
- .vow.it.should.be.a("object")
- .partial("contains pre")
- .partial("contains post")
- .partial("contains invariant")
-
-.batch()
-
- .context("the function prototype")
- .topic.is(function() { return Function.prototype; })
- .vow.it.should.be.a("function")
- .partial("contains pre")
- .partial("contains post")
- .partial("contains invariant")
-
-.batch()
-
- .context("contract(f).pre(g) ")
- .topic.is(function() {
- var promise = ev();
-
- var c = contract(function(a, b) {
- return a;
- });
- c = c.pre(function(a,b) {
- _should.exist(a);
- a.should.be.a("number");
- _should.exist(b);
- b.should.be.a("string");
- a.should.be.above(5).and.below(10);
- });
-
- return c.valueOf();
- })
- .vow.it.should.be.a("function")
- .context("when called (1)")
- .topic.is.an.invocation(1)
- .vow.it.should.error
- .vow.it.should.have
- .property("message", "expected undefined to exist")
- .parent()
- .context("when called (1,2)")
- .topic.is.an.invocation(1,2)
- .vow.it.should.error
- .vow.it.should.have
- .property("message", "expected 2 to be a string")
- .parent()
- .context("when called (1, 'foo')")
- .topic.is.an.invocation(1, 'foo')
- .vow.it.should.error
- .vow.it.should.have
- .property("message", "expected 1 to be above 5")
- .parent()
- .context("when called (6, 'foo')")
- .topic.is.an.invocation(6, 'foo')
- .vow.it.should.not.error
- .vow.it.should.equal(6)
- .suite()
-
-.batch()
-
- .context("contract(f).post(g) ")
- .topic.is(function() {
- var promise = ev();
-
- var c = contract(function(a, b) {
- return a;
- })
- c = c.post(function(ret, a, b) {
- console.log(arguments);
- ret.should.equal(b)
- });
-
- return c.valueOf();
- })
- .vow.it.should.be.a("function")
- .context("when called (5, 6)")
- .topic.is.an.invocation(5, 6)
- .vow.it.should.error
- .vow.it.should.have
- .property("message", "expected 5 to equal 6")
- .parent()
- .context("when called (5, 5)")
- .topic.is.an.invocation(5, 5)
- .vow.it.should.not.error
- .vow.it.should.equal(5)
- .parent()
-
-
-
+
+ .context("the contract function")
+ .topic.is(function() { return contract; })
+ .vow.it.should.be.a("function")
+ .partial("contains pre")
+ .partial("contains post")
+ .partial("contains invariant")
+ .context("when called returns an object which")
+ .topic.is(function(c) { return c(function() { }); })
+ .vow.it.should.be.a("object")
+ .partial("contains pre")
+ .partial("contains post")
+ .partial("contains invariant")
+
+.suite().batch()
+
+ .context("the function prototype")
+ .topic.is(function() { return Function.prototype; })
+ .vow.it.should.be.a("function")
+ .partial("contains pre")
+ .partial("contains post")
+ .partial("contains invariant")
+
+.suite().batch()
+
+ .context("contract(f).pre(pre) ")
+ .topic.is(function() {
+ var c = contract(function _f(a, b) {
+ return a;
+ });
+
+ c = c.pre(function _pre(a,b) {
+ _should.exist(a);
+ a.should.be.a("number");
+ _should.exist(b);
+ b.should.be.a("string");
+ a.should.be.above(5).and.below(10);
+ });
+
+ return c.valueOf();
+ })
+ .partial("pre")
+
+ .context("f.pre(pre) ")
+ .topic.is(function() {
+ var c = function _f(a, b) {
+ return a;
+ };
+
+ return c.pre(function _pre(a, b) {
+ _should.exist(a);
+ a.should.be.a("number");
+ _should.exist(b);
+ b.should.be.a("string");
+ a.should.be.above(5).and.below(10);
+ });
+ })
+ .partial("pre")
+
+ .context("contract.pre(pre, f) ")
+ .topic.is(function() {
+ var c = function _f(a, b) {
+ return a;
+ };
+
+ return contract.pre(function _pre(a, b) {
+ _should.exist(a);
+ a.should.be.a("number");
+ _should.exist(b);
+ b.should.be.a("string");
+ a.should.be.above(5).and.below(10);
+ }, c);
+ })
+ .partial("pre")
+
+.suite().batch()
+
+ .context("contract(f).post(post) ")
+ .topic.is(function() {
+ var c = contract(function _f(a, b) {
+ return a;
+ });
+
+ c = c.post(function _post(ret, a, b) {
+ ret.should.equal(b);
+ });
+
+ return c.valueOf();
+ })
+ .partial("post")
+
+ .context("f.post(post)")
+ .topic.is(function() {
+ var c = function _f(a, b) {
+ return a;
+ };
+
+ return c.post(function _post(ret, a, b) {
+ ret.should.equal(b);
+ });
+ })
+ .partial("post")
+
+ .context("contract.post(post, f) ")
+ .topic.is(function() {
+ var c = function(a, b) {
+ return a;
+ };
+
+ return contract.post(function _post(ret, a, b) {
+ ret.should.equal(b);
+ }, c)
+ })
+ .partial("post")
+
+.suite().batch()
+
+ .context("contract(o.f).invariant(invariant)")
+ .topic.is(function() {
+ var o = {
+ foobar: 50,
+ c: function(mutator) {
+ return this[mutator] = 42;
+ }
+ };
+
+ o.c = contract(o.c).invariant(function(before) {
+ before.foobar.should.equal(this.foobar);
+ }).valueOf();
+
+ return o.c.bind(o);
+ })
+ .partial("invariant")
+
+ .context("o.f.invariant(invariant)")
+ .topic.is(function() {
+ var o = {
+ foobar: 50,
+ c: function(mutator) {
+ return this[mutator] = 42;
+ }
+ };
+
+ o.c = o.c.invariant(function(before) {
+ before.foobar.should.equal(this.foobar);
+ });
+
+ return o.c.bind(o);
+ })
+ .partial("invariant")
+
+ .context("contract.invariant(invariant, o.f)")
+ .topic.is(function() {
+ var o = {
+ foobar: 50,
+ c: function(mutator) {
+ return this[mutator] = 42;
+ }
+ };
+
+ o.c = contract.invariant(function() {
+ before.foobar.should.equal(this.foobar);
+ }, o.c);
+
+ return o.c.bind(o);
+ })
+
.suite();
-
+
if (module.parent) {
- suite["export"](module);
+ suite["export"](module);
} else {
- suite.run({
- reporter: is.reporter
- }, function() {
- is.end();
- });
+ suite.run({
+ reporter: is.reporter
+ }, function() {
+ is.end();
+ });
}
-
+
Please sign in to comment.
Something went wrong with that request. Please try again.