<commit_before>var crud = require('../');
var express = require('express');
var assert = require('chai').assert;
var http = require('http');
var request = require('superagent');

function makeapp () {
  var app = express();
  app.set('controller path', __dirname + '/controllers');
  return app;
}

describe('express-crud', function() {
  var app, server, address;
  before(function(done) {
    app = makeapp();
    server = http.Server(app);
    server.listen(0, function () {
      address = server.address();
      done();
    });
  });

  after(function(done) {
    server.close();
    done();
  });

  describe('.controllers', function() {
    it('should contain all the correct controllers', function() {
      app.set('controller path', __dirname + '/controllers/');
      crud(app,{verbose:false});
      assert.isNotNull(app.controllers, 'Crud adds controllers to applications');
      assert.isNotNull(app.controllers['test'], 'Crud adds controllers to applications');
      assert.isNotNull(app.controllers['subtest'], 'Crud adds controllers to applications');
      assert.isNotNull(app.controllers['subtest'].error, 'Crud adds error handler from controllers to applications');
      assert.isTrue(app.controllers['test'].set('jsonp callback'));
    });
  });

  describe('routes', function() {
    it('should route requests to correct routes', function(done) {
      var expected = {
        'GET /test':{"test:":"tests"},
        'POST /test':{"test:":"test created"},
        'PUT /test/1':{"test:":"test 1"},
        'GET /test/1':{"test:":"test 1"},
        'DEL /test/1':{"test:":"test 1 delete"},
        'GET /test/1/subtest/1': {"subtest:":"subtest 1"},
        'GET /test/1/subtest': {"error":'subtest-error'}
      };
      var numRoutes = Object.keys(expected).length;
      Object.keys(expected).forEach(function(key) {
        var parts = key.split(' ');
        var method = parts[0];
        var path = parts[1];
        var result = expected[key];
        var url = 'http://' + address.address + ':' + address.port + path;
        request[method.toLowerCase()](url, function(error, res) {
          res.req.method = res.req.method == 'DELETE' ? 'DEL' : res.req.method;
          assert.deepEqual(JSON.parse(res.text), expected[res.req.method + ' '+res.req.path]);
          --numRoutes || done();
        });
      });
    });
  });
});<commit_msg>move error and object tests to own testblocks<commit_after>var crud = require('../');
var express = require('express');
var assert = require('chai').assert;
var http = require('http');
var request = require('superagent');

function makeapp () {
  var app = express();
  app.set('controller path', __dirname + '/controllers');
  return app;
}

describe('express-crud', function() {
  var app, server, address;
  before(function(done) {
    app = makeapp();
    server = http.Server(app);
    server.listen(0, function () {
      address = server.address();
      done();
    });
  });

  after(function(done) {
    server.close();
    done();
  });

  describe('.controllers', function() {
    it('should contain all the correct controllers', function() {
      app.set('controller path', __dirname + '/controllers/');
      crud(app,{verbose:false});
      assert.isNotNull(app.controllers, 'Crud adds controllers to applications');
      assert.isNotNull(app.controllers['test'], 'Crud adds controllers to applications');
      assert.isNotNull(app.controllers['subtest'], 'Crud adds controllers to applications');
    });
  });

  describe('routes', function() {
    it('should route requests to correct routes', function(done) {
      var expected = {
        'GET /test':{"test:":"tests"},
        'POST /test':{"test:":"test created"},
        'PUT /test/1':{"test:":"test 1"},
        'GET /test/1':{"test:":"test 1"},
        'DEL /test/1':{"test:":"test 1 delete"},
        'GET /test/1/subtest/1': {"subtest:":"subtest 1"},
        'GET /test/1/subtest': {"error":'subtest-error'}
      };
      var numRoutes = Object.keys(expected).length;
      Object.keys(expected).forEach(function(key) {
        var parts = key.split(' ');
        var method = parts[0];
        var path = parts[1];
        var result = expected[key];
        var url = 'http://' + address.address + ':' + address.port + path;
        request[method.toLowerCase()](url, function(error, res) {
          res.req.method = res.req.method == 'DELETE' ? 'DEL' : res.req.method;
          assert.deepEqual(JSON.parse(res.text), expected[res.req.method + ' '+res.req.path]);
          --numRoutes || done();
        });
      });
    });
    it('should set options to the controller app', function() {
      assert.isTrue(app.controllers['test'].set('jsonp callback'));
    });
    it('should set the error handler to controller app', function() {
      assert.isNotNull(app.controllers['subtest'].error, 'Crud adds error handler from controllers to applications');
    })
  });
});<|endoftext|>


<commit_before>'use strict';

var chai = require('chai');
var RpcClient = require('../');
var util = require('util');
var EventEmitter = require('events').EventEmitter;
var sinon = require('sinon');
var should = chai.should();
var http = require('http');
var https = require('https');
var async = require('async');

describe('RpcClient', function() {

  it('should initialize the main object', function() {
    should.exist(RpcClient);
  });

  it('should be able to create instance', function() {
    var s = new RpcClient();
    should.exist(s);
  });

  it('default to rejectUnauthorized as true', function() {
    var s = new RpcClient();
    should.exist(s);
    s.rejectUnauthorized.should.equal(true);
  });

  it('should be able to define a custom logger', function() {
    var customLogger = {
      info: function(){},
      warn: function(){},
      err: function(){},
      debug: function(){}
    };
    RpcClient.config.log = customLogger;
    var s = new RpcClient();
    s.log.should.equal(customLogger);
    RpcClient.config.log = false;
  });

  it('should be able to define the logger to normal', function() {
    RpcClient.config.logger = 'normal';
    var s = new RpcClient();
    s.log.should.equal(RpcClient.loggers.normal);
  });

  it('should be able to define the logger to none', function() {
    RpcClient.config.logger = 'none';
    var s = new RpcClient();
    s.log.should.equal(RpcClient.loggers.none);
  });

  function FakeResponse(){
    EventEmitter.call(this);
  }
  util.inherits(FakeResponse, EventEmitter);

  function FakeRequest(){
    EventEmitter.call(this);
    return this;
  }
  util.inherits(FakeRequest, EventEmitter);
  FakeRequest.prototype.setHeader = function() {};
  FakeRequest.prototype.write = function(data) {
    this.data = data;
  };
  FakeRequest.prototype.end = function() {};

  it('should use https', function() {

    var client = new RpcClient({
      user: 'user',
      pass: 'pass',
      port: 8332,
    });
    client.protocol.should.equal(https);

  });

  it('should use http', function() {

    var client = new RpcClient({
      user: 'user',
      pass: 'pass',
      host: 'localhost',
      port: 8332,
      protocol: 'http'
    });
    client.protocol.should.equal(http);

  });

  it('should call a method and receive response', function(done) {

    var client = new RpcClient({
      user: 'user',
      pass: 'pass',
      host: 'localhost',
      port: 8332,
      rejectUnauthorized: true,
      disableAgent: true
    });

    var requestStub = sinon.stub(client.protocol, 'request', function(options, callback){
      var res = new FakeResponse();
      var req =  new FakeRequest();
      setTimeout(function(){
        res.emit('data', '{}');
        res.emit('end');
      }, 10);
      callback(res);
      return req;
    });

    client.setTxFee(0.01, function(error, parsedBuf) {
      requestStub.restore();
      should.not.exist(error);
      should.exist(parsedBuf);
      done();
    });

  });

  it('accept many values for bool', function(done) {

    var client = new RpcClient({
      user: 'user',
      pass: 'pass',
      host: 'localhost',
      port: 8332,
      rejectUnauthorized: true,
      disableAgent: false
    });

    var requestStub = sinon.stub(client.protocol, 'request', function(options, callback){
      var res = new FakeResponse();
      var req = new FakeRequest();
      setTimeout(function(){
        res.emit('data', req.data);
        res.emit('end');
      }, 10);
      callback(res);
      return req;
    });

    async.eachSeries([true, 'true', 1, '1', 'True'], function(i, next) {
      client.importAddress('n28S35tqEMbt6vNad7A5K3mZ7vdn8dZ86X', '', i, function(error, parsedBuf) {
        should.not.exist(error);
        should.exist(parsedBuf);
        parsedBuf.params[2].should.equal(true);
        next();
      });
    }, function(err) {
      requestStub.restore();
      done();
    });

  });

  it('should batch calls for a method and receive a response', function(done) {

    var client = new RpcClient({
      user: 'user',
      pass: 'pass',
      host: 'localhost',
      port: 8332,
      rejectUnauthorized: true,
      disableAgent: false
    });

    var requestStub = sinon.stub(client.protocol, 'request', function(options, callback){
      var res = new FakeResponse();
      setTimeout(function(){
        res.emit('data', '[{}, {}, {}]');
        res.emit('end');
      }, 10);
      callback(res);
      return new FakeRequest();
    });

    client.batchedCalls = [];
    client.listReceivedByAccount(1, true);
    client.listReceivedByAccount(2, true);
    client.listReceivedByAccount(3, true);
    client.batchedCalls.length.should.equal(3);
    client.batch(function(){
      // batch started
    }, function(error, result){
      // batch ended
      requestStub.restore();
      should.not.exist(error);
      should.exist(result);
      result.length.should.equal(3);
      done();
    });

  });

  it('should handle connection rejected 401 unauthorized', function(done) {

    var client = new RpcClient({
      user: 'user',
      pass: 'pass',
      host: 'localhost',
      port: 8332,
      rejectUnauthorized: true,
      disableAgent: true
    });

    var requestStub = sinon.stub(client.protocol, 'request', function(options, callback){
      var res = new FakeResponse();
      res.statusCode = 401;
      setTimeout(function(){
        res.emit('end');
      }, 10);
      callback(res);
      return new FakeRequest();
    });

    client.getBalance('n28S35tqEMbt6vNad7A5K3mZ7vdn8dZ86X', 6, function(error, parsedBuf) {
      requestStub.restore();
      should.exist(error);
      error.message.should.equal('Bitcoin Core JSON-RPC: host=localhost port=8332: Connection Rejected: 401 Unnauthorized');
      done();
    });

  });

  it('should handle connection rejected 401 forbidden', function(done) {

    var client = new RpcClient({
      user: 'user',
      pass: 'pass',
      host: 'localhost',
      port: 8332,
      rejectUnauthorized: true,
      disableAgent: true
    });

    var requestStub = sinon.stub(client.protocol, 'request', function(options, callback){
      var res = new FakeResponse();
      res.statusCode = 403;
      setTimeout(function(){
        res.emit('end');
      }, 10);
      callback(res);
      return new FakeRequest();
    });

    client.getDifficulty(function(error, parsedBuf) {
      requestStub.restore();
      should.exist(error);
      error.message.should.equal('Bitcoin Core JSON-RPC: host=localhost port=8332: Connection Rejected: 403 Forbidden');
      done();
    });

  });

  it('should handle EPIPE error case 1', function(done) {

    var client = new RpcClient({
      user: 'user',
      pass: 'pass',
      host: 'localhost',
      port: 8332,
      rejectUnauthorized: true,
      disableAgent: true
    });

    var requestStub = sinon.stub(client.protocol, 'request', function(options, callback){
      var res = new FakeResponse();
      setTimeout(function(){
        res.emit('data', '{}');
        res.emit('end');
      }, 10);
      var req = new FakeRequest();
      setTimeout(function(){
        req.emit('error', new Error('write EPIPE'));
      }, 8);
      callback(res);
      return req;
    });

    client.getDifficulty(function(error, parsedBuf) {
      requestStub.restore();
      should.exist(error);
      error.message.should.equal('Bitcoin Core JSON-RPC: host=localhost port=8332: Request Error: write EPIPE');
      done();
    });

  });

  it('should handle EPIPE error case 2', function(done) {

    var client = new RpcClient({
      user: 'user',
      pass: 'pass',
      host: 'localhost',
      port: 8332,
      rejectUnauthorized: true,
      disableAgent: true
    });

    var requestStub = sinon.stub(client.protocol, 'request', function(options, callback){
      var res = new FakeResponse();
      setTimeout(function(){
        res.emit('data', '{}');
        res.emit('end');
      }, 8);
      var req = new FakeRequest();
      setTimeout(function(){
        req.emit('error', new Error('write EPIPE'));
      }, 10);
      callback(res);
      req.on('error', function(err) {
        requestStub.restore();
        done();
      });
      return req;
    });

    client.getDifficulty(function(error, parsedBuf) {});

  });

  it('should handle ECONNREFUSED error', function(done) {

    var client = new RpcClient({
      user: 'user',
      pass: 'pass',
      host: 'localhost',
      port: 8332,
      rejectUnauthorized: true,
      disableAgent: true
    });

    var requestStub = sinon.stub(client.protocol, 'request', function(options, callback){
      var res = new FakeResponse();
      var req = new FakeRequest();
      setTimeout(function(){
        req.emit('error', new Error('connect ECONNREFUSED'));
      }, 10);
      callback(res);
      return req;
    });

    client.getDifficulty(function(error, parsedBuf) {
      requestStub.restore();
      should.exist(error);
      error.message.should.equal('Bitcoin Core JSON-RPC: host=localhost port=8332: Request Error: connect ECONNREFUSED');
      done();
    });

  });

  it('should callback with error if invalid json', function(done) {

    var client = new RpcClient({
      user: 'user',
      pass: 'pass',
      host: 'localhost',
      port: 8332,
      rejectUnauthorized: true,
      disableAgent: true
    });

    var requestStub = sinon.stub(client.protocol, 'request', function(options, callback){
      var res = new FakeResponse();
      setTimeout(function(){
        res.emit('data', 'not a json string');
        res.emit('end');
      }, 8);
      var req = new FakeRequest();
      callback(res);
      return req;
    });

    client.getDifficulty(function(error, parsedBuf) {
      requestStub.restore();
      should.exist(error);
      error.message.should.equal('Bitcoin Core JSON-RPC: host=localhost port=8332: Error Parsing JSON: Unexpected token o');
      done();
    });

  });

  it('should callback with error if blank response', function(done) {

    var client = new RpcClient({
      user: 'user',
      pass: 'pass',
      host: 'localhost',
      port: 8332,
      rejectUnauthorized: true,
      disableAgent: true
    });

    var requestStub = sinon.stub(client.protocol, 'request', function(options, callback){
      var res = new FakeResponse();
      setTimeout(function(){
        res.emit('data', '');
        res.emit('end');
      }, 8);
      var req = new FakeRequest();
      callback(res);
      return req;
    });

    client.getDifficulty(function(error, parsedBuf) {
      requestStub.restore();
      should.exist(error);
      error.message.should.equal('Bitcoin Core JSON-RPC: host=localhost port=8332: Error Parsing JSON: Unexpected end of input');
      done();
    });

  });

  it('should add additional http options', function(done) {

    var client = new RpcClient({
      user: 'user',
      pass: 'pass',
      host: 'localhost',
      port: 8332,
      rejectUnauthorized: true,
      disableAgent: true
    });

    client.httpOptions = {
      port: 20001
    };

    var calledPort = false;

    var requestStub = sinon.stub(client.protocol, 'request', function(options, callback){
      calledPort = options.port;
      var res = new FakeResponse();
      setTimeout(function(){
        res.emit('data', '{}');
        res.emit('end');
      }, 8);
      var req = new FakeRequest();
      callback(res);
      return req;
    });

    client.getDifficulty(function(error, parsedBuf) {
      should.not.exist(error);
      should.exist(parsedBuf);
      calledPort.should.equal(20001);
      requestStub.restore();
      done();
    });

  });

});
<commit_msg>use setImmediate instead of setTimeout<commit_after>'use strict';

