<commit_before>module.exports.safe = true;

/*
Purpose:
  Set values in the context.

- set:
	key: value

- set:
	target: session_key
	source:
	  key: value

- set:
	target: <% object_reference %>
        mode: merge
	source:
	  key: value
 */

var _ = require("lodash");
var verror = require("verror");

module.exports.normalize = function (action, action_normalizer, path) {
	function doNormalize(mode) {
		var sub_object = action[mode];
		if (!_.isPlainObject(sub_object)) {
			throw new verror.VError({
				name: "ActionStructureError.set",
				info: {
					path: path + "." + mode,
					value: sub_object
				}
			}, "The value of .%s must be an object", mode);
		}
		delete action[mode];
		if (!_.has(sub_object, "source")) {
			// { "mode": sub_object } => { source: sub_object, mode: "mode" }
			action.set = {
				source: sub_object,
				mode
			};
		}
		else {
			sub_object.mode = mode;
			action.set = sub_object;
		}
		return action;
	}

	if (_.has(action, "set")) {
		var result = doNormalize("set");
		result.set.mode = "assign";
		return result;
	}
	else if (_.has(action, "assign")) {
		return doNormalize("assign");
	}
	else if (_.has(action, "defaults")) {
		return doNormalize("defaults");
	}
	else if (_.has(action, "defaultsDeep")) {
		return doNormalize("defaultsDeep");
	}
	else if (_.has(action, "merge")) {
		return doNormalize("merge");
	}
	else if (_.has(action, "mergeDeep")) {
		return doNormalize("mergeDeep");
	}
};

module.exports.process = function (context) {
	var target;
	if (_.isNil(this.set.target)) {
		target = context.session;
	}
	else {
		if (_.isString(this.set.target)) {
			target = _.get(context.session, this.set.target);
			if(this.set.mode == "assign" || !_.isPlainObject(target)) {
				if(!(this.set.mode == "defaults" && !_.isNil(target))) {
					_.set(context.session, this.set.target, this.set.source);
				}
				return;
			}
		}
		else {
			throw new verror.VError({
				name: "InvalidSetTargetError",
				info: {
					path: this.path + ".set.target"
				}
			}, "If .target is specified for a .set command, it must be a string session key");
		}
	}
	switch(this.set.mode) {
		case "assign":
			_.assign(target, this.set.source);
			break;
		case "defaults":
			_.defaults(target, this.set.source);
			break;
		case "defaultsDeep":
			_.defaultsDeep(target, this.set.source);
			break;
		case "merge":
			_.merge(target, this.set.source);
			break;
		case "mergeDeep":
			_.mergedeep(target, this.set.source);
			break;
		default:
			throw new verror.VError({
				name: "UnexpectedSetMode",
				info: {
					path: this.path + this.set.mode
				}
			}, "set.mode must be 'set', 'defaults', or 'merge'");
	}
};
<commit_msg>Fixed issue with `set` deepMerge option<commit_after>module.exports.safe = true;

/*
Purpose:
  Set values in the context.

- set:
	key: value

- set:
	target: session_key
	source:
	  key: value

- set:
	target: <% object_reference %>
        mode: merge
	source:
	  key: value
 */

var _ = require("lodash");
var verror = require("verror");

module.exports.normalize = function (action, action_normalizer, path) {
	function doNormalize(mode) {
		var sub_object = action[mode];
		if (!_.isPlainObject(sub_object)) {
			throw new verror.VError({
				name: "ActionStructureError.set",
				info: {
					path: path + "." + mode,
					value: sub_object
				}
			}, "The value of .%s must be an object", mode);
		}
		delete action[mode];
		if (!_.has(sub_object, "source")) {
			// { "mode": sub_object } => { source: sub_object, mode: "mode" }
			action.set = {
				source: sub_object,
				mode
			};
		}
		else {
			sub_object.mode = mode;
			action.set = sub_object;
		}
		return action;
	}

	if (_.has(action, "set")) {
		var result = doNormalize("set");
		result.set.mode = "assign";
		return result;
	}
	else if (_.has(action, "assign")) {
		return doNormalize("assign");
	}
	else if (_.has(action, "defaults")) {
		return doNormalize("defaults");
	}
	else if (_.has(action, "defaultsDeep")) {
		return doNormalize("defaultsDeep");
	}
	else if (_.has(action, "merge")) {
		return doNormalize("merge");
	}
	else if (_.has(action, "mergeDeep")) {
		return doNormalize("mergeDeep");
	}
};

module.exports.process = function (context) {
	var target;
	if (_.isNil(this.set.target)) {
		target = context.session;
	}
	else {
		if (_.isString(this.set.target)) {
			target = _.get(context.session, this.set.target);
			if(this.set.mode == "assign" || !_.isPlainObject(target)) {
				if(!(this.set.mode == "defaults" && !_.isNil(target))) {
					_.set(context.session, this.set.target, this.set.source);
				}
				return;
			}
		}
		else {
			throw new verror.VError({
				name: "InvalidSetTargetError",
				info: {
					path: this.path + ".set.target"
				}
			}, "If .target is specified for a .set command, it must be a string session key");
		}
	}
	switch(this.set.mode) {
		case "assign":
			_.assign(target, this.set.source);
			break;
		case "defaults":
			_.defaults(target, this.set.source);
			break;
		case "defaultsDeep":
			_.defaultsDeep(target, this.set.source);
			break;
		case "merge":
			_.merge(target, this.set.source);
			break;
		case "mergeDeep":
			_.mergeDeep(target, this.set.source);
			break;
		default:
			throw new verror.VError({
				name: "UnexpectedSetMode",
				info: {
					path: this.path + this.set.mode
				}
			}, "set.mode must be 'set', 'defaults', or 'merge'");
	}
};
<|endoftext|>


<commit_before>var fs = require('fs');
var demand = require('must');
var http = require('http');
var Mitm = require('mitm');

var Wemo = require('../index');
var deviceInfo = require('./fixtures/deviceinfo.json');

describe('Wemo', function() {

  it('must expose a public constructor', function() {
    Wemo.must.be.a.function();
  });

  it('must listen on a port', function(done) {
    var wemo = new Wemo();
    var address = wemo.getCallbackURL();
    http.get(address, function(res) {
      res.statusCode.must.equal(404);
      done();
    });
  });

});

describe('WemoClient', function() {

  var client;
  var mitm;

  beforeEach(function() {
    mitm = Mitm();
    client = (new Wemo()).client(deviceInfo);
  });

  afterEach(function() {
    mitm.disable();
  });

  describe('#soapAction(serviceType, action, body, cb)', function() {
    it('must use the correct endpoint', function(done) {
      mitm.on('request', function(req, res) {
        req.url.must.be('/upnp/control/deviceinfo1');
        req.method.must.be('POST');
        res.statusCode = 200;
        res.end();
      });
      client.soapAction('urn:Belkin:service:deviceinfo:1', 'TheAction', 'TheBody', done);
    });

    it('must send a soap header', function(done) {
      mitm.on('request', function(req, res) {
        req.headers.soapaction.must.be('"urn:Belkin:service:deviceinfo:1#TheAction"');
        res.statusCode = 200;
        res.end();
      });
      client.soapAction('urn:Belkin:service:deviceinfo:1', 'TheAction', 'TheBody', done);
    });

    it('must send a valid body', function(done) {
      mitm.on('request', function(req, res) {
        var data = '';
        req.on('data', function(chunk) { data += chunk; });
        req.on('end', function() {
          data.must.contain('<u:TheAction xmlns:u="urn:Belkin:service:deviceinfo:1">');
          data.must.contain('TheBody');
        });
        res.statusCode = 200;
        res.end();
      });
      client.soapAction('urn:Belkin:service:deviceinfo:1', 'TheAction', 'TheBody', done);
    });
  });

  describe('#setBinaryState(val)', function() {
    it('must send a BinaryState request', function(done) {
      mitm.on('request', function(req, res) {
        var data = '';
        req.on('data', function(chunk) { data += chunk; });
        req.on('end', function() {
          data.must.contain('<u:SetBinaryState xmlns:u="urn:Belkin:service:basicevent:1">');
          data.must.contain('<BinaryState>1</BinaryState>');
        });
        req.url.must.equal('/upnp/control/basicevent1');
        res.statusCode = 200;
        res.end();
      });
      client.setBinaryState(1, done);
    });
  });

  describe('#getEndDevices(err, cb)', function() {
    it('must handle grouped bulbs', function(done) {
      mitm.on('request', function(req, res) {
        var fixture = fs.readFileSync(__dirname + '/fixtures/getEndDevices_group.xml');
        res.write(fixture);
        res.end();
      });
      client.getEndDevices(function(err, endDevices) {
        demand(err).to.be.falsy();
        demand(endDevices).to.be.an.array();
        demand(endDevices).to.have.length(2);
        endDevices[0].friendlyName.must.be('First');
        endDevices[1].friendlyName.must.be('Second');
        done();
      });
    });

    it('must handle single bulbs', function(done) {
      mitm.on('request', function(req, res) {
        var fixture = fs.readFileSync(__dirname + '/fixtures/getEndDevices_single.xml');
        res.write(fixture);
        res.end();
      });
      client.getEndDevices(function(err, endDevices) {
        demand(err).to.be.falsy();
        demand(endDevices).to.be.an.array();
        demand(endDevices).to.have.length(2);
        endDevices[0].friendlyName.must.be('First');
        endDevices[1].friendlyName.must.be('Second');
        done();
      });
    });
  });

});
<commit_msg>Add test for setDeviceStatus<commit_after>var fs = require('fs');
var demand = require('must');
var http = require('http');
var Mitm = require('mitm');

