<commit_before>if (typeof window === 'undefined') {
    Formatter = require('./../lib/fomatto').Formatter;
    format = Formatter();
    FormatError = require('./../lib/fomatto').FormatError;

} else {
    var exports = {};
    format = Formatter();
}

exports.testObject = function(test) {
    test.expect(2);
    test.equals(format('Good morning Sir {name}.', {name: 'Lancelot'}),
                'Good morning Sir Lancelot.');

    test.equals(format('Good {time} Sir {name}.', {time: 'evening',
                                                   name: 'Lancelot'}),
                'Good evening Sir Lancelot.');

    test.done();
};

exports.testObjectNum = function(test) {
    test.expect(2);
    test.equals(format('Good morning Sir {0}.', {'0': 'Lancelot'}),
                'Good morning Sir Lancelot.');

    test.equals(format('Good {1} Sir {0}.', {'1': 'evening',
                                             '0': 'Lancelot'}),
                'Good evening Sir Lancelot.');

    test.done();
};

exports.testObjectProperties = function(test) {
    test.expect(8);
    test.equals(format('Good {msg.time} Sir {msg.name}.', {
        msg: {
            name: 'Lancelot',
            time: 'morning'
        }
    }), 'Good morning Sir Lancelot.');

    test.equals(format('Good {msg.time} Sir {msg.name}.', {
        msg: {
            name: 'Lancelot',
            time: 'evening'
        }
    }), 'Good evening Sir Lancelot.');

    test.equals(format('Good {msg["time"]} Sir {msg.name}.', {
        msg: {
            name: 'Lancelot',
            time: 'evening'
        }
    }), 'Good evening Sir Lancelot.');

    test.equals(format('Good {msg[\'values\'][1]} Sir {msg.values[0]}.', {
        msg: {
            values: ['Lancelot', 'evening']
        }
    }), 'Good evening Sir Lancelot.');

    test.equals(format('My favorite color is {colors[\'"favorite"\']}.', {
        colors: {
            '"favorite"': 'blue'
        }
    }), 'My favorite color is blue.');

    test.equals(format('My favorite color is {colors["\"favorite\""]}.', {
        colors: {
            '"favorite"': 'blue'
        }
    }), 'My favorite color is blue.');

    try {
        format('{favorite.color}', {msg: {name:'Lancelot'}});

    } catch(err) {
        test.ok(err instanceof FormatError);
        test.equal(err.message, 'Cannot access property "color" of undefined.');
    }
    test.done();
};

exports.testPrintObject = function(test) {
    var knight = {
        toString: function() {
            return 'Sir Lancelot';
        }
    };

    test.expect(3);
    test.equals(format('Good morning {knight}.', knight),
                'Good morning Sir Lancelot.');

    test.equals(format('Good morning {0}.', knight),
                'Good morning Sir Lancelot.');

    test.equals(format('Good morning {}.', knight),
                'Good morning Sir Lancelot.');

    test.done();
};

exports.testArrayIndex = function(test) {
    test.expect(3);
    test.equals(format('Good morning Sir {0}.', ['Lancelot']),
                'Good morning Sir Lancelot.');

    test.equals(format('Good {0} Sir {1}.', ['evening', 'Lancelot']),
                'Good evening Sir Lancelot.');

    test.equals(format('Good {-2} Sir {-1}.', ['evening', 'Lancelot', 'blue']),
                'Good evening Sir Lancelot.');

    test.done();
};

exports.testPrintArray = function(test) {
    test.expect(2);
    test.equals(format('Good morning Sir {}.', ['Lancelot']),
                'Good morning Sir Lancelot.');

    test.equals(format('Good {0} Sir {1}.', ['morning', 'Lancelot']),
                'Good morning Sir Lancelot.');

    test.done();
};

exports.testPlainKeys = function(test) {
    test.expect(2);
    test.equals(format('Good morning Sir {name}.', 'Lancelot'),
                'Good morning Sir Lancelot.');

    test.equals(format('Good {time} Sir {name}.', 'evening', 'Lancelot'),
                'Good evening Sir Lancelot.');

    test.done();
};

exports.testFormatting = function(test) {
    test.expect(22);
    test.equals(format('{:hex}', 32768), '8000');
    test.equals(format('{:bin}', 255), '11111111');
    test.equals(format('{:hex(true)}', 32768), '0x8000');
    test.equals(format('{:bin(true)}', 255), '0b11111111');
    test.equals(format('{:upper}', 'Lancelot'), 'LANCELOT');
    test.equals(format('{:lower}', 'Lancelot'), 'lancelot');
    test.equals(format('{:upper:lpad(12, " ")}', 'Lancelot'), '    LANCELOT');
    test.equals(format('{:lpad(12)}', 'Lancelot'), '    Lancelot');
    test.equals(format('{:rpad(12, " ")}', 'Lancelot'), 'Lancelot    ');
    test.equals(format('{:pad(12, "=")}', 'Lancelot'), '==Lancelot==');
    test.equals(format('{:pad(12, "\\"=")}', 'Lancelot'), '"="=Lancelot"="=');
    test.equals(format('{:pad(12, "\'=")}', 'Lancelot'), '\'=\'=Lancelot\'=\'=');
    test.equals(format('{:surround("(", ")")}', 'Lancelot'), '(Lancelot)');
    test.equals(format('{:surround("-")}', 'Lancelot'), '-Lancelot-');
    test.equals(format('{:surround("i", "i"):upper}', 'Lancelot'), 'ILANCELOTI');
    test.equals(format('{:surround(\'i\', \'i\'):upper}', 'Lancelot'), 'ILANCELOTI');
    test.equals(format('{name:upper}', {name: 'Lancelot'}), 'LANCELOT');
    test.equals(format('{name[0]:lower}', {name: ['Lancelot']}), 'lancelot');
    test.equals(format('{:join(" ")}', ['blue', 'red', 'green', 'yellow']),
                'blue red green yellow');

    test.equals(format('{:join(",")}', ['blue', 'red', 'green', 'yellow']),
                'blue,red,green,yellow');

    try {
        format('{:unicornify}', 'Lancelot');

    } catch(err) {
        test.ok(err instanceof FormatError);
        test.equal(err.message, 'Undefined formatter "unicornify".');
    }
    test.done();
};

exports.testCustomFormatting = function(test) {
    test.expect(1);
    var custom = Formatter({
        unicorns: function(value) {
            return value + ' unicorns!';
        }
    });

    test.equals(custom('Here come the {:unicorns}', 'five'),
                       'Here come the five unicorns!');
    test.done();
};

exports.testPlainAuto = function(test) {
    test.expect(3);
    test.equals(format('Good morning Sir {}.', 'Lancelot'),
                'Good morning Sir Lancelot.');

    test.equals(format('Good {} Sir {}.', 'evening', 'Lancelot'),
                'Good evening Sir Lancelot.');

    test.equals(format('Good {time} Sir {}.', 'evening', 'Lancelot'),
                'Good evening Sir Lancelot.');

    test.done();
};

exports.testNumbered = function(test) {
    test.expect(4);
    test.equals(format('Good morning Sir {0}.', 'Lancelot'),
                'Good morning Sir Lancelot.');

    test.equals(format('Good {0} Sir {1}.', 'evening', 'Lancelot'),
                'Good evening Sir Lancelot.');

    test.equals(format('Good {1} Sir {0}.', 'Lancelot', 'evening'),
                'Good evening Sir Lancelot.');

    test.equals(format('Good {-1} Sir {-2}.', 'Lancelot', 'evening', 'blue'),
                'Good evening Sir Lancelot.');

    test.done();
};

exports.testMixed = function(test) {
    test.expect(2);

    test.equals(format('Good {time} Sir {1}.', 'evening', 'Lancelot'),
                'Good evening Sir Lancelot.');

    test.equals(format('Good {0} Sir {name}.', 'evening', 'Lancelot'),
                'Good evening Sir Lancelot.');

    test.done();
};

<commit_msg>Clean up the tests<commit_after>
// Setup
if (typeof window === 'undefined') {
    Formatter = require('./../lib/fomatto').Formatter;
    format = Formatter();
    FormatError = require('./../lib/fomatto').FormatError;

} else {
    exports = {};
    format = Formatter();
}

// Plain ------------------------------------------------------------------------
// ------------------------------------------------------------------------------
exports.testPlainNamed = function(test) {
    test.expect(2);
    test.equals(format('Good morning Sir {name}.', 'Lancelot'),
                'Good morning Sir Lancelot.');

    test.equals(format('Good {time} Sir {name}.', 'evening', 'Lancelot'),
                'Good evening Sir Lancelot.');

    test.done();
};

exports.testPlainAuto = function(test) {
    test.expect(3);
    test.equals(format('Good morning Sir {}.', 'Lancelot'),
                'Good morning Sir Lancelot.');

    test.equals(format('Good {} Sir {}.', 'evening', 'Lancelot'),
                'Good evening Sir Lancelot.');

    test.equals(format('Good {time} Sir {}.', 'evening', 'Lancelot'),
                'Good evening Sir Lancelot.');

    test.done();
};

exports.testPlainIndex = function(test) {
    test.expect(4);
    test.equals(format('Good morning Sir {0}.', 'Lancelot'),
                'Good morning Sir Lancelot.');

    test.equals(format('Good {0} Sir {1}.', 'evening', 'Lancelot'),
                'Good evening Sir Lancelot.');

    test.equals(format('Good {1} Sir {0}.', 'Lancelot', 'evening'),
                'Good evening Sir Lancelot.');

    test.equals(format('Good {-1} Sir {-2}.', 'Lancelot', 'evening', 'blue'),
                'Good evening Sir Lancelot.');

    test.done();
};