var chai = require('chai');
var RpcClient = require('../');
var util = require('util');
var EventEmitter = require('events').EventEmitter;
var sinon = require('sinon');
var should = chai.should();
var http = require('http');
var https = require('https');
var async = require('async');

if(!setImmediate) setImmediate = setTimeout;

describe('RpcClient', function() {

  it('should initialize the main object', function() {
    should.exist(RpcClient);
  });

  it('should be able to create instance', function() {
    var s = new RpcClient();
    should.exist(s);
  });

  it('default to rejectUnauthorized as true', function() {
    var s = new RpcClient();
    should.exist(s);
    s.rejectUnauthorized.should.equal(true);
  });

  it('should be able to define a custom logger', function() {
    var customLogger = {
      info: function(){},
      warn: function(){},
      err: function(){},
      debug: function(){}
    };
    RpcClient.config.log = customLogger;
    var s = new RpcClient();
    s.log.should.equal(customLogger);
    RpcClient.config.log = false;
  });

  it('should be able to define the logger to normal', function() {
    RpcClient.config.logger = 'normal';
    var s = new RpcClient();
    s.log.should.equal(RpcClient.loggers.normal);
  });

  it('should be able to define the logger to none', function() {
    RpcClient.config.logger = 'none';
    var s = new RpcClient();
    s.log.should.equal(RpcClient.loggers.none);
  });

  function FakeResponse(){
    EventEmitter.call(this);
  }
  util.inherits(FakeResponse, EventEmitter);

  function FakeRequest(){
    EventEmitter.call(this);
    return this;
  }
  util.inherits(FakeRequest, EventEmitter);
  FakeRequest.prototype.setHeader = function() {};
  FakeRequest.prototype.write = function(data) {
    this.data = data;
  };
  FakeRequest.prototype.end = function() {};

  it('should use https', function() {

    var client = new RpcClient({
      user: 'user',
      pass: 'pass',
      port: 8332,
    });
    client.protocol.should.equal(https);

  });

  it('should use http', function() {

    var client = new RpcClient({
      user: 'user',
      pass: 'pass',
      host: 'localhost',
      port: 8332,
      protocol: 'http'
    });
    client.protocol.should.equal(http);

  });

  it('should call a method and receive response', function(done) {

    var client = new RpcClient({
      user: 'user',
      pass: 'pass',
      host: 'localhost',
      port: 8332,
      rejectUnauthorized: true,
      disableAgent: true
    });

    var requestStub = sinon.stub(client.protocol, 'request', function(options, callback){
      var res = new FakeResponse();
      var req =  new FakeRequest();
      setImmediate(function(){
        res.emit('data', '{}');
        res.emit('end');
      });
      callback(res);
      return req;
    });

    client.setTxFee(0.01, function(error, parsedBuf) {
      requestStub.restore();
      should.not.exist(error);
      should.exist(parsedBuf);
      done();
    });

  });

  it('accept many values for bool', function(done) {

    var client = new RpcClient({
      user: 'user',
      pass: 'pass',
      host: 'localhost',
      port: 8332,
      rejectUnauthorized: true,
      disableAgent: false
    });

    var requestStub = sinon.stub(client.protocol, 'request', function(options, callback){
      var res = new FakeResponse();
      var req = new FakeRequest();
      setImmediate(function(){
        res.emit('data', req.data);
        res.emit('end');
      });
      callback(res);
      return req;
    });

    async.eachSeries([true, 'true', 1, '1', 'True'], function(i, next) {
      client.importAddress('n28S35tqEMbt6vNad7A5K3mZ7vdn8dZ86X', '', i, function(error, parsedBuf) {
        should.not.exist(error);
        should.exist(parsedBuf);
        parsedBuf.params[2].should.equal(true);
        next();
      });
    }, function(err) {
      requestStub.restore();
      done();
    });

  });

  it('should batch calls for a method and receive a response', function(done) {

    var client = new RpcClient({
      user: 'user',
      pass: 'pass',
      host: 'localhost',
      port: 8332,
      rejectUnauthorized: true,
      disableAgent: false
    });

    var requestStub = sinon.stub(client.protocol, 'request', function(options, callback){
      var res = new FakeResponse();
      setImmediate(function(){
        res.emit('data', '[{}, {}, {}]');
        res.emit('end');
      });
      callback(res);
      return new FakeRequest();
    });

    client.batchedCalls = [];
    client.listReceivedByAccount(1, true);
    client.listReceivedByAccount(2, true);
    client.listReceivedByAccount(3, true);
    client.batchedCalls.length.should.equal(3);
    client.batch(function(){
      // batch started
    }, function(error, result){
      // batch ended
      requestStub.restore();
      should.not.exist(error);
      should.exist(result);
      result.length.should.equal(3);
      done();
    });

  });

  it('should handle connection rejected 401 unauthorized', function(done) {

    var client = new RpcClient({
      user: 'user',
      pass: 'pass',
      host: 'localhost',
      port: 8332,
      rejectUnauthorized: true,
      disableAgent: true
    });

    var requestStub = sinon.stub(client.protocol, 'request', function(options, callback){
      var res = new FakeResponse();
      res.statusCode = 401;
      setImmediate(function(){
        res.emit('end');
      });
      callback(res);
      return new FakeRequest();
    });

    client.getBalance('n28S35tqEMbt6vNad7A5K3mZ7vdn8dZ86X', 6, function(error, parsedBuf) {
      requestStub.restore();
      should.exist(error);
      error.message.should.equal('Bitcoin Core JSON-RPC: host=localhost port=8332: Connection Rejected: 401 Unnauthorized');
      done();
    });

  });

  it('should handle connection rejected 401 forbidden', function(done) {

    var client = new RpcClient({
      user: 'user',
      pass: 'pass',
      host: 'localhost',
      port: 8332,
      rejectUnauthorized: true,
      disableAgent: true
    });

    var requestStub = sinon.stub(client.protocol, 'request', function(options, callback){
      var res = new FakeResponse();
      res.statusCode = 403;
      setImmediate(function(){
        res.emit('end');
      });
      callback(res);
      return new FakeRequest();
    });

    client.getDifficulty(function(error, parsedBuf) {
      requestStub.restore();
      should.exist(error);
      error.message.should.equal('Bitcoin Core JSON-RPC: host=localhost port=8332: Connection Rejected: 403 Forbidden');
      done();
    });

  });

  it('should handle EPIPE error case 1', function(done) {

    var client = new RpcClient({
      user: 'user',
      pass: 'pass',
      host: 'localhost',
      port: 8332,
      rejectUnauthorized: true,
      disableAgent: true
    });

    var requestStub = sinon.stub(client.protocol, 'request', function(options, callback){
      var req = new FakeRequest();
      setImmediate(function(){
        req.emit('error', new Error('write EPIPE'));
      });
      var res = new FakeResponse();
      setImmediate(function(){
        res.emit('data', '{}');
        res.emit('end');
      });
      callback(res);
      return req;
    });

    client.getDifficulty(function(error, parsedBuf) {
      requestStub.restore();
      should.exist(error);
      error.message.should.equal('Bitcoin Core JSON-RPC: host=localhost port=8332: Request Error: write EPIPE');
      done();
    });

  });

  it('should handle EPIPE error case 2', function(done) {

    var client = new RpcClient({
      user: 'user',
      pass: 'pass',
      host: 'localhost',
      port: 8332,
      rejectUnauthorized: true,
      disableAgent: true
    });

    var requestStub = sinon.stub(client.protocol, 'request', function(options, callback){
      var res = new FakeResponse();
      setImmediate(function(){
        res.emit('data', '{}');
        res.emit('end');
      });
      var req = new FakeRequest();
      setImmediate(function(){
        req.emit('error', new Error('write EPIPE'));
      });
      callback(res);
      req.on('error', function(err) {
        requestStub.restore();
        done();
      });
      return req;
    });

    client.getDifficulty(function(error, parsedBuf) {});

  });

  it('should handle ECONNREFUSED error', function(done) {

    var client = new RpcClient({
      user: 'user',
      pass: 'pass',
      host: 'localhost',
      port: 8332,
      rejectUnauthorized: true,
      disableAgent: true
    });

    var requestStub = sinon.stub(client.protocol, 'request', function(options, callback){
      var res = new FakeResponse();
      var req = new FakeRequest();
      setImmediate(function(){
        req.emit('error', new Error('connect ECONNREFUSED'));
      });
      callback(res);
      return req;
    });

    client.getDifficulty(function(error, parsedBuf) {
      requestStub.restore();
      should.exist(error);
      error.message.should.equal('Bitcoin Core JSON-RPC: host=localhost port=8332: Request Error: connect ECONNREFUSED');
      done();
    });

  });

  it('should callback with error if invalid json', function(done) {

    var client = new RpcClient({
      user: 'user',
      pass: 'pass',
      host: 'localhost',
      port: 8332,
      rejectUnauthorized: true,
      disableAgent: true
    });

    var requestStub = sinon.stub(client.protocol, 'request', function(options, callback){
      var res = new FakeResponse();
      setImmediate(function(){
        res.emit('data', 'not a json string');
        res.emit('end');
      });
      var req = new FakeRequest();
      callback(res);
      return req;
    });

    client.getDifficulty(function(error, parsedBuf) {
      requestStub.restore();
      should.exist(error);
      error.message.should.equal('Bitcoin Core JSON-RPC: host=localhost port=8332: Error Parsing JSON: Unexpected token o');
      done();
    });

  });

  it('should callback with error if blank response', function(done) {

    var client = new RpcClient({
      user: 'user',
      pass: 'pass',
      host: 'localhost',
      port: 8332,
      rejectUnauthorized: true,
      disableAgent: true
    });

    var requestStub = sinon.stub(client.protocol, 'request', function(options, callback){
      var res = new FakeResponse();
      setImmediate(function(){
        res.emit('data', '');
        res.emit('end');
      });
      var req = new FakeRequest();
      callback(res);
      return req;
    });

    client.getDifficulty(function(error, parsedBuf) {
      requestStub.restore();
      should.exist(error);
      error.message.should.equal('Bitcoin Core JSON-RPC: host=localhost port=8332: Error Parsing JSON: Unexpected end of input');
      done();
    });

  });

  it('should add additional http options', function(done) {

    var client = new RpcClient({
      user: 'user',
      pass: 'pass',
      host: 'localhost',
      port: 8332,
      rejectUnauthorized: true,
      disableAgent: true
    });

    client.httpOptions = {
      port: 20001
    };

    var calledPort = false;

    var requestStub = sinon.stub(client.protocol, 'request', function(options, callback){
      calledPort = options.port;
      var res = new FakeResponse();
      setImmediate(function(){
        res.emit('data', '{}');
        res.emit('end');
      });
      var req = new FakeRequest();
      callback(res);
      return req;
    });

    client.getDifficulty(function(error, parsedBuf) {
      should.not.exist(error);
      should.exist(parsedBuf);
      calledPort.should.equal(20001);
      requestStub.restore();
      done();
    });

  });

});
<|endoftext|>