var Wemo = require('../index');
var deviceInfo = require('./fixtures/deviceinfo.json');

/* eslint-env mocha */

describe('Wemo', function() {

  it('must expose a public constructor', function() {
    Wemo.must.be.a.function();
  });

  it('must listen on a port', function(done) {
    var wemo = new Wemo();
    var address = wemo.getCallbackURL();
    http.get(address, function(res) {
      res.statusCode.must.equal(404);
      done();
    });
  });

});

describe('WemoClient', function() {

  var client;
  var mitm;

  beforeEach(function() {
    mitm = Mitm();
    client = (new Wemo()).client(deviceInfo);
  });

  afterEach(function() {
    mitm.disable();
  });

  describe('#soapAction(serviceType, action, body, cb)', function() {
    it('must use the correct endpoint', function(done) {
      mitm.on('request', function(req, res) {
        req.url.must.be('/upnp/control/deviceinfo1');
        req.method.must.be('POST');
        res.statusCode = 200;
        res.end();
      });
      client.soapAction('urn:Belkin:service:deviceinfo:1', 'TheAction', 'TheBody', done);
    });

    it('must send a soap header', function(done) {
      mitm.on('request', function(req, res) {
        req.headers.soapaction.must.be('"urn:Belkin:service:deviceinfo:1#TheAction"');
        res.statusCode = 200;
        res.end();
      });
      client.soapAction('urn:Belkin:service:deviceinfo:1', 'TheAction', 'TheBody', done);
    });

    it('must send a valid body', function(done) {
      mitm.on('request', function(req, res) {
        var data = '';
        req.on('data', function(chunk) { data += chunk; });
        req.on('end', function() {
          data.must.contain('<u:TheAction xmlns:u="urn:Belkin:service:deviceinfo:1">');
          data.must.contain('TheBody');
        });
        res.statusCode = 200;
        res.end();
      });
      client.soapAction('urn:Belkin:service:deviceinfo:1', 'TheAction', 'TheBody', done);
    });
  });

  describe('#setBinaryState(val)', function() {
    it('must send a BinaryState action', function(done) {
      mitm.on('request', function(req, res) {
        var data = '';
        req.on('data', function(chunk) { data += chunk; });
        req.on('end', function() {
          data.must.contain('<u:SetBinaryState xmlns:u="urn:Belkin:service:basicevent:1">');
          data.must.contain('<BinaryState>1</BinaryState>');
        });
        req.url.must.equal('/upnp/control/basicevent1');
        res.statusCode = 200;
        res.end();
      });
      client.setBinaryState(1, done);
    });
  });

  describe('#setDeviceStatus(deviceId, capabilityId, cb)', function() {
    it('must send a DeviceStatus action', function(done) {
      mitm.on('request', function(req, res) {
        var data = '';
        req.on('data', function(chunk) { data += chunk; });
        req.on('end', function() {
          data.must.contain('<u:SetDeviceStatus xmlns:u="urn:Belkin:service:bridge:1">');
          data.must.contain('<DeviceStatusList>');
          data.must.contain('<IsGroupAction>YES</IsGroupAction>');
          data.must.contain('<DeviceID available="YES">1432253402</DeviceID>');
          data.must.contain('<CapabilityID>10006</CapabilityID>');
          data.must.contain('<CapabilityValue>1</CapabilityValue>');
        });
        req.url.must.equal('/upnp/control/bridge1');
        res.statusCode = 200;
        res.end();
      });
      client.setDeviceStatus('1432253402', '10006', '1', done);
    });
  });

  describe('#getEndDevices(err, cb)', function() {
    it('must handle grouped bulbs', function(done) {
      mitm.on('request', function(req, res) {
        var fixture = fs.readFileSync(__dirname + '/fixtures/getEndDevices_group.xml');
        res.write(fixture);
        res.end();
      });
      client.getEndDevices(function(err, endDevices) {
        demand(err).to.be.falsy();
        demand(endDevices).to.be.an.array();
        demand(endDevices).to.have.length(2);
        endDevices[0].friendlyName.must.be('First');
        endDevices[1].friendlyName.must.be('Second');
        done();
      });
    });

    it('must handle single bulbs', function(done) {
      mitm.on('request', function(req, res) {
        var fixture = fs.readFileSync(__dirname + '/fixtures/getEndDevices_single.xml');
        res.write(fixture);
        res.end();
      });
      client.getEndDevices(function(err, endDevices) {
        demand(err).to.be.falsy();
        demand(endDevices).to.be.an.array();
        demand(endDevices).to.have.length(2);
        endDevices[0].friendlyName.must.be('First');
        endDevices[1].friendlyName.must.be('Second');
        done();
      });
    });
  });

});
<|endoftext|>


<commit_before>
var test = require('tape')
var spec = require('stream-spec')
var through = require('../')

/*
  I'm using these two functions, and not streams and pipe
  so there is less to break. if this test fails it must be
  the implementation of _through_
*/

function write(array, stream) {
  array = array.slice()
  function next() {
    while(array.length)
      if(stream.write(array.shift()) === false)
        return stream.once('drain', next)

    stream.end()
  }

  next()
}

function read(stream, callback) {
  var actual = []
  stream.on('data', function (data) {
    actual.push(data)
  })
  stream.once('end', function () {
    callback(null, actual)
  })
  stream.once('error', function (err) {
    callback(err)
  })
}

test('simple defaults', function(assert) {

  var l = 1000
    , expected = []

  while(l--) expected.push(l * Math.random())

  var t = through()
    spec(t)
      .through()
      .pausable()
      .validateOnExit()

  read(t, function (err, actual) {
    assert.ifError(err)
    assert.deepEqual(actual, expected)
    assert.end()
  })

  write(expected, t)
});

test('simple functions', function(assert) {

  var l = 1000
    , expected = []

  while(l--) expected.push(l * Math.random())

  var t = through(function (data) {
      this.emit('data', data*2)
    })
    spec(t)
      .through()
      .pausable()
      .validateOnExit()

  read(t, function (err, actual) {
    assert.ifError(err)
    assert.deepEqual(actual, expected.map(function (data) {
      return data*2
    }))
    assert.end()
  })

  write(expected, t)
})