exports.testPlainMixed = function(test) {
    test.expect(3);
    test.equals(format('Good {time} Sir {1}.', 'evening', 'Lancelot'),
                'Good evening Sir Lancelot.');

    test.equals(format('Good {0} Sir {name}.', 'evening', 'Lancelot'),
                'Good evening Sir Lancelot.');

    test.equals(format('Good {0} Sir {}.', 'evening', 'Lancelot'),
                'Good evening Sir Lancelot.');

    test.done();
};

// Arrays -----------------------------------------------------------------------
// ------------------------------------------------------------------------------
exports.testArrayToString = function(test) {
    test.expect(2);
    test.equals(format('Good morning Sir {}.', ['Lancelot']),
                'Good morning Sir Lancelot.');
    test.equals(format('Good morning {}.', ['Sir', 'Lancelot']),
                'Good morning Sir,Lancelot.');

    test.done();
};

exports.testArrayIndex = function(test) {
    test.expect(3);
    test.equals(format('Good morning Sir {0}.', ['Lancelot']),
                'Good morning Sir Lancelot.');

    test.equals(format('Good {0} Sir {1}.', ['evening', 'Lancelot']),
                'Good evening Sir Lancelot.');

    test.equals(format('Good {-2} Sir {-1}.', ['evening', 'Lancelot', 'blue']),
                'Good evening Sir Lancelot.');

    test.done();
};

// Objects-----------------------------------------------------------------------
// ------------------------------------------------------------------------------
exports.testObjectAccess = function(test) {
    test.expect(4);
    test.equals(format('Good morning Sir {name}.', {name: 'Lancelot'}),
                'Good morning Sir Lancelot.');

    test.equals(format('Good {time} Sir {name}.', {time: 'evening',
                                                   name: 'Lancelot'}),
                'Good evening Sir Lancelot.');

    test.equals(format('Good morning Sir {0}.', {'0': 'Lancelot'}),
                'Good morning Sir Lancelot.');

    test.equals(format('Good {1} Sir {0}.', {'1': 'evening', '0': 'Lancelot'}),
                'Good evening Sir Lancelot.');

    test.done();
};

exports.testObjectToString = function(test) {
    var knight = {
        toString: function() {
            return 'Sir Lancelot';
        }
    };

    test.expect(3);
    test.equals(format('Good morning {knight}.', knight),
                'Good morning Sir Lancelot.');

    test.equals(format('Good morning {0}.', knight),
                'Good morning Sir Lancelot.');

    test.equals(format('Good morning {}.', knight),
                'Good morning Sir Lancelot.');

    test.done();
};

// Property Access --------------------------------------------------------------
// ------------------------------------------------------------------------------
exports.testPropertyAccess = function(test) {
    test.expect(4);
    test.equals(format('Good {msg.time} Sir {msg.name}.', {
        msg: {
            name: 'Lancelot',
            time: 'morning'
        }
    }), 'Good morning Sir Lancelot.');

    test.equals(format('Good {msg.time} Sir {msg.name}.', {
        msg: {
            name: 'Lancelot',
            time: 'evening'
        }
    }), 'Good evening Sir Lancelot.');

    test.equals(format('Good {msg["time"]} Sir {msg.name}.', {
        msg: {
            name: 'Lancelot',
            time: 'evening'
        }
    }), 'Good evening Sir Lancelot.');

    test.equals(format('Good {msg[\'values\'][1]} Sir {msg.values[0]}.', {
        msg: {
            values: ['Lancelot', 'evening']
        }
    }), 'Good evening Sir Lancelot.');

    test.done();
};

exports.testPropertyAccessEscaped = function(test) {
    test.expect(4);
    test.equals(format('My favorite color is {colors[\'"favorite"\']}.', {
        colors: {
            '"favorite"': 'blue'
        }
    }), 'My favorite color is blue.');

    test.equals(format('My favorite color is {colors["\"favorite\""]}.', {
        colors: {
            '"favorite"': 'blue'
        }
    }), 'My favorite color is blue.');

    test.equals(format('My favorite color is {colors["\'favorite\'"]}.', {
        colors: {
            '\'favorite\'': 'blue'
        }
    }), 'My favorite color is blue.');

    test.equals(format('My favorite color is {colors[\'\'favorite\'\']}.', {
        colors: {
            '\'favorite\'': 'blue'
        }
    }), 'My favorite color is blue.');

    test.done();
};

exports.testPropertyAccessError = function(test) {
    test.expect(2);
    try {
        format('{favorite.color}', {msg: {name:'Lancelot'}});

    } catch(err) {
        test.ok(err instanceof FormatError);
        test.equal(err.message, 'Cannot access property "color" of undefined.');
    }
    test.done();
};

// Formatting -------------------------------------------------------------------
// ------------------------------------------------------------------------------
exports.testFormattingJoin = function(test) {
    test.expect(2);
    test.equals(format('{:join(" ")}', ['blue', 'red', 'green', 'yellow']),
                'blue red green yellow');

    test.equals(format('{:join(",")}', ['blue', 'red', 'green', 'yellow']),
                'blue,red,green,yellow');

    test.done();
};

exports.testFormattingSurround = function(test) {
    test.expect(2);
    test.equals(format('{:surround("(", ")")}', 'Lancelot'), '(Lancelot)');
    test.equals(format('{:surround("-")}', 'Lancelot'), '-Lancelot-');
    test.done();
};

exports.testFormattingCase = function(test) {
    test.expect(2);
    test.equals(format('{:upper}', 'Lancelot'), 'LANCELOT');
    test.equals(format('{:lower}', 'Lancelot'), 'lancelot');
    test.done();
};

exports.testFormattingBase = function(test) {
    test.expect(4);
    test.equals(format('{:hex}', 32768), '8000');
    test.equals(format('{:bin}', 255), '11111111');
    test.equals(format('{:hex(true)}', 32768), '0x8000');
    test.equals(format('{:bin(true)}', 255), '0b11111111');
    test.done();
};
exports.testFormattingPad = function(test) {
    test.expect(3);
    test.equals(format('{:lpad(12)}', 'Lancelot'), '    Lancelot');
    test.equals(format('{:rpad(12, " ")}', 'Lancelot'), 'Lancelot    ');
    test.equals(format('{:pad(12, "=")}', 'Lancelot'), '==Lancelot==');
    test.done();
};

exports.testFormattingAccess = function(test) {
    test.expect(2);
    test.equals(format('{name:upper}', {name: 'Lancelot'}), 'LANCELOT');
    test.equals(format('{name[0]:lower}', {name: ['Lancelot']}), 'lancelot');
    test.done();
};

exports.testFormattingMultiple = function(test) {
    test.expect(2);
    test.equals(format('{:upper:lpad(12, " ")}', 'Lancelot'), '    LANCELOT');
    test.equals(format('{:surround("i", "i"):upper}', 'Lancelot'), 'ILANCELOTI');
    test.done();
};

exports.testFormattingEscaped = function(test) {
    test.expect(3);
    test.equals(format('{:surround(\'i\', \'i\'):upper}', 'Lancelot'), 'ILANCELOTI');
    test.equals(format('{:pad(12, "\\"=")}', 'Lancelot'), '"="=Lancelot"="=');
    test.equals(format('{:pad(12, "\'=")}', 'Lancelot'), '\'=\'=Lancelot\'=\'=');
    test.done();
};

exports.testFormattingError = function(test) {
    test.expect(2);
    try {
        format('{:unicornify}', 'Lancelot');

    } catch(err) {
        test.ok(err instanceof FormatError);
        test.equal(err.message, 'Undefined formatter "unicornify".');
    }
    test.done();
};

exports.testFormattingCustom = function(test) {
    test.expect(1);
    var custom = Formatter({
        unicorns: function(value) {
            return value + ' unicorns!';
        }
    });

    test.equals(custom('Here come the {:unicorns}', 'five'),
                       'Here come the five unicorns!');
    test.done();
};

<|endoftext|>


<commit_before>function makeDict(login, dict) {
    dict["username"] = login["username"]
    dict["time"] = (new Date().getTime() / 1000).toString()

    console.log(dict)
    console.log(
            _.sortBy(
                _.pairs(dict),
                function(a) {return a[0]}
            ).concat([["secret", login["secret"]]])
    )

    console.log(
        _.reduce(
            _.sortBy(
                _.pairs(dict),
                function(a) {return a[0]}
            ).concat([["secret", login["secret"]]]),
            function(memo, item) { return memo.concat(item[1]) },
            ""
        )
    )

    dict["sign"] = MD5(
        _.reduce(
            _.sortBy(
                _.pairs(dict),
                function(a) {return a[0]}
            ).concat([["secret", login["secret"]]]),
            function(a,b) { return a[1].concat(b[1]) }
        )
    )

    return dict
}
<commit_msg>Registering now works<commit_after>function makeDict(login, dict) {
    dict["username"] = login["username"]
    dict["time"] = (new Date().getTime() / 1000).toString()
    dict["sign"] = MD5(
        _.reduce(
            _.sortBy(
                _.pairs(dict),
                function(a) {return a[0]}
            ).concat([["secret", login["secret"]]]),
            function(memo, item) { return memo.concat(item[1]) },
            ""
        )
    )

    return dict
}
<|endoftext|>


<commit_before>var expect = require('expect.js');
// Note: IE8 requires that catch be referenced as ['catch'] on a promise