<commit_before>/* ------------------------------------------------------------------------- *
 * Copyright 2002-2022, OpenNebula Project, OpenNebula Systems               *
 *                                                                           *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may   *
 * not use this file except in compliance with the License. You may obtain   *
 * a copy of the License at                                                  *
 *                                                                           *
 * http://www.apache.org/licenses/LICENSE-2.0                                *
 *                                                                           *
 * Unless required by applicable law or agreed to in writing, software       *
 * distributed under the License is distributed on an "AS IS" BASIS,         *
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  *
 * See the License for the specific language governing permissions and       *
 * limitations under the License.                                            *
 * ------------------------------------------------------------------------- */
import { memo, useMemo } from 'react'
import PropTypes from 'prop-types'

import {
  useMediaQuery,
  Typography,
  Box,
  Paper,
  Stack,
  Accordion,
  AccordionSummary,
  AccordionDetails,
} from '@mui/material'

import { rowStyles } from 'client/components/Tables/styles'
import { StatusChip } from 'client/components/Status'
import MultipleTags from 'client/components/MultipleTags'

import { Translate } from 'client/components/HOC'
import { stringToBoolean } from 'client/models/Helper'
import { groupBy } from 'client/utils'
import { T, Nic, NicAlias, PrettySecurityGroupRule } from 'client/constants'

const NicCard = memo(
  ({
    nic = {},
    actions,
    aliasActions,
    securityGroupActions,
    showParents = false,
    clipboardOnTags = true,
  }) => {
    const classes = rowStyles()
    const isMobile = useMediaQuery((theme) => theme.breakpoints.down('md'))

    /** @type {Nic|NicAlias} */
    const {
      NIC_ID,
      NETWORK = '-',
      IP,
      MAC,
      PCI_ID,
      RDP,
      SSH,
      PARENT,
      ADDRESS,
      ALIAS,
      SECURITY_GROUPS,
    } = nic

    const isAlias = !!PARENT?.length
    const isPciDevice = PCI_ID !== undefined
    const isAdditionalIp = NIC_ID !== undefined || NETWORK === 'Additional IP'

    const dataCy = isAlias ? 'alias' : 'nic'

    const noClipboardTags = [
      { text: stringToBoolean(RDP) && 'RDP', dataCy: `${dataCy}-rdp` },
      { text: stringToBoolean(SSH) && 'SSH', dataCy: `${dataCy}-ssh` },
      showParents && {
        text: isAlias ? `PARENT: ${PARENT}` : false,
        dataCy: `${dataCy}-parent`,
      },
    ].filter(({ text } = {}) => Boolean(text))

    const tags = [
      { text: IP, dataCy: `${dataCy}-ip` },
      { text: MAC, dataCy: `${dataCy}-mac` },
      { text: ADDRESS, dataCy: `${dataCy}-address` },
    ].filter(({ text } = {}) => Boolean(text))

    return (
      <Paper
        variant="outlined"
        className={classes.root}
        data-cy={`${dataCy}-${NIC_ID}`}
        sx={{ flexWrap: 'wrap', boxShadow: 'none !important' }}
      >
        <Box
          className={classes.main}
          {...(!isAlias && !showParents && { pl: '1em' })}
        >

            <Typography component="span" data-cy={`${dataCy}-name`}>
              {`${NIC_ID} | ${NETWORK}`}
            </Typography>

              {isAlias && <StatusChip stateColor="info" text={'ALIAS'} />}
              {noClipboardTags.map((tag) => (
                <StatusChip
                  key={`${dataCy}-${NIC_ID}-${tag.dataCy}`}
                  text={tag.text}
                  dataCy={tag.dataCy}
                />
              ))}
              <MultipleTags
                clipboard={clipboardOnTags}
                limitTags={isMobile ? 1 : 3}
                tags={tags}
              />

        </Box>
        {!isPciDevice && !isAdditionalIp && (

{actions}

        )}
        {!!ALIAS?.length && (
          <Box flexBasis="100%">
            {ALIAS?.map((alias) => (
              <NicCard
                key={alias.NIC_ID}
                nic={alias}
                actions={aliasActions?.({ alias })}
                showParents={showParents}
              />
            ))}
          </Box>
        )}
        {useMemo(() => {
          if (!Array.isArray(SECURITY_GROUPS) || !SECURITY_GROUPS?.length) {
            return null
          }

          const rulesById = Object.entries(groupBy(SECURITY_GROUPS, 'ID'))

          return (
            <Accordion>
              <AccordionSummary>
                <Typography variant="body1">
                  <Translate word={T.SecurityGroups} />
                </Typography>
              </AccordionSummary>
              {rulesById.map(([ID, rules]) => {
                const key = `nic-${NIC_ID}-secgroup-${ID}`
                const acts = securityGroupActions?.({ securityGroupId: ID })

                return (
                  <AccordionDetails key={key}>
                    <SecurityGroupRules
                      parentKey={key}
                      id={ID}
                      rules={rules}
                      actions={acts}
                    />
                  </AccordionDetails>
                )
              })}
            </Accordion>
          )
        }, [SECURITY_GROUPS])}
      </Paper>
    )
  }
)

NicCard.propTypes = {
  nic: PropTypes.object,
  actions: PropTypes.node,
  aliasActions: PropTypes.func,
  securityGroupActions: PropTypes.func,
  showParents: PropTypes.bool,
  clipboardOnTags: PropTypes.bool,
}

NicCard.displayName = 'NicCard'

const SecurityGroupRules = memo(({ parentKey, id, actions, rules }) => {
  const classes = rowStyles()

  const COLUMNS = useMemo(
    () => [T.Protocol, T.Type, T.Range, T.Network, T.IcmpType],
    []
  )

  const name = rules?.[0]?.NAME ?? 'default'

  return (
    <>
      <Stack direction="row" spacing={1} alignItems="center">
        <Typography
          noWrap
          component="span"
          variant="subtitle1"
          data-cy={`${parentKey}-rule-name`}
        >
          {`#${id} ${name}`}
        </Typography>
        {!!actions &&
{actions}
}
      </Stack>
      <Box display="grid" gridTemplateColumns="repeat(5, 1fr)" gap="0.5em">
        {COLUMNS.map((col) => (
          <Typography
            key={`${parentKey}-${col}`}
            noWrap
            component="span"
            variant="subtitle2"
          >
            <Translate word={col} />
          </Typography>
        ))}
        {rules.map((rule) => (
          <SecurityGroupRule
            key={`${parentKey}-rule-${rule.RULE_TYPE}`}
            data-cy={`${parentKey}-rule-${rule.RULE_TYPE}`}
            rule={rule}
          />
        ))}
      </Box>
    </>
  )
})

SecurityGroupRules.propTypes = {
  parentKey: PropTypes.string,
  id: PropTypes.string,
  rules: PropTypes.array,
  actions: PropTypes.node,
}

SecurityGroupRules.displayName = 'SecurityGroupRule'

const SecurityGroupRule = memo(({ rule, 'data-cy': parentCy }) => {
  /** @type {PrettySecurityGroupRule} */
  const { PROTOCOL, RULE_TYPE, ICMP_TYPE, RANGE, NETWORK_ID } = rule

  return (
    <>
      {[
        { text: PROTOCOL, dataCy: 'protocol' },
        { text: RULE_TYPE, dataCy: 'ruletype' },
        { text: RANGE, dataCy: 'range' },
        { text: NETWORK_ID, dataCy: 'networkid' },
        { text: ICMP_TYPE, dataCy: 'icmp-type' },
      ].map(({ text, dataCy }) => (
        <Typography
          noWrap
          key={`${parentCy}-${dataCy}`}
          data-cy={`${parentCy}-${dataCy}`.toLowerCase()}
          variant="subtitle2"
        >
          {text}
        </Typography>
      ))}
    </>
  )
})

SecurityGroupRule.propTypes = {
  rule: PropTypes.object,
  'data-cy': PropTypes.string,
}

SecurityGroupRule.displayName = 'SecurityGroupRule'

export default NicCard
<commit_msg>F #5422: Reformat styles to network info tab (#2025)<commit_after>/* ------------------------------------------------------------------------- *
 * Copyright 2002-2022, OpenNebula Project, OpenNebula Systems               *
 *                                                                           *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may   *
 * not use this file except in compliance with the License. You may obtain   *
 * a copy of the License at                                                  *
 *                                                                           *
 * http://www.apache.org/licenses/LICENSE-2.0                                *
 *                                                                           *
 * Unless required by applicable law or agreed to in writing, software       *
 * distributed under the License is distributed on an "AS IS" BASIS,         *
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  *
 * See the License for the specific language governing permissions and       *
 * limitations under the License.                                            *
 * ------------------------------------------------------------------------- */
import { memo, useMemo } from 'react'
import PropTypes from 'prop-types'

import {
  useMediaQuery,
  Typography,
  Box,
  Paper,
  Stack,
  Accordion,
  AccordionSummary,
  AccordionDetails,
} from '@mui/material'

import { rowStyles } from 'client/components/Tables/styles'
import { StatusChip } from 'client/components/Status'
import MultipleTags from 'client/components/MultipleTags'

import { Translate } from 'client/components/HOC'
import { stringToBoolean } from 'client/models/Helper'
import { groupBy } from 'client/utils'
import { T, Nic, NicAlias, PrettySecurityGroupRule } from 'client/constants'