test('pauses', function(assert) {

  var l = 1000
    , expected = []

  while(l--) expected.push(l) //Math.random())

  var t = through()
    spec(t)
      .through()
      .pausable()
      .validateOnExit()

  t.on('data', function () {
    if(Math.random() > 0.1) return
    t.pause()
    process.nextTick(function () {
      t.resume()
    })
  })

  read(t, function (err, actual) {
    assert.ifError(err)
    assert.deepEqual(actual, expected)
    assert.end()
  })

  write(expected, t)
})
<commit_msg>update test to work in the browser (without process.on("exit")<commit_after>
var test = require('tape')
var spec = require('stream-spec')
var through = require('../')

/*
  I'm using these two functions, and not streams and pipe
  so there is less to break. if this test fails it must be
  the implementation of _through_
*/

function write(array, stream) {
  array = array.slice()
  function next() {
    while(array.length)
      if(stream.write(array.shift()) === false)
        return stream.once('drain', next)

    stream.end()
  }

  next()
}

function read(stream, callback) {
  var actual = []
  stream.on('data', function (data) {
    actual.push(data)
  })
  stream.once('end', function () {
    callback(null, actual)
  })
  stream.once('error', function (err) {
    callback(err)
  })
}

test('simple defaults', function(assert) {

  var l = 1000
    , expected = []

  while(l--) expected.push(l * Math.random())

  var t = through()
  var s = spec(t).through().pausable()

  read(t, function (err, actual) {
    assert.ifError(err)
    assert.deepEqual(actual, expected)
    assert.end()
  })

  t.on('close', s.validate)

  write(expected, t)
});

test('simple functions', function(assert) {

  var l = 1000
    , expected = []

  while(l--) expected.push(l * Math.random())

  var t = through(function (data) {
      this.emit('data', data*2)
    })
  var s = spec(t).through().pausable()

  read(t, function (err, actual) {
    assert.ifError(err)
    assert.deepEqual(actual, expected.map(function (data) {
      return data*2
    }))
    assert.end()
  })

  t.on('close', s.validate)

  write(expected, t)
})

test('pauses', function(assert) {

  var l = 1000
    , expected = []

  while(l--) expected.push(l) //Math.random())

  var t = through()

  var s = spec(t)
      .through()
      .pausable()

  t.on('data', function () {
    if(Math.random() > 0.1) return
    t.pause()
    process.nextTick(function () {
      t.resume()
    })
  })

  read(t, function (err, actual) {
    assert.ifError(err)
    assert.deepEqual(actual, expected)
    assert.end()
  })

  t.on('close', s.validate)

  write(expected, t)
})
<|endoftext|>


<commit_before>import SerializablePath from '../SerializablePath';
import _ from 'lodash';
const newLine = /\n/g;
const defaultFontFamily = '"Helvetica Neue", "Helvetica", Arial';
const fontRegExp = /^\s*((?:(?:normal|bold|italic)\s+)*)(?:(\d+(?:\.\d+)?)[ptexm%]*(?:\s*\/.*?)?\s+)?\s*"?([^"]*)/i;
const fontFamilyPrefix = /^[\s"']*/;
const fontFamilySuffix = /[\s"']*$/;
let cachedFontObjectsFromString = {};

function childrenAsString(children) {
    if (!children) {
        return '';
    }
    if (typeof children === 'string') {
        return children;
    }
    if (children.length) {
        return children.join('\n');
    }
    return '';
}

function extractFontAndLines(font, text) {
    return {
        font: extractFont(font),
        lines: text.split(newLine)
    };
}

function extractSingleFontFamily(fontFamilyString = defaultFontFamily) {
    // ART on the web allows for multiple font-families to be specified.
    // For compatibility, we extract the first font-family, hoping
    // we'll get a match.
    return fontFamilyString.split(',')[0]
        .replace(fontFamilyPrefix, '')
        .replace(fontFamilySuffix, '');
}

function parseFontString(font) {
    if (cachedFontObjectsFromString.hasOwnProperty(font)) {
        return cachedFontObjectsFromString[font];
    }
    let match = fontRegExp.exec(font);
    if (!match) {
        return null;
    }
    let fontFamily = extractSingleFontFamily(match[3]);
    let fontSize = +match[2] || 12;
    let isBold = /bold/.exec(match[1]);
    let isItalic = /italic/.exec(match[1]);
    cachedFontObjectsFromString[font] = {
        fontFamily: fontFamily,
        fontSize: fontSize,
        fontWeight: isBold ? 'bold' : 'normal',
        fontStyle: isItalic ? 'italic' : 'normal'
    };
    return cachedFontObjectsFromString[font];
}

function extractFont(font) {
    if (_.isNil(font)) {
        return null;
    }
    if (typeof font === 'string') {
        return parseFontString(font);
    }
    let fontFamily = extractSingleFontFamily(font.fontFamily);
    let fontSize = +font.fontSize || 12;

    return {
        fontFamily: fontFamily,
        fontSize: fontSize,
        fontWeight: font.fontWeight,
        fontStyle: font.fontStyle
    };
}

const anchord = {
    end: 1,
    middle: 2,
    start: 0
};

export default function(props) {
    return {
        alignment: anchord[props.textAnchor] || 0,
        frame: extractFontAndLines(
            props,
            childrenAsString(props.children)
        ),
        path: props.path ? new SerializablePath(props.path).toJSON() : undefined
    };
}
<commit_msg>remove ART related comment<commit_after>import SerializablePath from '../SerializablePath';
import _ from 'lodash';
const newLine = /\n/g;
const defaultFontFamily = '"Helvetica Neue", "Helvetica", Arial';
const fontRegExp = /^\s*((?:(?:normal|bold|italic)\s+)*)(?:(\d+(?:\.\d+)?)[ptexm%]*(?:\s*\/.*?)?\s+)?\s*"?([^"]*)/i;
const fontFamilyPrefix = /^[\s"']*/;
const fontFamilySuffix = /[\s"']*$/;
let cachedFontObjectsFromString = {};

function childrenAsString(children) {
    if (!children) {
        return '';
    }
    if (typeof children === 'string') {
        return children;
    }
    if (children.length) {
        return children.join('\n');
    }
    return '';
}

function extractFontAndLines(font, text) {
    return {
        font: extractFont(font),
        lines: text.split(newLine)
    };
}

function extractSingleFontFamily(fontFamilyString = defaultFontFamily) {
    // SVG on the web allows for multiple font-families to be specified.
    // For compatibility, we extract the first font-family, hoping
    // we'll get a match.
    return fontFamilyString.split(',')[0]
        .replace(fontFamilyPrefix, '')
        .replace(fontFamilySuffix, '');
}

function parseFontString(font) {
    if (cachedFontObjectsFromString.hasOwnProperty(font)) {
        return cachedFontObjectsFromString[font];
    }
    let match = fontRegExp.exec(font);
    if (!match) {
        return null;
    }
    let fontFamily = extractSingleFontFamily(match[3]);
    let fontSize = +match[2] || 12;
    let isBold = /bold/.exec(match[1]);
    let isItalic = /italic/.exec(match[1]);
    cachedFontObjectsFromString[font] = {
        fontFamily: fontFamily,
        fontSize: fontSize,
        fontWeight: isBold ? 'bold' : 'normal',
        fontStyle: isItalic ? 'italic' : 'normal'
    };
    return cachedFontObjectsFromString[font];
}

function extractFont(font) {
    if (_.isNil(font)) {
        return null;
    }
    if (typeof font === 'string') {
        return parseFontString(font);
    }
    let fontFamily = extractSingleFontFamily(font.fontFamily);
    let fontSize = +font.fontSize || 12;

    return {
        fontFamily: fontFamily,
        fontSize: fontSize,
        fontWeight: font.fontWeight,
        fontStyle: font.fontStyle
    };
}

const anchord = {
    end: 1,
    middle: 2,
    start: 0
};

export default function(props) {
    return {
        alignment: anchord[props.textAnchor] || 0,
        frame: extractFontAndLines(
            props,
            childrenAsString(props.children)
        ),
        path: props.path ? new SerializablePath(props.path).toJSON() : undefined
    };
}
<|endoftext|>


<commit_before>var async = require('async');
var env = require('../lib/environment');
var test = require('tap').test;

module.exports = test;

/**
 * Generate a random string of specified length.
 *
 * @param {Integer} length
 * @return {String} Random string with `length` characters
 */

test.randomstring = function randomstring(length) {
  var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890-=<>?,./{}|[]\\!@#$%^&*()_+ ';
  var str = '';
  while (length--)
    str += chars[Math.random() * chars.length | 0];
  return str;
};

test.applyFixtures = function applyFixtures(fixtures, carryOn) {
  /**
   * Get an array of values from an object.
   */
  function values(obj) {
    return Object.keys(obj).map(function (key) { return obj[key] });
  }

  /**
   * Figure out all of the different models represented by fixtures
   */
  function models(fixtures) {
    return values(fixtures).reduce(function (arr, obj) {
      var model = obj.constructor;
      if (arr.indexOf(model) === -1)
        arr.push(model);
      return arr;
    }, []);
  }

  /**
   * Remove all entries from a collection
   */
  function flush(Model, callback) {
    function destroyer(thing, callback) {
      console.log('destroying');
      return thing.remove(callback);
    }
    Model.find({}, function (err, results) {
      async.map(results, destroyer, function (err, results) {
        if (err) throw err;
        callback(null, results);
      });
    });
  }

  /**
   * Flush all of the models for each of the fixtures.
   */
  function flushAll(callback) {
    async.map(models(fixtures), flush, function (err, results) {
      if (err) throw err;
      callback(results);
    })
  }

  /**
   * Save all of the fixtures.
   */
  function saveAll(callback) {
    function saver(thing, callback) {
      console.log('saving');
      return thing.save(callback);
    }
    async.map(values(fixtures), saver, function (err, results) {
      if (err) throw err;
      callback(null, results)
    });
  }

  flushAll(function () {
    saveAll(function () {
      carryOn(fixtures);
    });
  });
};<commit_msg>Remove space character from randomstring set.<commit_after>var async = require('async');
var env = require('../lib/environment');
var test = require('tap').test;

module.exports = test;

/**
 * Generate a random string of specified length.
 *
 * @param {Integer} length
 * @return {String} Random string with `length` characters
 */

test.randomstring = function randomstring(length) {
  var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890-=<>?,./{}|[]\\!@#$%^&*()_+';
  var str = '';
  while (length--)
    str += chars[Math.random() * chars.length | 0];
  return str;
};

test.applyFixtures = function applyFixtures(fixtures, carryOn) {
  /**
   * Get an array of values from an object.
   */
  function values(obj) {
    return Object.keys(obj).map(function (key) { return obj[key] });
  }

  /**
   * Figure out all of the different models represented by fixtures
   */
  function models(fixtures) {
    return values(fixtures).reduce(function (arr, obj) {
      var model = obj.constructor;
      if (arr.indexOf(model) === -1)
        arr.push(model);
      return arr;
    }, []);
  }

  /**
   * Remove all entries from a collection
   */
  function flush(Model, callback) {
    function destroyer(thing, callback) {
      console.log('destroying');
      return thing.remove(callback);
    }
    Model.find({}, function (err, results) {
      async.map(results, destroyer, function (err, results) {
        if (err) throw err;
        callback(null, results);
      });
    });
  }

  /**
   * Flush all of the models for each of the fixtures.
   */
  function flushAll(callback) {
    async.map(models(fixtures), flush, function (err, results) {
      if (err) throw err;
      callback(results);
    })
  }

  /**
   * Save all of the fixtures.
   */
  function saveAll(callback) {
    function saver(thing, callback) {
      console.log('saving');
      return thing.save(callback);
    }
    async.map(values(fixtures), saver, function (err, results) {
      if (err) throw err;
      callback(null, results)
    });
  }

  flushAll(function () {
    saveAll(function () {
      carryOn(fixtures);
    });
  });
};<|endoftext|>


<commit_before>const expect = require('expect');
const createProbot = require('..');

describe('Probot', () => {
  let probot;
  let event;

  beforeEach(() => {
    probot = createProbot();
    probot.robot.auth = () => Promise.resolve({});

    event = {
      event: 'push',
      payload: require('./fixtures/webhook/push')
    };
  });

  describe('receive', () => {
    it('delivers the event', async () => {
      spy = expect.createSpy();
      probot.load(robot => robot.on('push', spy));

      await probot.receive(event);

      expect(spy).toHaveBeenCalled();
    });

    it('raises errors thrown in plugins', async () => {
      spy = expect.createSpy();

      probot.load(robot => robot.on('push', () => {
        throw new Error('something happened');
      }));

      expect(async () => {
        await probot.receive(event);
      }).toThrow();
    });
  });
});
<commit_msg>Fix lint errors<commit_after>const expect = require('expect');
const createProbot = require('..');

describe('Probot', () => {
  let probot;
  let event;

  beforeEach(() => {
    probot = createProbot();
    probot.robot.auth = () => Promise.resolve({});

    event = {
      event: 'push',
      payload: require('./fixtures/webhook/push')
    };
  });

  describe('receive', () => {
    it('delivers the event', async () => {
      const spy = expect.createSpy();
      probot.load(robot => robot.on('push', spy));

      await probot.receive(event);

      expect(spy).toHaveBeenCalled();
    });

    it('raises errors thrown in plugins', async () => {
      probot.load(robot => robot.on('push', () => {
        throw new Error('something happened');
      }));

      expect(async () => {
        await probot.receive(event);
      }).toThrow();
    });
  });
});
<|endoftext|>


<commit_before>var fs = require( 'fs' );
var path = require( 'path' );
var broccoli = require( 'broccoli' );
var pick = require( 'broccoli-static-compiler' );
var chai = require( 'chai' );
var imageVars = require( '..' );

imageVars.output = '_result.scss';
chai.should();
var expect = chai.expect;

describe( 'broccoli-sass-image-vars', function(){
    var fixturesDir = path.normalize( path.basename( __dirname ) + '/fixtures/' );
    var expectedDir = path.normalize( path.basename( __dirname ) + '/expected/' );
    var builder;

    function compare( expected, result ){
        result = fs.readFileSync( result.directory + path.sep + imageVars.output ).toString();
        expected = fs.readFileSync( expected ).toString().split( '\n' ).slice( 1 ).join( '\n' );
        return result.split( '\n' ).slice( 1 ).join( '\n' ).should.be.equal( expected );
    }

    function check( trees, expectedScss, options ){
        if( typeof trees === 'string' )
            trees = fixturesDir + trees;
        else if( Array.isArray( trees ) )
            trees = trees.map(function( tree ){ return typeof tree === 'string' ? fixturesDir + tree : tree });
        var tree = new imageVars( trees, options );
        builder = new broccoli.Builder( tree );
        return builder.build().then( compare.bind( undefined, expectedDir + expectedScss ) );
    }

    afterEach(function(){
        if( builder )
            return builder.cleanup();
    });

    it( 'should create the correct scss file for a single directory with images', function(){
        return check( 'single', '_single.scss' );
    });
    it( 'should throw an error if the "output" option isn\'t specified', function(){
        return expect(function(){
            check( 'glob', '_input_string.scss', { output: undefined });
        }).to.throw( /output/ );
    });
    it( 'should create the correct scss file with the string "input" option', function(){
        return check( 'glob', '_input_string.scss', {
            input: '**/*.*'
        });
    });
    it( 'should create the correct scss file with the array "input" option', function(){
        return check( 'glob', '_input_array.scss', {
            input: [ '*.*', 'aaa/*.*' ]
        });
    });
    it( 'should not throw any errors if the "input" option doesn\'t find any images', function(){
        return check( 'single', '_input_unexisting.scss', {
            input: 'unexisting/*.*'
        });
    });
    it( 'should create the correct scss file with the string "inline" option', function(){
        return check( 'single', '_inline_string.scss', {
            inline: '*.svg'
        });
    });
    it( 'should create the correct scss file with the array "inline" option', function(){
        return check( 'glob', '_inline_array.scss', {
            inline: [ '**/*.png', '**/*.gif' ]
        });
    });
    it( 'should not throw any errors if the "inline" option doesn\'t find any images', function(){
        return check( 'single', '_inline_unexisting.scss', {
            inline: 'unexisting/*.*'
        });
    });
    it( 'should create the correct scss file with both "input" and "inline" options', function(){
        return check( 'glob', '_input_and_inline.scss', {
            input: '*.png',
            inline: '**/*.gif'
        });
    });
    it( 'should create the correct scss file with the "url_prefix" option', function(){
        return check( 'single', '_url_prefix.scss', {
            url_prefix: 'prefix/url'
        });
    });
    it( 'should create the correct scss file with the "image_root" option', function(){
        return check( 'single', '_image_root.scss', {
            image_root: 'test/fixtures'
        });
    });
    it( 'should create the correct scss file with a valid Broccoli tree and the "url_prefix" option', function(){
        var tree = pick( fixturesDir + 'single', {
            srcDir: '.',
            destDir: '.'
        });
        return check( tree, '_broccoli_tree_and_url_prefix.scss', {
            url_prefix: '/prefix'
        });
    });
    it( 'should create the correct scss file with a Broccoli tree (which moves images) and the "url_prefix" option', function(){
        var tree = pick( fixturesDir + 'single', {
            srcDir: '.',
            destDir: 'nice_place'
        });
        return check( tree, '_broccoli_moving_tree_and_url_prefix.scss', {
            input: 'nice_place/*.*',
            url_prefix: '/prefix'
        });
    });
    it( 'should throw an error if the Broccoli tree is used and the "url_prefix" option isn\'t specified', function(){
        var tree = pick( fixturesDir + 'single', {
            srcDir: '.',
            destDir: '.'
        });
        return expect(function(){ check( tree, '_broccoli_tree_and_url_prefix.scss' ) }).to.throw( /url_prefix/ );
    });
});
<commit_msg>(+) Added a placeholder for the test with "cache_buster" option<commit_after>var fs = require( 'fs' );
var path = require( 'path' );
var broccoli = require( 'broccoli' );
var pick = require( 'broccoli-static-compiler' );
var chai = require( 'chai' );
var imageVars = require( '..' );

imageVars.output = '_result.scss';
chai.should();
var expect = chai.expect;

describe( 'broccoli-sass-image-vars', function(){
    var fixturesDir = path.normalize( path.basename( __dirname ) + '/fixtures/' );
    var expectedDir = path.normalize( path.basename( __dirname ) + '/expected/' );
    var builder;

    function compare( expected, result ){
        result = fs.readFileSync( result.directory + path.sep + imageVars.output ).toString();
        expected = fs.readFileSync( expected ).toString().split( '\n' ).slice( 1 ).join( '\n' );
        return result.split( '\n' ).slice( 1 ).join( '\n' ).should.be.equal( expected );
    }

    function check( trees, expectedScss, options ){
        if( typeof trees === 'string' )
            trees = fixturesDir + trees;
        else if( Array.isArray( trees ) )
            trees = trees.map(function( tree ){ return typeof tree === 'string' ? fixturesDir + tree : tree });
        var tree = new imageVars( trees, options );
        builder = new broccoli.Builder( tree );
        return builder.build().then( compare.bind( undefined, expectedDir + expectedScss ) );
    }

    afterEach(function(){
        if( builder )
            return builder.cleanup();
    });

    it( 'should create the correct scss file for a single directory with images', function(){
        return check( 'single', '_single.scss' );
    });
    it( 'should throw an error if the "output" option isn\'t specified', function(){
        return expect(function(){
            check( 'glob', '_input_string.scss', { output: undefined });
        }).to.throw( /output/ );
    });
    it( 'should create the correct scss file with the string "input" option', function(){
        return check( 'glob', '_input_string.scss', {
            input: '**/*.*'
        });
    });
    it( 'should create the correct scss file with the array "input" option', function(){
        return check( 'glob', '_input_array.scss', {
            input: [ '*.*', 'aaa/*.*' ]
        });
    });
    it( 'should not throw any errors if the "input" option doesn\'t find any images', function(){
        return check( 'single', '_input_unexisting.scss', {
            input: 'unexisting/*.*'
        });
    });
    it( 'should create the correct scss file with the string "inline" option', function(){
        return check( 'single', '_inline_string.scss', {
            inline: '*.svg'
        });
    });
    it( 'should create the correct scss file with the array "inline" option', function(){
        return check( 'glob', '_inline_array.scss', {
            inline: [ '**/*.png', '**/*.gif' ]
        });
    });
    it( 'should not throw any errors if the "inline" option doesn\'t find any images', function(){
        return check( 'single', '_inline_unexisting.scss', {
            inline: 'unexisting/*.*'
        });
    });
    it( 'should create the correct scss file with both "input" and "inline" options', function(){
        return check( 'glob', '_input_and_inline.scss', {
            input: '*.png',
            inline: '**/*.gif'
        });
    });
    it( 'should create the correct scss file with the "url_prefix" option', function(){
        return check( 'single', '_url_prefix.scss', {
            url_prefix: 'prefix/url'
        });
    });
    it( 'should create the correct scss file with the "image_root" option', function(){
        return check( 'single', '_image_root.scss', {
            image_root: 'test/fixtures'
        });
    });
    it( 'should create the correct scss file with the "cache_buster" option' );
    it( 'should create the correct scss file with a valid Broccoli tree and the "url_prefix" option', function(){
        var tree = pick( fixturesDir + 'single', {
            srcDir: '.',
            destDir: '.'
        });
        return check( tree, '_broccoli_tree_and_url_prefix.scss', {
            url_prefix: '/prefix'
        });
    });
    it( 'should create the correct scss file with a Broccoli tree (which moves images) and the "url_prefix" option', function(){
        var tree = pick( fixturesDir + 'single', {
            srcDir: '.',
            destDir: 'nice_place'
        });
        return check( tree, '_broccoli_moving_tree_and_url_prefix.scss', {
            input: 'nice_place/*.*',
            url_prefix: '/prefix'
        });
    });
    it( 'should throw an error if the Broccoli tree is used and the "url_prefix" option isn\'t specified', function(){
        var tree = pick( fixturesDir + 'single', {
            srcDir: '.',
            destDir: '.'
        });
        return expect(function(){ check( tree, '_broccoli_tree_and_url_prefix.scss' ) }).to.throw( /url_prefix/ );
    });
});
<|endoftext|>


<commit_before>"use strict";
var fs = require('fs-extra');
var path = require('path');
var test = require('tape');
var globby = require('globby');
var yamlMarkdownToHtml = require('../');

test('errors', function(is) {
  is.plan(2);

  is.throws(function() {
    yamlMarkdownToHtml({
      source: 'test/src',
      destination: 'test/dest',
      render: ''
    });
  }, 'render !== function throws');

  is.doesNotThrow(function() {
    yamlMarkdownToHtml({
      source: 'test/src',
      destination: 'test/dest',
      render: function() { return Promise.resolve('html'); }
    });
  }, 'valid render function');
});

test('usage', function(is) {
  is.plan(106);

  var sourcePatterns = ['**/*.md', '**/*.markdown']
    .map(function(file) {
      return path.join('test/src', file);
    });

  var sourceFiles = globby.sync(sourcePatterns, { nodir: true });

  fs.removeSync('test/dest');
  yamlMarkdownToHtml({
    source: 'test/src',
    destination: 'test/dest',
    render: render,
    postRender: postRender,
  });

  function render(currentFile, filesInCurrentFolder, allFiles) {
    is.pass('render called');

    is.equal(typeof currentFile, 'object', 'currentFile is object');
    is.ok('markdown' in currentFile, 'currentFile has markdown');
    is.ok('path' in currentFile, 'currentFile has path');

    is.ok(Array.isArray(allFiles), 'allFiles is array');
    is.equal(allFiles.length, sourceFiles.length, 'allFiles’ length is same as sourceFiles');
    is.ok(allFiles.every(function(file) { return typeof file === 'object'; }), 'allFiles contains objects');
    is.ok('markdown' in allFiles[0], 'first item of allFiles has markdown');
    is.ok('path' in allFiles[0], 'first item of allFiles has path');

    if (currentFile.path === 'index') {
      is.equal(filesInCurrentFolder.length, 2, 'two other file in test/src');
      is.ok(filesInCurrentFolder.some(function(file) {
        return file.path === 'test';
      }), 'one of the files in test/src is "test"');
      is.ok(filesInCurrentFolder.some(function(file) {
        return file.path === 'folder/index';
      }), 'one of the files in test/src is "folder/index"');
    }
    if (currentFile.path === 'test') {
      is.equal(filesInCurrentFolder.length, 2, 'two other file in test/src');
      is.ok(filesInCurrentFolder.some(function(file) {
        return file.path === 'index';
      }), 'one of the files in test/src is "index"');
      is.ok(filesInCurrentFolder.some(function(file) {
        return file.path === 'folder/index';
      }), 'one of the files in test/src is "folder/index"');
    }
    if (currentFile.path === 'folder/another') {
      is.equal(filesInCurrentFolder.length, 4, 'four other files in test/src/folder');
      is.ok(filesInCurrentFolder.some(function(file) {
        return file.path === 'folder/empty';
      }), 'one of the files in test/src/folder is "empty"');
      is.ok(filesInCurrentFolder.some(function(file) {
        return file.path === 'folder/yaml-only';
      }), 'one of the files in test/src/folder is "yaml-only"');
      is.ok(filesInCurrentFolder.some(function(file) {
        return file.path === 'folder/index';
      }), 'one of the files in test/src/folder is "index"');
      is.ok(filesInCurrentFolder.some(function(file) {
        return file.path === 'folder/another_folder/index';
      }), 'one of the files in test/src/folder is "another_folder/index"');
    }
    if (currentFile.path === 'folder/another_folder/index') {
      is.equal(filesInCurrentFolder.length, 2, 'two other file in test/src/folder/another_folder');
      is.equal(filesInCurrentFolder[0].path, 'folder/another_folder/another-deeply-nested', 'other file in test/src/folder/another_folder is "another-deeply-nested"');
      is.equal(filesInCurrentFolder[1].path, 'folder/another_folder/deeply-nested', 'other file in test/src/folder/another_folder is "deeply-nested"');
    }
    if (currentFile.path === 'folder/another_folder/deeply-nested') {
      is.equal(filesInCurrentFolder.length, 2, 'two other file in test/src/folder/another_folder');
      is.equal(filesInCurrentFolder[0].path, 'folder/another_folder/another-deeply-nested', 'other file in test/src/folder/another_folder is "another-deeply-nested"');
      is.equal(filesInCurrentFolder[1].path, 'folder/another_folder/index', 'other file in test/src/folder/another_folder is "index"');
    }
    if (currentFile.path === 'folder/another_folder/another-deeply-nested') {
      is.equal(filesInCurrentFolder.length, 2, 'two other file in test/src/folder/another_folder');
      is.equal(filesInCurrentFolder[0].path, 'folder/another_folder/deeply-nested', 'other file in test/src/folder/another_folder is "deeply-nested"');
      is.equal(filesInCurrentFolder[1].path, 'folder/another_folder/index', 'other file in test/src/folder/another_folder is "index"');
    }

    return Promise.resolve(JSON.stringify(currentFile, null, 2));
  }

  function postRender(renderedFiles) {
    is.pass('postRender called');

    is.ok(renderedFiles.every(function(file) { return typeof file === 'object'; }), 'renderedFiles contains objects');
    is.equal(path.extname(renderedFiles[0].renderedPath), '.html');
    is.equal(sourceFiles.length, renderedFiles.length);
    is.deepEqual(
      sourceFiles.map(function(file) {
        return file.replace('.md', '').replace('.markdown', '').replace('/src/', '/dest/');
      }),
      renderedFiles.map(function(file) {
        return file.renderedPath.replace('.html', '');
      })
    );

    return Promise.resolve(htmlPaths);
  }
});
<commit_msg>test: fix returning undefined variable<commit_after>"use strict";
var fs = require('fs-extra');
var path = require('path');
var test = require('tape');
var globby = require('globby');
var yamlMarkdownToHtml = require('../');

test('errors', function(is) {
  is.plan(2);

  is.throws(function() {
    yamlMarkdownToHtml({
      source: 'test/src',
      destination: 'test/dest',
      render: ''
    });
  }, 'render !== function throws');

  is.doesNotThrow(function() {
    yamlMarkdownToHtml({
      source: 'test/src',
      destination: 'test/dest',
      render: function() { return Promise.resolve('html'); }
    });
  }, 'valid render function');
});

test('usage', function(is) {
  is.plan(106);

  var sourcePatterns = ['**/*.md', '**/*.markdown']
    .map(function(file) {
      return path.join('test/src', file);
    });

  var sourceFiles = globby.sync(sourcePatterns, { nodir: true });

  fs.removeSync('test/dest');
  yamlMarkdownToHtml({
    source: 'test/src',
    destination: 'test/dest',
    render: render,
    postRender: postRender,
  });

  function render(currentFile, filesInCurrentFolder, allFiles) {
    is.pass('render called');

    is.equal(typeof currentFile, 'object', 'currentFile is object');
    is.ok('markdown' in currentFile, 'currentFile has markdown');
    is.ok('path' in currentFile, 'currentFile has path');

    is.ok(Array.isArray(allFiles), 'allFiles is array');
    is.equal(allFiles.length, sourceFiles.length, 'allFiles’ length is same as sourceFiles');
    is.ok(allFiles.every(function(file) { return typeof file === 'object'; }), 'allFiles contains objects');
    is.ok('markdown' in allFiles[0], 'first item of allFiles has markdown');
    is.ok('path' in allFiles[0], 'first item of allFiles has path');

    if (currentFile.path === 'index') {
      is.equal(filesInCurrentFolder.length, 2, 'two other file in test/src');
      is.ok(filesInCurrentFolder.some(function(file) {
        return file.path === 'test';
      }), 'one of the files in test/src is "test"');
      is.ok(filesInCurrentFolder.some(function(file) {
        return file.path === 'folder/index';
      }), 'one of the files in test/src is "folder/index"');
    }
    if (currentFile.path === 'test') {
      is.equal(filesInCurrentFolder.length, 2, 'two other file in test/src');
      is.ok(filesInCurrentFolder.some(function(file) {
        return file.path === 'index';
      }), 'one of the files in test/src is "index"');
      is.ok(filesInCurrentFolder.some(function(file) {
        return file.path === 'folder/index';
      }), 'one of the files in test/src is "folder/index"');
    }
    if (currentFile.path === 'folder/another') {
      is.equal(filesInCurrentFolder.length, 4, 'four other files in test/src/folder');
      is.ok(filesInCurrentFolder.some(function(file) {
        return file.path === 'folder/empty';
      }), 'one of the files in test/src/folder is "empty"');
      is.ok(filesInCurrentFolder.some(function(file) {
        return file.path === 'folder/yaml-only';
      }), 'one of the files in test/src/folder is "yaml-only"');
      is.ok(filesInCurrentFolder.some(function(file) {
        return file.path === 'folder/index';
      }), 'one of the files in test/src/folder is "index"');
      is.ok(filesInCurrentFolder.some(function(file) {
        return file.path === 'folder/another_folder/index';
      }), 'one of the files in test/src/folder is "another_folder/index"');
    }
    if (currentFile.path === 'folder/another_folder/index') {
      is.equal(filesInCurrentFolder.length, 2, 'two other file in test/src/folder/another_folder');
      is.equal(filesInCurrentFolder[0].path, 'folder/another_folder/another-deeply-nested', 'other file in test/src/folder/another_folder is "another-deeply-nested"');
      is.equal(filesInCurrentFolder[1].path, 'folder/another_folder/deeply-nested', 'other file in test/src/folder/another_folder is "deeply-nested"');
    }
    if (currentFile.path === 'folder/another_folder/deeply-nested') {
      is.equal(filesInCurrentFolder.length, 2, 'two other file in test/src/folder/another_folder');
      is.equal(filesInCurrentFolder[0].path, 'folder/another_folder/another-deeply-nested', 'other file in test/src/folder/another_folder is "another-deeply-nested"');
      is.equal(filesInCurrentFolder[1].path, 'folder/another_folder/index', 'other file in test/src/folder/another_folder is "index"');
    }
    if (currentFile.path === 'folder/another_folder/another-deeply-nested') {
      is.equal(filesInCurrentFolder.length, 2, 'two other file in test/src/folder/another_folder');
      is.equal(filesInCurrentFolder[0].path, 'folder/another_folder/deeply-nested', 'other file in test/src/folder/another_folder is "deeply-nested"');
      is.equal(filesInCurrentFolder[1].path, 'folder/another_folder/index', 'other file in test/src/folder/another_folder is "index"');
    }

    return Promise.resolve(JSON.stringify(currentFile, null, 2));
  }

  function postRender(renderedFiles) {
    is.pass('postRender called');

    is.ok(renderedFiles.every(function(file) { return typeof file === 'object'; }), 'renderedFiles contains objects');
    is.equal(path.extname(renderedFiles[0].renderedPath), '.html');
    is.equal(sourceFiles.length, renderedFiles.length);
    is.deepEqual(
      sourceFiles.map(function(file) {
        return file.replace('.md', '').replace('.markdown', '').replace('/src/', '/dest/');
      }),
      renderedFiles.map(function(file) {
        return file.renderedPath.replace('.html', '');
      })
    );

    return Promise.resolve(renderedFiles);
  }
});
<|endoftext|>


<commit_before>(function (tree) {
//
// CSS @import node
//
// The general strategy here is that we don't want to wait
// for the parsing to be completed, before we start importing
// the file. That's because in the context of a browser,
// most of the time will be spent waiting for the server to respond.
//
// On creation, we push the import path to our import queue, though
// `import,push`, we also pass it a callback, which it'll call once
// the file has been fetched, and parsed.
//
tree.Import = function (path, imports, features, once, index, rootpath) {
    var that = this;

    this.once = once;
    this.index = index;
    this._path = path;
    this.features = features && new(tree.Value)(features);
    this.rootpath = rootpath;

    // The '.less' extension is optional
    if (path instanceof tree.Quoted) {
        this.path = /\.(le?|c)ss(\?.*)?$/.test(path.value) ? path.value : path.value + '.less';
    } else {
        this.path = path.value.value || path.value;
    }

    this.css = /css(\?.*)?$/.test(this.path);

    // Only pre-compile .less files
    if (! this.css) {
        imports.push(this.path, function (e, root, imported) {
            if (e) { e.index = index }
            if (imported && that.once) that.skip = imported;
            that.root = root || new(tree.Ruleset)([], []);
        });
    }
};

//
// The actual import node doesn't return anything, when converted to CSS.
// The reason is that it's used at the evaluation stage, so that the rules
// it imports can be treated like any other rules.
//
// In `eval`, we make sure all Import nodes get evaluated, recursively, so
// we end up with a flat structure, which can easily be imported in the parent
// ruleset.
//
tree.Import.prototype = {
    toCSS: function (env) {
        var features = this.features ? ' ' + this.features.toCSS(env) : '';

        if (this.css) {
            // Add the base path if the import is relative
            if (typeof this._path.value === "string" && !/^(?:[a-z-]+:|\/)/.test(this._path.value)) {
                this._path.value = this.rootpath + this._path.value;
            }
            return "@import " + this._path.toCSS() + features + ';\n';
        } else {
            return "";
        }
    },
    eval: function (env) {
        var ruleset, features = this.features && this.features.eval(env);

        if (this.skip) return [];

        if (this.css) {
            return this;
        } else {
            ruleset = new(tree.Ruleset)([], this.root.rules.slice(0));

            ruleset.evalImports(env);

            return this.features ? new(tree.Media)(ruleset.rules, this.features.value) : ruleset.rules;
        }
    }
};

})(require('../tree'));
<commit_msg>Do not add .less if the file has an extension already or has url parameters. Also support ';' instead of '?'. Fixes #784 and fixes #204<commit_after>(function (tree) {
//
// CSS @import node
//
// The general strategy here is that we don't want to wait
// for the parsing to be completed, before we start importing
// the file. That's because in the context of a browser,
// most of the time will be spent waiting for the server to respond.
//
// On creation, we push the import path to our import queue, though
// `import,push`, we also pass it a callback, which it'll call once
// the file has been fetched, and parsed.
//
tree.Import = function (path, imports, features, once, index, rootpath) {
    var that = this;

    this.once = once;
    this.index = index;
    this._path = path;
    this.features = features && new(tree.Value)(features);
    this.rootpath = rootpath;

    // The '.less' extension is optional
    if (path instanceof tree.Quoted) {
        this.path = /(\.[a-z]*$)|([\?;].*)?$/.test(path.value) ? path.value : path.value + '.less';
    } else {
        this.path = path.value.value || path.value;
    }

    this.css = /css([\?;].*)?$/.test(this.path);

    // Only pre-compile .less files
    if (! this.css) {
        imports.push(this.path, function (e, root, imported) {
            if (e) { e.index = index }
            if (imported && that.once) that.skip = imported;
            that.root = root || new(tree.Ruleset)([], []);
        });
    }
};

//
// The actual import node doesn't return anything, when converted to CSS.
// The reason is that it's used at the evaluation stage, so that the rules
// it imports can be treated like any other rules.
//
// In `eval`, we make sure all Import nodes get evaluated, recursively, so
// we end up with a flat structure, which can easily be imported in the parent
// ruleset.
//
tree.Import.prototype = {
    toCSS: function (env) {
        var features = this.features ? ' ' + this.features.toCSS(env) : '';

        if (this.css) {
            // Add the base path if the import is relative
            if (typeof this._path.value === "string" && !/^(?:[a-z-]+:|\/)/.test(this._path.value)) {
                this._path.value = this.rootpath + this._path.value;
            }
            return "@import " + this._path.toCSS() + features + ';\n';
        } else {
            return "";
        }
    },
    eval: function (env) {
        var ruleset, features = this.features && this.features.eval(env);

        if (this.skip) return [];

        if (this.css) {
            return this;
        } else {
            ruleset = new(tree.Ruleset)([], this.root.rules.slice(0));

            ruleset.evalImports(env);

            return this.features ? new(tree.Media)(ruleset.rules, this.features.value) : ruleset.rules;
        }
    }
};

})(require('../tree'));
<|endoftext|>