describe('CrossStorageClient', function() {
  // Mocha detects the frame id as being leaked in IE
  var userAgent = window.navigator.userAgent;
  var ieDetected = (userAgent.indexOf('MSIE ') !== false ||
    !!navigator.userAgent.match(/Trident.*rv\:11\./));

  if (global.mocha && ieDetected) {
    global.mocha.globals(['CrossStorageClient-*']);
  }

  var origin, url, storage;

  this.timeout((window.location.hostname === 'localhost') ? 5000 : 60000);
  origin = CrossStorageClient._getOrigin(window.location.href);
  url = origin + '/test/hub.html';

  // Create initial client
  before(function(done) {
    var invoked = false;
    var next = function(msg) {
      if (msg.data !== 'ready' || invoked) return;
      invoked = true;
      done();
    };

    if (window.addEventListener) {
      window.addEventListener('message', next, false);
    } else {
      window.attachEvent('onmessage', next);
    }

    storage = new CrossStorageClient(url, {timeout: 10000});
  });

  // Cleanup old iframes
  afterEach(function() {
    var iframes = document.getElementsByTagName('iframe');
    for (var i = 0; i < iframes.length; i++) {
      if (iframes[i].src !== url) {
        iframes[i].parentNode.removeChild(iframes[i]);
      }
    }
  });

  var setGet = function(key, value, ttl) {
    return function() {
      return storage.set(key, value, ttl).then(function() {
        return storage.get(key);
      });
    };
  };

  // Used to delete keys before each test
  var cleanup = function(fn) {
    storage.onConnect().then(function() {
      return storage.del('key1', 'key2');
    })
    .then(fn)
    ['catch'](fn);
  };

  describe('Constructor', function() {
    it('parses the passed url and stores its origin', function() {
      expect(storage._origin).to.be(origin);
    });

    it('sets _timeout to opts.timeout, if provided', function() {
      expect(storage._timeout).to.be(10000);
    });

    it('sets its connected status to false', function() {
      var storage = new CrossStorageClient(url);
      expect(storage._connected).to.be(false);
    });

    it('initializes _requests as an empty object', function() {
      var storage = new CrossStorageClient(url);
      expect(storage._requests).to.eql({});
    });

    it('creates a hidden iframe', function() {
      var frame = document.getElementsByTagName('iframe')[0];
      expect(frame.style.display).to.be('none');
      expect(frame.style.position).to.be('absolute');
      expect(frame.style.top).to.be('-999px');
      expect(frame.style.left).to.be('-999px');
    });

    it('sets the iframe src to the hub url', function() {
      var frame = document.getElementsByTagName('iframe')[0];
      expect(frame.src).to.be(url);
    });

    it('sets the frame id to _frameId', function() {
      var frame = document.getElementById(storage._frameId);
      expect(frame).not.to.be(null);
    });

    it('stores the frame context window in _hub', function() {
      // constructor.name isn't cross browser, and the window function name
      // varies between browsers (WindowConstructor, Window, etc)
      expect(storage._hub).to.not.be(null);
    });
  });

  describe('onConnect', function() {
    beforeEach(function(done) {
      cleanup(done);
    });

    it('returns a promise that is resolved when connected', function(done) {
      storage.onConnect().then(done);
    });

    it('is not fulfilled if a connection is not established', function(done) {
      var storage = new CrossStorageClient('http://localhost:9999');
      var invoked = false;

      storage.onConnect().then(function() {
        invoked = true;
      });

      setTimeout(function() {
        if (!invoked) return done();

        done(new Error('onConnect fired without connecting'));
      }, 100);
    });
  });

  describe('close', function() {
    var storage;

    before(function(done) {
      storage = new CrossStorageClient(url);
      storage.onConnect().then(function() {
        storage.close();
        done();
      });
    });

    it('sets _connected to false', function() {
      expect(storage._connected).to.be(false);
    });

    it('deletes the iframe', function() {
      var frame = document.getElementById(storage._frameId);
      expect(frame).to.be(null);
    });
  });

  it('fails to make any requests not within its permissions', function(done) {
    var url = origin + '/test/getOnlyHub.html';
    var storage = new CrossStorageClient(url, {timeout: 50000});

    storage.onConnect().then(function() {
      return storage.set('key1', 'new');
    })['catch'](function(err) {
      expect(err.message).to.be('Invalid permissions for set');
      done();
    });
  });

  it('fails to make any requests if not of an allowed origin', function(done) {
    var url = origin + '/test/invalidOriginHub.html';
    var storage = new CrossStorageClient(url, {timeout: 50000});

    storage.onConnect().then(function() {
      return storage.set('key1', 'new');
    })['catch'](function(err) {
      expect(err.message).to.be('Invalid permissions for set');
      done();
    });
  });

  describe('given sufficient permissions', function() {
    beforeEach(function(done) {
      cleanup(done);
    });

    it('returns null when calling get on a non-existent key', function(done) {
      storage.onConnect()
      .then(function() {
        return storage.get('key1');
      }).then(function(res) {
        expect(res).to.be(null);
        done();
      })['catch'](done);
    });

    it('can set a key to the specified value', function(done) {
      var key = 'key1';
      var value = 'foo';

      storage.onConnect()
      .then(setGet(key, value))
      .then(function(res) {
        expect(res).to.eql(value);
        done();
      })['catch'](done);
    });

    it('can set objects as the value', function(done) {
      var key = 'key1';
      var object = {foo: 'bar'};

      storage.onConnect()
      .then(setGet(key, object))
      .then(function(res) {
        expect(res).to.eql(object);
        done();
      })['catch'](done);
    });

    it('can overwrite existing values', function(done) {
      var key = 'key1';
      var value = 'new';

      storage.onConnect().then(function() {
        return storage.set(key, 'old');
      })
      .then(setGet(key, value))
      .then(function(res) {
        expect(res).to.eql(value);
        done();
      })['catch'](done);
    });

    it('can set a ttl on the key', function(done) {
      var key = 'key1';
      var value = 'foobar';

      var delay = function() {
        // Delay by 100ms
        return new Promise(function(resolve, reject) {
          setTimeout(resolve, 100);
        });
      };

      storage.onConnect()
      .then(setGet(key, value, 50))
      .then(delay)
      .then(function() {
        return storage.get(key);
      }).then(function(res) {
        expect(res).to.be(null);
        done();
      })['catch'](done);
    });

    it('returns an array of values if get is passed multiple keys', function(done) {
      var keys = ['key1', 'key2'];
      var values = ['foo', 'bar'];

      storage.onConnect()
      .then(setGet(keys[0], values[0]))
      .then(setGet(keys[1], values[1]))
      .then(function() {
        return storage.get(keys[0], keys[1]);
      })
      .then(function(res) {
        expect(res).to.eql([values[0], values[1]]);
        done();
      })['catch'](done);
    });

    it('can delete multiple keys', function(done) {
      var keys = ['key1', 'key2'];
      var values = ['foo', 'bar'];

      storage.onConnect()
      .then(setGet(keys[0], values[0]))
      .then(setGet(keys[1], values[1]))
      .then(function() {
        return storage.del(keys[0], keys[1]);
      }).then(function() {
        return storage.get(keys[0], keys[1]);
      })
      .then(function(res) {
        expect(res).to.eql([null, null]);
        done();
      })['catch'](done);
    });

    it('can retrieve all keys using getKeys', function(done) {
      var keys = ['key1', 'key2'];
      var values = ['foo', 'bar'];

      storage.onConnect()
      .then(setGet(keys[0], values[0]))
      .then(setGet(keys[1], values[1]))
      .then(function() {
        return storage.getKeys();
      })
      .then(function(res) {
        // key order varies in some browsers
        expect(res).to.have.length(2);
        expect(res).to.contain(keys[0], keys[1]);
        done();
      })['catch'](done);
    });
  });
});
<commit_msg>Add missing spec for promise rejection when client is closed<commit_after>var expect = require('expect.js');
// Note: IE8 requires that catch be referenced as ['catch'] on a promise