const NicCard = memo(
  ({
    nic = {},
    actions,
    aliasActions,
    securityGroupActions,
    showParents = false,
    clipboardOnTags = true,
  }) => {
    const classes = rowStyles()
    const isMobile = useMediaQuery((theme) => theme.breakpoints.down('md'))

    /** @type {Nic|NicAlias} */
    const {
      NIC_ID,
      NETWORK = '-',
      IP,
      MAC,
      PCI_ID,
      RDP,
      SSH,
      PARENT,
      ADDRESS,
      ALIAS,
      SECURITY_GROUPS,
    } = nic

    const isAlias = !!PARENT?.length
    const isPciDevice = PCI_ID !== undefined
    const isAdditionalIp = NIC_ID !== undefined || NETWORK === 'Additional IP'

    const dataCy = isAlias ? 'alias' : 'nic'

    const noClipboardTags = [
      { text: stringToBoolean(RDP) && 'RDP', dataCy: `${dataCy}-rdp` },
      { text: stringToBoolean(SSH) && 'SSH', dataCy: `${dataCy}-ssh` },
      showParents && {
        text: isAlias ? `PARENT: ${PARENT}` : false,
        dataCy: `${dataCy}-parent`,
      },
    ].filter(({ text } = {}) => Boolean(text))

    const tags = [
      { text: IP, dataCy: `${dataCy}-ip` },
      { text: MAC, dataCy: `${dataCy}-mac` },
      { text: ADDRESS, dataCy: `${dataCy}-address` },
    ].filter(({ text } = {}) => Boolean(text))

    return (
      <Paper
        variant="outlined"
        className={classes.root}
        data-cy={`${dataCy}-${NIC_ID}`}
        sx={{ flexWrap: 'wrap', boxShadow: 'none !important' }}
      >
        <Box
          className={classes.main}
          {...(!isAlias && !showParents && { pl: '1em' })}
        >

            <Typography
              component="span"
              fontWeight="bold"
              data-cy={`${dataCy}-name`}
            >
              {`${NIC_ID} | ${NETWORK}`}
            </Typography>

              {isAlias && <StatusChip stateColor="info" text={'ALIAS'} />}
              {noClipboardTags.map((tag) => (
                <StatusChip
                  key={`${dataCy}-${NIC_ID}-${tag.dataCy}`}
                  text={tag.text}
                  dataCy={tag.dataCy}
                />
              ))}
              <MultipleTags
                clipboard={clipboardOnTags}
                limitTags={isMobile ? 1 : 3}
                tags={tags}
              />

        </Box>
        {!isPciDevice && !isAdditionalIp && (

{actions}

        )}
        {!!ALIAS?.length && (
          <Stack direction="column" gap="1em" flexBasis="100%" my="0.5em">
            {ALIAS?.map((alias, aliasIdx) => (
              <NicCard
                key={alias.NIC_ID}
                nic={{ ...alias, NIC_ID: `${NIC_ID}.${aliasIdx + 1}` }}
                actions={aliasActions?.({ alias })}
                showParents={showParents}
              />
            ))}
          </Stack>
        )}
        {useMemo(() => {
          if (!Array.isArray(SECURITY_GROUPS) || !SECURITY_GROUPS?.length) {
            return null
          }

          const rulesById = Object.entries(groupBy(SECURITY_GROUPS, 'ID'))

          return (
            <Accordion>
              <AccordionSummary>
                <Typography variant="body1">
                  <Translate word={T.SecurityGroups} />
                </Typography>
              </AccordionSummary>
              {rulesById.map(([ID, rules]) => {
                const key = `nic-${NIC_ID}-secgroup-${ID}`
                const acts = securityGroupActions?.({ securityGroupId: ID })

                return (
                  <AccordionDetails key={key}>
                    <SecurityGroupRules
                      parentKey={key}
                      id={ID}
                      rules={rules}
                      actions={acts}
                    />
                  </AccordionDetails>
                )
              })}
            </Accordion>
          )
        }, [SECURITY_GROUPS])}
      </Paper>
    )
  }
)

NicCard.propTypes = {
  nic: PropTypes.object,
  actions: PropTypes.node,
  aliasActions: PropTypes.func,
  securityGroupActions: PropTypes.func,
  showParents: PropTypes.bool,
  clipboardOnTags: PropTypes.bool,
}

NicCard.displayName = 'NicCard'

const SecurityGroupRules = memo(({ parentKey, id, actions, rules }) => {
  const classes = rowStyles()

  const COLUMNS = useMemo(
    () => [T.Protocol, T.Type, T.Range, T.Network, T.IcmpType],
    []
  )

  const name = rules?.[0]?.NAME ?? 'default'

  return (
    <>
      <Stack direction="row" spacing={1} alignItems="center">
        <Typography
          noWrap
          component="span"
          variant="subtitle1"
          data-cy={`${parentKey}-rule-name`}
        >
          {`#${id} ${name}`}
        </Typography>
        {!!actions &&
{actions}
}
      </Stack>
      <Box display="grid" gridTemplateColumns="repeat(5, 1fr)" gap="0.5em">
        {COLUMNS.map((col) => (
          <Typography
            key={`${parentKey}-${col}`}
            noWrap
            component="span"
            variant="subtitle2"
          >
            <Translate word={col} />
          </Typography>
        ))}
        {rules.map((rule) => (
          <SecurityGroupRule
            key={`${parentKey}-rule-${rule.RULE_TYPE}`}
            data-cy={`${parentKey}-rule-${rule.RULE_TYPE}`}
            rule={rule}
          />
        ))}
      </Box>
    </>
  )
})

SecurityGroupRules.propTypes = {
  parentKey: PropTypes.string,
  id: PropTypes.string,
  rules: PropTypes.array,
  actions: PropTypes.node,
}

SecurityGroupRules.displayName = 'SecurityGroupRule'

const SecurityGroupRule = memo(({ rule, 'data-cy': parentCy }) => {
  /** @type {PrettySecurityGroupRule} */
  const { PROTOCOL, RULE_TYPE, ICMP_TYPE, RANGE, NETWORK_ID } = rule

  return (
    <>
      {[
        { text: PROTOCOL, dataCy: 'protocol' },
        { text: RULE_TYPE, dataCy: 'ruletype' },
        { text: RANGE, dataCy: 'range' },
        { text: NETWORK_ID, dataCy: 'networkid' },
        { text: ICMP_TYPE, dataCy: 'icmp-type' },
      ].map(({ text, dataCy }) => (
        <Typography
          noWrap
          key={`${parentCy}-${dataCy}`}
          data-cy={`${parentCy}-${dataCy}`.toLowerCase()}
          variant="subtitle2"
        >
          {text}
        </Typography>
      ))}
    </>
  )
})

SecurityGroupRule.propTypes = {
  rule: PropTypes.object,
  'data-cy': PropTypes.string,
}

SecurityGroupRule.displayName = 'SecurityGroupRule'

export default NicCard
<|endoftext|>


<commit_before>import test from 'ava';
import postcss from 'postcss';
import postcssNested from 'postcss-nested';
import plugin from '../dist';

function processFactory(...plugins) {
  return (t, input, expected) => {
    const actual = postcss(plugins).process(input).css;
    t.is(actual, expected);
  };
}

function titleFactory(version) {
  return (providedTitle, input, expected) => providedTitle ?
    `${providedTitle} in ${version}` :
    `"${input}" becomes "${expected}" in ${version}`;
}

const processCSS = processFactory(plugin);
const processNestedCSS = processFactory(postcssNested, plugin);

processCSS.title = titleFactory('css');
processNestedCSS.title = titleFactory('nested css');

test(
  'unique class',
  [processCSS, processNestedCSS],
  '.module {}',
  '.module {}'
);

test(
  'unique id',
  [processCSS, processNestedCSS],
  '#one {}',
  '#one {}'
);

test(
  'unique tag',
  [processCSS, processNestedCSS],
  'a {}',
  'a {}'
);

test(
  'unique universal',
  [processCSS, processNestedCSS],
  '* {}',
  '* {}'
);

test(
  'unique classes',
  [processCSS, processNestedCSS],
  '.one {} .two {}',
  '.one {} .two {}'
);

test(
  'unique ids',
  [processCSS, processNestedCSS],
  '#one {} #two {}',
  '#one {} #two {}'
);

test(
  'unique tags',
  [processCSS, processNestedCSS],
  'a {} b {}',
  'a {} b {}'
);

test(
  'unique universals',
  [processCSS, processNestedCSS],
  '* a {} * b {}',
  '* a {} * b {}'
);

test(
  'unique combinations of classes',
  [processCSS, processNestedCSS],
  '.one.two {} .one .two {}',
  '.one.two {} .one .two {}'
);

test(
  'unique combinations of ids',
  [processCSS, processNestedCSS],
  '#one#two {} #one #two {}',
  '#one#two {} #one #two {}'
);

test(
  'duplicated class',
  [processCSS, processNestedCSS],
  '.module {} .module {}',
  '.module {}'
);

test(
  'duplicated id',
  [processCSS, processNestedCSS],
  '#one {} #one {}',
  '#one {}'
);

test(
  'duplicated tag',
  [processCSS, processNestedCSS],
  'a {} a {}',
  'a {}'
);

test(
  'duplicated universal',
  [processCSS, processNestedCSS],
  '* {} * {}',
  '* {}'
);

test(
  'duplicated classes with " " combinator',
  [processCSS, processNestedCSS],
  '.one .two {} .one .two {}',
  '.one .two {}'
);

test(
  'duplicated classes with ">" combinator',
  [processCSS, processNestedCSS],
  '.one>.two {} .one > .two {}',
  '.one>.two {}'
);

test(
  'duplicated classes with "+" combinator',
  [processCSS, processNestedCSS],
  '.one+.two {} .one + .two {}',
  '.one+.two {}'
);

test(
  'duplicated classes with "~" combinator',
  [processCSS, processNestedCSS],
  '.one~.two {} .one ~ .two {}',
  '.one~.two {}'
);

test(
  'duplicated ids with " " combinator',
  [processCSS, processNestedCSS],
  '#one #two {} #one #two {}',
  '#one #two {}'
);

test(
  'duplicated ids with ">" combinator',
  [processCSS, processNestedCSS],
  '#one>#two {} #one > #two {}',
  '#one>#two {}'
);

test(
  'duplicated ids with "+" combinator',
  [processCSS, processNestedCSS],
  '#one+#two {} #one + #two {}',
  '#one+#two {}'
);

test(
  'duplicated ids with "~" combinator',
  [processCSS, processNestedCSS],
  '#one~#two {} #one ~ #two {}',
  '#one~#two {}'
);

test(
  'duplicated tags with " " combinator',
  [processCSS, processNestedCSS],
  'a b {} a  b {}',
  'a b {}'
);

test(
  'duplicated tags with ">" combinator',
  [processCSS, processNestedCSS],
  'a>b {} a > b {}',
  'a>b {}'
);

test(
  'duplicated tags with "+" combinator',
  [processCSS, processNestedCSS],
  'a+b {} a + b {}',
  'a+b {}'
);

test(
  'duplicated tags with "~" combinator',
  [processCSS, processNestedCSS],
  'a~b {} a ~ b {}',
  'a~b {}'
);

test(
  'duplicated universals with " " combinator',
  [processCSS, processNestedCSS],
  '* * {} *  * {}',
  '* * {}'
);

test(
  'duplicated universals with ">" combinator',
  [processCSS, processNestedCSS],
  '*>* {} * > * {}',
  '*>* {}'
);

test(
  'duplicated universals with "+" combinator',
  [processCSS, processNestedCSS],
  '*+* {} * + * {}',
  '*+* {}'
);

test(
  'duplicated universals with "~" combinator',
  [processCSS, processNestedCSS],
  '*~* {} * ~ * {}',
  '*~* {}'
);

test(
  'duplicated class with declarations',
  [processCSS, processNestedCSS],
  '.module {color: green} .module {background: red}',
  '.module {color: green;background: red}'
);

test(
  'duplicated id with declarations',
  [processCSS, processNestedCSS],
  '#one {color: green} #one {background: red}',
  '#one {color: green;background: red}'
);

test(
  'duplicated tag with declarations',
  [processCSS, processNestedCSS],
  'a {color: green} a {background: red}',
  'a {color: green;background: red}'
);

test(
  'duplicated universal with declarations',
  [processCSS, processNestedCSS],
  '* {color: green} * {background: red}',
  '* {color: green;background: red}'
);

test(
  'duplicated classes with different spacing and declarations',
  [processCSS, processNestedCSS],
  '.one .two {color: green} .one  .two {background: red}',
  '.one .two {color: green;background: red}'
);

test(
  'duplicated ids with different spacing and declarations',
  [processCSS, processNestedCSS],
  '#one #two {color: green} #one  #two {background: red}',
  '#one #two {color: green;background: red}'
);