<commit_before>import test from 'ava'
import { join } from 'path'
import build from '../server/build'
import { render as _render } from '../server/render'

const dir = join(__dirname, 'fixtures', 'basic')

test.before(() => build(dir))

test(async t => {
  const html = await render('/stateless')
  t.true(html.includes('<meta charset="utf-8" class="next-head"/>'))
  t.true(html.includes('
My component!
'))
})

test(async t => {
  const html = await render('/css')
  t.true(html.includes('.css-im3wl1'))
  t.true(html.includes('
This is red
'))
})

test(async t => {
  const html = await render('/stateful')
  t.true(html.includes('

The answer is 42

'))
})

test(async t => {
  const html = await (render('/head'))
  t.true(html.includes('<meta charset="iso-8859-5" class="next-head"/>'))
  t.true(html.includes('<meta content="my meta" class="next-head"/>'))
  t.true(html.includes('

I can haz meta tags

'))
})

test(async t => {
  const html = await render('/async-props')
  t.true(html.includes('
Diego Milito
'))
})

function render (url, ctx) {
  return _render(url, ctx, { dir, staticMarkup: true })
}
<commit_msg>fix a test<commit_after>import test from 'ava'
import { join } from 'path'
import build from '../server/build'
import { render as _render } from '../server/render'

const dir = join(__dirname, 'fixtures', 'basic')

test.before(() => build(dir))

test(async t => {
  const html = await render('/stateless')
  t.true(html.includes('<meta charset="utf-8" class="next-head"/>'))
  t.true(html.includes('
My component!
'))
})

test(async t => {
  const html = await render('/css')
  t.regex(html, /\.css-\w+/)
  t.regex(html, /
This is red<\/div>/)
})

test(async t => {
  const html = await render('/stateful')
  t.true(html.includes('

The answer is 42

'))
})

test(async t => {
  const html = await (render('/head'))
  t.true(html.includes('<meta charset="iso-8859-5" class="next-head"/>'))
  t.true(html.includes('<meta content="my meta" class="next-head"/>'))
  t.true(html.includes('

I can haz meta tags

'))
})

test(async t => {
  const html = await render('/async-props')
  t.true(html.includes('
Diego Milito
'))
})

function render (url, ctx) {
  return _render(url, ctx, { dir, staticMarkup: true })
}
<|endoftext|>


<commit_before>var path = require('path')
var test = require('tape')
var deglob = require('../')

var playground = path.join(__dirname, 'playground')
var opts = { cwd: playground, gitIgnoreFile: 'custom-gitignore' }

test('all of the things', function (t) {
  globbies.forEach(function (obj) {
    deglob(obj.globs, obj.opts, checkEm)

    function checkEm (err, files) {
      if (err) throw err
      var testName = obj.name + ' -- matches ' + obj.expectedFiles.length + ' files'
      t.equals(files.length, obj.expectedFiles.length, testName)
      obj.expectedFiles.forEach(function (expectedFile) {
        t.ok(files.indexOf(path.join(playground, expectedFile)) > -1, 'File in Result: ' + expectedFile)
      })
    }
  })

  t.end()
})

var globbies = [
  {
    name: '*.txt useGitIgnore: default, usePackageJson: default',
    globs: '*.txt',
    opts: Object.assign({}, opts),
    expectedFiles: ['blah.txt']
  },
  {
    name: '*.txt useGitIgnore: false, usePackageJson: default',
    globs: '*.txt',
    opts: Object.assign({}, opts, { useGitIgnore: false }),
    expectedFiles: [
      'ignored-by-git.txt',
      'blah.txt']
  },
  {
    name: '*.txt useGitIgnore: false, usePackageJson: false',
    globs: '*.txt',
    opts: Object.assign({}, opts, { useGitIgnore: false, usePackageJson: false }),
    expectedFiles: [
      'ignored-by-git.txt',
      'ignored-by-package-json.txt',
      'blah.txt']
  },
  {
    name: '*.txt and *.json useGitIgnore: default, usePackageJson: false',
    globs: ['*.txt', '*.json'],
    opts: Object.assign({}, opts, { usePackageJson: false }),
    expectedFiles: [
      'ignored-by-package-json.txt',
      'blah.txt',
      'package.json']
  },
  {
    name: '*.txt and *.json useGitIgnore: default, usePackageJson: default, configKey: custom-ignore-blah',
    globs: ['*.txt'],
    opts: Object.assign({}, opts, { configKey: 'custom-ignore-blah' }),
    expectedFiles: ['ignored-by-package-json.txt']
  }
]
<commit_msg>test: fix t.end() error in tests for tape 5<commit_after>var path = require('path')
var test = require('tape')
var deglob = require('../')

var playground = path.join(__dirname, 'playground')
var opts = { cwd: playground, gitIgnoreFile: 'custom-gitignore' }

const globbies = [
  {
    name: '*.txt useGitIgnore: default, usePackageJson: default',
    globs: '*.txt',
    opts: Object.assign({}, opts),
    expectedFiles: ['blah.txt']
  },
  {
    name: '*.txt useGitIgnore: false, usePackageJson: default',
    globs: '*.txt',
    opts: Object.assign({}, opts, { useGitIgnore: false }),
    expectedFiles: [
      'ignored-by-git.txt',
      'blah.txt']
  },
  {
    name: '*.txt useGitIgnore: false, usePackageJson: false',
    globs: '*.txt',
    opts: Object.assign({}, opts, { useGitIgnore: false, usePackageJson: false }),
    expectedFiles: [
      'ignored-by-git.txt',
      'ignored-by-package-json.txt',
      'blah.txt']
  },
  {
    name: '*.txt and *.json useGitIgnore: default, usePackageJson: false',
    globs: ['*.txt', '*.json'],
    opts: Object.assign({}, opts, { usePackageJson: false }),
    expectedFiles: [
      'ignored-by-package-json.txt',
      'blah.txt',
      'package.json']
  },
  {
    name: '*.txt and *.json useGitIgnore: default, usePackageJson: default, configKey: custom-ignore-blah',
    globs: ['*.txt'],
    opts: Object.assign({}, opts, { configKey: 'custom-ignore-blah' }),
    expectedFiles: ['ignored-by-package-json.txt']
  }
]

globbies.forEach(function (obj) {
  test('Testing ' + obj.name, function (t) {
    deglob(obj.globs, obj.opts, checkEm)

    function checkEm (err, files) {
      if (err) throw err
      var testName = obj.name + ' -- matches ' + obj.expectedFiles.length + ' files'
      t.equals(files.length, obj.expectedFiles.length, testName)
      obj.expectedFiles.forEach(function (expectedFile) {
        t.ok(files.indexOf(path.join(playground, expectedFile)) > -1, 'File in Result: ' + expectedFile)
      })
      t.end()
    }
  })
})
<|endoftext|>


<commit_before>/* The ViewManager takes care of detecting whether the user uses the old or
 * new Compose in Gmail. Once it finds out, it takes care of instantiating
 * the appropriate view (regularView or updatedView).
 */
var ViewManager = function () {
    if (arguments.callee.singleton_instance) {
        return arguments.callee.singleton_instance;
    }

    arguments.callee.singleton_instance = new (function () {
        var observerCallbacks = [];
        var cloudy_view;
        var mytimer;
        var enabled;

        this.addViewObserver = function (fn) {
            observerCallbacks.push(fn);
        }

        this.getView = function(){
            return cloudy_view;
        }

        /* Look for an element named "subject". If found, then a Compose window
         * must be open. If a DOM element with name "from" exists, and it is of
         * type "input", then we must be encountering the new Gmail Compose.
         * Otherwise, we're dealing with the old one.
         */
        var checkCompose = function() {
            if (enabled && document.getElementsByName("subject").length) {
                if (!document.getElementsByClassName("I5").length) {
                    // Gmail's old interface
                    cloudy_view = new RegularView();
                } else {
                    // Gmail's new interface
                    cloudy_view = new UpdatedView();
                }
                for (var i = 0; i < observerCallbacks.length; i++) {
                    cloudy_view.addObserver(observerCallbacks[i]);
                }
                clearInterval(mytimer);
                enabled = false;
            }
        }

        var loadSocialButtons = function() {
            // Load Tweet button
            (!function(d,s,id) {
                console.log("loading twitter");
                var js,fjs=d.getElementsByTagName(s)[0];
                if(!d.getElementById(id)) {
                    js=d.createElement(s);
                    js.id=id;
                    js.async = true;
                    js.src="https://platform.twitter.com/widgets.js";
                    fjs.parentNode.insertBefore(js,fjs);
                }
            } (document,"script","twitter-wjs"));

            // Load Google +1 button
            (function(d, s, id) {
                console.log("loading G+");
                var po = d.createElement(s);
                if (d.getElementById(id)) return;
                po.type = 'text/javascript';
                po.async = true;
                po.src = 'https://apis.google.com/js/plusone.js';
                var s = d.getElementsByTagName('script')[0];
                s.parentNode.insertBefore(po, s);
            })(document, 'script', 'googleplus-jssdk');

            // Load Pinterest "Pin it" button
            (function(d, s, id) {
                console.log("loading Pinterest");
                var js, fjs = d.getElementsByTagName(s)[0];
                if (d.getElementById(id)) return;
                js = d.createElement(s);
                js.id = id;
                js.src = "https://assets.pinterest.com/js/pinit.js";
                js.async = true;
                fjs.parentNode.insertBefore(js, fjs);
            } (document, 'script', 'pinterest-jssdk'));
        }

        var init = function() {
            mytimer = setInterval(checkCompose, 500);
            enabled = true;

            // check for promo bubble, display it if loaded
            var notification_bubble = document.getElementById("cloudy_bubble");
            if (notification_bubble) {
                console.log("Showing notification");

                if ($jQcl(notification_bubble).hasClass("cloudy_social")) {
                    loadSocialButtons();
                }
                /* why does this not work? */
                //$jQcl(notification_bubble).show();
                notification_bubble.style.display = "block";
                $jQcl(notification_bubble).delay(1500).fadeTo(1000, 1,
                        function() {
                    var cloudy_events =
                        document.getElementById("cloudy_events");
                    if (cloudy_events) {
                        var e = document.createEvent("Events");
                        e.initEvent("cloudy_notificationDisplayed",
                            false, true);
                        cloudy_events.dispatchEvent(e);
                    }
                });
                $jQcl("#cloudy_bubble_close").click(function(){
                    $jQcl(notification_bubble).fadeTo(600, 0, function(){
                        notification_bubble.parentNode.removeChild(
                            notification_bubble);
                    });
                });
            }
        }

        init.call(this);
        return this;
    })();

    return arguments.callee.singleton_instance;
}
<commit_msg>hiding bubble instead of removing it entirely. Otherwise pinterest creates errors.<commit_after>/* The ViewManager takes care of detecting whether the user uses the old or
 * new Compose in Gmail. Once it finds out, it takes care of instantiating
 * the appropriate view (regularView or updatedView).
 */
var ViewManager = function () {
    if (arguments.callee.singleton_instance) {
        return arguments.callee.singleton_instance;
    }

    arguments.callee.singleton_instance = new (function () {
        var observerCallbacks = [];
        var cloudy_view;
        var mytimer;
        var enabled;

        this.addViewObserver = function (fn) {
            observerCallbacks.push(fn);
        }

        this.getView = function(){
            return cloudy_view;
        }

        /* Look for an element named "subject". If found, then a Compose window
         * must be open. If a DOM element with name "from" exists, and it is of
         * type "input", then we must be encountering the new Gmail Compose.
         * Otherwise, we're dealing with the old one.
         */
        var checkCompose = function() {
            if (enabled && document.getElementsByName("subject").length) {
                if (!document.getElementsByClassName("I5").length) {
                    // Gmail's old interface
                    cloudy_view = new RegularView();
                } else {
                    // Gmail's new interface
                    cloudy_view = new UpdatedView();
                }
                for (var i = 0; i < observerCallbacks.length; i++) {
                    cloudy_view.addObserver(observerCallbacks[i]);
                }
                clearInterval(mytimer);
                enabled = false;
            }
        }

        var loadSocialButtons = function() {
            // Load Tweet button
            (!function(d,s,id) {
                console.log("loading twitter");
                var js,fjs=d.getElementsByTagName(s)[0];
                if(!d.getElementById(id)) {
                    js=d.createElement(s);
                    js.id=id;
                    js.async = true;
                    js.src="https://platform.twitter.com/widgets.js";
                    fjs.parentNode.insertBefore(js,fjs);
                }
            } (document,"script","twitter-wjs"));

            // Load Google +1 button
            (function(d, s, id) {
                console.log("loading G+");
                var po = d.createElement(s);
                if (d.getElementById(id)) return;
                po.type = 'text/javascript';
                po.async = true;
                po.src = 'https://apis.google.com/js/plusone.js';
                var s = d.getElementsByTagName('script')[0];
                s.parentNode.insertBefore(po, s);
            })(document, 'script', 'googleplus-jssdk');

            // Load Pinterest "Pin it" button
            (function(d, s, id) {
                console.log("loading Pinterest");
                var js, fjs = d.getElementsByTagName(s)[0];
                if (d.getElementById(id)) return;
                js = d.createElement(s);
                js.id = id;
                js.src = "https://assets.pinterest.com/js/pinit.js";
                js.async = true;
                fjs.parentNode.insertBefore(js, fjs);
            } (document, 'script', 'pinterest-jssdk'));
        }

        var init = function() {
            mytimer = setInterval(checkCompose, 500);
            enabled = true;

            // check for promo bubble, display it if loaded
            var notification_bubble = document.getElementById("cloudy_bubble");
            if (notification_bubble) {
                console.log("Showing notification");

                if ($jQcl(notification_bubble).hasClass("cloudy_social")) {
                    loadSocialButtons();
                }
                /* why does this not work? */
                //$jQcl(notification_bubble).show();
                notification_bubble.style.display = "block";
                $jQcl(notification_bubble).delay(1500).fadeTo(1000, 1,
                        function() {
                    var cloudy_events =
                        document.getElementById("cloudy_events");
                    if (cloudy_events) {
                        var e = document.createEvent("Events");
                        e.initEvent("cloudy_notificationDisplayed",
                            false, true);
                        cloudy_events.dispatchEvent(e);
                    }
                });
                $jQcl("#cloudy_bubble_close").click(function(){
                    $jQcl(notification_bubble).fadeTo(600, 0, function(){
                        notification_bubble.hide();
                        //notification_bubble.parentNode.removeChild(
                        //    notification_bubble);
                    });
                });
            }
        }

        init.call(this);
        return this;
    })();

    return arguments.callee.singleton_instance;
}
<|endoftext|>