describe('CrossStorageClient', function() {
  // Mocha detects the frame id as being leaked in IE
  var userAgent = window.navigator.userAgent;
  var ieDetected = (userAgent.indexOf('MSIE ') !== false ||
    !!navigator.userAgent.match(/Trident.*rv\:11\./));

  if (global.mocha && ieDetected) {
    global.mocha.globals(['CrossStorageClient-*']);
  }

  var origin, url, storage;

  this.timeout((window.location.hostname === 'localhost') ? 5000 : 60000);
  origin = CrossStorageClient._getOrigin(window.location.href);
  url = origin + '/test/hub.html';

  // Create initial client
  before(function(done) {
    var invoked = false;
    var next = function(msg) {
      if (msg.data !== 'ready' || invoked) return;
      invoked = true;
      done();
    };

    if (window.addEventListener) {
      window.addEventListener('message', next, false);
    } else {
      window.attachEvent('onmessage', next);
    }

    storage = new CrossStorageClient(url, {timeout: 10000});
  });

  // Cleanup old iframes
  afterEach(function() {
    var iframes = document.getElementsByTagName('iframe');
    for (var i = 0; i < iframes.length; i++) {
      if (iframes[i].src !== url) {
        iframes[i].parentNode.removeChild(iframes[i]);
      }
    }
  });

  var setGet = function(key, value, ttl) {
    return function() {
      return storage.set(key, value, ttl).then(function() {
        return storage.get(key);
      });
    };
  };

  // Used to delete keys before each test
  var cleanup = function(fn) {
    storage.onConnect().then(function() {
      return storage.del('key1', 'key2');
    })
    .then(fn)
    ['catch'](fn);
  };

  describe('Constructor', function() {
    it('parses the passed url and stores its origin', function() {
      expect(storage._origin).to.be(origin);
    });

    it('sets _timeout to opts.timeout, if provided', function() {
      expect(storage._timeout).to.be(10000);
    });

    it('sets its connected status to false', function() {
      var storage = new CrossStorageClient(url);
      expect(storage._connected).to.be(false);
    });

    it('initializes _requests as an empty object', function() {
      var storage = new CrossStorageClient(url);
      expect(storage._requests).to.eql({});
    });

    it('creates a hidden iframe', function() {
      var frame = document.getElementsByTagName('iframe')[0];
      expect(frame.style.display).to.be('none');
      expect(frame.style.position).to.be('absolute');
      expect(frame.style.top).to.be('-999px');
      expect(frame.style.left).to.be('-999px');
    });

    it('sets the iframe src to the hub url', function() {
      var frame = document.getElementsByTagName('iframe')[0];
      expect(frame.src).to.be(url);
    });

    it('sets the frame id to _frameId', function() {
      var frame = document.getElementById(storage._frameId);
      expect(frame).not.to.be(null);
    });

    it('stores the frame context window in _hub', function() {
      // constructor.name isn't cross browser, and the window function name
      // varies between browsers (WindowConstructor, Window, etc)
      expect(storage._hub).to.not.be(null);
    });
  });

  describe('onConnect', function() {
    beforeEach(function(done) {
      cleanup(done);
    });

    it('returns a promise that is resolved when connected', function(done) {
      storage.onConnect().then(done);
    });

    it('is not fulfilled if a connection is not established', function(done) {
      var storage = new CrossStorageClient('http://localhost:9999');
      var invoked = false;

      storage.onConnect().then(function() {
        invoked = true;
      });

      setTimeout(function() {
        if (!invoked) return done();

        done(new Error('onConnect fired without connecting'));
      }, 100);
    });
  });

  describe('close', function() {
    var storage;

    before(function(done) {
      storage = new CrossStorageClient(url);
      storage.onConnect().then(function() {
        storage.close();
        done();
      });
    });

    it('sets _connected to false', function() {
      expect(storage._connected).to.be(false);
    });

    it('deletes the iframe', function() {
      var frame = document.getElementById(storage._frameId);
      expect(frame).to.be(null);
    });
  });

  it('fails to make any requests not within its permissions', function(done) {
    var url = origin + '/test/getOnlyHub.html';
    var storage = new CrossStorageClient(url, {timeout: 50000});

    storage.onConnect().then(function() {
      return storage.set('key1', 'new');
    })['catch'](function(err) {
      expect(err.message).to.be('Invalid permissions for set');
      done();
    });
  });

  it('fails to make any requests if not of an allowed origin', function(done) {
    var url = origin + '/test/invalidOriginHub.html';
    var storage = new CrossStorageClient(url, {timeout: 50000});

    storage.onConnect().then(function() {
      return storage.set('key1', 'new');
    })['catch'](function(err) {
      expect(err.message).to.be('Invalid permissions for set');
      done();
    });
  });

  it('fails to make any requests if the client has closed', function(done) {
    var storage = new CrossStorageClient(url, {timeout: 50000});

    storage.onConnect().then(function() {
      storage.close();

      return storage.set('key1', 'new');
    })['catch'](function(err) {
      expect(err.message).to.be('CrossStorageClient has closed');
      done();
    });
  });

  describe('given sufficient permissions', function() {
    beforeEach(function(done) {
      cleanup(done);
    });

    it('returns null when calling get on a non-existent key', function(done) {
      storage.onConnect()
      .then(function() {
        return storage.get('key1');
      }).then(function(res) {
        expect(res).to.be(null);
        done();
      })['catch'](done);
    });

    it('can set a key to the specified value', function(done) {
      var key = 'key1';
      var value = 'foo';

      storage.onConnect()
      .then(setGet(key, value))
      .then(function(res) {
        expect(res).to.eql(value);
        done();
      })['catch'](done);
    });

    it('can set objects as the value', function(done) {
      var key = 'key1';
      var object = {foo: 'bar'};

      storage.onConnect()
      .then(setGet(key, object))
      .then(function(res) {
        expect(res).to.eql(object);
        done();
      })['catch'](done);
    });

    it('can overwrite existing values', function(done) {
      var key = 'key1';
      var value = 'new';

      storage.onConnect().then(function() {
        return storage.set(key, 'old');
      })
      .then(setGet(key, value))
      .then(function(res) {
        expect(res).to.eql(value);
        done();
      })['catch'](done);
    });

    it('can set a ttl on the key', function(done) {
      var key = 'key1';
      var value = 'foobar';

      var delay = function() {
        // Delay by 100ms
        return new Promise(function(resolve, reject) {
          setTimeout(resolve, 100);
        });
      };

      storage.onConnect()
      .then(setGet(key, value, 50))
      .then(delay)
      .then(function() {
        return storage.get(key);
      }).then(function(res) {
        expect(res).to.be(null);
        done();
      })['catch'](done);
    });

    it('returns an array of values if get is passed multiple keys', function(done) {
      var keys = ['key1', 'key2'];
      var values = ['foo', 'bar'];

      storage.onConnect()
      .then(setGet(keys[0], values[0]))
      .then(setGet(keys[1], values[1]))
      .then(function() {
        return storage.get(keys[0], keys[1]);
      })
      .then(function(res) {
        expect(res).to.eql([values[0], values[1]]);
        done();
      })['catch'](done);
    });

    it('can delete multiple keys', function(done) {
      var keys = ['key1', 'key2'];
      var values = ['foo', 'bar'];

      storage.onConnect()
      .then(setGet(keys[0], values[0]))
      .then(setGet(keys[1], values[1]))
      .then(function() {
        return storage.del(keys[0], keys[1]);
      }).then(function() {
        return storage.get(keys[0], keys[1]);
      })
      .then(function(res) {
        expect(res).to.eql([null, null]);
        done();
      })['catch'](done);
    });

    it('can retrieve all keys using getKeys', function(done) {
      var keys = ['key1', 'key2'];
      var values = ['foo', 'bar'];

      storage.onConnect()
      .then(setGet(keys[0], values[0]))
      .then(setGet(keys[1], values[1]))
      .then(function() {
        return storage.getKeys();
      })
      .then(function(res) {
        // key order varies in some browsers
        expect(res).to.have.length(2);
        expect(res).to.contain(keys[0], keys[1]);
        done();
      })['catch'](done);
    });
  });
});
<|endoftext|>


<commit_before>const expect = require('expect.js');
const localStorage = require('localStorage');
const Loggerage = require("../build/loggerage").Loggerage;
const LoggerageLevel = require("../build/loggerage").LoggerageLevel;

describe("Loggerage", function() {
    let logger = new Loggerage(Date.now());
    logger.setStorage(localStorage);
    let i = 0;

    beforeEach(function() {
        logger = new Loggerage(Date.now() + i);
        logger.setStorage(localStorage);
        i += 1;
    });

    describe("Test constructor", function () {
        it("app es igual a (Date.now() + i)", function() {
            const app = Date.now() + i;
            i += 1;
            logger = new Loggerage(app, LoggerageLevel.INFO);
            expect(logger.getApp()).to.equal(app);
        });

        it("log level es igual a INFO", function() {
            logger = new Loggerage(Date.now() + i, LoggerageLevel.INFO);
            i += 1;
            expect(logger.getDefaultLogLevel()).to.equal("INFO");
        });

        it("version es igual a 2", function() {
            logger = new Loggerage(Date.now() + i, LoggerageLevel.INFO, 2);
            i += 1;
            expect(logger.getVersion()).to.equal(2);
        });
    });

    describe("Test get y set logs", function () {
        it("log vacío de inicio (log == [])", function() {
            const log = logger.getLog();
            expect(log.length).to.equal(0);
        });

        it("tiene 1 log", function() {
            logger.info("Un log");
            const log = logger.getLog();
            expect(log.length).to.equal(1);
        });

        it("tiene 3 logs", function() {
            Array.apply(null, Array(3)).forEach(function() {
                logger.info("Log");
            });
            const log = logger.getLog();
            expect(log.length).to.equal(3);
        });

        it("tiene 100 logs", function() {
            Array.apply(null, Array(100)).forEach(function() {
                logger.debug("Log");
            });
            const log = logger.getLog();
            expect(log.length).to.equal(100);
        });

        it("tiene 1 log con mensaje 'Un log' y level INFO", function() {
            logger.info("Un log");
            const log = logger.getLog();
            expect(log.length).to.equal(1);
            expect(log[0].level).to.equal("INFO");
            expect(log[0].message).to.equal("Un log");
        });

        it("Después de limpiar tiene log vacío (log == [])", function() {
            logger.info("Un log");
            logger.info("Otro log");
            logger.info("Otro log más");
            let log = logger.getLog();
            expect(log.length).to.equal(3);
            logger.clearLog();
            log = logger.getLog();
            expect(log.length).to.equal(0);
        });

        it("tiene 1 log con level DEBUG", function() {
            logger.debug("Un log DEBUG");
            const log = logger.getLog();
            expect(log[0].level).to.equal("DEBUG");
        });
        it("tiene 1 log con level TRACE", function() {
            logger.trace("Un log TRACE");
            const log = logger.getLog();
            expect(log[0].level).to.equal("TRACE");
        });
        it("tiene 1 log con level SUCCESS", function() {
            logger.success("Un log SUCCESS");
            const log = logger.getLog();
            expect(log[0].level).to.equal("SUCCESS");
        });
        it("tiene 1 log con level INFO", function() {
            logger.info("Un log INFO");
            const log = logger.getLog();
            expect(log[0].level).to.equal("INFO");
        });
        it("tiene 1 log con level WARN", function() {
            logger.warn("Un log WARN");
            const log = logger.getLog();
            expect(log[0].level).to.equal("WARN");
        });
        it("tiene 1 log con level ERROR", function() {
            logger.error("Un log ERROR");
            const log = logger.getLog();
            expect(log[0].level).to.equal("ERROR");
        });
        it("tiene 1 log con level FAILURE", function() {
            logger.failure("Un log FAILURE");
            const log = logger.getLog();
            expect(log[0].level).to.equal("FAILURE");
        });
        it("tiene 1 log con level ERROR, mensaje 'Error' y stacktrace '[Stack Trace: Error StackTrace]'", function() {
            logger.error("Error", "Error StackTrace");
            const log = logger.getLog();
            expect(log[0].message.split("\n")[0]).to.equal("Error");
            expect(log[0].message.split("\n")[1]).to.equal("[Stack Trace: Error StackTrace]");
        });
    });

    describe("Sin Blob", function () {
        it("Lanza excepción al descargar archivo porque no existe Blob (borrado)", function () {
            expect(function() {
                logger.downloadFileLog();
            }).to.throwException("Your browser does not support File APIs. Visit http://browsehappy.com for update or your official page browser.");
        });
    });
});<commit_msg>adapted to node 4 and 5<commit_after>const expect = require('expect.js');
const localStorage = require('localStorage');
const Loggerage = require("../build/loggerage").Loggerage;
const LoggerageLevel = require("../build/loggerage").LoggerageLevel;