test(
  'duplicated tags with different spacing and declarations',
  [processCSS, processNestedCSS],
  'a b {color: green} a  b {background: red}',
  'a b {color: green;background: red}'
);

test(
  'duplicated universals with different spacing and declarations',
  [processCSS, processNestedCSS],
  '* * {color: green} *  * {background: red}',
  '* * {color: green;background: red}'
);

test(
  'nested class selectors',
  processNestedCSS,
  '.one.two {color: green} .one {&.two {background: red}}',
  '.one.two {color: green;background: red}'
);

test(
  'nested class selectors with  " " combinator',
  processNestedCSS,
  '.one .two {color: green} .one {.two {background: red}}',
  '.one .two {color: green;background: red}'
);

test(
  'reordered nested selectors',
  processNestedCSS,
  '.one.two {} .two { .one& {} }',
  '.one.two {}'
);

test(
  'multi-level nested selectors',
  processNestedCSS,
  '.one .two .three {} .one { .two { .three {} } }',
  '.one .two .three {}'
);
<commit_msg>Add failing test<commit_after>import test from 'ava';
import postcss from 'postcss';
import postcssNested from 'postcss-nested';
import plugin from '../dist';

function processFactory(...plugins) {
  return (t, input, expected) => {
    const actual = postcss(plugins).process(input).css;
    t.is(actual, expected);
  };
}

function titleFactory(version) {
  return (providedTitle, input, expected) => providedTitle ?
    `${providedTitle} in ${version}` :
    `"${input}" becomes "${expected}" in ${version}`;
}

const processCSS = processFactory(plugin);
const processNestedCSS = processFactory(postcssNested, plugin);

processCSS.title = titleFactory('css');
processNestedCSS.title = titleFactory('nested css');

test(
  'unique class',
  [processCSS, processNestedCSS],
  '.module {}',
  '.module {}'
);

test(
  'unique id',
  [processCSS, processNestedCSS],
  '#one {}',
  '#one {}'
);

test(
  'unique tag',
  [processCSS, processNestedCSS],
  'a {}',
  'a {}'
);

test(
  'unique universal',
  [processCSS, processNestedCSS],
  '* {}',
  '* {}'
);

test(
  'unique classes',
  [processCSS, processNestedCSS],
  '.one {} .two {}',
  '.one {} .two {}'
);

test(
  'unique ids',
  [processCSS, processNestedCSS],
  '#one {} #two {}',
  '#one {} #two {}'
);

test(
  'unique tags',
  [processCSS, processNestedCSS],
  'a {} b {}',
  'a {} b {}'
);

test(
  'unique universals',
  [processCSS, processNestedCSS],
  '* a {} * b {}',
  '* a {} * b {}'
);

test(
  'unique combinations of classes',
  [processCSS, processNestedCSS],
  '.one.two {} .one .two {}',
  '.one.two {} .one .two {}'
);

test(
  'unique combinations of ids',
  [processCSS, processNestedCSS],
  '#one#two {} #one #two {}',
  '#one#two {} #one #two {}'
);

test(
  'duplicated class',
  [processCSS, processNestedCSS],
  '.module {} .module {}',
  '.module {}'
);

test(
  'duplicated id',
  [processCSS, processNestedCSS],
  '#one {} #one {}',
  '#one {}'
);

test(
  'duplicated tag',
  [processCSS, processNestedCSS],
  'a {} a {}',
  'a {}'
);

test(
  'duplicated universal',
  [processCSS, processNestedCSS],
  '* {} * {}',
  '* {}'
);

test(
  'duplicated classes with " " combinator',
  [processCSS, processNestedCSS],
  '.one .two {} .one .two {}',
  '.one .two {}'
);

test(
  'duplicated classes with ">" combinator',
  [processCSS, processNestedCSS],
  '.one>.two {} .one > .two {}',
  '.one>.two {}'
);

test(
  'duplicated classes with "+" combinator',
  [processCSS, processNestedCSS],
  '.one+.two {} .one + .two {}',
  '.one+.two {}'
);

test(
  'duplicated classes with "~" combinator',
  [processCSS, processNestedCSS],
  '.one~.two {} .one ~ .two {}',
  '.one~.two {}'
);

test(
  'duplicated ids with " " combinator',
  [processCSS, processNestedCSS],
  '#one #two {} #one #two {}',
  '#one #two {}'
);

test(
  'duplicated ids with ">" combinator',
  [processCSS, processNestedCSS],
  '#one>#two {} #one > #two {}',
  '#one>#two {}'
);

test(
  'duplicated ids with "+" combinator',
  [processCSS, processNestedCSS],
  '#one+#two {} #one + #two {}',
  '#one+#two {}'
);

test(
  'duplicated ids with "~" combinator',
  [processCSS, processNestedCSS],
  '#one~#two {} #one ~ #two {}',
  '#one~#two {}'
);

test(
  'duplicated tags with " " combinator',
  [processCSS, processNestedCSS],
  'a b {} a  b {}',
  'a b {}'
);

test(
  'duplicated tags with ">" combinator',
  [processCSS, processNestedCSS],
  'a>b {} a > b {}',
  'a>b {}'
);

test(
  'duplicated tags with "+" combinator',
  [processCSS, processNestedCSS],
  'a+b {} a + b {}',
  'a+b {}'
);

test(
  'duplicated tags with "~" combinator',
  [processCSS, processNestedCSS],
  'a~b {} a ~ b {}',
  'a~b {}'
);

test(
  'duplicated universals with " " combinator',
  [processCSS, processNestedCSS],
  '* * {} *  * {}',
  '* * {}'
);

test(
  'duplicated universals with ">" combinator',
  [processCSS, processNestedCSS],
  '*>* {} * > * {}',
  '*>* {}'
);

test(
  'duplicated universals with "+" combinator',
  [processCSS, processNestedCSS],
  '*+* {} * + * {}',
  '*+* {}'
);

test(
  'duplicated universals with "~" combinator',
  [processCSS, processNestedCSS],
  '*~* {} * ~ * {}',
  '*~* {}'
);

test(
  'duplicated class with declarations',
  [processCSS, processNestedCSS],
  '.module {color: green} .module {background: red}',
  '.module {color: green;background: red}'
);

test(
  'duplicated id with declarations',
  [processCSS, processNestedCSS],
  '#one {color: green} #one {background: red}',
  '#one {color: green;background: red}'
);

test(
  'duplicated tag with declarations',
  [processCSS, processNestedCSS],
  'a {color: green} a {background: red}',
  'a {color: green;background: red}'
);

test(
  'duplicated universal with declarations',
  [processCSS, processNestedCSS],
  '* {color: green} * {background: red}',
  '* {color: green;background: red}'
);

test(
  'duplicated classes with different spacing and declarations',
  [processCSS, processNestedCSS],
  '.one .two {color: green} .one  .two {background: red}',
  '.one .two {color: green;background: red}'
);

test(
  'duplicated ids with different spacing and declarations',
  [processCSS, processNestedCSS],
  '#one #two {color: green} #one  #two {background: red}',
  '#one #two {color: green;background: red}'
);

test(
  'duplicated tags with different spacing and declarations',
  [processCSS, processNestedCSS],
  'a b {color: green} a  b {background: red}',
  'a b {color: green;background: red}'
);

test(
  'duplicated universals with different spacing and declarations',
  [processCSS, processNestedCSS],
  '* * {color: green} *  * {background: red}',
  '* * {color: green;background: red}'
);

test(
  'nested class selectors',
  processNestedCSS,
  '.one.two {color: green} .one {&.two {background: red}}',
  '.one.two {color: green;background: red}'
);

test(
  'nested class selectors with  " " combinator',
  processNestedCSS,
  '.one .two {color: green} .one {.two {background: red}}',
  '.one .two {color: green;background: red}'
);

test(
  'reordered nested selectors',
  processNestedCSS,
  '.one.two {} .two { .one& {} }',
  '.one.two {}'
);

test(
  'multi-level nested selectors',
  processNestedCSS,
  '.one .two .three {} .one { .two { .three {} } }',
  '.one .two .three {}'
);

test(
  'multiple properties',
  processCSS,
  '.a {color: black; height: 10px} .a {background-color: red; width: 20px}',
  '.a {color: black; height: 10px; background-color: red; width: 20px}'
);
<|endoftext|>


<commit_before>'use strict'

require('./get')
require('./is')
require('./path')
require('./uuid')
require('./flatten')
<commit_msg>Added tests<commit_after>'use strict'

require('./get')
require('./is')
require('./path')
require('./uuid')
require('./flatten')
require('./unflatten')
require('./hash')
<|endoftext|>


<commit_before>
var levelup = require('levelup')
var rimraf  = require('rimraf')
var mac     = require('macgyver')().autoValidate()
var trigger = require('..')

var path = '/tmp/level-trigger-test'

rimraf(path, function () {
  levelup(path, {createIfMissing: true}, function (err, db) {

    trigger(db)

    var reduced = null

    db.trigger.add({

      name: 'test',

      map: function (item) {
        console.log('MAP', JSON.stringify({
          key: ''+item.key,
          type: item.type
        }))
        var obj = item.value ? JSON.parse(item.value) : null
        return JSON.stringify({
          key: ''+item.key,
          type: item.type
        })
      },

      job: function (value, done) {
        value = JSON.parse(value)

        function reduce (acc, n, put) {
          return (acc || 0) + (put ? 1 : -1)
        }

        var put = value.type == 'put'

        reduced = reduce(reduced, value, put)
        console.log('thing', reduced)

        db.put('~trigger:reduced', JSON.stringify(reduced), done)

        db.emit('test:reduce', reduced)
      }

    })

    //if we don't wait for the queue to drain,
    //then it will read puts from these twice.
    //TODO: add snapshot option for leveldb.
    db.once('queue:drain', function () {
      console.log('QUEUE')
      db.put('hello-A', JSON.stringify({thing: 1}))
      db.put('hello-B', JSON.stringify({thing: 2}))
      db.put('hello-C', JSON.stringify({thing: 3}))
      db.put('hello-D', JSON.stringify({thing: 6}))
      db.del('hello-C')
    })

    db.on('test:reduce', mac().times(5))
  })
})
<commit_msg>rewite tests!<commit_after>
var levelup = require('levelup')
var rimraf  = require('rimraf')
var mac     = require('macgyver')().autoValidate()
var Trigger = require('..')
var SubLevel = require('level-sublevel')

var path = '/tmp/level-trigger-test'

rimraf(path, function () {
  levelup(path, {createIfMissing: true}, function (err, db) {

  SubLevel(db)
  var reduceDb = db.sublevel('reduce')
  var reduced

  var trigDb = Trigger(db, 'test-trigger', function (item) {
        //map
        console.log('MAP', JSON.stringify({
          key: ''+item.key,
          type: item.type
        }))
        var obj = item.value ? JSON.parse(item.value) : null
        return JSON.stringify({
          key: ''+item.key,
          type: item.type
        })
      },
      function (value, done) {
        value = JSON.parse(value)

        function reduce (acc, n, put) {
          return (acc || 0) + (put ? 1 : -1)
        }

        var put = value.type == 'put'

        reduced = reduce(reduced, value, put)
        console.log('reduced', reduced)
        reduceDb.put('reduced', JSON.stringify(reduced), done)
        db.emit('test:reduce', reduced)
      })

    //if we don't wait for the queue to drain,
    //then it will read puts from these twice.
    //TODO: add snapshot option for leveldb.
//    db.once('queue:drain', function () {
    //  console.log('QUEUE')
      db.put('hello-A', JSON.stringify({thing: 1}))
      db.put('hello-B', JSON.stringify({thing: 2}))
      db.put('hello-C', JSON.stringify({thing: 3}))
      db.put('hello-D', JSON.stringify({thing: 6}))
      db.del('hello-C')
  //  })

    db.on('test:reduce', mac().times(5))
  })
})
<|endoftext|>


<commit_before>/*
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
*/

/*jslint sloppy:true, plusplus:true*/
/*global require, module, console */

var cordova = require('cordova');
var execProxy = require('cordova/exec/proxy');

