Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

We’re showing branches in this repository, but you can also compare across forks.

base fork: youngjay/rxc
base: ab3fd62e29
...
head fork: youngjay/rxc
compare: de9da7c79e
  • 5 commits
  • 16 files changed
  • 0 commit comments
  • 1 contributor
341 coverage.html
View
@@ -1,341 +0,0 @@
-<!DOCTYPE html><html><head><title>Coverage</title><script>
-
-headings = [];
-
-onload = function(){
- headings = document.querySelectorAll('h2');
-};
-
-onscroll = function(e){
- var heading = find(window.scrollY);
- if (!heading) return;
- var links = document.querySelectorAll('#menu a')
- , link;
-
- for (var i = 0, len = links.length; i < len; ++i) {
- link = links[i];
- link.className = link.getAttribute('href') == '#' + heading.id
- ? 'active'
- : '';
- }
-};
-
-function find(y) {
- var i = headings.length
- , heading;
-
- while (i--) {
- heading = headings[i];
- if (y >= heading.offsetTop) {
- return heading;
- }
- }
-}
-</script>
-<style>
-
-body {
- font: 14px/1.6 "Helvetica Neue", Helvetica, Arial, sans-serif;
- margin: 0;
- color: #2C2C2C;
- border-top: 2px solid #ddd;
-}
-
-#coverage {
- padding: 60px;
-}
-
-h1 a {
- color: inherit;
- font-weight: inherit;
-}
-
-h1 a:hover {
- text-decoration: none;
-}
-
-.onload h1 {
- opacity: 1;
-}
-
-h2 {
- width: 80%;
- margin-top: 80px;
- margin-bottom: 0;
- font-weight: 100;
- letter-spacing: 1px;
- border-bottom: 1px solid #eee;
-}
-
-a {
- color: #8A6343;
- font-weight: bold;
- text-decoration: none;
-}
-
-a:hover {
- text-decoration: underline;
-}
-
-ul {
- margin-top: 20px;
- padding: 0 15px;
- width: 100%;
-}
-
-ul li {
- float: left;
- width: 40%;
- margin-top: 5px;
- margin-right: 60px;
- list-style: none;
- border-bottom: 1px solid #eee;
- padding: 5px 0;
- font-size: 12px;
-}
-
-ul::after {
- content: '.';
- height: 0;
- display: block;
- visibility: hidden;
- clear: both;
-}
-
-code {
- font: 12px monaco, monospace;
-}
-
-pre {
- margin: 30px;
- padding: 30px;
- border: 1px solid #eee;
- border-bottom-color: #ddd;
- -webkit-border-radius: 2px;
- -moz-border-radius: 2px;
- -webkit-box-shadow: inset 0 0 10px #eee;
- -moz-box-shadow: inset 0 0 10px #eee;
- overflow-x: auto;
-}
-
-img {
- margin: 30px;
- padding: 1px;
- -webkit-border-radius: 3px;
- -moz-border-radius: 3px;
- -webkit-box-shadow: 0 3px 10px #dedede, 0 1px 5px #888;
- -moz-box-shadow: 0 3px 10px #dedede, 0 1px 5px #888;
- max-width: 100%;
-}
-
-footer {
- background: #eee;
- width: 100%;
- padding: 50px 0;
- text-align: right;
- border-top: 1px solid #ddd;
-}
-
-footer span {
- display: block;
- margin-right: 30px;
- color: #888;
- font-size: 12px;
-}
-
-#menu {
- position: fixed;
- font-size: 12px;
- overflow-y: auto;
- top: 0;
- right: 0;
- margin: 0;
- height: 100%;
- padding: 15px 0;
- text-align: right;
- border-left: 1px solid #eee;
- -moz-box-shadow: 0 0 2px #888
- , inset 5px 0 20px rgba(0,0,0,.5)
- , inset 5px 0 3px rgba(0,0,0,.3);
- -webkit-box-shadow: 0 0 2px #888
- , inset 5px 0 20px rgba(0,0,0,.5)
- , inset 5px 0 3px rgba(0,0,0,.3);
- -webkit-font-smoothing: antialiased;
- background: url("data:image/png;base64,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");
-}
-
-#menu::after {
- display: block;
- content: '';
- padding-top: 80px;
-}
-
-#logo {
- position: fixed;
- bottom: 10px;
- right: 10px;
- background: rgba(255,255,255,.1);
- font-size: 11px;
- display: block;
- width: 20px;
- height: 20px;
- line-height: 20px;
- text-align: center;
- -webkit-border-radius: 20px;
- -moz-border-radius: 20px;
- -webkit-box-shadow: 0 0 3px rgba(0,0,0,.2);
- -moz-box-shadow: 0 0 3px rgba(0,0,0,.2);
- color: inherit;
-}
-
-#menu li a {
- display: block;
- color: white;
- padding: 0 35px 0 25px;
- -webkit-transition: background 300ms;
- -moz-transition: background 300ms;
-}
-
-#menu li {
- position: relative;
- list-style: none;
-}
-
-#menu a:hover,
-#menu a.active {
- text-decoration: none;
- background: rgba(255,255,255,.1);
-}
-
-#menu li:hover .cov {
- opacity: 1;
-}
-
-#menu li .dirname {
- opacity: .60;
- padding-right: 2px;
-}
-
-#menu li .basename {
- opacity: 1;
-}
-
-#menu .cov {
- background: rgba(0,0,0,.4);
- position: absolute;
- top: 0;
- right: 8px;
- font-size: 9px;
- opacity: .6;
- text-align: left;
- width: 17px;
- -webkit-border-radius: 10px;
- -moz-border-radius: 10px;
- padding: 2px 3px;
- text-align: center;
-}
-
-#stats:nth-child(2n) {
- display: inline-block;
- margin-top: 15px;
- border: 1px solid #eee;
- padding: 10px;
- -webkit-box-shadow: inset 0 0 2px #eee;
- -moz-box-shadow: inset 0 0 2px #eee;
- -webkit-border-radius: 5px;
- -moz-border-radius: 5px;
-}
-
-#stats div {
- float: left;
- padding: 0 5px;
-}
-
-#stats::after {
- display: block;
- content: '';
- clear: both;
-}
-
-#stats .sloc::after {
- content: ' SLOC';
- color: #b6b6b6;
-}
-
-#stats .percentage::after {
- content: ' coverage';
- color: #b6b6b6;
-}
-
-#stats .hits,
-#stats .misses {
- display: none;
-}
-
-.high {
- color: #00d4b4;
-}
-.medium {
- color: #e87d0d;
-}
-.low {
- color: #d4081a;
-}
-.terrible {
- color: #d4081a;
- font-weight: bold;
-}
-
-table {
- width: 80%;
- margin-top: 10px;
- border-collapse: collapse;
- border: 1px solid #cbcbcb;
- color: #363636;
- -webkit-border-radius: 3px;
- -moz-border-radius: 3px;
-}
-
-table thead {
- display: none;
-}
-
-table td.line,
-table td.hits {
- width: 20px;
- background: #eaeaea;
- text-align: center;
- font-size: 11px;
- padding: 0 10px;
- color: #949494;
-}
-
-table td.hits {
- width: 10px;
- padding: 2px 5px;
- color: rgba(0,0,0,.2);
- background: #f0f0f0;
-}
-
-tr.miss td.line,
-tr.miss td.hits {
- background: #e6c3c7;
-}
-
-tr.miss td {
- background: #f8d5d8;
-}
-
-td.source {
- padding-left: 15px;
- line-height: 15px;
- white-space: pre;
- font: 12px monaco, monospace;
-}
-
-code .comment { color: #ddd }
-code .init { color: #2F6FAD }
-code .string { color: #5890AD }
-code .keyword { color: #8A6343 }
-code .number { color: #2F6FAD }
-</style></head><body><div id="coverage"><h1 id="overview">Coverage</h1><div id="menu"><li><a href="#overview">overview</a></li><li><span class="cov medium">71</span><a href="#class.js"><span class="basename">class.js</span></a></li><li><span class="cov high">94</span><a href="#index.js"><span class="basename">index.js</span></a></li><li><span class="cov high">80</span><a href="#mutable.js"><span class="basename">mutable.js</span></a></li><li><span class="cov high">91</span><a href="#preserved-subscribable.js"><span class="basename">preserved-subscribable.js</span></a></li><li><span class="cov medium">64</span><a href="#subscribable.js"><span class="basename">subscribable.js</span></a></li><a id="logo" href="http://visionmedia.github.com/mocha/">m</a></div><div id="stats" class="high"><div class="percentage">82%</div><div class="sloc">144</div><div class="hits">119</div><div class="misses">25</div></div><div id="files"><div class="file"><h2 id="class.js">class.js</h2><div id="stats" class="medium"><div class="percentage">71%</div><div class="sloc">46</div><div class="hits">33</div><div class="misses">13</div></div><table id="source"><thead><tr><th>Line</th><th>Hits</th><th>Source</th></tr></thead><tbody><tr class="hit"> <td class="line">1</td><td class="hits">1</td><td class="source">var _ = require('underscore');</td></tr><tr class="hit"> <td class="line">2</td><td class="hits">1</td><td class="source">var slice = [].slice;</td></tr><tr><td class="line">3</td><td class="hits"></td><td class="source"> </td></tr><tr><td class="line">4</td><td class="hits"></td><td class="source"> </td></tr><tr class="hit"> <td class="line">5</td><td class="hits">1</td><td class="source">var INITS = '__inits';</td></tr><tr><td class="line">6</td><td class="hits"></td><td class="source"> </td></tr><tr class="hit"> <td class="line">7</td><td class="hits">1</td><td class="source">var Abstract = function() {};</td></tr><tr><td class="line">8</td><td class="hits"></td><td class="source"> </td></tr><tr><td class="line">9</td><td class="hits"></td><td class="source">// &#233;&#129;&#191;&#229;&#133;&#141;&#230;&#138;&#138;Abstract&#230;&#156;&#172;&#232;&#186;&#171;&#228;&#189;&#156;&#228;&#184;&#186;&#230;&#158;&#132;&#233;&#128;&#160;&#229;&#135;&#189;&#230;&#149;&#176;</td></tr><tr class="hit"> <td class="line">10</td><td class="hits">1</td><td class="source">Abstract.prototype[INITS] = [];</td></tr><tr><td class="line">11</td><td class="hits"></td><td class="source"> </td></tr><tr class="hit"> <td class="line">12</td><td class="hits">1</td><td class="source">_.extend(Abstract, {</td></tr><tr><td class="line">13</td><td class="hits"></td><td class="source"> mix: function() {</td></tr><tr class="hit"> <td class="line">14</td><td class="hits">4</td><td class="source"> var self = this;</td></tr><tr class="hit"> <td class="line">15</td><td class="hits">4</td><td class="source"> var proto = this.prototype;</td></tr><tr><td class="line">16</td><td class="hits"></td><td class="source"> </td></tr><tr class="hit"> <td class="line">17</td><td class="hits">4</td><td class="source"> var inits = proto[INITS];</td></tr><tr><td class="line">18</td><td class="hits"></td><td class="source"> </td></tr><tr><td class="line">19</td><td class="hits"></td><td class="source"> // proto[INITS] &#229;&#156;&#168;&#232;&#191;&#153;&#233;&#135;&#140;&#229;&#143;&#175;&#232;&#131;&#189;&#228;&#188;&#154;&#232;&#162;&#171;&#232;&#166;&#134;&#231;&#155;&#150;&#230;&#142;&#137;&#239;&#188;&#140;&#228;&#189;&#134;&#230;&#152;&#175;&#230;&#178;&#161;&#229;&#133;&#179;&#231;&#179;&#187;&#239;&#188;&#140;&#230;&#156;&#128;&#229;&#144;&#142;&#228;&#188;&#154;&#229;&#143;&#136;&#231;&#187;&#153;&#229;&#174;&#131;&#232;&#181;&#139;&#229;&#128;&#188;</td></tr><tr class="hit"> <td class="line">20</td><td class="hits">4</td><td class="source"> _.each(arguments, function(o) {</td></tr><tr class="hit"> <td class="line">21</td><td class="hits">9</td><td class="source"> if (!o) {</td></tr><tr class="miss"> <td class="line">22</td><td class="hits">0</td><td class="source"> return;</td></tr><tr><td class="line">23</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">24</td><td class="hits"></td><td class="source"> </td></tr><tr class="hit"> <td class="line">25</td><td class="hits">9</td><td class="source"> if (typeof o === 'function') {</td></tr><tr class="hit"> <td class="line">26</td><td class="hits">6</td><td class="source"> var srcProto = o.prototype;</td></tr><tr><td class="line">27</td><td class="hits"></td><td class="source"> </td></tr><tr class="hit"> <td class="line">28</td><td class="hits">6</td><td class="source"> if (srcProto[INITS]) {</td></tr><tr class="hit"> <td class="line">29</td><td class="hits">4</td><td class="source"> inits.push.apply(inits, srcProto[INITS]);</td></tr><tr><td class="line">30</td><td class="hits"></td><td class="source"> } else {</td></tr><tr class="hit"> <td class="line">31</td><td class="hits">2</td><td class="source"> inits.push(o);</td></tr><tr><td class="line">32</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">33</td><td class="hits"></td><td class="source"> </td></tr><tr class="hit"> <td class="line">34</td><td class="hits">6</td><td class="source"> _.extend(proto, srcProto);</td></tr><tr class="hit"> <td class="line">35</td><td class="hits">6</td><td class="source"> _.extend(self, o);</td></tr><tr class="hit"> <td class="line">36</td><td class="hits">6</td><td class="source"> return;</td></tr><tr><td class="line">37</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">38</td><td class="hits"></td><td class="source"> </td></tr><tr class="hit"> <td class="line">39</td><td class="hits">3</td><td class="source"> if (typeof o === 'object') {</td></tr><tr class="hit"> <td class="line">40</td><td class="hits">3</td><td class="source"> _.extend(proto, o);</td></tr><tr class="hit"> <td class="line">41</td><td class="hits">3</td><td class="source"> return;</td></tr><tr><td class="line">42</td><td class="hits"></td><td class="source"> } </td></tr><tr><td class="line">43</td><td class="hits"></td><td class="source"> </td></tr><tr class="miss"> <td class="line">44</td><td class="hits">0</td><td class="source"> console.log(o);</td></tr><tr class="miss"> <td class="line">45</td><td class="hits">0</td><td class="source"> throw new Error('`mix` called with invalid arg type'); </td></tr><tr><td class="line">46</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">47</td><td class="hits"></td><td class="source"> </td></tr><tr class="hit"> <td class="line">48</td><td class="hits">4</td><td class="source"> proto[INITS] = _.uniq(inits);</td></tr><tr class="hit"> <td class="line">49</td><td class="hits">4</td><td class="source"> proto.constructor = this;</td></tr><tr><td class="line">50</td><td class="hits"></td><td class="source"> </td></tr><tr class="hit"> <td class="line">51</td><td class="hits">4</td><td class="source"> return this;</td></tr><tr><td class="line">52</td><td class="hits"></td><td class="source"> }, </td></tr><tr><td class="line">53</td><td class="hits"></td><td class="source"> </td></tr><tr><td class="line">54</td><td class="hits"></td><td class="source"> mixStatic: function() {</td></tr><tr class="miss"> <td class="line">55</td><td class="hits">0</td><td class="source"> var self = this;</td></tr><tr class="miss"> <td class="line">56</td><td class="hits">0</td><td class="source"> _.each(arguments, function(o) {</td></tr><tr class="miss"> <td class="line">57</td><td class="hits">0</td><td class="source"> if (typeof o === 'object') {</td></tr><tr class="miss"> <td class="line">58</td><td class="hits">0</td><td class="source"> _.extend(self, o);</td></tr><tr class="miss"> <td class="line">59</td><td class="hits">0</td><td class="source"> return;</td></tr><tr><td class="line">60</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">61</td><td class="hits"></td><td class="source"> </td></tr><tr class="miss"> <td class="line">62</td><td class="hits">0</td><td class="source"> console.log(o);</td></tr><tr class="miss"> <td class="line">63</td><td class="hits">0</td><td class="source"> throw new Error('`mixStatic` called with invalid arg type'); </td></tr><tr><td class="line">64</td><td class="hits"></td><td class="source"> });</td></tr><tr class="miss"> <td class="line">65</td><td class="hits">0</td><td class="source"> return this;</td></tr><tr><td class="line">66</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">67</td><td class="hits"></td><td class="source"> </td></tr><tr><td class="line">68</td><td class="hits"></td><td class="source"> extend: function() {</td></tr><tr class="hit"> <td class="line">69</td><td class="hits">4</td><td class="source"> var Class = function() {</td></tr><tr class="hit"> <td class="line">70</td><td class="hits">417</td><td class="source"> var self = this, args = arguments;</td></tr><tr class="hit"> <td class="line">71</td><td class="hits">417</td><td class="source"> _.each(this[INITS], function(init) {</td></tr><tr class="hit"> <td class="line">72</td><td class="hits">443</td><td class="source"> init.apply(self, args);</td></tr><tr><td class="line">73</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">74</td><td class="hits"></td><td class="source"> };</td></tr><tr><td class="line">75</td><td class="hits"></td><td class="source"> </td></tr><tr class="hit"> <td class="line">76</td><td class="hits">4</td><td class="source"> Class.prototype[INITS] = [];</td></tr><tr><td class="line">77</td><td class="hits"></td><td class="source"> </td></tr><tr><td class="line">78</td><td class="hits"></td><td class="source"> // &#230;&#138;&#138;parent &#229;&#138;&#160;&#229;&#133;&#165;mixin&#229;&#136;&#151;&#232;&#161;&#168;</td></tr><tr class="hit"> <td class="line">79</td><td class="hits">4</td><td class="source"> [].unshift.call(arguments, this);</td></tr><tr><td class="line">80</td><td class="hits"></td><td class="source"> </td></tr><tr class="hit"> <td class="line">81</td><td class="hits">4</td><td class="source"> return this.mix.apply(Class, arguments);</td></tr><tr><td class="line">82</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">83</td><td class="hits"></td><td class="source"> </td></tr><tr><td class="line">84</td><td class="hits"></td><td class="source"> // o&#230;&#152;&#175;&#229;&#144;&#166;&#229;&#174;&#158;&#231;&#142;&#176;&#228;&#186;&#134;Class&#231;&#154;&#132;&#230;&#142;&#165;&#229;&#143;&#163;</td></tr><tr><td class="line">85</td><td class="hits"></td><td class="source"> test: function(o) {</td></tr><tr class="miss"> <td class="line">86</td><td class="hits">0</td><td class="source"> return _.all(this.prototype, function(value, key) {</td></tr><tr class="miss"> <td class="line">87</td><td class="hits">0</td><td class="source"> return typeof value === typeof o[key];</td></tr><tr><td class="line">88</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">89</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">90</td><td class="hits"></td><td class="source">});</td></tr><tr><td class="line">91</td><td class="hits"></td><td class="source"> </td></tr><tr class="hit"> <td class="line">92</td><td class="hits">1</td><td class="source">module.exports = Abstract.extend();</td></tr><tr><td class="line">93</td><td class="hits"></td><td class="source"> </td></tr><tr><td class="line">94</td><td class="hits"></td><td class="source"> </td></tr></tbody></table></div><div class="file"><h2 id="index.js">index.js</h2><div id="stats" class="high"><div class="percentage">94%</div><div class="sloc">18</div><div class="hits">17</div><div class="misses">1</div></div><table id="source"><thead><tr><th>Line</th><th>Hits</th><th>Source</th></tr></thead><tbody><tr class="hit"> <td class="line">1</td><td class="hits">1</td><td class="source">var PreservedSubscribable = require('./preserved-subscribable');</td></tr><tr class="hit"> <td class="line">2</td><td class="hits">1</td><td class="source">var Mutable = require('./mutable');</td></tr><tr class="hit"> <td class="line">3</td><td class="hits">1</td><td class="source">var _ = require('underscore');</td></tr><tr class="hit"> <td class="line">4</td><td class="hits">1</td><td class="source">var slice = [].slice;</td></tr><tr><td class="line">5</td><td class="hits"></td><td class="source"> </td></tr><tr class="hit"> <td class="line">6</td><td class="hits">1</td><td class="source">var then = function(fn) {</td></tr><tr class="hit"> <td class="line">7</td><td class="hits">95</td><td class="source"> var subscribable = new PreservedSubscribable();</td></tr><tr class="hit"> <td class="line">8</td><td class="hits">95</td><td class="source"> fn(function() {</td></tr><tr class="hit"> <td class="line">9</td><td class="hits">95</td><td class="source"> subscribable._notify.apply(subscribable, arguments);</td></tr><tr><td class="line">10</td><td class="hits"></td><td class="source"> });</td></tr><tr class="hit"> <td class="line">11</td><td class="hits">95</td><td class="source"> return subscribable;</td></tr><tr><td class="line">12</td><td class="hits"></td><td class="source">};</td></tr><tr><td class="line">13</td><td class="hits"></td><td class="source"> </td></tr><tr class="hit"> <td class="line">14</td><td class="hits">1</td><td class="source">var fromNodeStyleMethod = function(method, args, target) {</td></tr><tr class="hit"> <td class="line">15</td><td class="hits">88</td><td class="source"> args = slice.call(args);</td></tr><tr class="hit"> <td class="line">16</td><td class="hits">88</td><td class="source"> return then(function(fn) {</td></tr><tr class="hit"> <td class="line">17</td><td class="hits">88</td><td class="source"> method.apply(target, args.concat(function(err) {</td></tr><tr class="hit"> <td class="line">18</td><td class="hits">88</td><td class="source"> if (err) {</td></tr><tr class="miss"> <td class="line">19</td><td class="hits">0</td><td class="source"> console.log(err);</td></tr><tr><td class="line">20</td><td class="hits"></td><td class="source"> } else { </td></tr><tr class="hit"> <td class="line">21</td><td class="hits">88</td><td class="source"> fn.apply(null, slice.call(arguments, 1));</td></tr><tr><td class="line">22</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">23</td><td class="hits"></td><td class="source"> }));</td></tr><tr><td class="line">24</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">25</td><td class="hits"></td><td class="source">};</td></tr><tr><td class="line">26</td><td class="hits"></td><td class="source"> </td></tr><tr class="hit"> <td class="line">27</td><td class="hits">1</td><td class="source">module.exports = _.extend(PreservedSubscribable.merge, {</td></tr><tr><td class="line">28</td><td class="hits"></td><td class="source"> fromNodeStyleMethod: fromNodeStyleMethod,</td></tr><tr><td class="line">29</td><td class="hits"></td><td class="source"> then: then,</td></tr><tr><td class="line">30</td><td class="hits"></td><td class="source"> mutable: function() {</td></tr><tr class="hit"> <td class="line">31</td><td class="hits">26</td><td class="source"> return new Mutable();</td></tr><tr><td class="line">32</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">33</td><td class="hits"></td><td class="source">});</td></tr></tbody></table></div><div class="file"><h2 id="mutable.js">mutable.js</h2><div id="stats" class="high"><div class="percentage">80%</div><div class="sloc">5</div><div class="hits">4</div><div class="misses">1</div></div><table id="source"><thead><tr><th>Line</th><th>Hits</th><th>Source</th></tr></thead><tbody><tr class="hit"> <td class="line">1</td><td class="hits">1</td><td class="source">var PreservedSubscribable = require('./preserved-subscribable');</td></tr><tr><td class="line">2</td><td class="hits"></td><td class="source"> </td></tr><tr class="hit"> <td class="line">3</td><td class="hits">1</td><td class="source">module.exports = PreservedSubscribable.extend(</td></tr><tr><td class="line">4</td><td class="hits"></td><td class="source"> function() {</td></tr><tr class="hit"> <td class="line">5</td><td class="hits">26</td><td class="source"> if (arguments.length) {</td></tr><tr class="miss"> <td class="line">6</td><td class="hits">0</td><td class="source"> this.value.apply(this, arguments);</td></tr><tr><td class="line">7</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">8</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">9</td><td class="hits"></td><td class="source"> {</td></tr><tr><td class="line">10</td><td class="hits"></td><td class="source"> value: function() {</td></tr><tr class="hit"> <td class="line">11</td><td class="hits">25</td><td class="source"> this._notify.apply(this, arguments);</td></tr><tr><td class="line">12</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">13</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">14</td><td class="hits"></td><td class="source">);</td></tr></tbody></table></div><div class="file"><h2 id="preserved-subscribable.js">preserved-subscribable.js</h2><div id="stats" class="high"><div class="percentage">91%</div><div class="sloc">61</div><div class="hits">56</div><div class="misses">5</div></div><table id="source"><thead><tr><th>Line</th><th>Hits</th><th>Source</th></tr></thead><tbody><tr class="hit"> <td class="line">1</td><td class="hits">1</td><td class="source">var slice = [].slice;</td></tr><tr class="hit"> <td class="line">2</td><td class="hits">1</td><td class="source">var _ = require('underscore');</td></tr><tr class="hit"> <td class="line">3</td><td class="hits">1</td><td class="source">var Subscribable = require('./subscribable');</td></tr><tr class="hit"> <td class="line">4</td><td class="hits">1</td><td class="source">var notify = Subscribable.prototype._notify;</td></tr><tr class="hit"> <td class="line">5</td><td class="hits">1</td><td class="source">var subscribe = Subscribable.prototype.subscribe;</td></tr><tr><td class="line">6</td><td class="hits"></td><td class="source"> </td></tr><tr><td class="line">7</td><td class="hits"></td><td class="source"> </td></tr><tr class="hit"> <td class="line">8</td><td class="hits">1</td><td class="source">var PreservedSubscribable = Subscribable.extend({</td></tr><tr><td class="line">9</td><td class="hits"></td><td class="source"> _notify: function() {</td></tr><tr class="hit"> <td class="line">10</td><td class="hits">458</td><td class="source"> if (!this._isChanged(this, arguments)) {</td></tr><tr class="miss"> <td class="line">11</td><td class="hits">0</td><td class="source"> return;</td></tr><tr><td class="line">12</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">13</td><td class="hits"></td><td class="source"> </td></tr><tr class="hit"> <td class="line">14</td><td class="hits">458</td><td class="source"> this._args = arguments;</td></tr><tr class="hit"> <td class="line">15</td><td class="hits">458</td><td class="source"> return notify.apply(this, arguments);</td></tr><tr><td class="line">16</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">17</td><td class="hits"></td><td class="source"> </td></tr><tr><td class="line">18</td><td class="hits"></td><td class="source"> _isChanged: function(args) {</td></tr><tr class="hit"> <td class="line">19</td><td class="hits">458</td><td class="source"> if (!this._args) {</td></tr><tr class="hit"> <td class="line">20</td><td class="hits">413</td><td class="source"> return true;</td></tr><tr><td class="line">21</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">22</td><td class="hits"></td><td class="source"> </td></tr><tr class="hit"> <td class="line">23</td><td class="hits">45</td><td class="source"> if (this._args.length !== args.length) {</td></tr><tr class="hit"> <td class="line">24</td><td class="hits">45</td><td class="source"> return true;</td></tr><tr><td class="line">25</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">26</td><td class="hits"></td><td class="source"> </td></tr><tr class="miss"> <td class="line">27</td><td class="hits">0</td><td class="source"> var self = this;</td></tr><tr class="miss"> <td class="line">28</td><td class="hits">0</td><td class="source"> return !_.all(this._args, function(arg, i) {</td></tr><tr class="miss"> <td class="line">29</td><td class="hits">0</td><td class="source"> return self.compare(arg === args[i]);</td></tr><tr><td class="line">30</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">31</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">32</td><td class="hits"></td><td class="source"> </td></tr><tr><td class="line">33</td><td class="hits"></td><td class="source"> compare: function(a, b) {</td></tr><tr class="miss"> <td class="line">34</td><td class="hits">0</td><td class="source"> return a === b;</td></tr><tr><td class="line">35</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">36</td><td class="hits"></td><td class="source"> </td></tr><tr><td class="line">37</td><td class="hits"></td><td class="source"> subscribe: function(fn) {</td></tr><tr class="hit"> <td class="line">38</td><td class="hits">415</td><td class="source"> if (this._args) {</td></tr><tr class="hit"> <td class="line">39</td><td class="hits">148</td><td class="source"> fn.apply(null, this._args);</td></tr><tr><td class="line">40</td><td class="hits"></td><td class="source"> }</td></tr><tr class="hit"> <td class="line">41</td><td class="hits">415</td><td class="source"> return subscribe.call(this, fn);</td></tr><tr><td class="line">42</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">43</td><td class="hits"></td><td class="source"> </td></tr><tr><td class="line">44</td><td class="hits"></td><td class="source"> then: function(fn) {</td></tr><tr class="hit"> <td class="line">45</td><td class="hits">98</td><td class="source"> var subscribable = new PreservedSubscribable();</td></tr><tr class="hit"> <td class="line">46</td><td class="hits">98</td><td class="source"> this.subscribe(function() {</td></tr><tr class="hit"> <td class="line">47</td><td class="hits">98</td><td class="source"> var then = function() {</td></tr><tr class="hit"> <td class="line">48</td><td class="hits">95</td><td class="source"> mergeArray(arguments).subscribe(function(arr) {</td></tr><tr class="hit"> <td class="line">49</td><td class="hits">95</td><td class="source"> subscribable._notify.apply(subscribable, arr);</td></tr><tr><td class="line">50</td><td class="hits"></td><td class="source"> }); </td></tr><tr><td class="line">51</td><td class="hits"></td><td class="source"> };</td></tr><tr><td class="line">52</td><td class="hits"></td><td class="source"> </td></tr><tr class="hit"> <td class="line">53</td><td class="hits">98</td><td class="source"> var ret = fn.apply(null, slice.call(arguments).concat([then]));</td></tr><tr><td class="line">54</td><td class="hits"></td><td class="source"> </td></tr><tr class="hit"> <td class="line">55</td><td class="hits">98</td><td class="source"> if (ret !== undefined) {</td></tr><tr class="hit"> <td class="line">56</td><td class="hits">22</td><td class="source"> then(ret);</td></tr><tr><td class="line">57</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">58</td><td class="hits"></td><td class="source"> });</td></tr><tr class="hit"> <td class="line">59</td><td class="hits">98</td><td class="source"> return subscribable;</td></tr><tr><td class="line">60</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">61</td><td class="hits"></td><td class="source">});</td></tr><tr><td class="line">62</td><td class="hits"></td><td class="source"> </td></tr><tr class="hit"> <td class="line">63</td><td class="hits">1</td><td class="source">var mergeArray = function(deps) {</td></tr><tr class="hit"> <td class="line">64</td><td class="hits">198</td><td class="source"> var subscribable = new PreservedSubscribable();</td></tr><tr class="hit"> <td class="line">65</td><td class="hits">198</td><td class="source"> var results = new Array(deps.length);</td></tr><tr class="hit"> <td class="line">66</td><td class="hits">198</td><td class="source"> var isFull = false;</td></tr><tr><td class="line">67</td><td class="hits"></td><td class="source"> </td></tr><tr class="hit"> <td class="line">68</td><td class="hits">198</td><td class="source"> var check = function() {</td></tr><tr class="hit"> <td class="line">69</td><td class="hits">395</td><td class="source"> if (isFull) {</td></tr><tr class="hit"> <td class="line">70</td><td class="hits">45</td><td class="source"> notify();</td></tr><tr class="hit"> <td class="line">71</td><td class="hits">45</td><td class="source"> return;</td></tr><tr><td class="line">72</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">73</td><td class="hits"></td><td class="source"> </td></tr><tr class="hit"> <td class="line">74</td><td class="hits">350</td><td class="source"> for (var i = 0; i &lt; deps.length; i++) {</td></tr><tr class="hit"> <td class="line">75</td><td class="hits">532</td><td class="source"> if (!results[i]) {</td></tr><tr class="hit"> <td class="line">76</td><td class="hits">152</td><td class="source"> return;</td></tr><tr><td class="line">77</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">78</td><td class="hits"></td><td class="source"> }</td></tr><tr class="hit"> <td class="line">79</td><td class="hits">198</td><td class="source"> isFull = true;</td></tr><tr class="hit"> <td class="line">80</td><td class="hits">198</td><td class="source"> notify();</td></tr><tr><td class="line">81</td><td class="hits"></td><td class="source"> };</td></tr><tr><td class="line">82</td><td class="hits"></td><td class="source"> </td></tr><tr class="hit"> <td class="line">83</td><td class="hits">198</td><td class="source"> var notify = function() { </td></tr><tr class="hit"> <td class="line">84</td><td class="hits">243</td><td class="source"> subscribable._notify(results.reduce(function(ret, args) {</td></tr><tr class="hit"> <td class="line">85</td><td class="hits">379</td><td class="source"> ret.push.apply(ret, args);</td></tr><tr class="hit"> <td class="line">86</td><td class="hits">379</td><td class="source"> return ret;</td></tr><tr><td class="line">87</td><td class="hits"></td><td class="source"> }, []));</td></tr><tr><td class="line">88</td><td class="hits"></td><td class="source"> };</td></tr><tr><td class="line">89</td><td class="hits"></td><td class="source"> </td></tr><tr class="hit"> <td class="line">90</td><td class="hits">198</td><td class="source"> _.each(deps, function(dep, i) {</td></tr><tr class="hit"> <td class="line">91</td><td class="hits">317</td><td class="source"> if (_.isArray(dep)) {</td></tr><tr class="hit"> <td class="line">92</td><td class="hits">90</td><td class="source"> dep = mergeArray(dep);</td></tr><tr><td class="line">93</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">94</td><td class="hits"></td><td class="source"> </td></tr><tr class="hit"> <td class="line">95</td><td class="hits">317</td><td class="source"> if (dep.subscribe) {</td></tr><tr class="hit"> <td class="line">96</td><td class="hits">197</td><td class="source"> dep.subscribe(function() {</td></tr><tr class="hit"> <td class="line">97</td><td class="hits">197</td><td class="source"> results[i] = slice.call(arguments);</td></tr><tr class="hit"> <td class="line">98</td><td class="hits">197</td><td class="source"> check(); </td></tr><tr><td class="line">99</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">100</td><td class="hits"></td><td class="source"> } else {</td></tr><tr class="hit"> <td class="line">101</td><td class="hits">120</td><td class="source"> results[i] = [dep];</td></tr><tr><td class="line">102</td><td class="hits"></td><td class="source"> } </td></tr><tr><td class="line">103</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">104</td><td class="hits"></td><td class="source"> </td></tr><tr class="hit"> <td class="line">105</td><td class="hits">198</td><td class="source"> check();</td></tr><tr><td class="line">106</td><td class="hits"></td><td class="source"> </td></tr><tr class="hit"> <td class="line">107</td><td class="hits">198</td><td class="source"> return subscribable;</td></tr><tr><td class="line">108</td><td class="hits"></td><td class="source">};</td></tr><tr><td class="line">109</td><td class="hits"></td><td class="source"> </td></tr><tr class="hit"> <td class="line">110</td><td class="hits">1</td><td class="source">PreservedSubscribable.merge = function() {</td></tr><tr class="hit"> <td class="line">111</td><td class="hits">13</td><td class="source"> return mergeArray(arguments).then(function(arr, callback) {</td></tr><tr class="hit"> <td class="line">112</td><td class="hits">13</td><td class="source"> callback.apply(null, arr);</td></tr><tr><td class="line">113</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">114</td><td class="hits"></td><td class="source">};</td></tr><tr><td class="line">115</td><td class="hits"></td><td class="source"> </td></tr><tr class="hit"> <td class="line">116</td><td class="hits">1</td><td class="source">module.exports = PreservedSubscribable;</td></tr></tbody></table></div><div class="file"><h2 id="subscribable.js">subscribable.js</h2><div id="stats" class="medium"><div class="percentage">64%</div><div class="sloc">14</div><div class="hits">9</div><div class="misses">5</div></div><table id="source"><thead><tr><th>Line</th><th>Hits</th><th>Source</th></tr></thead><tbody><tr class="hit"> <td class="line">1</td><td class="hits">1</td><td class="source">var slice = [].slice;</td></tr><tr><td class="line">2</td><td class="hits"></td><td class="source"> </td></tr><tr class="hit"> <td class="line">3</td><td class="hits">1</td><td class="source">module.exports = require('./class')</td></tr><tr><td class="line">4</td><td class="hits"></td><td class="source"> .extend(</td></tr><tr><td class="line">5</td><td class="hits"></td><td class="source"> function() {</td></tr><tr class="hit"> <td class="line">6</td><td class="hits">417</td><td class="source"> this.__subscribers = [];</td></tr><tr><td class="line">7</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">8</td><td class="hits"></td><td class="source"> {</td></tr><tr><td class="line">9</td><td class="hits"></td><td class="source"> subscribe: function(fn) {</td></tr><tr class="hit"> <td class="line">10</td><td class="hits">415</td><td class="source"> var subscribers = this.__subscribers;</td></tr><tr class="hit"> <td class="line">11</td><td class="hits">415</td><td class="source"> subscribers.push(fn);</td></tr><tr class="hit"> <td class="line">12</td><td class="hits">415</td><td class="source"> return function() {</td></tr><tr class="miss"> <td class="line">13</td><td class="hits">0</td><td class="source"> var i = subscribers.indexOf(fn);</td></tr><tr class="miss"> <td class="line">14</td><td class="hits">0</td><td class="source"> if (i === -1) {</td></tr><tr class="miss"> <td class="line">15</td><td class="hits">0</td><td class="source"> return false;</td></tr><tr><td class="line">16</td><td class="hits"></td><td class="source"> } else {</td></tr><tr class="miss"> <td class="line">17</td><td class="hits">0</td><td class="source"> subscribers.splice(i, 1);</td></tr><tr class="miss"> <td class="line">18</td><td class="hits">0</td><td class="source"> return true;</td></tr><tr><td class="line">19</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">20</td><td class="hits"></td><td class="source"> };</td></tr><tr><td class="line">21</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">22</td><td class="hits"></td><td class="source"> </td></tr><tr><td class="line">23</td><td class="hits"></td><td class="source"> _notify: function() {</td></tr><tr class="hit"> <td class="line">24</td><td class="hits">458</td><td class="source"> var args = arguments;</td></tr><tr class="hit"> <td class="line">25</td><td class="hits">458</td><td class="source"> slice.call(this.__subscribers).forEach(function(subscriber) {</td></tr><tr class="hit"> <td class="line">26</td><td class="hits">267</td><td class="source"> subscriber.apply(null, args);</td></tr><tr><td class="line">27</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">28</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">29</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">30</td><td class="hits"></td><td class="source"> );</td></tr></tbody></table></div></div></div></body></html>
57 lib/class.js
View
@@ -4,6 +4,26 @@ var slice = [].slice;
var INITS = '__inits';
+var buildClass = function() {
+ var Class = function() {
+ // 不通过new 来调用
+ if (!this[INITS]) {
+ var proto = Object.create(Class.prototype);
+ Class.apply(proto, arguments);
+ return proto;
+ }
+
+ var self = this, args = arguments;
+ _.each(this[INITS], function(init) {
+ init.apply(self, args);
+ });
+ };
+
+ Class.prototype[INITS] = [];
+
+ return Class;
+};
+
var Abstract = function() {};
// 避免把Abstract本身作为构造函数
@@ -66,14 +86,7 @@ _.extend(Abstract, {
},
extend: function() {
- var Class = function() {
- var self = this, args = arguments;
- _.each(this[INITS], function(init) {
- init.apply(self, args);
- });
- };
-
- Class.prototype[INITS] = [];
+ var Class = buildClass();
// 把parent 加入mixin列表
[].unshift.call(arguments, this);
@@ -86,7 +99,33 @@ _.extend(Abstract, {
return _.all(this.prototype, function(value, key) {
return typeof value === typeof o[key];
});
- }
+ },
+
+ getPrefixedProperties: function(prefix) {
+ var len = prefix.length;
+
+ return _.reduce(this.prototype, function(ret, value, key) {
+ if (key.indexOf(prefix) === 0) {
+ ret[key.substring(len)] = value;
+ }
+ return ret;
+ }, {});
+ },
+
+ setPrefixedProperties: function(prefix, config) {
+ var proto = this.prototype;
+
+ _.each(config, function(value, key) {
+ key = prefix + key;
+ if (_.isObject(proto[key]) && _.isObject(value)) {
+ _.extend(proto[key], value);
+ } else {
+ proto[key] = value;
+ }
+ });
+
+ return this;
+ },
});
module.exports = Abstract.extend();
27 lib/event.js
View
@@ -0,0 +1,27 @@
+var slice = [].slice;
+
+module.exports = require('./subscribable')
+ .extend(
+ function() {
+ this.__subscribers = [];
+ },
+ {
+ subscribe: function(fn) {
+ var subscribers = this.__subscribers;
+ subscribers.push(fn);
+ return function() {
+ var i = subscribers.indexOf(fn);
+ if (i !== -1) {
+ subscribers.splice(i, 1);
+ }
+ };
+ },
+
+ notify: function() {
+ var args = arguments;
+ slice.call(this.__subscribers).forEach(function(subscriber) {
+ subscriber.apply(null, args);
+ });
+ }
+ }
+ );
36 lib/index.js
View
@@ -1,30 +1,14 @@
-var PreservedSubscribable = require('./preserved-subscribable');
-var Mutable = require('./mutable');
-var _ = require('underscore');
-var slice = [].slice;
+var Promise = require('./promise');
-var merge = PreservedSubscribable.merge;
+module.exports = {
+ Event: require('./event'),
+ Promise: Promise,
-var then = function(fn) {
- return (new Mutable()).value().then(fn);
-};
+ then: function(fn) {
+ return new Promise(fn);
+ },
-var fromNodeStyleMethod = function(method, args, target) {
- return then(function(fn) {
- method.apply(target, slice.call(args).concat(function(err) {
- if (err) {
- console.log(err);
- } else {
- fn.apply(null, slice.call(arguments, 1));
- }
- }));
- });
-};
-
-module.exports = _.extend(merge, {
- fromNodeStyleMethod: fromNodeStyleMethod,
- then: then,
- mutable: function() {
- return new Mutable();
+ when: function() {
+ return Promise.when.apply(Promise, arguments);
}
-});
+};
10 lib/mutable.js
View
@@ -1,10 +0,0 @@
-var PreservedSubscribable = require('./preserved-subscribable');
-
-module.exports = PreservedSubscribable.extend(
- {
- value: function() {
- this._notify.apply(this, arguments);
- return this;
- }
- }
-);
18 lib/preserved-event.js
View
@@ -0,0 +1,18 @@
+var Event = require('./event');
+var notify = Event.prototype.notify;
+var subscribe = Event.prototype.subscribe;
+
+module.exports = Event.extend({
+ notify: function() {
+ this._lastArgs = arguments;
+ return notify.apply(this, arguments);
+ },
+
+ subscribe: function(fn) {
+ var dispose = subscribe.apply(this, arguments);
+ if (this._lastArgs) {
+ fn.apply(null, this._lastArgs);
+ }
+ return dispose;
+ }
+});
116 lib/preserved-subscribable.js
View
@@ -1,116 +0,0 @@
-var slice = [].slice;
-var _ = require('underscore');
-var Subscribable = require('./subscribable');
-var notify = Subscribable.prototype._notify;
-var subscribe = Subscribable.prototype.subscribe;
-
-
-var PreservedSubscribable = Subscribable.extend({
- _notify: function() {
- if (!this._isChanged(this, arguments)) {
- return;
- }
-
- this._args = arguments;
- return notify.apply(this, arguments);
- },
-
- _isChanged: function(args) {
- if (!this._args) {
- return true;
- }
-
- if (this._args.length !== args.length) {
- return true;
- }
-
- var self = this;
- return !_.all(this._args, function(arg, i) {
- return self.compare(arg === args[i]);
- });
- },
-
- compare: function(a, b) {
- return a === b;
- },
-
- subscribe: function(fn) {
- if (this._args) {
- fn.apply(null, this._args);
- }
- return subscribe.call(this, fn);
- },
-
- then: function(fn) {
- var subscribable = new PreservedSubscribable();
- this.subscribe(function() {
- var then = function() {
- mergeArray(arguments).subscribe(function(arr) {
- subscribable._notify.apply(subscribable, arr);
- });
- };
-
- var ret = fn.apply(null, slice.call(arguments).concat([then]));
-
- if (ret !== undefined) {
- then(ret);
- }
- });
- return subscribable;
- }
-});
-
-var mergeArray = function(deps) {
- var subscribable = new PreservedSubscribable();
- var results = new Array(deps.length);
- var isFull = false;
-
- var check = function() {
- if (isFull) {
- notify();
- return;
- }
-
- for (var i = 0; i < deps.length; i++) {
- if (!results[i]) {
- return;
- }
- }
- isFull = true;
- notify();
- };
-
- var notify = function() {
- subscribable._notify(results.reduce(function(ret, args) {
- ret.push.apply(ret, args);
- return ret;
- }, []));
- };
-
- _.each(deps, function(dep, i) {
- if (_.isArray(dep)) {
- dep = mergeArray(dep);
- }
-
- if (dep.subscribe) {
- dep.subscribe(function() {
- results[i] = slice.call(arguments);
- check();
- });
- } else {
- results[i] = [dep];
- }
- });
-
- check();
-
- return subscribable;
-};
-
-PreservedSubscribable.merge = function() {
- return mergeArray(arguments).then(function(arr, callback) {
- callback.apply(null, arr);
- });
-};
-
-module.exports = PreservedSubscribable;
164 lib/promise.js
View
@@ -0,0 +1,164 @@
+var PreservedEvent = require('../lib/preserved-event');
+var slice = [].slice;
+var _ = require('underscore');
+var Class = require('./class');
+var Subscribable = require('./subscribable');
+
+var noop = function() {};
+
+var PromiseInterFace = Subscribable.extend({
+ _handle: function(subscriber) {
+ throw new Error('to be implemented')
+ },
+
+ subscribe: function(subscriber) {
+ return this._handle(subscriber || noop);
+ },
+
+ then: function(transformer) {
+ var self = this;
+ return new Promise(function(subscriber) {
+ return self.subscribe(function() {
+ var ret = transformer.apply(null, slice.call(arguments).concat([subscriber]));
+ if (ret !== undefined) {
+ subscriber(ret);
+ }
+ });
+ });
+ }
+ })
+ .mixStatic({
+ when: function() {
+ return whenAllSubscribablesAreNotified(arguments).then(function(arr, callback) {
+ callback.apply(null, arr);
+ });
+ }
+ })
+
+var Promise = PromiseInterFace.extend(
+ function(handle) {
+ this._handle = function(subscriber) {
+ var isDisposed = false;
+
+ var dispose = handle(function() {
+ if (!isDisposed) {
+ whenAllSubscribablesAreNotified(arguments).subscribe(function(arr) {
+ subscriber.apply(null, arr);
+ });
+ }
+ });
+
+ return function() {
+ if (!isDisposed) {
+ isDisposed = true;
+ if (_.isFunction(dispose)) {
+ dispose();
+ }
+ }
+ }
+ }
+ }
+);
+
+var ReturnObjectPromise = PromiseInterFace.extend(
+ function() {
+ var args = arguments;
+ this._handle = function(subscriber) {
+ subscriber.apply(null, args);
+ return noop;
+ }
+ }
+);
+
+var containsSubscribable = function(o) {
+ if (!o) {
+ return false;
+ }
+
+ if (Subscribable.test(o)) {
+ return true;
+ }
+
+ if (typeof o === 'object' && typeof o.length === 'number') {
+ return _.some(o, arguments.callee);
+ }
+
+ return false;
+};
+
+var whenAllSubscribablesAreNotified = function(subscribables) {
+
+ subscribables = slice.call(subscribables);
+
+ return containsSubscribable(subscribables) ? new Promise(function(callback) {
+ var results = new Array(subscribables.length);
+
+ var check = creatCheck(results, callback);
+
+ var disposes = checkEachSubscribables(subscribables, check);
+
+ return function() {
+ disposes.forEach(function(dispose) {
+ dispose();
+ });
+ }
+ }) :
+ new ReturnObjectPromise(subscribables);
+ ;
+};
+
+var creatCheck = function(results, callback) {
+ var isFull = false;
+
+ var notify = function() {
+ callback(results.reduce(function(ret, args) {
+ return ret.concat(args);
+ }, []));
+ };
+
+ return results.length ?
+ function(resultsIndex, args) {
+ results[resultsIndex] = args;
+
+ if (isFull) {
+ notify();
+ return;
+ }
+
+ for (var i = 0; i < results.length; i++) {
+ if (!results[i]) {
+ return;
+ }
+ }
+
+ isFull = true;
+ notify();
+ } :
+ notify
+ ;
+};
+
+var checkEachSubscribables = function(subscribables, check) {
+ var disposes = [];
+ if (subscribables.length) {
+ _.each(subscribables, function(dep, i) {
+ if (_.isArray(dep)) {
+ dep = whenAllSubscribablesAreNotified(dep);
+ }
+
+ if (Subscribable.test(dep)) {
+ disposes.push(dep.subscribe(function() {
+ check(i, slice.call(arguments));
+ }));
+ } else {
+ check(i, [dep]);
+ }
+ });
+ } else {
+ check();
+ }
+
+ return disposes;
+};
+
+module.exports = Promise;
35 lib/subscribable.js
View
@@ -1,30 +1,5 @@
-var slice = [].slice;
-
-module.exports = require('./class')
- .extend(
- function() {
- this.__subscribers = [];
- },
- {
- subscribe: function(fn) {
- var subscribers = this.__subscribers;
- subscribers.push(fn);
- return function() {
- var i = subscribers.indexOf(fn);
- if (i === -1) {
- return false;
- } else {
- subscribers.splice(i, 1);
- return true;
- }
- };
- },
-
- _notify: function() {
- var args = arguments;
- slice.call(this.__subscribers).forEach(function(subscriber) {
- subscriber.apply(null, args);
- });
- }
- }
- );
+module.exports = require('./class').extend({
+ subscribe: function() {
+ throw new Error('to be implemented');
+ }
+});
19 fs.js → node/fs.js
View
@@ -1,7 +1,21 @@
var fs = require('fs');
var _ = require('underscore');
-var rx = require('./index');
+var rx = require('../lib/index');
var p = require('path');
+var slice = [].slice;
+
+var fromNodeStyleMethod = function(method, args, target) {
+ return rx.then(function(fn) {
+ method.apply(target, slice.call(args).concat(function(err) {
+ if (err) {
+ console.log(err);
+ } else {
+ fn.apply(null, slice.call(arguments, 1));
+ }
+ }));
+ });
+};
+
var returnTrue = function() {return true};
@@ -142,7 +156,7 @@ var rfs = module.exports = {
_.each(fs, function(fn, key) {
if (!/Sync$/.test(key)) {
rfs[key] = function() {
- return rx.fromNodeStyleMethod(fn, arguments);
+ return fromNodeStyleMethod(fn, arguments);
};
}
});
@@ -156,3 +170,4 @@ _.each(fs, function(fn, key) {
}
});
+
3  package.json
View
@@ -16,7 +16,8 @@
"main": "./index",
"devDependencies": {
"mocha": "*",
- "spec": "*"
+ "spec": "*",
+ "sinon": "*"
},
"dependencies" : {
"underscore": "*"
38 test/event.js
View
@@ -0,0 +1,38 @@
+var Event = require('../lib/event');
+var sinon = require('sinon');
+var assert = require('assert');
+
+
+describe('event', function() {
+ var ev, spy;
+
+ beforeEach(function() {
+ ev = new Event();
+ spy = sinon.spy();
+ })
+
+ describe('#notify()', function() {
+
+ it('should notify subscriber', function() {
+ ev.subscribe(spy);
+ ev.notify(1, 2);
+ assert(spy.calledWith(1, 2), true);
+
+
+ ev.notify(2, 2);
+ assert(spy.calledWith(2, 2), true);
+
+ })
+
+ });
+
+
+ describe('dispose', function() {
+ it('should not call subscriber after dispose', function() {
+ var dispose = ev.subscribe(spy);
+ dispose();
+ ev.notify(1, 2);
+ assert.equal(spy.callCount, 0);
+ })
+ });
+});
6 test/fs.js
View
@@ -1,7 +1,7 @@
var assert = require("assert")
var slice = [].slice;
var rx = require('../index')
-var rfs = require('../fs');
+var rfs = require('../node/fs');
var path = require('path')
var DATA_FILE_DIR = path.join(__dirname, 'data');
@@ -12,6 +12,8 @@ var TXT2 = path.join(DATA_FILE_DIR, '2.txt');
var TXT1_CONTENT = '100'
var TXT2_CONTENT = '1000'
+
+
describe('fs', function() {
describe('#readFile', function() {
var file1 = rfs.readFile(TXT1, 'utf8'), file2 = rfs.readFile(TXT2, 'utf8');
@@ -24,7 +26,7 @@ describe('fs', function() {
})
it('rx merge file', function(done) {
- rx(file1, file2).subscribe(function() {
+ rx.when(file1, file2).subscribe(function() {
assert.deepEqual(slice.call(arguments), [TXT1_CONTENT, TXT2_CONTENT]);
done();
})
42 test/preserved-event.js
View
@@ -0,0 +1,42 @@
+var PreservedEvent = require('../lib/preserved-event');
+var sinon = require('sinon');
+var assert = require('assert');
+
+
+describe('preserved-event', function() {
+ var ev, spy;
+
+ beforeEach(function() {
+ ev = new PreservedEvent();
+ spy = sinon.spy();
+ })
+
+ describe('#notify()', function() {
+
+ it('subscriber should be notify for last notify action', function() {
+ ev.notify(1, 2);
+ ev.subscribe(spy);
+ assert(spy.calledWith(1, 2), true);
+
+
+ ev.notify(2, 2);
+ assert(spy.calledWith(2, 2), true);
+
+ })
+
+ });
+
+
+ describe('dispose', function() {
+ it('should not call subscriber after dispose', function() {
+ ev.notify(1, 2);
+ var dispose = ev.subscribe(spy);
+ assert(spy.calledWith(1, 2), true);
+ dispose();
+
+ // not affect
+ ev.notify(2, 2);
+ assert(spy.calledWith(1, 2), true);
+ })
+ });
+});
181 test/promise.js
View
@@ -0,0 +1,181 @@
+var Promise = require('../lib/promise');
+var sinon = require('sinon');
+var assert = require('assert');
+var slice = [].slice;
+
+describe('promise', function() {
+ var r1 = new Promise(function(callback) {
+ callback(1)
+ });
+
+ var a, b;
+ var spy
+
+ var clock;
+
+ before(function () { clock = sinon.useFakeTimers(); });
+ after(function () { clock.restore(); });
+
+ beforeEach(function() {
+ spy = sinon.spy();
+ a = new Promise(function(callback) {
+ callback(1, 2)
+ });
+ b = new Promise(function(callback) {
+ callback(3, 4)
+ });
+ })
+
+ describe('::new', function() {
+ it('evaluate promise', function() {
+ var a = new Promise(function(callback) {
+ callback(new Promise(function(callback2) {
+ callback2(2)
+ }))
+ });
+
+ a.subscribe(spy);
+
+ assert(spy.calledWith(2))
+ });
+ });
+
+ describe('then', function() {
+ it('should transform data', function() {
+ r1.then(function(a, next) {
+ next(a + 1);
+ }).subscribe(function() {
+ assert.deepEqual(slice.call(arguments), [2])
+ });
+ });
+
+ it('should transform promise data', function() {
+ r1.then(function(a, next) {
+ next(new Promise(function(callback) {
+ callback(a + 1)
+ }));
+ }).subscribe(spy);
+
+ assert(spy.calledWith(2))
+ });
+
+ it('transform return value like callback', function() {
+ r1.then(function(a, next) {
+ return a + 1;
+ }).subscribe(spy);
+
+ assert(spy.calledWith(2))
+ })
+
+ it('transform return promise like callback', function() {
+ r1.then(function(a, next) {
+ return [new Promise(function(callback) {
+ callback(a + 1)
+ })];
+ }).subscribe(spy);
+
+ assert(spy.calledWith([2]))
+ });
+
+ })
+
+ describe('when', function() {
+ it('call without args should notify', function(done) {
+ Promise.when().subscribe(function() {
+ assert.equal(arguments.length, 0)
+ assert.deepEqual(slice.call(arguments), []);
+ done();
+ });
+ });
+
+ it('call without empty array should notify', function(done) {
+ Promise.when([]).subscribe(function() {
+ assert.equal(arguments.length, 1)
+ assert.deepEqual(slice.call(arguments), [[]]);
+ done();
+ });
+ });
+
+ it('notify for each promise', function() {
+ Promise.when(a, new Promise(function(callback) {
+ callback(1);
+ setTimeout(function() {
+ callback(2)
+ }, 100)
+ })).subscribe(spy);
+
+ assert(spy.calledWith(1,2,1));
+ clock.tick(100);
+ assert(spy.calledWith(1,2,2));
+ clock.tick(100);
+ assert.equal(spy.callCount, 2);
+ });
+
+ it('dispose', function() {
+ var spy = sinon.spy();
+ var dispose = Promise.when(a, new Promise(function(callback) {
+ callback(1);
+ setTimeout(function() {
+ callback(2)
+ }, 100)
+ })).subscribe(spy);
+
+ assert(spy.calledWith(1,2,1));
+ dispose();
+
+ clock.tick(101);
+ assert.equal(spy.callCount, 1);
+ });
+
+
+ it('args should be right1', function(done) {
+ Promise.when(a, b).subscribe(function() {
+ assert.equal(arguments.length, 4)
+ assert.deepEqual(slice.call(arguments), [1,2,3,4]);
+ done();
+ });
+ });
+
+ it('args should be right2', function(done) {
+ Promise.when([a, b]).subscribe(function() {
+ assert.equal(arguments.length, 1)
+ assert.deepEqual(slice.call(arguments), [[1,2,3,4]]);
+ done();
+ });
+ });
+
+
+ it(' should be merged', function(done) {
+ Promise.when([a, b]).subscribe(function() {
+ assert.deepEqual(slice.call(arguments), [[1,2,3,4]])
+ done();
+ });
+ });
+
+ it(' should be merged', function(done) {
+ Promise.when(a, [a, [a, b]]).subscribe(function() {
+ assert.deepEqual(slice.call(arguments), [1,2,[1,2, [1,2,3,4]]])
+ done();
+ });
+ });
+
+ it('im should be accept', function(done) {
+ Promise.when(a, [a, [a, b, 10], 10]).subscribe(function() {
+ assert.deepEqual(slice.call(arguments), [1,2,[1,2, [1,2,3,4, 10], 10]])
+ done();
+ });
+ });
+
+ it('nested rx should be accept', function(done) {
+ var c = Promise.when(a, b);
+ var d = Promise.when([a], c);
+
+ d.subscribe(function() {
+ assert.deepEqual(slice.call(arguments), [[1,2], 1,2,3,4])
+ done();
+ });
+ })
+
+ })
+
+})
487 test/rx.js
View
@@ -1,183 +1,320 @@
-var assert = require("assert")
-var slice = [].slice;
-var rx = require('../index');
+// var assert = require("assert")
+// var slice = [].slice;
+// var rx = require('../index');
+// var sinon = require('sinon');
-describe('rx', function() {
- describe('#mutable()', function() {
- var mu;
+// describe('rx', function() {
- beforeEach(function() {
- mu = rx.mutable();
- });
+// var clock;
- it('mutable should be subscribable', function() {
- assert.equal(typeof mu.subscribe, 'function')
- })
+// before(function () { clock = sinon.useFakeTimers(); });
+// after(function () { clock.restore(); });
+// describe('#mutable()', function() {
+// var mu;
- it('value before subscribe should be receive by subscribe', function(done) {
- mu.value(1, 2);
- mu.subscribe(function() {
- assert.deepEqual(slice.call(arguments), [1, 2]);
- done();
- })
- });
+// beforeEach(function() {
+// mu = rx.mutable();
+// });
- it('value after subscribe should be receive by subscribe', function(done) {
+// it('mutable should be subscribable', function() {
+// assert.equal(typeof mu.subscribe, 'function')
+// })
+
+
+// it('value before subscribe should be receive by subscribe', function(done) {
+// mu.value(1, 2);
+// mu.subscribe(function() {
+// assert.deepEqual(slice.call(arguments), [1, 2]);
+// done();
+// })
+// });
+
+// it('value after subscribe should be receive by subscribe', function(done) {
- mu.subscribe(function() {
- assert.deepEqual(slice.call(arguments), [1, 2]);
- done();
- })
- mu.value(1, 2);
- });
- });
-
- describe('#()', function() {
- var a, b;
-
- beforeEach(function() {
- a = rx.mutable();
- b = rx.mutable();
-
- a.value(1, 2);
- b.value(3, 4);
- })
-
- it('mutable should be merged', function(done) {
- rx(a, b).subscribe(function() {
- assert.deepEqual(slice.call(arguments), [1,2,3,4])
- done();
- });
- });
-
- it('mutable should be merged', function(done) {
- rx([a, b]).subscribe(function() {
- assert.deepEqual(slice.call(arguments), [[1,2,3,4]])
- done();
- });
- });
-
- it('mutable should be merged', function(done) {
- rx(a, [a, [a, b]]).subscribe(function() {
- assert.deepEqual(slice.call(arguments), [1,2,[1,2, [1,2,3,4]]])
- done();
- });
- });
-
- it('immutable should be accept', function(done) {
- rx(a, [a, [a, b, 10], 10]).subscribe(function() {
- assert.deepEqual(slice.call(arguments), [1,2,[1,2, [1,2,3,4, 10], 10]])
- done();
- });
- });
-
- it('nested rx should be accept', function(done) {
- var c = rx(a, b);
- var d = rx([a], c);
-
- d.subscribe(function() {
- assert.deepEqual(slice.call(arguments), [[1,2], 1,2,3,4])
- done();
- });
- })
-
- });
-
- describe('rx.then', function() {
- it('should be subscribed', function(done) {
- rx.then(function() {
- return 1;
- }).subscribe(function() {
- assert.deepEqual(slice.call(arguments), [1]);
- done();
- })
- });
-
-
- it('should be subscribed', function(done) {
- rx.then(function(callback) {
- return callback(1, 2);
- }).subscribe(function() {
- assert.deepEqual(slice.call(arguments), [1, 2]);
- done();
- })
- });
- });
-
- describe('#then', function() {
- var a, b;
-
- beforeEach(function() {
- a = rx.mutable();
- b = rx.mutable();
-
- a.value(1, 2);
- b.value(3, 4);
- })
-
-
- it('then args should be right', function(done) {
- a.then(function() {
- assert.equal(arguments.length, 3)
- assert.deepEqual(slice.call(arguments, 0, arguments.length - 1), [1,2]);
- assert.equal(typeof arguments[arguments.length - 1], 'function');
- done();
- });
- });
-
- it('then args should be right', function(done) {
- rx(a, b).then(function() {
- assert.equal(arguments.length, 5)
- assert.deepEqual(slice.call(arguments, 0, arguments.length - 1), [1,2,3,4]);
- assert.equal(typeof arguments[arguments.length - 1], 'function');
- done();
- });
- });
-
- it('then args should be right', function(done) {
- rx([a, b]).then(function() {
- assert.equal(arguments.length, 2)
- assert.deepEqual(slice.call(arguments, 0, arguments.length - 1), [[1,2,3,4]]);
- assert.equal(typeof arguments[arguments.length - 1], 'function');
- done();
- });
- });
-
-
- it('then should pass right value', function(done) {
- a.then(function(j, k, fn) {
- fn(k, j);
- }).subscribe(function() {
- assert.equal(arguments.length, 2)
- assert.deepEqual(slice.call(arguments), [2, 1])
- done();
- });
- })
-
- it('then should pass right value', function(done) {
- a.then(function(j, k, fn) {
- fn([k, j]);
- }).subscribe(function() {
- assert.equal(arguments.length, 1)
- assert.deepEqual(slice.call(arguments), [[2, 1]])
- done();
- });
- })
-
- it('then auto proccess rx', function(done) {
- a.then(function(j, k, fn) {
- var c = rx.mutable();
- fn(c);
- setTimeout(function() {
- c.value(k, j)
- }, 40);
- }).subscribe(function() {
- assert.equal(arguments.length, 2)
- assert.deepEqual(slice.call(arguments), [2, 1])
- done();
- });
- });
- });
-});
+// mu.subscribe(function() {
+// assert.deepEqual(slice.call(arguments), [1, 2]);
+// done();
+// })
+// mu.value(1, 2);
+// });
+// });
+
+// describe('#()', function() {
+// var a, b;
+
+// beforeEach(function() {
+// a = rx.mutable();
+// b = rx.mutable();
+
+// a.value(1, 2);
+// b.value(3, 4);
+// })
+
+// it('mutable should be merged', function(done) {
+// rx(a, b).subscribe(function() {
+// assert.deepEqual(slice.call(arguments), [1,2,3,4])
+// done();
+// });
+// });
+
+// it('mutable should be merged', function(done) {
+// rx([a, b]).subscribe(function() {
+// assert.deepEqual(slice.call(arguments), [[1,2,3,4]])
+// done();
+// });
+// });
+
+// it('mutable should be merged', function(done) {
+// rx(a, [a, [a, b]]).subscribe(function() {
+// assert.deepEqual(slice.call(arguments), [1,2,[1,2, [1,2,3,4]]])
+// done();
+// });
+// });
+
+// it('immutable should be accept', function(done) {
+// rx(a, [a, [a, b, 10], 10]).subscribe(function() {
+// assert.deepEqual(slice.call(arguments), [1,2,[1,2, [1,2,3,4, 10], 10]])
+// done();
+// });
+// });
+
+// it('nested rx should be accept', function(done) {
+// var c = rx(a, b);
+// var d = rx([a], c);
+
+// d.subscribe(function() {
+// assert.deepEqual(slice.call(arguments), [[1,2], 1,2,3,4])
+// done();
+// });
+// })
+
+// });
+
+// describe('rx.then', function() {
+// it('should be subscribed', function(done) {
+// rx.then(function() {
+// return 1;
+// }).subscribe(function() {
+// assert.deepEqual(slice.call(arguments), [1]);
+// done();
+// })
+// });
+
+
+// it('should be subscribed', function(done) {
+// rx.then(function(callback) {
+// return callback(1, 2);
+// }).subscribe(function() {
+// assert.deepEqual(slice.call(arguments), [1, 2]);
+// done();
+// })
+// });
+// });
+
+// describe('#then', function() {
+// var a, b, spy;
+
+// beforeEach(function() {
+// spy = sinon.spy();
+// a = rx.mutable();
+// b = rx.mutable();
+
+// a.value(1, 2);
+// b.value(3, 4);
+// })
+
+
+// // it('then args should be right', function(done) {
+// // a.subscribe(function() {
+// // assert.equal(arguments.length, 3)
+// // assert.deepEqual(slice.call(arguments, 0, arguments.length - 1), [1,2]);
+// // assert.equal(typeof arguments[arguments.length - 1], 'function');
+// // done();
+// // });
+// // });
+
+// // it('then args should be right', function(done) {
+// // rx(a, b).subscribe(function() {
+// // assert.equal(arguments.length, 5)
+// // assert.deepEqual(slice.call(arguments, 0, arguments.length - 1), [1,2,3,4]);
+// // assert.equal(typeof arguments[arguments.length - 1], 'function');
+// // done();
+// // });
+// // });
+
+// // it('then args should be right', function(done) {
+// // rx([a, b]).subscribe(function() {
+// // assert.equal(arguments.length, 2)
+// // assert.deepEqual(slice.call(arguments, 0, arguments.length - 1), [[1,2,3,4]]);
+// // assert.equal(typeof arguments[arguments.length - 1], 'function');
+// // done();
+// // });
+// // });
+
+
+// it('then should pass right value', function(done) {
+// a.then(function(j, k, fn) {
+// fn(k, j);
+// }).subscribe(function() {
+// assert.equal(arguments.length, 2)
+// assert.deepEqual(slice.call(arguments), [2, 1])
+// done();
+// });
+// })
+
+// it('then should pass right value', function(done) {
+// a.then(function(j, k, fn) {
+// fn([k, j]);
+// }).subscribe(function() {
+// assert.equal(arguments.length, 1)
+// assert.deepEqual(slice.call(arguments), [[2, 1]])
+// done();
+// });
+// })
+
+// it('then auto proccess rx', function(done) {
+// a.then(function(j, k, fn) {
+// var c = rx.mutable();
+// fn(c);
+// setTimeout(function() {
+// c.value(k, j)
+// }, 40);
+// }).subscribe(function() {
+// assert.equal(arguments.length, 2)
+// assert.deepEqual(slice.call(arguments), [2, 1])
+// done();
+// });
+// });
+// });
+
+
+
+// describe('dispose', function() {
+// var mu;
+// beforeEach(function() {
+// clock = sinon.useFakeTimers();
+// mu = rx.then(function(callback) {
+// setTimeout(function() {
+// callback();
+// }, 100)
+// });
+// });
+
+// it('should dispose when dispose was called after notify but before execute', function() {
+// var spy = sinon.spy();
+// var dispose = mu.subscribe(spy);
+// clock.tick(99);
+// dispose();
+// clock.tick(10);
+// assert.equal(spy.called, false);
+// })
+// });
+
+// });
+
+
+
+
+// describe('Observable', function() {
+// var notifyNow, notifyLater, spy;
+
+// var clock;
+
+// before(function () { clock = sinon.useFakeTimers(); });
+// after(function () { clock.restore(); });
+
+// beforeEach(function() {
+// spy = sinon.spy();
+
+// notifyNow = rx.Observable(function(callback) {
+// callback();
+// });
+
+// notifyLater = rx.Observable(function(callback) {
+// setTimeout(function() {
+// callback();
+// }, 100)
+// });
+// });
+
+// describe('subscribe', function() {
+// it('should call subscriber', function() {
+// notifyNow.subscribe(spy);
+// assert.equal(spy.callCount, 1);
+// });
+
+
+// it('should call subscriber multiple times', function() {
+// notifyNow.subscribe(spy);
+// notifyNow.subscribe(spy);
+// assert.equal(spy.callCount, 2);
+// });
+
+
+// it('lazy handle should call subscriber', function() {
+// notifyLater.subscribe(spy);
+// assert.equal(spy.callCount, 0);
+// clock.tick(100);
+// assert.equal(spy.callCount, 1);
+// });
+
+// it('can be dispose', function() {
+// var dispose = notifyLater.subscribe(spy);
+// assert.equal(spy.callCount, 0);
+
+// clock.tick(10);
+// assert.equal(spy.callCount, 0);
+// dispose();
+
+// clock.tick(100);
+// assert.equal(spy.callCount, 0);
+// });
+
+// it('handle\'s dispose should be called', function() {
+// var disposeSpy = sinon.spy();
+
+// notifyLater = rx.Observable(function(callback) {
+// setTimeout(function() {
+// callback();
+// }, 100);
+// return disposeSpy
+// });
+
+// var dispose = notifyLater.subscribe(function() {});
+// dispose();
+// dispose();
+
+// assert.equal(disposeSpy.callCount, 1);
+
+// })
+
+// })
+
+
+// describe('then', function() {
+// var r1 = rx.Observable(function(callback) {
+// callback(1)
+// });
+
+
+// it('should transform data', function() {
+// r1.then(function(a, next) {
+// next(a + 1);
+// }).subscribe(function() {
+// assert.deepEqual(slice.call(arguments), [2])
+// });
+// });
+
+// it('should not called without subscribe', function() {
+// r1.then(spy)
+
+
+// assert.equal(spy.callCount, 0);
+// });
+// })
+
+
+
+// });

No commit comments for this range

Something went wrong with that request. Please try again.