describe("Loggerage", function() {
    var logger = new Loggerage(Date.now());
    logger.setStorage(localStorage);
    var i = 0;

    beforeEach(function() {
        logger = new Loggerage(Date.now() + i);
        logger.setStorage(localStorage);
        i += 1;
    });

    describe("Test constructor", function () {
        it("app es igual a (Date.now() + i)", function() {
            const app = Date.now() + i;
            i += 1;
            logger = new Loggerage(app, LoggerageLevel.INFO);
            expect(logger.getApp()).to.equal(app);
        });

        it("log level es igual a INFO", function() {
            logger = new Loggerage(Date.now() + i, LoggerageLevel.INFO);
            i += 1;
            expect(logger.getDefaultLogLevel()).to.equal("INFO");
        });

        it("version es igual a 2", function() {
            logger = new Loggerage(Date.now() + i, LoggerageLevel.INFO, 2);
            i += 1;
            expect(logger.getVersion()).to.equal(2);
        });
    });

    describe("Test get y set logs", function () {
        it("log vacío de inicio (log == [])", function() {
            const log = logger.getLog();
            expect(log.length).to.equal(0);
        });

        it("tiene 1 log", function() {
            logger.info("Un log");
            const log = logger.getLog();
            expect(log.length).to.equal(1);
        });

        it("tiene 3 logs", function() {
            Array.apply(null, Array(3)).forEach(function() {
                logger.info("Log");
            });
            const log = logger.getLog();
            expect(log.length).to.equal(3);
        });

        it("tiene 100 logs", function() {
            Array.apply(null, Array(100)).forEach(function() {
                logger.debug("Log");
            });
            const log = logger.getLog();
            expect(log.length).to.equal(100);
        });

        it("tiene 1 log con mensaje 'Un log' y level INFO", function() {
            logger.info("Un log");
            const log = logger.getLog();
            expect(log.length).to.equal(1);
            expect(log[0].level).to.equal("INFO");
            expect(log[0].message).to.equal("Un log");
        });

        it("Después de limpiar tiene log vacío (log == [])", function() {
            logger.info("Un log");
            logger.info("Otro log");
            logger.info("Otro log más");
            var log = logger.getLog();
            expect(log.length).to.equal(3);
            logger.clearLog();
            log = logger.getLog();
            expect(log.length).to.equal(0);
        });

        it("tiene 1 log con level DEBUG", function() {
            logger.debug("Un log DEBUG");
            const log = logger.getLog();
            expect(log[0].level).to.equal("DEBUG");
        });
        it("tiene 1 log con level TRACE", function() {
            logger.trace("Un log TRACE");
            const log = logger.getLog();
            expect(log[0].level).to.equal("TRACE");
        });
        it("tiene 1 log con level SUCCESS", function() {
            logger.success("Un log SUCCESS");
            const log = logger.getLog();
            expect(log[0].level).to.equal("SUCCESS");
        });
        it("tiene 1 log con level INFO", function() {
            logger.info("Un log INFO");
            const log = logger.getLog();
            expect(log[0].level).to.equal("INFO");
        });
        it("tiene 1 log con level WARN", function() {
            logger.warn("Un log WARN");
            const log = logger.getLog();
            expect(log[0].level).to.equal("WARN");
        });
        it("tiene 1 log con level ERROR", function() {
            logger.error("Un log ERROR");
            const log = logger.getLog();
            expect(log[0].level).to.equal("ERROR");
        });
        it("tiene 1 log con level FAILURE", function() {
            logger.failure("Un log FAILURE");
            const log = logger.getLog();
            expect(log[0].level).to.equal("FAILURE");
        });
        it("tiene 1 log con level ERROR, mensaje 'Error' y stacktrace '[Stack Trace: Error StackTrace]'", function() {
            logger.error("Error", "Error StackTrace");
            const log = logger.getLog();
            expect(log[0].message.split("\n")[0]).to.equal("Error");
            expect(log[0].message.split("\n")[1]).to.equal("[Stack Trace: Error StackTrace]");
        });
    });

    describe("Sin Blob", function () {
        it("Lanza excepción al descargar archivo porque no existe Blob (borrado)", function () {
            expect(function() {
                logger.downloadFileLog();
            }).to.throwException("Your browser does not support File APIs. Visit http://browsehappy.com for update or your official page browser.");
        });
    });
});<|endoftext|>


<commit_before>var assert = require('chai').assert
  , factory = require('../index')
  , moment = require('moment')
  , recurrence1 = 'R/2016-01-20T00:00:00Z/P2D'
  , P2D_seconds = 172800
  , start_date_seconds = 1453248000
  , jan_26_2017 = 1485406800
  , jan_27_2017 = 1485493200
  , jan_28_2017 = 1485579600
  , jan_29_2017 = 1485666000
  , jan_30_2017 = 1485752400
  , navigator;

console.log(moment('2016-01-20T00:00:00Z').unix());

describe('Navigator', function() {
  describe('factory', function () {
    it('should return a valid navigator', function() {
      navigator = factory(recurrence1);
      assert.isObject(navigator);
      assert.isObject(navigator.errors);
      assert.isFunction(navigator.next);
      assert.isFunction(navigator.prev);
      assert.isObject(navigator.duration);
      assert.isObject(navigator.start_date);
      assert.isUndefined(navigator.end_date);
      assert.isNumber(navigator.repeats);
    });

  });

  describe('duration', function() {
    it('should have a duration of 2 days', function() {
      assert.isFunction(navigator.duration.asSeconds);
      assert.equal(navigator.duration.asSeconds(), P2D_seconds);
    });
  });

  describe('start_date', function() {
    it('should have a start_date of Jan 20, 2016', function() {
      assert.isFunction(navigator.start_date.unix);
      assert.equal(navigator.start_date.unix(), start_date_seconds);
    });
  });

  describe('repeats', function() {
    it('should have a repeats of Infinity', function() {
      assert.equal(navigator.repeats, Infinity);
    });
  });

  describe('next', function() {
    it('should return Jan 30, 2017 when given Jan 28, 2017', function() {
      assert.equal(navigator.next(jan_28_2017), jan_30_2017);
    });
    it('should return Jan 30, 2017 when given Jan 28, 2017', function() {
      assert.equal(navigator.next(jan_29_2017), jan_30_2017);
    });

    it('should callback Jan 30, 2017 when given Jan 28, 2017', function(done) {
      navigator.next(jan_28_2017, function(err, result) {
        assert.notOk(err);
        assert.equal(result, jan_30_2017);
        done();
      });
    });
    it('should callback Jan 30, 2017 when given Jan 28, 2017', function(done) {
      navigator.next(jan_29_2017, function(err, result) {
        assert.notOk(err);
        assert.equal(result, jan_30_2017);
        done();
      });
    });
  });

  describe('prev', function() {
    it('should return Jan 26, 2017 when given Jan 28, 2017', function() {
      assert.equal(navigator.prev(jan_28_2017), jan_26_2017);
    });
    it('should return Jan 26, 2017 when given Jan 27, 2017', function() {
      assert.equal(navigator.prev(jan_29_2017), jan_26_2017);
    });

    it('should callback Jan 26, 2017 when given Jan 28, 2017', function(done) {
      navigator.next(jan_28_2017, function(err, result) {
        assert.notOk(err);
        assert.equal(result, jan_26_2017);
        done();
      });
    });
    it('should callback Jan 26, 2017 when given Jan 27, 2017', function(done) {
      navigator.next(jan_27_2017, function(err, result) {
        assert.notOk(err);
        assert.equal(result, jan_26_2017);
        done();
      });
    });
  });

});
<commit_msg>automate some extra tests<commit_after>var assert = require('chai').assert
  , factory = require('../index')
  , moment = require('moment')
  , designators = ['/', '--']
  , repeats = [Infinity, 0, 1, 2, 5]
  , starts = ['2016-01-20T00:00:00Z', '2015-01-20T00:00:00Z']
  , periods = ['P2D', 'P1W', 'PT3H45M', 'P1DT12H']
  , ends = ['2016-01-22T00:00:00Z', '2016-01-23T12:00:00Z']
  , cases = [];