/**
 * Execute a cordova command.  It is up to the native side whether this action
 * is synchronous or asynchronous.  The native side can return:
 *      Synchronous: PluginResult object as a JSON string
 *      Asynchronous: Empty string ""
 * If async, the native side will cordova.callbackSuccess or cordova.callbackError,
 * depending upon the result of the action.
 *
 * @param {Function} success    The success callback
 * @param {Function} fail       The fail callback
 * @param {String} service      The name of the service to use
 * @param {String} action       Action to be run in cordova
 * @param {String[]} [args]     Zero or more arguments to pass to the method
 */
module.exports = function (success, fail, service, action, args) {

    var proxy = execProxy.get(service, action),
        callbackId,
        onSuccess,
        onError;

    args = args || [];

    if (proxy) {
        callbackId = service + cordova.callbackId++;
        // console.log("EXEC:" + service + " : " + action);
        if (typeof success === "function" || typeof fail === "function") {
            cordova.callbacks[callbackId] = {success: success, fail: fail};
        }
        try {
            // callbackOptions param represents additional optional parameters command could pass back, like keepCallback or
            // custom callbackId, for example {callbackId: id, keepCallback: true, status: cordova.callbackStatus.JSON_EXCEPTION }
            // CB-5806 [Windows8] Add keepCallback support to proxy
            onSuccess = function (result, callbackOptions) {
                callbackOptions = callbackOptions || {};
                var callbackStatus;
                if (callbackOptions.status !== null && callbackOptions.status !== undefined) {
                    callbackStatus = callbackOptions.status;
                }
                else {
                    callbackStatus = cordova.callbackStatus.OK;
                }
                cordova.callbackSuccess(callbackOptions.callbackId || callbackId,
                    {
                        status: callbackStatus,
                        message: result,
                        keepCallback: callbackOptions.keepCallback || false
                    });
            };
            onError = function (err, callbackOptions) {
                callbackOptions = callbackOptions || {};
                var callbackStatus;
                if (callbackOptions.status !== null && callbackOptions.status !== undefined) {
                    callbackStatus = callbackOptions.status;
                }
                else {
                    callbackStatus = cordova.callbackStatus.OK;
                }
                cordova.callbackError(callbackOptions.callbackId || callbackId,
                    {
                        status: callbackStatus,
                        message: err,
                        keepCallback: callbackOptions.keepCallback || false
                    });
            };
            proxy(onSuccess, onError, args);

        } catch (e) {
            console.log("Exception calling native with command :: " + service + " :: " + action  + " ::exception=" + e);
        }
    } else {
        if (typeof fail === "function") {
            fail("Missing Command Error");
        }
    }
};
<commit_msg>Removed verbose strict inequality tests<commit_after>/*
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
*/

/*jslint sloppy:true, plusplus:true*/
/*global require, module, console */

var cordova = require('cordova');
var execProxy = require('cordova/exec/proxy');

/**
 * Execute a cordova command.  It is up to the native side whether this action
 * is synchronous or asynchronous.  The native side can return:
 *      Synchronous: PluginResult object as a JSON string
 *      Asynchronous: Empty string ""
 * If async, the native side will cordova.callbackSuccess or cordova.callbackError,
 * depending upon the result of the action.
 *
 * @param {Function} success    The success callback
 * @param {Function} fail       The fail callback
 * @param {String} service      The name of the service to use
 * @param {String} action       Action to be run in cordova
 * @param {String[]} [args]     Zero or more arguments to pass to the method
 */
module.exports = function (success, fail, service, action, args) {

    var proxy = execProxy.get(service, action),
        callbackId,
        onSuccess,
        onError;

    args = args || [];

    if (proxy) {
        callbackId = service + cordova.callbackId++;
        // console.log("EXEC:" + service + " : " + action);
        if (typeof success === "function" || typeof fail === "function") {
            cordova.callbacks[callbackId] = {success: success, fail: fail};
        }
        try {
            // callbackOptions param represents additional optional parameters command could pass back, like keepCallback or
            // custom callbackId, for example {callbackId: id, keepCallback: true, status: cordova.callbackStatus.JSON_EXCEPTION }
            // CB-5806 [Windows8] Add keepCallback support to proxy
            onSuccess = function (result, callbackOptions) {
                callbackOptions = callbackOptions || {};
                var callbackStatus;
                if (callbackOptions.status != null) {
                    callbackStatus = callbackOptions.status;
                }
                else {
                    callbackStatus = cordova.callbackStatus.OK;
                }
                cordova.callbackSuccess(callbackOptions.callbackId || callbackId,
                    {
                        status: callbackStatus,
                        message: result,
                        keepCallback: callbackOptions.keepCallback || false
                    });
            };
            onError = function (err, callbackOptions) {
                callbackOptions = callbackOptions || {};
                var callbackStatus;
                if (callbackOptions.status != null) {
                    callbackStatus = callbackOptions.status;
                }
                else {
                    callbackStatus = cordova.callbackStatus.OK;
                }
                cordova.callbackError(callbackOptions.callbackId || callbackId,
                    {
                        status: callbackStatus,
                        message: err,
                        keepCallback: callbackOptions.keepCallback || false
                    });
            };
            proxy(onSuccess, onError, args);

        } catch (e) {
            console.log("Exception calling native with command :: " + service + " :: " + action  + " ::exception=" + e);
        }
    } else {
        if (typeof fail === "function") {
            fail("Missing Command Error");
        }
    }
};
<|endoftext|>


<commit_before>'use strict';

var gulp = require('gulp');
var del = require('del');
var chalk = require('chalk');
var bowerFiles = require('main-bower-files');
var runSequence = require('run-sequence');
var sq = require('streamqueue');
var path = require('path');
var $ = require('gulp-load-plugins')();

process.env.NODE_ENV = $.util.env.env || 'development';

var config = require('./server/config/environment');

var openOpts = {
  url: 'http://localhost:' + config.port
};

var toInject = [
  'client/app.js',
  'client/directives/**/*.js', '!client/directives/**/*.spec.js',
  'client/filters/**/*.js', '!client/filters/**/*.spec.js',
  'client/services/**/*.js', '!client/services/**/*.spec.js',
  'client/views/**/*.js', '!client/views/**/*.spec.js',
  'client/styles/css/app.css'
];

var toDelete = [];

/**
 * Log. With options.
 *
 * @param {String} msg
 * @param {Object} options
 */
function log (msg, options) {
  options = options || {};
  console.log(
    (options.padding ? '\n' : '') +
    chalk.yellow(' > ' + msg) +
    (options.padding ? '\n' : '')
  );
}

/**
 * Compile sass
 */
gulp.task('sass', function () {
  return gulp.src('client/styles/app.scss')
    .pipe($.plumber())
    .pipe($.sass())
    .pipe(gulp.dest('client/styles/css'));
});

/**
 * Inject css/js files in index.html
 */
gulp.task('inject', ['sass'], function () {
  var sources = gulp.src(toInject, { read: false });

  return gulp.src('client/index.html')
    .pipe($.inject(gulp.src(bowerFiles(), { read: false }), {
      name: 'bower',
      relative: 'true'
    }))
    .pipe($.inject(sources, { relative: true }))
    .pipe(gulp.dest('client'));
});

/**
 * Watch files and reload page.
 * Recompile scss if needed.
 * Reinject files
 */
gulp.task('watch', ['inject'], function () {

  $.livereload.listen();

  gulp.watch('bower.json', function () {
    gulp.src('client/index.html')
      .pipe($.inject(gulp.src(bowerFiles(), { read: false }), {
        name: 'bower',
        relative: 'true'
      }))
      .pipe(gulp.dest('client'));
  });

  gulp.watch(['client/index.html', 'client/app.js'])
    .on('change', $.livereload.changed);

  $.watch('client/styles/**/*.scss', function () {
    gulp.src('client/styles/app.scss')
      .pipe($.plumber())
      .pipe($.sass())
      .pipe(gulp.dest('client/styles/css'))
      .pipe($.livereload());
  });

  $.watch([
    'client/views',
    'client/views/**/*.html',
    'client/views/**/*.js',
    '!client/views/**/*.spec.js',
    'client/directives',
    'client/directives/**/*.html',
    'client/directives/**/*.js',
    '!client/directives/**/*.spec.js',
    'client/services',
    'client/services/**/*.js',
    '!client/services/**/*.spec.js',
    'client/filters',
    'client/filters/**/*.js',
    '!client/filters/**/*.spec.js'
  ], function () {
    gulp.src('client/index.html')
      .pipe($.inject(gulp.src(toInject), { relative: true }))
      .pipe(gulp.dest('client'));
  });

});

/**
 * Control things
 */
gulp.task('control', function () {
  return gulp.src([
    'client/**/**/*.js',
    'server/**/**/*.js',
    '!client/bower_components/**'
  ])
    .pipe($.jshint())
    .pipe($.jshint.reporter('default'));
});

/**
 * Tests
 */
function testServer (done) {

  log('Running server test...', { padding: true });

  gulp.src('server/**/*.spec.js', { read: false })
    .pipe($.plumber())
    .pipe($.mocha({ reporter: 'spec' }))
    .once('end', function () {
      done();
    });
}

function testClient (done) {

  log('Running client test...', { padding: true });

  gulp.src([
    'client/bower_components/angular/angular.js',
    'client/bower_components/angular-mocks/angular-mocks.js',
    'client/bower_components/angular-route/angular-route.js',<% if (filters.ngCookies) { %>
    'client/bower_components/angular-cookies/angular-cookies.js',<% } %><% if (filters.ngResource) { %>
    'client/bower_components/angular-resource/angular-resource.js',<% } %>
    'client/app.js',
    'client/views/**/*.js',
    'client/services/**/*.js',
    'client/directives/**/*.js',
    'client/filters/**/*.js'
  ])
    .pipe($.karma({
      action: 'run',
      configFile: 'client/karma.conf.js'
    }))
    .on('error', function (err) {
      console.log(err);
      this.emit('end');
    })
    .once('end', function () {
      done();
    });
}

gulp.task('test', function (done) {
  process.env.NODE_ENV = 'test';
  var filter = process.argv[3] ? process.argv[3].substr(2) : false;
  if (filter === 'client') {
    return testClient(function () { process.exit(); done(); });
  } else if (filter === 'server') {
    return testServer(function () { process.exit(); done(); });
  } else if (filter === false) {
    return testClient(function () {
      testServer(function () {
        process.exit();
        done();
      });
    });
  } else {
    console.log('Wrong parameter [%s], availables : --client, --server', filter);
  }
});

/**
 * Launch server
 */
gulp.task('serve', ['watch'], function () {
  return $.nodemon({ script: 'server/server.js', ext: 'js', ignore: ['client', 'dist', 'node_modules'] })
    .on('restart',  function () {
      gulp.src('client/index.html')
        .pipe($.wait(250))
        .pipe($.livereload());
    });
});

gulp.task('preview', ['build'], function () {
  process.env.NODE_ENV = 'production';
  require('./dist/server/server');
  return gulp.src('client/index.html')
    .pipe($.open('', openOpts));
});

/**
 * Build
 */
gulp.task('clean:dist', function (cb) {
  del(['dist/**', '!dist', '!dist/.git{,/**}'], cb);
});

gulp.task('clean:finish', function (cb) {
  del([
    '.tmp/**',
    'dist/client/app.{css,js}'
  ].concat(toDelete), cb);
});

gulp.task('copy:dist', function () {
  var main = gulp.src(['server/**/*', 'package.json'], { base: './' });
  var assets = gulp.src('client/assets/**/*', { base: './' });

  return sq({ objectMode: true }, main, assets)
    .pipe(gulp.dest('dist/'));
});

gulp.task('usemin', ['inject'], function () {
  return gulp.src('client/index.html')
    .pipe($.plumber())
    .pipe($.usemin())
    .pipe(gulp.dest('dist/client/'));
});

gulp.task('cssmin', function () {
  return gulp.src('dist/client/app.css')
    .pipe($.minifyCss())
    .pipe(gulp.dest('dist/client/'));
});

gulp.task('scripts', function () {
  var tpl = gulp.src('client/views/**/*.html')
    .pipe($.angularTemplatecache({
      root: 'views',
      module: '<%= _.slugify(appname) %>'
    }));

  var app = gulp.src('dist/client/app.js');

  return sq({ objectMode: true }, app, tpl)
    .pipe($.concat('app.js'))
    .pipe($.ngAnnotate())
    .pipe($.uglify())
    .pipe(gulp.dest('dist/client/'));
});

gulp.task('replace', function () {
  return gulp.src('dist/client/index.html')
    .pipe($.replace(/<script.*livereload.*><\/script>\n*/, ''))
    .pipe(gulp.dest('dist/client'));
});

gulp.task('rev', function () {
  return gulp.src('dist/client/**')
    .pipe($.revAll({
      ignore: ['favicon.ico', '.html'],
      quiet: true,
      transformFilename: function (file, hash) {
        toDelete.push(path.resolve(file.path));
        var ext = path.extname(file.path);
        return path.basename(file.path, ext) + '.' + hash.substr(0, 8) + ext;
      }
    }))
    .pipe(gulp.dest('dist/client/'))
});

gulp.task('build', function (cb) {
  runSequence(
    ['clean:dist', 'sass'],
    ['usemin', 'copy:dist'],
    ['replace', 'scripts', 'cssmin'],
    'rev',
    'clean:finish',
    cb);
});

gulp.task('open', ['serve'], function () {
  gulp.src('client/index.html')
    .pipe($.open('', openOpts));
});

gulp.task('default', ['open']);
<commit_msg>fix(gulpfile): fix karma paths<commit_after>'use strict';

var gulp = require('gulp');
var del = require('del');
var chalk = require('chalk');
var bowerFiles = require('main-bower-files');
var runSequence = require('run-sequence');
var sq = require('streamqueue');
var path = require('path');
var $ = require('gulp-load-plugins')();

process.env.NODE_ENV = $.util.env.env || 'development';

var config = require('./server/config/environment');

var openOpts = {
  url: 'http://localhost:' + config.port
};

var toInject = [
  'client/app.js',
  'client/directives/**/*.js', '!client/directives/**/*.spec.js',
  'client/filters/**/*.js', '!client/filters/**/*.spec.js',
  'client/services/**/*.js', '!client/services/**/*.spec.js',
  'client/views/**/*.js', '!client/views/**/*.spec.js',
  'client/styles/css/app.css'
];

var toDelete = [];

/**
 * Log. With options.
 *
 * @param {String} msg
 * @param {Object} options
 */
function log (msg, options) {
  options = options || {};
  console.log(
    (options.padding ? '\n' : '') +
    chalk.yellow(' > ' + msg) +
    (options.padding ? '\n' : '')
  );
}

/**
 * Compile sass
 */
gulp.task('sass', function () {
  return gulp.src('client/styles/app.scss')
    .pipe($.plumber())
    .pipe($.sass())
    .pipe(gulp.dest('client/styles/css'));
});

/**
 * Inject css/js files in index.html
 */
gulp.task('inject', ['sass'], function () {
  var sources = gulp.src(toInject, { read: false });

  return gulp.src('client/index.html')
    .pipe($.inject(gulp.src(bowerFiles(), { read: false }), {
      name: 'bower',
      relative: 'true'
    }))
    .pipe($.inject(sources, { relative: true }))
    .pipe(gulp.dest('client'));
});

/**
 * Watch files and reload page.
 * Recompile scss if needed.
 * Reinject files
 */
gulp.task('watch', ['inject'], function () {

  $.livereload.listen();

  gulp.watch('bower.json', function () {
    gulp.src('client/index.html')
      .pipe($.inject(gulp.src(bowerFiles(), { read: false }), {
        name: 'bower',
        relative: 'true'
      }))
      .pipe(gulp.dest('client'));
  });

  gulp.watch(['client/index.html', 'client/app.js'])
    .on('change', $.livereload.changed);

  $.watch('client/styles/**/*.scss', function () {
    gulp.src('client/styles/app.scss')
      .pipe($.plumber())
      .pipe($.sass())
      .pipe(gulp.dest('client/styles/css'))
      .pipe($.livereload());
  });

  $.watch([
    'client/views',
    'client/views/**/*.html',
    'client/views/**/*.js',
    '!client/views/**/*.spec.js',
    'client/directives',
    'client/directives/**/*.html',
    'client/directives/**/*.js',
    '!client/directives/**/*.spec.js',
    'client/services',
    'client/services/**/*.js',
    '!client/services/**/*.spec.js',
    'client/filters',
    'client/filters/**/*.js',
    '!client/filters/**/*.spec.js'
  ], function () {
    gulp.src('client/index.html')
      .pipe($.inject(gulp.src(toInject), { relative: true }))
      .pipe(gulp.dest('client'));
  });

});

/**
 * Control things
 */
gulp.task('control', function () {
  return gulp.src([
    'client/**/**/*.js',
    'server/**/**/*.js',
    '!client/bower_components/**'
  ])
    .pipe($.jshint())
    .pipe($.jshint.reporter('default'));
});

/**
 * Tests
 */
function testServer (done) {

  log('Running server test...', { padding: true });

  gulp.src('server/**/*.spec.js', { read: false })
    .pipe($.plumber())
    .pipe($.mocha({ reporter: 'spec' }))
    .once('end', function () {
      done();
    });
}

function testClient (done) {

  log('Running client test...', { padding: true });

  gulp.src([
    'client/bower_components/angular/angular.js',
    'client/bower_components/angular-mocks/angular-mocks.js',
    'client/bower_components/angular-route/angular-route.js',<% if (filters.ngAnimate) { %>
    'client/bower_components/angular-animate/angular-animate.js',<% } if (filters.ngSanitize) { %>
    'client/bower_components/angular-sanitize/angular-sanitize.js',<% } if (filters.ngCookies) { %>
    'client/bower_components/angular-cookies/angular-cookies.js',<% } if (filters.ngResource) { %>
    'client/bower_components/angular-resource/angular-resource.js',<% } %>
    'client/app.js',
    'client/views/**/*.js',
    'client/services/**/*.js',
    'client/directives/**/*.js',
    'client/filters/**/*.js'
  ])
    .pipe($.karma({
      action: 'run',
      configFile: 'client/karma.conf.js'
    }))
    .on('error', function (err) {
      console.log(err);
      this.emit('end');
    })
    .once('end', function () {
      done();
    });
}

gulp.task('test', function (done) {
  process.env.NODE_ENV = 'test';
  var filter = process.argv[3] ? process.argv[3].substr(2) : false;
  if (filter === 'client') {
    return testClient(function () { process.exit(); done(); });
  } else if (filter === 'server') {
    return testServer(function () { process.exit(); done(); });
  } else if (filter === false) {
    return testClient(function () {
      testServer(function () {
        process.exit();
        done();
      });
    });
  } else {
    console.log('Wrong parameter [%s], availables : --client, --server', filter);
  }
});

/**
 * Launch server
 */
gulp.task('serve', ['watch'], function () {
  return $.nodemon({ script: 'server/server.js', ext: 'js', ignore: ['client', 'dist', 'node_modules'] })
    .on('restart',  function () {
      gulp.src('client/index.html')
        .pipe($.wait(250))
        .pipe($.livereload());
    });
});

gulp.task('preview', ['build'], function () {
  process.env.NODE_ENV = 'production';
  require('./dist/server/server');
  return gulp.src('client/index.html')
    .pipe($.open('', openOpts));
});

/**
 * Build
 */
gulp.task('clean:dist', function (cb) {
  del(['dist/**', '!dist', '!dist/.git{,/**}'], cb);
});

gulp.task('clean:finish', function (cb) {
  del([
    '.tmp/**',
    'dist/client/app.{css,js}'
  ].concat(toDelete), cb);
});

gulp.task('copy:dist', function () {
  var main = gulp.src(['server/**/*', 'package.json'], { base: './' });
  var assets = gulp.src('client/assets/**/*', { base: './' });

  return sq({ objectMode: true }, main, assets)
    .pipe(gulp.dest('dist/'));
});

gulp.task('usemin', ['inject'], function () {
  return gulp.src('client/index.html')
    .pipe($.plumber())
    .pipe($.usemin())
    .pipe(gulp.dest('dist/client/'));
});

gulp.task('cssmin', function () {
  return gulp.src('dist/client/app.css')
    .pipe($.minifyCss())
    .pipe(gulp.dest('dist/client/'));
});

gulp.task('scripts', function () {
  var tpl = gulp.src('client/views/**/*.html')
    .pipe($.angularTemplatecache({
      root: 'views',
      module: '<%= _.slugify(appname) %>'
    }));

  var app = gulp.src('dist/client/app.js');

  return sq({ objectMode: true }, app, tpl)
    .pipe($.concat('app.js'))
    .pipe($.ngAnnotate())
    .pipe($.uglify())
    .pipe(gulp.dest('dist/client/'));
});

gulp.task('replace', function () {
  return gulp.src('dist/client/index.html')
    .pipe($.replace(/<script.*livereload.*><\/script>\n*/, ''))
    .pipe(gulp.dest('dist/client'));
});

gulp.task('rev', function () {
  return gulp.src('dist/client/**')
    .pipe($.revAll({
      ignore: ['favicon.ico', '.html'],
      quiet: true,
      transformFilename: function (file, hash) {
        toDelete.push(path.resolve(file.path));
        var ext = path.extname(file.path);
        return path.basename(file.path, ext) + '.' + hash.substr(0, 8) + ext;
      }
    }))
    .pipe(gulp.dest('dist/client/'))
});

gulp.task('build', function (cb) {
  runSequence(
    ['clean:dist', 'sass'],
    ['usemin', 'copy:dist'],
    ['replace', 'scripts', 'cssmin'],
    'rev',
    'clean:finish',
    cb);
});

gulp.task('open', ['serve'], function () {
  gulp.src('client/index.html')
    .pipe($.open('', openOpts));
});

gulp.task('default', ['open']);
<|endoftext|>


<commit_before>var tools = require('./tools');

/**
  ### `constrain-bandwidth(value) => fn(sdp) => sdp`

  Create a filter function that can apply a `b=AS` line to the supplied SDP.

  <<< examples/constrain-bandwidth.js

**/
module.exports = function(value, mediaType) {
  return function(sdp) {
    var lines = tools.split(sdp);

    // remove existing b=AS lines
    lines = lines.filter(function(line) {
      return line.slice(0, 3) !== 'b=AS'
    });

    console.log(lines);

    return tools.join(lines);
  };
};
<commit_msg>Initial implementation complete<commit_after>var tools = require('./tools');

/**
  ### `constrain-bandwidth(value) => fn(sdp) => sdp`

  Create a filter function that can apply a `b=AS` line to the supplied SDP.

  <<< examples/constrain-bandwidth.js

**/
module.exports = function(value, mediaType) {
  return function(sdp) {
    var lines = tools.split(sdp);
    var lineRegex = new RegExp(mediaType ? ('^m=' + mediaType) : '^s=');
    var locations;

    // remove existing b=AS lines
    lines = lines.filter(function(line) {
      return line.slice(0, 3) !== 'b=AS'
    });

    // find the splice locations for the bandwidth lines
    locations = tools.locate(lineRegex, lines);

    // iterate through the locations and add the new b=AS lines
    locations.forEach(function(idx) {
      lines.splice(idx + 1, 0, 'b=AS:' + value);
    });

    return tools.join(lines);
  };
};
<|endoftext|>


<commit_before>'use strict';

var pkg = require('./package.json'),
  autoprefixer = require('gulp-autoprefixer'),
  browserify = require('browserify'),
  buffer = require('vinyl-buffer'),
  connect = require('gulp-connect'),
  csso = require('gulp-csso'),
  del = require('del'),
<% if (useAsciiDoc) { -%>
  exec = require('gulp-exec'),
<% } -%>
  ghpages = require('gh-pages'),
  gulp = require('gulp'),
  gutil = require('gulp-util'),
  path = require('path'),
  plumber = require('gulp-plumber'),
<% if (usePug) { -%>
  pug = require('gulp-pug'),
<% } -%>
  rename = require('gulp-rename'),
  source = require('vinyl-source-stream'),
  stylus = require('gulp-stylus'),
  through = require('through'),
  uglify = require('gulp-uglify'),
  isDist = process.argv.indexOf('serve') === -1,
  // browserifyPlumber fills the role of plumber() when working with browserify
  browserifyPlumber = function(e) {
    if (isDist) throw e;
    gutil.log(e.stack);
    this.emit('end');
  };