designators.forEach(function(designator) {
  var start = null
    , end = null
    , period = null
    , interval;
  repeats.forEach(function(repeat) {
    var R = repeat===Infinity ? 'R' : 'R' + repeat;
    starts.forEach(function(start) {
      ends.forEach(function(end) {
        interval = [R, start, end].join(designator);
        cases.push(build_test_case(interval, period, start, end, repeat));
      });
      periods.forEach(function(period) {
        interval = [R, start, period].join(designator);
        cases.push(build_test_case(interval, period, start, end, repeat));
      });
    });
    ends.forEach(function(end) {
      periods.forEach(function(period) {
        interval = [R, period, end].join(designator);
        cases.push(build_test_case(interval, period, start, end, repeat));
      });
    });
    periods.forEach(function(period) {
      interval = [R, period].join(designator);
      cases.push(build_test_case(interval, period, start, end, repeat));
    });
  });
});

function build_test_case(interval, period, start, end, repeat) {
  var millis, period_seconds, half, test_case
    , cases = [];

  if(!period) {
    millis = moment(end).diff(moment(start));
    period = moment.duration(millis).toISOString();
    end = null; // if there was no period, then the end is just a period marker
  }

  period_seconds = moment.duration(period).asSeconds();
  period_far_seconds = period_seconds * Math.floor(Math.random() * 1000);

  test_case = {
    test: interval,
    repeats: repeat,

    period: period,
    period_human: moment.duration(period).toISOString(),
    period_seconds: period_seconds,
    period_far_seconds: period_far_seconds
  };

  far_seconds = test_case.period_seconds_far

  if(start!==null) {
    var start_seconds = moment(start).unix();
    test_case.start = start;
    test_case.start_seconds = start_seconds;
    if(repeat===Infinity) {
      cases = cases.concat(build_triples(start_seconds + period_far_seconds, period_seconds));
    }
  }

  if(end!==null) {
    var end_seconds = moment(end).unix();
    test_case.end = end;
    test_case.end_seconds = end_seconds;
    if(repeat===Infinity) {
      cases = cases.concat(build_triples(end_seconds - period_far_seconds, period_seconds));
    }
  }

  test_case.cases = cases;

  return test_case;
}

function build_triples(base, period, edge, recurrences) {
  var triples = []
    , bump = 1 // 1s
    , half = Math.floor(period*0.5)
    , halfAgain = Math.floor(period*1.5);
  if(recurrences===0) {
    // these are all the cases we can test for this
    return [[undefined, base-bump, base],
            [undefined, base, base],
            [base, base+bump, undefined],
            [undefined, base-half, base],
            [undefined, base, base],
            [base, base+half, undefined]];
  }

  if(edge==='upper') {
    triples = [[base-period, base-bump, base],
               [base-period, base,   base],
               [base,        base+bump, undefined]];
    if(recurrences===1) {
      triples.concat([[undefined, base-halfAgain, base],
                      [base,      base+halfAgain, undefined]]);
    }
  } else if (edge==='lower') {
    triples = [[undefined, base-bump, base],
               [undefined, base,   base],
               [base,      base+bump, base+period]];
    if(recurrences===1) {
      triples.concat([[undefined,   base-halfAgain, base],
                      [base+period, base+halfAgain, undefined]]);
    }
  } else {
    triples = [[base-period, base-bump, base],
               [base-period, base,   base],
               [base,        base+bump, base+period]];
  }

  return triples;
}

function momentize(timestamp) {
  if(timestamp===undefined) {
    return undefined;
  }
  return moment.unix(timestamp);
}

// turn seconds into milliseconds DRYly
function m(seconds) {
  return seconds * 1000;
}

function is_a_navigator(nav) {
  assert.isObject(nav);
  assert.isObject(nav.errors);
  assert.isFunction(nav.next);
  assert.isFunction(nav.prev);
  assert.isFunction(nav.previous);
  assert.isObject(nav.duration);
  if(nav.start_date !== undefined) {
    assert.isObject(nav.start_date);
  }
  if(nav.end_date !== undefined) {
    assert.isObject(nav.end_date);
  }
  assert.isNumber(nav.repeats);
  return nav;
}

cases.forEach(function(test) {
  var nav, cb_nav;
  describe('Navigator', function() {
    describe('factory', function () {
      it('should return and callback the same valid navigator for '+test.test, function(done) {
        nav = factory(test.test, function(err, result) {
          assert.notOk(err);
          cb_nav = result;
          is_a_navigator(cb_nav);
          done();
        })
        nav = is_a_navigator(nav);
      });

      after(function() {
        assert.equal(cb_nav, nav);
      });
    });

    describe('duration', function() {
      it('should have a duration of '+test.period_human, function() {
        assert.isFunction(nav.duration.asSeconds);
        assert.equal(nav.duration.asSeconds(), test.period_seconds);
      });
    });

    if(test.start) {
      describe('start_date', function() {
        it('should have a start_date of '+test.start, function() {
          assert.isFunction(nav.start_date.unix);
          assert.equal(nav.start_date.unix(), test.start_seconds);
          assert.isUndefined(nav.end_date);
        });
      });
    }

    if(test.end) {
      describe('end_date', function() {
        it('should have a end_date of '+test.end, function() {
          assert.isFunction(nav.end_date.unix);
          assert.equal(nav.end_date.unix(), test.end_seconds);
          assert.isUndefined(nav.start_date);
        });
      });
    }

    describe('repeats', function() {
      it('should have a repeats of '+test.repeats, function() {
        assert.equal(nav.repeats, test.repeats);
      });
    });
    test.cases.forEach(function(triple) {
      var triple = triple
        , prev = triple[0]//===undefined ? triple[0] : triple[0].unix()
        , base = triple[1]//===undefined ? triple[1] : triple[1].unix()
        , next = triple[2]//===undefined ? triple[2] : triple[2].unix()
        , prev_human = prev===undefined ? 'undefined' : momentize(triple[0]).toISOString()
        , base_human = momentize(triple[1]).toISOString()
        , next_human = next===undefined ? 'undefined' : momentize(triple[2]).toISOString();
      describe('next('+base+') '+base_human, function() {
        it('should return and callback '+next+' ('+next_human+')', function(done) {
          var returned = nav.next(m(base), function(err, result) {
            assert.notOk(err);
            assert.equal(result, next);
            done();
          });
          //assert.equal(returned, next);
        });
      });

      describe('prev('+base+' s) '+base_human, function() {
        it('should return and callback '+prev+' ('+prev_human+')', function(done) {
          var returned = nav.prev(m(base), function(err, result) {
            assert.notOk(err);
            assert.equal(result, prev);
            done();
          });
          assert.equal(returned, prev);
        });
      });
    });
  });

/*

should return a valid navigator with all four types of recurrence interval

in the case of a start_date
 should return no previous before that start_date
 in the case of a repeat, should return no next after (start_date + (period * repeats))

in the case of an end_date
 should return no next after that end_date
 in the case of a repeat, should return no previous before (end_date - (period * repeats))

*/

});
<|endoftext|>


<commit_before>import {h, Component} 				from 'preact/preact';

import NavLink							from 'com/nav-link/link';

import ContentLoading					from 'com/content-loading/loading';
import ContentError						from 'com/content-error/error';

import ContentCommon					from 'com/content-common/common';

import ContentCommonBody				from 'com/content-common/common-body';
import ContentCommonBodyBy				from 'com/content-common/common-body-by';
import ContentCommonBodyTitle			from 'com/content-common/common-body-title';
import ContentCommonBodyAvatar			from 'com/content-common/common-body-avatar';
import ContentCommonBodyMarkup			from 'com/content-common/common-body-markup';

import PieChart							from 'com/visualization/piechart/piechart';
import BarChart							from 'com/visualization/barchart/barchart';

import $Stats							from '../../shrub/js/stats/stats';

export default class ContentStatsEvent extends Component {
	constructor( props ) {
		super(props);

		this.state = {
			'stats': null
		};
	}

	componentDidMount() {
		//var props = this.props;
		var state = this.state;

//		if ( state.stats )
		this.getStats();
	}

//	componentWillUpdate( newProps, newState ) {
//		if ( this.props.node !== newProps.node ) {
//			if ( this.props.authored ) {
//				this.getAuthor(newProps.node);
//			}
//			if ( this.props.authors ) {
//				this.getAuthors(newProps.node);
//			}
//		}
//	}

	getStats() {
		var props = this.props;

		$Stats.Get(props.node.id).then(r => {
			if ( r.stats ) {
				this.setState({'stats': r.stats});
			}
		});
	}

	render( props, state ) {
		props = Object.assign({}, props);	// Shallow copy we can change props
		var Class = [];

		var node = props.node;
		var user = props.user;
		var path = props.path;
		var extra = props.extra;

		if ( node && node.slug && state.stats ) {
			var stats = state.stats;

			Class.push("content-stats");
			Class.push("content-stats-event");

			//console.log(state.stats);

			var EventMode = 0;
			if ( node && node.meta && node.meta['theme-mode'] )
				EventMode = parseInt(node.meta['theme-mode']);

			var Data = [];
			if ( EventMode ) {
				Data.push(
Number of Users:
);
				Data.push(
Signups: {stats.signups}
);
				Data.push(
Unique Authors: {stats.authors}
);

				if ( EventMode >= 5 ) {
					Data.push(
Number of Submissions: {stats.jam+stats.compo+stats.craft}
);
					let entries = [
						stats.compo,
						stats.jam
					];
					let entrienames = [
						'Jam',
						'Compo'
					];
					Data.push(<PieChart values={entries} labels={entrienames}></PieChart>);

					Data.push(
Unfinished: {stats.unfinished}
);
					Data.push(
Unpublished: {stats.unpublished}
);
					Data.push(
Warmups: {stats.warmup}
);
				}
				if ( EventMode >= 6 ) {
					Data.push(
Number of Ratings Recived (Per Game):
);
					let grades = [
						stats['grade-20-plus'],
						stats['grade-15-20'],
						stats['grade-10-15'],
						stats['grade-5-10'],
						stats['grade-0-5']-stats['grade-0-only'],
						stats['grade-0-only']
					];
					let gradenames = [
						'20 or more',
						'15 to 20',
						'10 to 15',
						'5 to 10',
						'1 to 5',
						'0'
					];

					Data.push(<BarChart values={grades.reverse()} labels={gradenames.reverse()}></BarChart>);

					Data.push(
Types of Entries:
);
					let types = [
						stats.game,
						stats.craft,
						stats.demo,
						stats.tool
					];
					let typenames = [
						'Games',
						'Crafts',
						'Demos',
						'Tools'
					];
					Data.push(<PieChart values={types} labels={typenames}></PieChart>);

				}

				Data.push(
Last Updated: {stats.timestamp}
);

				return (
					<ContentCommon {...props} class={cN(Class)}>
						<ContentCommonBodyTitle title="Statistics" />
						<ContentCommonBody>
							{Data}
						</ContentCommonBody>
					</ContentCommon>
				);
			}
			return
;
		}
		else {
			return <ContentLoading />;
		}
	}
}
<commit_msg>Also fix Jam/Compo mixup in event stats<commit_after>import {h, Component} 				from 'preact/preact';