gulp.task('js', ['clean:js'], function() {
  // see https://wehavefaces.net/gulp-browserify-the-gulp-y-way-bb359b3f9623
  return browserify('src/scripts/main.js').bundle()
    .on('error', browserifyPlumber)
    .pipe(source('src/scripts/main.js'))
    .pipe(buffer())
    .pipe(isDist ? uglify() : through())
    .pipe(rename('build.js'))
    .pipe(gulp.dest('dist/build'))
    .pipe(connect.reload());
});

gulp.task('html', ['clean:html'], function() {
<% if (usePug) { -%>
  return gulp.src('src/index.pug')
    .pipe(isDist ? through() : plumber())
    .pipe(pug({ pretty: '  ' }))
    .pipe(rename('index.html'))
<% } -%>
<% if (useAsciiDoc) { -%>
  return gulp.src('src/index.adoc')
    .pipe(isDist ? through() : plumber())
    .pipe(exec('bundle exec asciidoctor-bespoke -o - src/index.adoc', { pipeStdout: true }))
    .pipe(exec.reporter({ stdout: false }))
    .pipe(rename('index.html'))
<% } -%>
<% if (useHtml) { -%>
  return gulp.src('src/index.html')
<% } -%>
    .pipe(gulp.dest('dist'))
    .pipe(connect.reload());
});

gulp.task('css', ['clean:css'], function() {
  return gulp.src('src/styles/main.styl')
    .pipe(isDist ? through() : plumber())
    .pipe(stylus({ 'include css': true, paths: ['./node_modules'] }))
    .pipe(autoprefixer({ browsers: ['last 2 versions'], cascade: false }))
    .pipe(isDist ? csso() : through())
    .pipe(rename('build.css'))
    .pipe(gulp.dest('dist/build'))
    .pipe(connect.reload());
});

gulp.task('images', ['clean:images'], function() {
  return gulp.src('src/images/**/*')
    .pipe(gulp.dest('dist/images'))
    .pipe(connect.reload());
});

gulp.task('clean', function() {
  return del('dist');
});

gulp.task('clean:html', function() {
  return del('dist/index.html');
});

gulp.task('clean:js', function() {
  return del('dist/build/build.js');
});

gulp.task('clean:css', function() {
  return del('dist/build/build.css');
});

gulp.task('clean:images', function() {
  return del('dist/images');
});

gulp.task('connect', ['build'], function() {
  connect.server({ root: 'dist', port: 8080, livereload: true });
});

gulp.task('watch', function() {
<% if (usePug) { -%>
  gulp.watch('src/**/*.pug', ['html']);
<% } -%>
<% if (useAsciiDoc) { -%>
  gulp.watch('src/**/*.adoc', ['html']);
<% } -%>
<% if (useHtml) { -%>
  gulp.watch('src/**/*.html', ['html']);
<% } -%>
  gulp.watch('src/styles/**/*.styl', ['css']);
  gulp.watch('src/images/**/*', ['images']);
  gulp.watch([
    'src/scripts/**/*.js',
    'bespoke-theme-*/dist/*.js' // Allow themes to be developed in parallel
  ], ['js']);
});
gulp.task('deploy', ['build'], function(done) {
  ghpages.publish(path.join(__dirname, 'dist'), { logger: gutil.log }, done);
});

gulp.task('build', ['js', 'html', 'css', 'images']);

gulp.task('serve', ['connect', 'watch']);

gulp.task('default', ['build']);
<commit_msg>feat: don't watch scripts inside theme folder (to simplify)<commit_after>'use strict';

var pkg = require('./package.json'),
  autoprefixer = require('gulp-autoprefixer'),
  browserify = require('browserify'),
  buffer = require('vinyl-buffer'),
  connect = require('gulp-connect'),
  csso = require('gulp-csso'),
  del = require('del'),
<% if (useAsciiDoc) { -%>
  exec = require('gulp-exec'),
<% } -%>
  ghpages = require('gh-pages'),
  gulp = require('gulp'),
  gutil = require('gulp-util'),
  path = require('path'),
  plumber = require('gulp-plumber'),
<% if (usePug) { -%>
  pug = require('gulp-pug'),
<% } -%>
  rename = require('gulp-rename'),
  source = require('vinyl-source-stream'),
  stylus = require('gulp-stylus'),
  through = require('through'),
  uglify = require('gulp-uglify'),
  isDist = process.argv.indexOf('serve') === -1,
  // browserifyPlumber fills the role of plumber() when working with browserify
  browserifyPlumber = function(e) {
    if (isDist) throw e;
    gutil.log(e.stack);
    this.emit('end');
  };

gulp.task('js', ['clean:js'], function() {
  // see https://wehavefaces.net/gulp-browserify-the-gulp-y-way-bb359b3f9623
  return browserify('src/scripts/main.js').bundle()
    .on('error', browserifyPlumber)
    .pipe(source('src/scripts/main.js'))
    .pipe(buffer())
    .pipe(isDist ? uglify() : through())
    .pipe(rename('build.js'))
    .pipe(gulp.dest('dist/build'))
    .pipe(connect.reload());
});

gulp.task('html', ['clean:html'], function() {
<% if (usePug) { -%>
  return gulp.src('src/index.pug')
    .pipe(isDist ? through() : plumber())
    .pipe(pug({ pretty: '  ' }))
    .pipe(rename('index.html'))
<% } -%>
<% if (useAsciiDoc) { -%>
  return gulp.src('src/index.adoc')
    .pipe(isDist ? through() : plumber())
    .pipe(exec('bundle exec asciidoctor-bespoke -o - src/index.adoc', { pipeStdout: true }))
    .pipe(exec.reporter({ stdout: false }))
    .pipe(rename('index.html'))
<% } -%>
<% if (useHtml) { -%>
  return gulp.src('src/index.html')
<% } -%>
    .pipe(gulp.dest('dist'))
    .pipe(connect.reload());
});

gulp.task('css', ['clean:css'], function() {
  return gulp.src('src/styles/main.styl')
    .pipe(isDist ? through() : plumber())
    .pipe(stylus({ 'include css': true, paths: ['./node_modules'] }))
    .pipe(autoprefixer({ browsers: ['last 2 versions'], cascade: false }))
    .pipe(isDist ? csso() : through())
    .pipe(rename('build.css'))
    .pipe(gulp.dest('dist/build'))
    .pipe(connect.reload());
});

gulp.task('images', ['clean:images'], function() {
  return gulp.src('src/images/**/*')
    .pipe(gulp.dest('dist/images'))
    .pipe(connect.reload());
});

gulp.task('clean', function() {
  return del('dist');
});

gulp.task('clean:html', function() {
  return del('dist/index.html');
});

gulp.task('clean:js', function() {
  return del('dist/build/build.js');
});

gulp.task('clean:css', function() {
  return del('dist/build/build.css');
});

gulp.task('clean:images', function() {
  return del('dist/images');
});

gulp.task('connect', ['build'], function() {
  connect.server({ root: 'dist', port: 8080, livereload: true });
});

gulp.task('watch', function() {
<% if (usePug) { -%>
  gulp.watch('src/**/*.pug', ['html']);
<% } -%>
<% if (useAsciiDoc) { -%>
  gulp.watch('src/**/*.adoc', ['html']);
<% } -%>
<% if (useHtml) { -%>
  gulp.watch('src/**/*.html', ['html']);
<% } -%>
  gulp.watch('src/scripts/**/*.js', ['js']);
  gulp.watch('src/styles/**/*.styl', ['css']);
  gulp.watch('src/images/**/*', ['images']);
});
gulp.task('deploy', ['build'], function(done) {
  ghpages.publish(path.join(__dirname, 'dist'), { logger: gutil.log }, done);
});

gulp.task('build', ['js', 'html', 'css', 'images']);

gulp.task('serve', ['connect', 'watch']);

gulp.task('default', ['build']);
<|endoftext|>


<commit_before>import "6to5/polyfill";

import test from "tape-catch";

import m from "mithril";
import n from "../source/n";

test("Doesn't break Mithril", function (is) {
    var noop = function () {};

    is.deepEqual
        ( m("div", {an: "attribute", onclick: noop})
        , n("div", {an: "attribute", onclick: noop})
        , "Does the same as Mithril with a vnode,"
        );

    is.deepEqual
        ( m("div", {an: "attribute", onclick: noop}, m("a"), [m(".b"), m("#c")])
        , n("div", {an: "attribute", onclick: noop}, m("a"), [m(".b"), m("#c")])
        , "even when the vnode has children."
        );

    var changed = false;
    m.render(document.body,
        n(".something", {config: function () { changed = true; }})
        );
    is.true
        ( changed
        , "Doesn't break an existing config attribute."
        );

    is.end();
    });

test.skip("Renders real nodes", function (is) {
    is.pass("Renders a bunch of child nodes mixed with virtual nodes");
    is.pass("in the correct order");
    is.pass("without breaking references.");
    is.pass("Even when called more than once in a single view.");
    is.end();
    });

test.skip("Updates real nodes", function (is) {
    is.pass("Reacts to updates on the parent vnode,");
    is.pass("or on virtual children,");
    is.pass("still keeping node references.");
    is.end();
    });
<commit_msg>Add test case<commit_after>import "6to5/polyfill";

import test from "tape-catch";

import m from "mithril";
import n from "../source/n";

test("Doesn't break Mithril", function (is) {
    var noop = function () {};

    is.deepEqual
        ( m("div", {an: "attribute", onclick: noop})
        , n("div", {an: "attribute", onclick: noop})
        , "Does the same as Mithril with a vnode,"
        );

    is.deepEqual
        ( m("div", {an: "attribute", onclick: noop}, m("a"), [m(".b"), m("#c")])
        , n("div", {an: "attribute", onclick: noop}, m("a"), [m(".b"), m("#c")])
        , "even when the vnode has children."
        );

    var changed = false;
    m.render(document.body,
        n(".something", {config: function () { changed = true; }})
        );
    is.true
        ( changed
        , "Doesn't break an existing config attribute,"
        );

    var changedAgain = false;
    m.render(document.body,
        n(".somethingElse", {config: function () { changedAgain = true; }},
            document.createElement("div")
            )
        );
    is.true
        ( changedAgain
        , "even when rendering a node."
        );

    is.end();
    });

test.skip("Renders real nodes", function (is) {
    is.pass("Renders a bunch of child nodes mixed with virtual nodes");
    is.pass("in the correct order");
    is.pass("without breaking references.");
    is.pass("Even when called more than once in a single view.");
    is.end();
    });

test.skip("Updates real nodes", function (is) {
    is.pass("Reacts to updates on the parent vnode,");
    is.pass("or on virtual children,");
    is.pass("still keeping node references.");
    is.end();
    });
<|endoftext|>


<commit_before>/* global describe, it */
var assert = require('assert');
var now = require('../');

describe('perfnow', function () {
	it('should start near 0', function () {
		assert(now() < 20);
	});
	it('should return a positve value', function () {
		assert(now() > 0);
	});
	it('should increase in subsequent calls', function () {
		assert(now() < now());
	});
	it('should be fast like lightning', function () {
		assert(Math.abs(now() - now()) < 0.005);
	});
	it('should be accurate', function (done) {
		var n = now();
		setTimeout(function () {
			var d = now() - n;
			assert(d > 999);
			assert(d < 1020);
			done();
		}, 1000);
	});
});
<commit_msg>travis is really quite a bit slower than my local machine<commit_after>/* global describe, it */
var assert = require('assert');
var now = require('../');

describe('perfnow', function () {
	it('should start near 0', function () {
		assert(now() < 20);
	});
	it('should return a positve value', function () {
		assert(now() > 0);
	});
	it('should increase in subsequent calls', function () {
		assert(now() < now());
	});
	it('should be fast like lightning', function () {
		assert(Math.abs(now() - now()) < 0.01);
	});
	it('should be accurate', function (done) {
		var n = now();
		setTimeout(function () {
			var d = now() - n;
			assert(d > 999);
			assert(d < 1020);
			done();
		}, 1000);
	});
});
<|endoftext|>