import NavLink							from 'com/nav-link/link';

import ContentLoading					from 'com/content-loading/loading';
import ContentError						from 'com/content-error/error';

import ContentCommon					from 'com/content-common/common';

import ContentCommonBody				from 'com/content-common/common-body';
import ContentCommonBodyBy				from 'com/content-common/common-body-by';
import ContentCommonBodyTitle			from 'com/content-common/common-body-title';
import ContentCommonBodyAvatar			from 'com/content-common/common-body-avatar';
import ContentCommonBodyMarkup			from 'com/content-common/common-body-markup';

import PieChart							from 'com/visualization/piechart/piechart';
import BarChart							from 'com/visualization/barchart/barchart';

import $Stats							from '../../shrub/js/stats/stats';

export default class ContentStatsEvent extends Component {
	constructor( props ) {
		super(props);

		this.state = {
			'stats': null
		};
	}

	componentDidMount() {
		//var props = this.props;
		var state = this.state;

//		if ( state.stats )
		this.getStats();
	}

//	componentWillUpdate( newProps, newState ) {
//		if ( this.props.node !== newProps.node ) {
//			if ( this.props.authored ) {
//				this.getAuthor(newProps.node);
//			}
//			if ( this.props.authors ) {
//				this.getAuthors(newProps.node);
//			}
//		}
//	}

	getStats() {
		var props = this.props;

		$Stats.Get(props.node.id).then(r => {
			if ( r.stats ) {
				this.setState({'stats': r.stats});
			}
		});
	}

	render( props, state ) {
		props = Object.assign({}, props);	// Shallow copy we can change props
		var Class = [];

		var node = props.node;
		var user = props.user;
		var path = props.path;
		var extra = props.extra;

		if ( node && node.slug && state.stats ) {
			var stats = state.stats;

			Class.push("content-stats");
			Class.push("content-stats-event");

			//console.log(state.stats);

			var EventMode = 0;
			if ( node && node.meta && node.meta['theme-mode'] )
				EventMode = parseInt(node.meta['theme-mode']);

			var Data = [];
			if ( EventMode ) {
				Data.push(
Number of Users:
);
				Data.push(
Signups: {stats.signups}
);
				Data.push(
Unique Authors: {stats.authors}
);

				if ( EventMode >= 5 ) {
					Data.push(
Number of Submissions: {stats.jam+stats.compo+stats.craft}
);
					let entries = [
						stats.jam,
						stats.compo
					];
					let entrienames = [
						'Jam',
						'Compo'
					];
					Data.push(<PieChart values={entries} labels={entrienames}></PieChart>);

					Data.push(
Unfinished: {stats.unfinished}
);
					Data.push(
Unpublished: {stats.unpublished}
);
					Data.push(
Warmups: {stats.warmup}
);
				}
				if ( EventMode >= 6 ) {
					Data.push(
Number of Ratings Recived (Per Game):
);
					let grades = [
						stats['grade-20-plus'],
						stats['grade-15-20'],
						stats['grade-10-15'],
						stats['grade-5-10'],
						stats['grade-0-5']-stats['grade-0-only'],
						stats['grade-0-only']
					];
					let gradenames = [
						'20 or more',
						'15 to 20',
						'10 to 15',
						'5 to 10',
						'1 to 5',
						'0'
					];

					Data.push(<BarChart values={grades.reverse()} labels={gradenames.reverse()}></BarChart>);

					Data.push(
Types of Entries:
);
					let types = [
						stats.game,
						stats.craft,
						stats.demo,
						stats.tool
					];
					let typenames = [
						'Games',
						'Crafts',
						'Demos',
						'Tools'
					];
					Data.push(<PieChart values={types} labels={typenames}></PieChart>);

				}

				Data.push(
Last Updated: {stats.timestamp}
);

				return (
					<ContentCommon {...props} class={cN(Class)}>
						<ContentCommonBodyTitle title="Statistics" />
						<ContentCommonBody>
							{Data}
						</ContentCommonBody>
					</ContentCommon>
				);
			}
			return
;
		}
		else {
			return <ContentLoading />;
		}
	}
}
<|endoftext|>


<commit_before>'use strict';

import test from 'ava';
import * as ReactDOMServer from 'react-dom/server';
import renderHTML from '../index';

let renderTest = (t, reactEl, expectedHTML) => {
  t.is(ReactDOMServer.renderToStaticMarkup(reactEl), expectedHTML);
};

let singeElementTest = (t, html) => {
  renderTest(t, renderHTML(html), html);
};

test('returns a single React element rendering a provided HTML', t => {
  singeElementTest(t, '
' +
                        '
hihi
' +
                        '

helloworld

react

' +
                      '
');
});

test('returns an array of React elements if several nodes are provided', t => {
  let arr = renderHTML('
hihi
' +
                       '

helloworld

react

');
  t.is(arr.length, 2);
  renderTest(t, arr[0], '
hihi
');
  renderTest(t, arr[1], '

helloworld

react

');
});

test('parse the style attribute when specified as a string', t => {
  singeElementTest(t, '
' +
                        '
hihi
' +
                        '

helloworld

react

' +
                      '
');
});
<commit_msg>Add test for comment<commit_after>'use strict';

import test from 'ava';
import * as ReactDOMServer from 'react-dom/server';
import renderHTML from '../index';

let renderTest = (t, reactEl, expectedHTML) => {
  t.is(ReactDOMServer.renderToStaticMarkup(reactEl), expectedHTML);
};

let singeElementTest = (t, html) => {
  renderTest(t, renderHTML(html), html);
};

test('returns a single React element rendering a provided HTML', t => {
  singeElementTest(t, '
' +
                        '
hihi
' +
                        '

helloworld

react

' +
                      '
');
});

test('returns an array of React elements if several nodes are provided', t => {
  let arr = renderHTML('
hihi
' +
                       '

helloworld

react

');
  t.is(arr.length, 2);
  renderTest(t, arr[0], '
hihi
');
  renderTest(t, arr[1], '

helloworld

react

');
});

test('parse the style attribute when specified as a string', t => {
  singeElementTest(t, '
' +
                        '
hihi
' +
                        '

helloworld

react

' +
                      '
');
});

test('parse comment as undefined', t => {
  t.falsy(renderHTML(''));
});
<|endoftext|>


<commit_before>define(['require', './normalize'], function(req, normalize) {
  var cssAPI = {};

  var isWindows = !!process.platform.match(/^win/);

  function compress(css) {
    if (typeof process !== "undefined" && process.versions && !!process.versions.node && require.nodeRequire) {
      try {
        var csso = require.nodeRequire('csso');
      }
      catch(e) {
        console.log('Compression module not installed. Use "npm install csso -g" to enable.');
        return css;
      }
      var csslen = css.length;
      try {
        css =  csso.justDoIt(css);
      }
      catch(e) {
        console.log('Compression failed due to a CSS syntax error.');
        return css;
      }
      console.log('Compressed CSS output to ' + Math.round(css.length / csslen * 100) + '%.');
      return css;
    }
    console.log('Compression not supported outside of nodejs environments.');
    return css;
  }

  //load file code - stolen from text plugin
  function loadFile(path) {
    if (typeof process !== "undefined" && process.versions && !!process.versions.node && require.nodeRequire) {
      var fs = require.nodeRequire('fs');
      var file = fs.readFileSync(path, 'utf8');
      if (file.indexOf('\uFEFF') === 0)
        return file.substring(1);
      return file;
    }
    else {
      var file = new java.io.File(path),
        lineSeparator = java.lang.System.getProperty("line.separator"),
        input = new java.io.BufferedReader(new java.io.InputStreamReader(new java.io.FileInputStream(file), 'utf-8')),
        stringBuffer, line;
      try {
        stringBuffer = new java.lang.StringBuffer();
        line = input.readLine();
        if (line && line.length() && line.charAt(0) === 0xfeff)
          line = line.substring(1);
        stringBuffer.append(line);
        while ((line = input.readLine()) !== null) {
          stringBuffer.append(lineSeparator).append(line);
        }
        return String(stringBuffer.toString());
      }
      finally {
        input.close();
      }
    }
  }

  function saveFile(path, data) {
    if (typeof process !== "undefined" && process.versions && !!process.versions.node && require.nodeRequire) {
      var fs = require.nodeRequire('fs');
      fs.writeFileSync(path, data, 'utf8');
    }
    else {
      var content = new java.lang.String(data);
      var output = new java.io.BufferedWriter(new java.io.OutputStreamWriter(new java.io.FileOutputStream(path), 'utf-8'));

      try {
        output.write(content, 0, content.length());
        output.flush();
      }
      finally {
        output.close();
      }
    }
  }

  //when adding to the link buffer, paths are normalised to the baseUrl
  //when removing from the link buffer, paths are normalised to the output file path
  function escape(content) {
    return content.replace(/(["'\\])/g, '\\$1')
      .replace(/[\f]/g, "\\f")
      .replace(/[\b]/g, "\\b")
      .replace(/[\n]/g, "\\n")
      .replace(/[\t]/g, "\\t")
      .replace(/[\r]/g, "\\r");
  }

  // NB add @media query support for media imports
  var importRegEx = /@import\s*(url)?\s*(('([^']*)'|"([^"]*)")|\(('([^']*)'|"([^"]*)"|([^\)]*))\))\s*;?/g;
  var absUrlRegEx = /^([^\:\/]+:\/)?\//;

  var siteRoot;

  var baseParts = req.toUrl('base_url').split('/');
  baseParts[baseParts.length - 1] = '';
  var baseUrl = baseParts.join('/');

  var curModule = 0;
  var config;

  var layerBuffer = [];
  var cssBuffer = {};

  cssAPI.load = function(name, req, load, _config) {

    //store config
    config = config || _config;

    if (!siteRoot) {
      siteRoot = path.resolve(config.dir || path.dirname(config.out), config.siteRoot || '.') + '/';
      if (isWindows)
        siteRoot = siteRoot.replace(/\\/g, '/');
    }

    //external URLS don't get added (just like JS requires)
    if (name.match(absUrlRegEx))
      return load();

    var fileUrl = req.toUrl(name + '.css');

    //add to the buffer
    cssBuffer[name] = normalize(loadFile(fileUrl), isWindows ? fileUrl.replace(/\\/g, '/') : fileUrl, siteRoot);

    load();
  }

  cssAPI.normalize = function(name, normalize) {
    if (name.substr(name.length - 4, 4) == '.css')
      name = name.substr(0, name.length - 4);
    return normalize(name);
  }

  cssAPI.write = function(pluginName, moduleName, write, parse) {
    //external URLS don't get added (just like JS requires)
    if (moduleName.match(absUrlRegEx))
      return;

    layerBuffer.push(cssBuffer[moduleName]);

    if (config.buildCSS != false)
    write.asModule(pluginName + '!' + moduleName, 'define(function(){})');
  }

  cssAPI.onLayerEnd = function(write, data) {
    if (config.separateCSS && config.IESelectorLimit)
      throw 'RequireCSS: separateCSS option is not compatible with ensuring the IE selector limit';

    if (config.separateCSS) {
      console.log('Writing CSS! file: ' + data.name + '\n');

      var outPath = config.appDir ? config.baseUrl + data.name + '.css' : config.out.replace(/(\.js)?$/, '.css');

      saveFile(outPath, compress(css));
    }
    else if (config.buildCSS != false) {
      var styles = config.IESelectorLimit ? layerBuffer : [layerBuffer.join('')];
      for (var i = 0; i < styles.length; i++) {
        if (styles[i] == '')
          return;
        write(
          "(function(c){var d=document,a='appendChild',i='styleSheet',s=d.createElement('style');s.type='text/css';d.getElementsByTagName('head')[0][a](s);s[i]?s[i].cssText=c:s[a](d.createTextNode(c));})\n"
          + "('" + escape(compress(styles[i])) + "');\n"
        );
      }
    }
    //clear layer buffer for next layer
    layerBuffer = [];
  }

  return cssAPI;
});
<commit_msg>build fixes<commit_after>define(['require', './normalize'], function(req, normalize) {
  var cssAPI = {};

  var isWindows = !!process.platform.match(/^win/);

  function compress(css) {
    if (typeof process !== "undefined" && process.versions && !!process.versions.node && require.nodeRequire) {
      try {
        var csso = require.nodeRequire('csso');
      }
      catch(e) {
        console.log('Compression module not installed. Use "npm install csso -g" to enable.');
        return css;
      }
      var csslen = css.length;
      try {
        css =  csso.justDoIt(css);
      }
      catch(e) {
        console.log('Compression failed due to a CSS syntax error.');
        return css;
      }
      console.log('Compressed CSS output to ' + Math.round(css.length / csslen * 100) + '%.');
      return css;
    }
    console.log('Compression not supported outside of nodejs environments.');
    return css;
  }

  //load file code - stolen from text plugin
  function loadFile(path) {
    if (typeof process !== "undefined" && process.versions && !!process.versions.node && require.nodeRequire) {
      var fs = require.nodeRequire('fs');
      var file = fs.readFileSync(path, 'utf8');
      if (file.indexOf('\uFEFF') === 0)
        return file.substring(1);
      return file;
    }
    else {
      var file = new java.io.File(path),
        lineSeparator = java.lang.System.getProperty("line.separator"),
        input = new java.io.BufferedReader(new java.io.InputStreamReader(new java.io.FileInputStream(file), 'utf-8')),
        stringBuffer, line;
      try {
        stringBuffer = new java.lang.StringBuffer();
        line = input.readLine();
        if (line && line.length() && line.charAt(0) === 0xfeff)
          line = line.substring(1);
        stringBuffer.append(line);
        while ((line = input.readLine()) !== null) {
          stringBuffer.append(lineSeparator).append(line);
        }
        return String(stringBuffer.toString());
      }
      finally {
        input.close();
      }
    }
  }

  function saveFile(path, data) {
    if (typeof process !== "undefined" && process.versions && !!process.versions.node && require.nodeRequire) {
      var fs = require.nodeRequire('fs');
      fs.writeFileSync(path, data, 'utf8');
    }
    else {
      var content = new java.lang.String(data);
      var output = new java.io.BufferedWriter(new java.io.OutputStreamWriter(new java.io.FileOutputStream(path), 'utf-8'));

      try {
        output.write(content, 0, content.length());
        output.flush();
      }
      finally {
        output.close();
      }
    }
  }

  //when adding to the link buffer, paths are normalised to the baseUrl
  //when removing from the link buffer, paths are normalised to the output file path
  function escape(content) {
    return content.replace(/(["'\\])/g, '\\$1')
      .replace(/[\f]/g, "\\f")
      .replace(/[\b]/g, "\\b")
      .replace(/[\n]/g, "\\n")
      .replace(/[\t]/g, "\\t")
      .replace(/[\r]/g, "\\r");
  }

  // NB add @media query support for media imports
  var importRegEx = /@import\s*(url)?\s*(('([^']*)'|"([^"]*)")|\(('([^']*)'|"([^"]*)"|([^\)]*))\))\s*;?/g;
  var absUrlRegEx = /^([^\:\/]+:\/)?\//;

  var siteRoot;

  var baseParts = req.toUrl('base_url').split('/');
  baseParts[baseParts.length - 1] = '';
  var baseUrl = baseParts.join('/');

  var curModule = 0;
  var config;

  var layerBuffer = [];
  var cssBuffer = {};

  cssAPI.load = function(name, req, load, _config) {

    //store config
    config = config || _config;

    if (!siteRoot) {
      siteRoot = path.resolve(config.dir || path.dirname(config.out), config.siteRoot || '.') + '/';
      if (isWindows)
        siteRoot = siteRoot.replace(/\\/g, '/');
    }

    //external URLS don't get added (just like JS requires)
    if (name.match(absUrlRegEx))
      return load();

    var fileUrl = req.toUrl(name + '.css');

    //add to the buffer
    cssBuffer[name] = normalize(loadFile(fileUrl), isWindows ? fileUrl.replace(/\\/g, '/') : fileUrl, siteRoot);

    load();
  }

  cssAPI.normalize = function(name, normalize) {
    if (name.substr(name.length - 4, 4) == '.css')
      name = name.substr(0, name.length - 4);
    return normalize(name);
  }

  cssAPI.write = function(pluginName, moduleName, write, parse) {
    //external URLS don't get added (just like JS requires)
    if (moduleName.match(absUrlRegEx))
      return;

    layerBuffer.push(cssBuffer[moduleName]);

    if (config.buildCSS != false)
    write.asModule(pluginName + '!' + moduleName, 'define(function(){})');
  }

  cssAPI.onLayerEnd = function(write, data) {
    if (config.separateCSS && config.IESelectorLimit)
      throw 'RequireCSS: separateCSS option is not compatible with ensuring the IE selector limit';

    if (config.separateCSS) {
      console.log('Writing CSS! file: ' + data.name + '\n');

      fs.mkdirSync(data.name)
      var outPath = config.dir ? path.resolve(config.dir, config.baseUrl, data.name + '.css') : config.out.replace(/(\.js)?$/, '.css');

      var css = layerBuffer.join('');

      if (fs.existsSync(outPath))
        console.log('RequireCSS: Warning, separateCSS module path "' + outPath + '" already exists and is being replaced by the layer CSS.');

      process.nextTick(function() {
        saveFile(outPath, compress(css));
      });

    }
    else if (config.buildCSS != false) {
      var styles = config.IESelectorLimit ? layerBuffer : [layerBuffer.join('')];
      for (var i = 0; i < styles.length; i++) {
        if (styles[i] == '')
          return;
        write(
          "(function(c){var d=document,a='appendChild',i='styleSheet',s=d.createElement('style');s.type='text/css';d.getElementsByTagName('head')[0][a](s);s[i]?s[i].cssText=c:s[a](d.createTextNode(c));})\n"
          + "('" + escape(compress(styles[i])) + "');\n"
        );
      }
    }
    //clear layer buffer for next layer
    layerBuffer = [];
  }

  return cssAPI;
});
<|endoftext|>