<commit_before>var vows = require('vows'),
    assert = require('assert'),
    deepCopy = require('../');

var testConstructor = function() { this.foo = "test_foo"; };
testConstructor.prototype = { bar: "test_bar" };
testConstructor.baz = "test_baz";

var testTimestamp = Date.now();
var testDate = new Date(testTimestamp);
var testNumber = 12345;
var testString = "12345";
var testArray = ["foo", "bar"];
var testRegExp = /./g;
var testBoolean = true;
var testFunction = function _test() { return "test"; };
var testObject = { foo: "test_foo" };

var testComplexObject = {
	number : testNumber,
	string : testString,
	regexp : new RegExp(testRegExp),
	"null" : null,
	"undefined" : undefined,
	boolean : testBoolean,
	date : testDate,
	"function" : testFunction,
	constructor : testConstructor,
	constructed : new testConstructor(),
	object : testObject,
	array : testArray,
	cycles : {},
	cycles2 :{}
};

//add some cycles
testComplexObject.cycles.parent = testComplexObject;
testComplexObject.cycles2.other = testComplexObject.cycles;
testComplexObject.cycles.complex = testComplexObject.object;

//we pre-exec the regex to add some internal state
testComplexObject.regexp.exec(testString);

vows.describe('Deep Clone').addBatch({
	'Number': {
		topic: function(){ return deepCopy(testNumber); },
		'Correct Value' : function (clone) {
			assert.equal (clone, testNumber);
		}
	},
	'String': {
		topic: function(){ return deepCopy(testString); },
		'Correct Value' : function (clone) {
			assert.equal (clone, testString);
		}
	},
	'Date': {
		topic: function(){ return deepCopy(testDate); },
		'Correct Value' : function (clone) {
			assert.equal (clone.getTime(), testDate.getTime());
		}
	},
	'Boolean': {
		topic: function(){ return deepCopy(testBoolean); },
		'Correct Value' : function (clone) {
			assert.equal (clone, testBoolean);
		}
	},
	'Array': {
		topic: function(){ return deepCopy(testArray); },
		'Correct Value' : function (clone) {
			assert.deepEqual (clone, testArray);
		},
		'Changes Independently' : function (clone) {
			clone[0] = 'something';
			clone[1] = 'different';
			assert.equal (testArray[0], "foo");
			assert.equal (testArray[1], "bar");
		}
	},
	'Function': {
		topic: function(){ return deepCopy(testFunction); },
		'Correct Value' : function (clone) {
			assert.equal (clone(), testFunction());
		}
	},
	'Simple Object': {
		topic: function(){ return deepCopy(testObject); },
		'Correct Value' : function (clone) {
			assert.deepEqual (clone, testObject);
		},
		'Changes Independently' : function (clone) {
			clone.foo = 'different';
			assert.equal (testObject.foo, "test_foo");
		}
	},
	'Complex Object': {
		topic: function(){ return deepCopy(testComplexObject); },

		'number' : function (clone) {
			assert.equal (clone.number, testNumber);
			clone.number = 14;
			assert.equal (testComplexObject.number, testNumber);
		},
		'string': function (clone) {
			assert.equal (clone.string, testString);
			clone.string = 'changed';
			assert.equal (testComplexObject.string, testString);
		},
		'regexp': function (clone) {
			assert.deepEqual (clone.regexp.exec(testString)[0], "1");
			assert.equal (clone.regexp.exec(testString)[0], "2");
			assert.equal (testComplexObject.regexp.exec(testString)[0], "2");
		},
		'null': function (clone) {
			assert.equal (clone.null, null);
		},
		'undefined' : function(clone) {
			assert.equal (typeof clone.undefined, 'undefined');
		},
		'boolean' : function(clone) {
			assert.isTrue (clone.boolean);
			clone.boolean = false;
			assert.isTrue (testComplexObject.boolean);
		},
		'date' : function(clone) {
			assert.equal (clone.date.getTime(), testTimestamp);
			clone.date = new Date();
			assert.equal (testComplexObject.date.getTime(), testTimestamp);
		},
		'function' : function(clone) {
			assert.equal (clone.function(), 'test');
			assert.equal (clone.function.name, '_test');
			clone.function.name = 'changed';
			assert.equal (testComplexObject.function(), 'test');
			assert.equal (testComplexObject.function.name, '_test');
		},
		'constructor' : function(clone) {
			assert.isFalse (clone.constructor === testComplexObject.constructor);
			assert.equal (clone.constructor.baz, 'test_baz');
			clone.constructor.baz = 'changed';
			assert.equal (testComplexObject.constructor.baz, 'test_baz');
		},
		'constructed' : function(clone) {
			assert.isFalse (clone.constructed === testComplexObject.constructed);

			assert.equal (clone.constructed.foo, 'test_foo');
			clone.constructed.foo = 'changed';
			assert.equal (testComplexObject.constructed.foo, 'test_foo');

			assert.equal (clone.constructed.bar, 'test_bar');
			Object.getPrototypeOf(clone.constructed).bar = 'changed';
			assert.equal (testComplexObject.constructed.bar, 'changed');
		},
		'object' : function(clone) {
			assert.equal (clone.object.foo, 'test_foo');
			clone.object.foo = 'changed';
			assert.equal (testComplexObject.object.foo, 'test_foo');
		},
		'array' : function(clone) {
			assert.deepEqual (clone.array, ['foo', 'bar']);
			clone.array[0] = 'changed';
			assert.deepEqual (testComplexObject.array, ['foo', 'bar']);
		},
		'cycles' : function(clone) {
			assert.equal (clone.cycles2.other, clone.cycles);
			assert.equal (clone, clone.cycles.parent);
		}
	}
}).export(module);
<commit_msg>Added tests for typed array cloning<commit_after>var vows = require('vows'),
    assert = require('assert'),
    deepCopy = require('../');

var testConstructor = function() { this.foo = "test_foo"; };
testConstructor.prototype = { bar: "test_bar" };
testConstructor.baz = "test_baz";

var testTimestamp = Date.now();
var testDate = new Date(testTimestamp);
var testNumber = 12345;
var testString = "12345";
var testArray = ["foo", "bar"];
var testRegExp = /./g;
var testBoolean = true;
var testFunction = function _test() { return "test"; };
var testObject = { foo: "test_foo" };
var testTypedArray = new Int32Array(3);
testTypedArray[0] = 6;
testTypedArray[1] = 3;
testTypedArray[2] = -99;

var testComplexObject = {
	number : testNumber,
	string : testString,
	regexp : new RegExp(testRegExp),
	"null" : null,
	"undefined" : undefined,
	boolean : testBoolean,
	date : testDate,
	"function" : testFunction,
	constructor : testConstructor,
	constructed : new testConstructor(),
	object : testObject,
	array : testArray,
	cycles : {},
	cycles2 :{},
	typedArray: testTypedArray
};

//add some cycles
testComplexObject.cycles.parent = testComplexObject;
testComplexObject.cycles2.other = testComplexObject.cycles;
testComplexObject.cycles.complex = testComplexObject.object;

//we pre-exec the regex to add some internal state
testComplexObject.regexp.exec(testString);

vows.describe('Deep Clone').addBatch({
	'Number': {
		topic: function(){ return deepCopy(testNumber); },
		'Correct Value' : function (clone) {
			assert.equal (clone, testNumber);
		}
	},
	'String': {
		topic: function(){ return deepCopy(testString); },
		'Correct Value' : function (clone) {
			assert.equal (clone, testString);
		}
	},
	'Date': {
		topic: function(){ return deepCopy(testDate); },
		'Correct Value' : function (clone) {
			assert.equal (clone.getTime(), testDate.getTime());
		}
	},
	'Boolean': {
		topic: function(){ return deepCopy(testBoolean); },
		'Correct Value' : function (clone) {
			assert.equal (clone, testBoolean);
		}
	},
	'Array': {
		topic: function(){ return deepCopy(testArray); },
		'Correct Value' : function (clone) {
			assert.deepEqual (clone, testArray);
		},
		'Changes Independently' : function (clone) {
			clone[0] = 'something';
			clone[1] = 'different';
			assert.equal (testArray[0], "foo");
			assert.equal (testArray[1], "bar");
		}
	},
	'Function': {
		topic: function(){ return deepCopy(testFunction); },
		'Correct Value' : function (clone) {
			assert.equal (clone(), testFunction());
		}
	},
	'Typed Array': {
		topic: function(){ return deepCopy(testTypedArray); },
		'Correct Value' : function (clone) {
			assert.deepEqual (clone, testTypedArray);
		},
		'Changes Independently' : function (clone) {
			clone[0] = 0;
			assert.equal (testTypedArray[0], 6);
		}
	},
	'Simple Object': {
		topic: function(){ return deepCopy(testObject); },
		'Correct Value' : function (clone) {
			assert.deepEqual (clone, testObject);
		},
		'Changes Independently' : function (clone) {
			clone.foo = 'different';
			assert.equal (testObject.foo, "test_foo");
		}
	},
	'Complex Object': {
		topic: function(){ return deepCopy(testComplexObject); },

		'number' : function (clone) {
			assert.equal (clone.number, testNumber);
			clone.number = 14;
			assert.equal (testComplexObject.number, testNumber);
		},
		'string': function (clone) {
			assert.equal (clone.string, testString);
			clone.string = 'changed';
			assert.equal (testComplexObject.string, testString);
		},
		'regexp': function (clone) {
			assert.deepEqual (clone.regexp.exec(testString)[0], "1");
			assert.equal (clone.regexp.exec(testString)[0], "2");
			assert.equal (testComplexObject.regexp.exec(testString)[0], "2");
		},
		'null': function (clone) {
			assert.equal (clone.null, null);
		},
		'undefined' : function(clone) {
			assert.equal (typeof clone.undefined, 'undefined');
		},
		'boolean' : function(clone) {
			assert.isTrue (clone.boolean);
			clone.boolean = false;
			assert.isTrue (testComplexObject.boolean);
		},
		'date' : function(clone) {
			assert.equal (clone.date.getTime(), testTimestamp);
			clone.date = new Date();
			assert.equal (testComplexObject.date.getTime(), testTimestamp);
		},
		'function' : function(clone) {
			assert.equal (clone.function(), 'test');
			assert.equal (clone.function.name, '_test');
			clone.function.name = 'changed';
			assert.equal (testComplexObject.function(), 'test');
			assert.equal (testComplexObject.function.name, '_test');
		},
		'constructor' : function(clone) {
			assert.isFalse (clone.constructor === testComplexObject.constructor);
			assert.equal (clone.constructor.baz, 'test_baz');
			clone.constructor.baz = 'changed';
			assert.equal (testComplexObject.constructor.baz, 'test_baz');
		},
		'constructed' : function(clone) {
			assert.isFalse (clone.constructed === testComplexObject.constructed);

			assert.equal (clone.constructed.foo, 'test_foo');
			clone.constructed.foo = 'changed';
			assert.equal (testComplexObject.constructed.foo, 'test_foo');

			assert.equal (clone.constructed.bar, 'test_bar');
			Object.getPrototypeOf(clone.constructed).bar = 'changed';
			assert.equal (testComplexObject.constructed.bar, 'changed');
		},
		'object' : function(clone) {
			assert.equal (clone.object.foo, 'test_foo');
			clone.object.foo = 'changed';
			assert.equal (testComplexObject.object.foo, 'test_foo');
		},
		'array' : function(clone) {
			assert.deepEqual (clone.array, ['foo', 'bar']);
			clone.array[0] = 'changed';
			assert.deepEqual (testComplexObject.array, ['foo', 'bar']);
		},
		'cycles' : function(clone) {
			assert.equal (clone.cycles2.other, clone.cycles);
			assert.equal (clone, clone.cycles.parent);
		},
		'typed array' : function (clone) {
			assert.deepEqual (clone.typedArray, testTypedArray);
			clone.typedArray[0] = 0;
			assert.equal (testTypedArray[0], 6);
		}
	}
}).export(module);
<|endoftext|>


<commit_before>var rewire = require("rewire");
var Connection = rewire("../lib/connection");

var sinon = require("sinon");

describe("Connection", function() {
	describe('constructor', function () {
		var originalEnv;

		before(function() {
			originalEnv = process.env.NODE_ENV;
		});

		after(function() {
			process.env.NODE_ENV = originalEnv;
		})

		beforeEach(function() {
			process.env.NODE_ENV = "";
		})

		// Issue #50
		it("should use gateway.sandbox.push.apple.com as the default connection address", function () {
			expect(Connection().options.address).to.equal("gateway.sandbox.push.apple.com");
		});

		it("should use gateway.push.apple.com when NODE_ENV=production", function () {
			process.env.NODE_ENV = "production";
			expect(Connection().options.address).to.equal("gateway.push.apple.com");
		});

		it("should give precedence to production flag over NODE_ENV=production", function () {
			process.env.NODE_ENV = "production";
			expect(Connection({ production: false }).options.address).to.equal("gateway.sandbox.push.apple.com");
		});

		it("should use gateway.push.apple.com when production:true", function () {
			expect(Connection({production:true}).options.address).to.equal("gateway.push.apple.com");
		});

		it("should use a custom address when passed", function () {
			expect(Connection({address: "testaddress"}).options.address).to.equal("testaddress");
		});
	});

	describe('#initialize', function () {
		describe("with valid credentials", function() {
			var initialization;
			before(function() {
				initialization = Connection({ cert: "test/credentials/support/cert.pem", key: "test/credentials/support/key.pem", passphrase: "apntest" }).initialize();
			});

			it("should be fulfilled", function () {
				return expect(initialization).to.be.fulfilled;
			});

			describe("resolution value", function() {
				it("contains the key data", function() {
					return expect(initialization.get("key")).to.eventually.have.length(1680);
				});

				it("includes passphrase", function() {
					return expect(initialization.get("passphrase")).to.eventually.equal("apntest");
				});
			});
		});

		describe("with sandbox certificate in production", function() {
			it("should be rejected", function() {
				var connection = Connection({ cert: "test/credentials/support/cert.pem", key: "test/credentials/support/key.pem", production: true });
				return expect(connection.initialize()).to.be.rejected;
			});
		});

		describe("with unreadable file", function() {
			it("should be fulfilled", function() {
				var connection = Connection({ pfx: "test/credentials/support/cert.pem" });
				return expect(connection.initialize()).to.eventually.be.fulfilled;
			});

			var reset;
			beforeEach(function() {
				reset = Connection.__set__("debug", sinon.spy());
			});

			afterEach(function() {
				reset();
			});

			it("should log an error", function() {
				var connection = Connection({ pfx: "test/credentials/support/cert.pem" });
				return connection.initialize().finally(function() {
					expect(Connection.__get__("debug")).to.be.calledWith(sinon.match(function(err) {
						return err.message ? err.message.match(/unable to read credentials/) : false;
					}, "\"unable to read credentials\""));
				});
			});
		});

		describe("with invalid file path", function() {
			it("should be rejected", function() {
				var connection = Connection({ pfx: "a-non-existant-file-which-really-shouldnt-exist.pfx" });
				return expect(connection.initialize()).to.eventually.be.rejected;
			});
		});
	});

	describe("connect", function() {
		var socketStub, removeStub;
		before(function() {
			socketStub = sinon.stub();
			removeStub = Connection.__set__("createSocket", socketStub);
		});

		after(function() {
			removeStub();
		});

		afterEach(function() {
			socketStub.reset();
		});

		it("initializes the module", function(done) {
			socketStub.callsArg(2);
	 		socketStub.returns({ on: function() {}, once: function() {}, end: function() {} });

			var connection = Connection({ pfx: "myCredentials.pfx" });
			sinon.spy(connection, "initialize");
			connection.connect().finally(function() {
				expect(connection.initialize).to.have.been.calledOnce;
				connection.initialize.restore();
				done();
			});
		});

		describe("with valid credentials", function() {
			beforeEach(function() {
				socketStub.callsArg(2);
				socketStub.returns({ on: function() {}, once: function() {}, end: function() {} });
			});

			it("resolves", function() {
				var connection = Connection({
					cert: "test/credentials/support/cert.pem",
					key: "test/credentials/support/key.pem"
				});
				return expect(connection.connect()).to.be.fulfilled;
			});

			describe("the call to create socket", function() {
				var connect;

				it("passes PFX data", function() {
					connect = Connection({
						pfx: "test/credentials/support/certIssuerKeyPassphrase.p12",
						passphrase: "apntest"
					}).connect();
					return connect.then(function() {
						var socketOptions = socketStub.args[0][1];
						expect(socketOptions.pfx).to.have.length(3517);
					});
				});

				it("passes the passphrase", function() {
					connect = Connection({
						passphrase: "apntest",
						cert: "test/credentials/support/cert.pem",
						key: "test/credentials/support/key.pem"
					}).connect();
					return connect.then(function() {
						var socketOptions = socketStub.args[0][1];
						expect(socketOptions.passphrase).to.equal("apntest");
					});
				});

				it("passes the cert", function() {
					connect = Connection({
						cert: "test/credentials/support/cert.pem",
						key: "test/credentials/support/key.pem"
					}).connect();
					return connect.then(function() {
						var socketOptions = socketStub.args[0][1];
						expect(socketOptions.cert).to.have.length(1355);
					});
				});

				it("passes the key", function() {
					connect = Connection({
						cert: "test/credentials/support/cert.pem",
						key: "test/credentials/support/key.pem"
					}).connect();
					return connect.then(function() {
						var socketOptions = socketStub.args[0][1];
						expect(socketOptions.key).to.have.length(1680);
					});
				});

				it("passes the ca certificates", function() {
					connect = Connection({
						cert: "test/credentials/support/cert.pem",
						key: "test/credentials/support/key.pem",
						ca: [ "test/credentials/support/issuerCert.pem" ]
					}).connect();
					return connect.then(function() {
						var socketOptions = socketStub.args[0][1];
						expect(socketOptions.ca[0]).to.have.length(1285);
					});
				});
			});
		});

		describe("intialization failure", function() {
			it("is rejected", function() {
				var connection = Connection({ pfx: "a-non-existant-file-which-really-shouldnt-exist.pfx" });
				return expect(connection.connect()).to.be.rejected;
			});
		});
	});
});<commit_msg>More collaboration tests.<commit_after>var rewire = require("rewire");
var Connection = rewire("../lib/connection");

var sinon = require("sinon");
var Q = require("q");

describe("Connection", function() {
	describe('constructor', function () {
		var originalEnv;

		before(function() {
			originalEnv = process.env.NODE_ENV;
		});

		after(function() {
			process.env.NODE_ENV = originalEnv;
		})

		beforeEach(function() {
			process.env.NODE_ENV = "";
		})

		// Issue #50
		it("should use gateway.sandbox.push.apple.com as the default connection address", function () {
			expect(Connection().options.address).to.equal("gateway.sandbox.push.apple.com");
		});

		it("should use gateway.push.apple.com when NODE_ENV=production", function () {
			process.env.NODE_ENV = "production";
			expect(Connection().options.address).to.equal("gateway.push.apple.com");
		});

		it("should give precedence to production flag over NODE_ENV=production", function () {
			process.env.NODE_ENV = "production";
			expect(Connection({ production: false }).options.address).to.equal("gateway.sandbox.push.apple.com");
		});

		it("should use gateway.push.apple.com when production:true", function () {
			expect(Connection({production:true}).options.address).to.equal("gateway.push.apple.com");
		});

		it("should use a custom address when passed", function () {
			expect(Connection({address: "testaddress"}).options.address).to.equal("testaddress");
		});
	});

	describe('#initialize', function () {
		describe("with valid credentials", function() {
			var initialization;
			before(function() {
				initialization = Connection({ cert: "test/credentials/support/cert.pem", key: "test/credentials/support/key.pem", passphrase: "apntest" }).initialize();
			});

			it("should be fulfilled", function () {
				return expect(initialization).to.be.fulfilled;
			});

			describe("resolution value", function() {
				it("contains the key data", function() {
					return expect(initialization.get("key")).to.eventually.have.length(1680);
				});

				it("includes passphrase", function() {
					return expect(initialization.get("passphrase")).to.eventually.equal("apntest");
				});
			});
		});

		describe("with sandbox certificate in production", function() {
			it("should be rejected", function() {
				var connection = Connection({ cert: "test/credentials/support/cert.pem", key: "test/credentials/support/key.pem", production: true });
				return expect(connection.initialize()).to.be.rejected;
			});
		});

		describe("with unreadable file", function() {
			it("should be fulfilled", function() {
				var connection = Connection({ pfx: "test/credentials/support/cert.pem" });
				return expect(connection.initialize()).to.eventually.be.fulfilled;
			});

			var reset;
			beforeEach(function() {
				reset = Connection.__set__("debug", sinon.spy());
			});

			afterEach(function() {
				reset();
			});

			it("should log an error", function() {
				var connection = Connection({ pfx: "test/credentials/support/cert.pem" });
				return connection.initialize().finally(function() {
					expect(Connection.__get__("debug")).to.be.calledWith(sinon.match(function(err) {
						return err.message ? err.message.match(/unable to read credentials/) : false;
					}, "\"unable to read credentials\""));
				});
			});
		});

		describe("with invalid file path", function() {
			it("should be rejected", function() {
				var connection = Connection({ pfx: "a-non-existant-file-which-really-shouldnt-exist.pfx" });
				return expect(connection.initialize()).to.eventually.be.rejected;
			});
		});
	});

	describe("connect", function() {
		var socketStub, removeSocketStub;

		before(function() {
			var initializeStub = sinon.stub(Connection.prototype, "initialize");
			initializeStub.returns(Q({
				pfx: "pfxData",
				key: "keyData",
				cert: "certData",
				ca: ["caData1", "caData2"],
				passphrase: "apntest" }));
		});

		beforeEach(function() {
			socketStub = sinon.stub();
			socketStub.callsArg(2);
			socketStub.returns({ on: function() {}, once: function() {}, end: function() {} });

			removeSocketStub = Connection.__set__("createSocket", socketStub);
		});

		afterEach(function() {
			removeSocketStub();
		});

		it("initializes the module", function(done) {
			var connection = Connection({ pfx: "myCredentials.pfx" });
			return connection.connect().finally(function() {
				expect(connection.initialize).to.have.been.calledOnce;
				done();
			});
		});

		describe("with valid credentials", function() {
			it("resolves", function() {
				var connection = Connection({
					cert: "myCert.pem",
					key: "myKey.pem"
				});
				return expect(connection.connect()).to.be.fulfilled;
			});

			describe("the call to create socket", function() {
				var connect;

				it("passes PFX data", function() {
					connect = Connection({
						pfx: "myCredentials.pfx",
						passphrase: "apntest"
					}).connect();
					return connect.then(function() {
						var socketOptions = socketStub.args[0][1];
						expect(socketOptions.pfx).to.equal("pfxData");
					});
				});

				it("passes the passphrase", function() {
					connect = Connection({
						passphrase: "apntest",
						cert: "myCert.pem",
						key: "myKey.pem"
					}).connect();
					return connect.then(function() {
						var socketOptions = socketStub.args[0][1];
						expect(socketOptions.passphrase).to.equal("apntest");
					});
				});

				it("passes the cert", function() {
					connect = Connection({
						cert: "myCert.pem",
						key: "myKey.pem"
					}).connect();
					return connect.then(function() {
						var socketOptions = socketStub.args[0][1];
						expect(socketOptions.cert).to.equal("certData");
					});
				});

				it("passes the key", function() {
					connect = Connection({
						cert: "test/credentials/support/cert.pem",
						key: "test/credentials/support/key.pem"
					}).connect();
					return connect.then(function() {
						var socketOptions = socketStub.args[0][1];
						expect(socketOptions.key).to.equal("keyData");
					});
				});

				it("passes the ca certificates", function() {
					connect = Connection({
						cert: "test/credentials/support/cert.pem",
						key: "test/credentials/support/key.pem",
						ca: [ "test/credentials/support/issuerCert.pem" ]
					}).connect();
					return connect.then(function() {
						var socketOptions = socketStub.args[0][1];
						expect(socketOptions.ca[0]).to.equal("caData1");
					});
				});
			});
		});

		describe("intialization failure", function() {
			it("is rejected", function() {
				var connection = Connection({ pfx: "a-non-existant-file-which-really-shouldnt-exist.pfx" });
				connection.initialize.returns(Q.reject(new Error("initialize failed")));

				return expect(connection.connect()).to.be.rejectedWith("initialize failed");
			});
		});
	});
});<|endoftext|>


<commit_before>var assert = require('assert');

var R = require('..');
var eq = require('./shared/eq');

describe('dissocPath', function() {
  it('makes a shallow clone of an object, omitting only what is necessary for the path', function() {
    var obj1 = {a: {b: 1, c: 2, d: {e: 3}}, f: [{ g: 4}, {h: 5, i: 6, j: {k: 7, l: 8}}], m: 9};
    var obj2 = R.dissocPath(['f', 1, 'i'], obj1);
    eq(obj2,
      {a: {b: 1, c: 2, d: {e: 3}}, f: [{g: 4}, {h: 5, j: {k: 7, l: 8}}], m: 9}
    );
    // Note: reference equality below!
    assert.strictEqual(obj2.a, obj1.a);
    assert.strictEqual(obj2.m, obj1.m);
    assert.strictEqual(obj2.f[0], obj1.f[0]);
    assert.strictEqual(obj2.f[1].h, obj1.f[1].h);
    assert.strictEqual(obj2.f[1].j, obj1.f[1].j);
  });

  it('does not try to omit inner properties that do not exist', function() {
    var obj1 = {a: 1, b: {c: 2, d: 3}, e: 4, f: 5};
    var obj2 = R.dissocPath(['x', 0, 'z'], obj1);
    eq(obj2, {a: 1, b: {c: 2, d: 3}, e: 4, f: 5});
    // Note: reference equality below!
    assert.strictEqual(obj2.a, obj1.a);
    assert.strictEqual(obj2.b, obj1.b);
    assert.strictEqual(obj2.f, obj1.f);
  });

  it('leaves an empty object when all properties omitted', function() {
    var obj1 = {a: 1, b: {c: 2}, d: 3};
    var obj2 = R.dissocPath(['b', 'c'], obj1);
    eq(obj2,
      {a: 1, b: {}, d: 3}
    );
  });

  it('leaves an empty array when all indexes are omitted', function() {
    var obj1 = {a: 1, b: [2], d: 3};
    var obj2 = R.dissocPath(['b', 0], obj1);
    eq(obj2,
      {a: 1, b: [], d: 3}
    );
  });

  it('flattens properties from prototype', function() {
    var F = function() {};
    F.prototype.a = 1;
    var obj1 = new F();
    obj1.b = {c: 2, d: 3};
    var obj2 = R.dissocPath(['b', 'c'], obj1);
    eq(obj2,
      {a: 1, b: {d: 3}}
    );
  });

  it('accepts empty path', function() {
    eq(R.dissocPath([], {a: 1, b: 2}), {a: 1, b: 2});
  });

  it('coerces non-string types', function() {
    eq(R.dissocPath([42], {a: 1, b: 2, 42: 3}), {a: 1, b: 2});
    eq(R.dissocPath([null], {a: 1, b: 2, 'null': 3}), {a: 1, b: 2});
    eq(R.dissocPath([undefined], {a: 1, b: 2, undefined: 3}), {a: 1, b: 2});
  });

});
<commit_msg>test simplification - better expresses intent<commit_after>var assert = require('assert');

var R = require('..');
var eq = require('./shared/eq');

describe('dissocPath', function() {
  it('makes a shallow clone of an object, omitting only what is necessary for the path', function() {
    var obj1 = {a: {b: 1, c: 2, d: {e: 3}}, f: [{ g: 4}, {h: 5, i: 6, j: {k: 7, l: 8}}], m: 9};
    var obj2 = R.dissocPath(['f', 1, 'i'], obj1);
    eq(obj2,
      {a: {b: 1, c: 2, d: {e: 3}}, f: [{g: 4}, {h: 5, j: {k: 7, l: 8}}], m: 9}
    );
    // Note: reference equality below!
    assert.strictEqual(obj2.a, obj1.a);
    assert.strictEqual(obj2.m, obj1.m);
    assert.strictEqual(obj2.f[0], obj1.f[0]);
    assert.strictEqual(obj2.f[1].h, obj1.f[1].h);
    assert.strictEqual(obj2.f[1].j, obj1.f[1].j);
  });

  it('does not try to omit inner properties that do not exist', function() {
    var obj1 = {a: 1, b: {c: 2, d: 3}, e: 4, f: 5};
    var obj2 = R.dissocPath(['x', 0, 'z'], obj1);
    eq(obj2, {a: 1, b: {c: 2, d: 3}, e: 4, f: 5});
    // Note: reference equality below!
    assert.strictEqual(obj2.a, obj1.a);
    assert.strictEqual(obj2.b, obj1.b);
    assert.strictEqual(obj2.f, obj1.f);
  });

  it('leaves an empty object when all properties omitted', function() {
    var obj1 = {a: 1, b: {c: 2}, d: 3};
    var obj2 = R.dissocPath(['b', 'c'], obj1);
    eq(obj2,
      {a: 1, b: {}, d: 3}
    );
  });

  it('leaves an empty array when all indexes are omitted', function() {
    var obj1 = {a: 1, b: [2], d: 3};
    var obj2 = R.dissocPath(['b', 0], obj1);
    eq(obj2,
      {a: 1, b: [], d: 3}
    );
  });

  it('flattens properties from prototype', function() {
    var F = function() {};
    F.prototype.a = 1;
    var obj1 = new F();
    obj1.b = {c: 2, d: 3};
    var obj2 = R.dissocPath(['b', 'c'], obj1);
    eq(obj2,
      {a: 1, b: {d: 3}}
    );
  });

  it('accepts empty path', function() {
    eq(R.dissocPath([], {a: 1, b: 2}), {a: 1, b: 2});
  });

  it('allow use integer key for object', function() {
    eq(R.dissocPath([42], {a: 1, b: 2, 42: 3}), {a: 1, b: 2});
  });

});
<|endoftext|>


<commit_before>const {Fragment} = require("../model")
const {Transform, insertPoint} = require("../transform")
const {Selection} = require("../selection")

// ;; A selection-aware extension of `Transform`. Use `EditorState.tr`
// to create an instance.
class EditorTransform extends Transform {
  constructor(state) {
    super(state.doc)
    this.state = state
    this.curSelection = state.selection
    this.curSelectionAt = 0
    this.selectionSet = false
  }

  // :: Selection
  // The transform's current selection. This defaults to the
  // editor selection [mapped](#Selection.map) through the steps in
  // this transform, but can be overwritten with
  // [`setSelection`](#EditorTransform.setSelection).
  get selection() {
    if (this.curSelectionAt < this.steps.length) {
      this.curSelection = this.curSelection.map(this.doc, this.mapping.slice(this.curSelectionAt))
      this.curSelectionAt = this.steps.length
    }
    return this.curSelection
  }

  // :: (Selection) → EditorTransform
  // Update the transform's current selection. This will determine the
  // selection that the editor gets when the transform is applied.
  setSelection(selection) {
    this.curSelection = selection
    this.curSelectionAt = this.steps.length
    this.selectionSet = true
    return this
  }

  // :: (?Node, ?bool) → EditorTransform
  // Replace the selection with the given node, or delete it if `node`
  // is null. When `inheritMarks` is true and the node is an inline
  // node, it inherits the marks from the place where it is inserted.
  replaceSelection(node, inheritMarks) {
    let {empty, $from, $to, from, to, node: selNode} = this.selection

    if (node && node.isInline && inheritMarks !== false)
      node = node.mark(empty ? this.state.view.storedMarks : this.doc.marksAt(from))
    let fragment = Fragment.from(node)

    if (selNode && selNode.isTextblock && node && node.isInline) {
      // Putting inline stuff onto a selected textblock puts it
      // inside, so cut off the sides
      from++
      to--
    } else if (selNode) {
      let depth = $from.depth
      // This node can not simply be removed/replaced. Remove its parent as well
      while (depth && $from.node(depth).childCount == 1 &&
             !$from.node(depth).canReplace($from.index(depth), $to.indexAfter(depth), fragment)) {
        depth--
      }
      if (depth < $from.depth) {
        from = $from.before(depth + 1)
        to = $from.after(depth + 1)
      }
    } else if (node && from == to) {
      let point = insertPoint(this.doc, from, node.type, node.attrs)
      if (point != null) from = to = point
    }

    this.replaceWith(from, to, fragment)
    let map = this.mapping.maps[this.mapping.maps.length - 1]
    this.setSelection(Selection.near(this.doc.resolve(map.map(to))))
    return this
  }

  // :: () → EditorTransform
  // Delete the selection.
  deleteSelection() {
    return this.replaceSelection()
  }

  // :: (string) → EditorTransform
  // Replace the selection with a text node containing the given string.
  typeText(text) {
    return this.replaceSelection(this.state.schema.text(text), true)
  }

  apply(options) {
    return this.state.applyTransform(this, options)
  }

  applyAndScroll() {
    return this.state.applyTransform(this, {scrollIntoView: true,
                                            selection: this.selectionSet ? this.selection : null})
  }
}
exports.EditorTransform = EditorTransform
<commit_msg>Move most selection test out of browser test suite<commit_after>const {Fragment} = require("../model")
const {Transform, insertPoint} = require("../transform")
const {Selection} = require("../selection")

// ;; A selection-aware extension of `Transform`. Use `EditorState.tr`
// to create an instance.
class EditorTransform extends Transform {
  constructor(state) {
    super(state.doc)
    this.state = state
    this.curSelection = state.selection
    this.curSelectionAt = 0
    this.selectionSet = false
  }

  // :: Selection
  // The transform's current selection. This defaults to the
  // editor selection [mapped](#Selection.map) through the steps in
  // this transform, but can be overwritten with
  // [`setSelection`](#EditorTransform.setSelection).
  get selection() {
    if (this.curSelectionAt < this.steps.length) {
      this.curSelection = this.curSelection.map(this.doc, this.mapping.slice(this.curSelectionAt))
      this.curSelectionAt = this.steps.length
    }
    return this.curSelection
  }

  // :: (Selection) → EditorTransform
  // Update the transform's current selection. This will determine the
  // selection that the editor gets when the transform is applied.
  setSelection(selection) {
    this.curSelection = selection
    this.curSelectionAt = this.steps.length
    this.selectionSet = true
    return this
  }

  // :: (?Node, ?bool) → EditorTransform
  // Replace the selection with the given node, or delete it if `node`
  // is null. When `inheritMarks` is true and the node is an inline
  // node, it inherits the marks from the place where it is inserted.
  replaceSelection(node, inheritMarks) {
    let {empty, $from, $to, from, to, node: selNode} = this.selection

    if (node && node.isInline && inheritMarks !== false)
      node = node.mark(empty ? this.state.view.storedMarks : this.doc.marksAt(from))
    let fragment = Fragment.from(node)

    if (selNode && selNode.isTextblock && node && node.isInline) {
      // Putting inline stuff onto a selected textblock puts it
      // inside, so cut off the sides
      from++
      to--
    } else if (selNode) {
      let depth = $from.depth
      // This node can not simply be removed/replaced. Remove its parent as well
      while (depth && $from.node(depth).childCount == 1 &&
             !$from.node(depth).canReplace($from.index(depth), $to.indexAfter(depth), fragment)) {
        depth--
      }
      if (depth < $from.depth) {
        from = $from.before(depth + 1)
        to = $from.after(depth + 1)
      }
    } else if (node && from == to) {
      let point = insertPoint(this.doc, from, node.type, node.attrs)
      if (point != null) from = to = point
    }

    this.replaceWith(from, to, fragment)
    let map = this.mapping.maps[this.mapping.maps.length - 1]
    this.setSelection(Selection.near(this.doc.resolve(map.map(to)), node && node.isInline ? -1 : 1))
    return this
  }

  // :: () → EditorTransform
  // Delete the selection.
  deleteSelection() {
    return this.replaceSelection()
  }

  // :: (string) → EditorTransform
  // Replace the selection with a text node containing the given string.
  typeText(text) {
    return this.replaceSelection(this.state.schema.text(text), true)
  }

  apply(options) {
    if (this.selectionSet && (!options || !options.selection)) {
      let newOptions = {selection: this.selection}
      if (options) for (let prop in options) newOptions[prop] = options[prop]
      options = newOptions
    }
    return this.state.applyTransform(this, options)
  }

  applyAndScroll() {
    return this.state.applyTransform(this, {scrollIntoView: true,
                                            selection: this.selectionSet ? this.selection : null})
  }
}
exports.EditorTransform = EditorTransform
<|endoftext|>


<commit_before>var fs = require( 'fs' );
var path = require( 'path' );
var assert = require( 'assert' );
var rimraf = require( 'rimraf' );
var store = require( '../src/file-store' );

describe( 'store(filepath)', function() {

  it( 'returns a file object with read and write methods', function() {
    var filepath = path.resolve( __dirname, './fixtures/users.json' );
    var file = store( filepath );

    assert.equal( typeof file.read, 'function' );
    assert.equal( typeof file.write, 'function' );
  });

  describe( 'returned file object .read()', function() {
    it( 'throws if the path does not exist', function() {
      var filepath = path.resolve( __dirname, './fixtures/asdf.json' );
      var file = store( filepath );

      assert.throws( function() {
        file.read();
      });
    });

    it( 'throws if the given filepath is not properly formatted json', function() {
      var filepath = path.resolve( __dirname, './fixtures/incorrect.json' );
      var file = store( filepath );

      assert.throws( function() {
        file.read();
      });
    });

    it( 'returns an object with the proper values', function() {
      var filepath = path.resolve( __dirname, './fixtures/users.json' );
      var file = store( filepath );
      var obj = file.read();

      assert.equal( obj.length, 3 );
      assert.equal( obj[0].id, 1 );
    });
  });

  describe( 'returned file object .write()', function() {
    var filepath = path.resolve( __dirname, './fixtures/temp.json' );

    // Remove the temp file if it exists
    before( function (done) {
      fs.unlink( filepath, function (err) {
        if ( err ) console.error( err );
        done();
      });
    });

    // Clean up temp file
    after( function (done) {
      fs.unlink( filepath, function (err) {
        if ( err ) console.error( err );
        done();
      });
    });

    // Remove the temporary dirs
    after( function(done) {
      var dir = path.resolve( __dirname, './fixtures/a' );

      rimraf( dir, function (err) {
        if ( err ) console.error( err );
        done();
      });
    });

    it( 'returns a promise', function() {
      var file = store( filepath );
      var result = file.write({ "name": "test" });

      assert.equal( typeof result.then, 'function' );
    });

    it( 'creates the file if it did not exist', function( done ) {
      var file = store( filepath );
      var promise = file.write({ "name": "test" });

      promise.then( function() {
        fs.exists( filepath, function( exists ) {
          assert( exists );
          done();
        });
      });
    });

    it( 'creates the directory path if it does not exist', function( done ) {
      var filepath = path.resolve( __dirname, './fixtures/a/b/c/temp.json' );
      var dirname = path.dirname( filepath );
      var file = store( filepath );

      file
        .write({ "name": "user" })
        .then(function () {
          fs.exists( filepath, function (exists) {
            assert( exists );
            done();
          });
        });
    });
  });

  describe( 'returned file object .exists', function() {
    it( 'is true when the filepath exists', function() {
      var filepath = path.resolve( __dirname, './fixtures/asdf.json' );
      var file = store( filepath );

      assert.strictEqual( file.exists, false );
    });

    it( 'is false when the filepath does not exist', function() {
      var filepath = path.resolve( __dirname, './fixtures/users.json' );
      var file = store( filepath );

      assert.strictEqual( file.exists, true );
    });
  });
});<commit_msg>fix test labels<commit_after>var fs = require( 'fs' );
var path = require( 'path' );
var assert = require( 'assert' );
var rimraf = require( 'rimraf' );
var store = require( '../src/file-store' );

describe( 'store(filepath)', function() {

  it( 'returns a file object with read and write methods', function() {
    var filepath = path.resolve( __dirname, './fixtures/users.json' );
    var file = store( filepath );

    assert.equal( typeof file.read, 'function' );
    assert.equal( typeof file.write, 'function' );
  });

  describe( 'returned file object .read()', function() {
    it( 'throws if the path does not exist', function() {
      var filepath = path.resolve( __dirname, './fixtures/asdf.json' );
      var file = store( filepath );

      assert.throws( function() {
        file.read();
      });
    });

    it( 'throws if the given filepath is not properly formatted json', function() {
      var filepath = path.resolve( __dirname, './fixtures/incorrect.json' );
      var file = store( filepath );

      assert.throws( function() {
        file.read();
      });
    });

    it( 'returns an object with the proper values', function() {
      var filepath = path.resolve( __dirname, './fixtures/users.json' );
      var file = store( filepath );
      var obj = file.read();

      assert.equal( obj.length, 3 );
      assert.equal( obj[0].id, 1 );
    });
  });

  describe( 'returned file object .write()', function() {
    var filepath = path.resolve( __dirname, './fixtures/temp.json' );

    // Remove the temp file if it exists
    before( function (done) {
      fs.unlink( filepath, function (err) {
        if ( err ) console.error( err );
        done();
      });
    });

    // Clean up temp file
    after( function (done) {
      fs.unlink( filepath, function (err) {
        if ( err ) console.error( err );
        done();
      });
    });

    // Remove the temporary dirs
    after( function(done) {
      var dir = path.resolve( __dirname, './fixtures/a' );

      rimraf( dir, function (err) {
        if ( err ) console.error( err );
        done();
      });
    });

    it( 'returns a promise', function() {
      var file = store( filepath );
      var result = file.write({ "name": "test" });

      assert.equal( typeof result.then, 'function' );
    });

    it( 'creates the file if it did not exist', function( done ) {
      var file = store( filepath );
      var promise = file.write({ "name": "test" });

      promise.then( function() {
        fs.exists( filepath, function( exists ) {
          assert( exists );
          done();
        });
      });
    });

    it( 'creates the directory path if it does not exist', function( done ) {
      var filepath = path.resolve( __dirname, './fixtures/a/b/c/temp.json' );
      var dirname = path.dirname( filepath );
      var file = store( filepath );

      file
        .write({ "name": "user" })
        .then(function () {
          fs.exists( filepath, function (exists) {
            assert( exists );
            done();
          });
        });
    });
  });

  describe( 'returned file object .exists', function() {
    it( 'is false when the filepath does not exist', function() {
      var filepath = path.resolve( __dirname, './fixtures/asdf.json' );
      var file = store( filepath );

      assert.strictEqual( file.exists, false );
    });

    it( 'is true when the filepath exists', function() {
      var filepath = path.resolve( __dirname, './fixtures/users.json' );
      var file = store( filepath );

      assert.strictEqual( file.exists, true );
    });
  });
});<|endoftext|>


<commit_before>function trapezoid(){
  var ret = {
    processors: {
      GET:[]
    },
    process: function(event){
      var method = event.request.method;
      var path = event.request.url.substr(self.location.href.lastIndexOf("/"));

      var processors = ret.processors[method];

      for(var i = 0 ; i < processors.length; i++){
        var processor = processors[i];
        if( processor.path === path ){
          var init = {
            status: 200,
            statusText: "OK",
            headers: {'Content-Type': 'text/html'}
          };

          var res = {
            send: function(text){
              var response = new Response(text, init);
              event.respondWith(
                response
              );
            }
          }
          processor.fn(event.request,res)
          return;
        }
      }
    },
    get: function(path,fn){
      ret.processors.GET.push({
        path: path,
        fn:fn
      })
    }
  }
  return ret;
}
<commit_msg>adding other methods<commit_after>function trapezoid(){
  var ret = {
    processors: {
      GET:[],
      POST:[],
      PUT:[],
      DELETE:[]
    },
    process: function(event){
      var method = event.request.method;
      var path = event.request.url.substr(self.location.href.lastIndexOf("/"));

      var processors = ret.processors[method];

      for(var i = 0 ; i < processors.length; i++){
        var processor = processors[i];
        if( processor.path === path ){
          var init = {
            status: 200,
            statusText: "OK",
            headers: {'Content-Type': 'text/html'}
          };

          var res = {
            send: function(text){
              var response = new Response(text, init);
              event.respondWith(
                response
              );
            }
          }
          processor.fn(event.request,res)
          return;
        }
      }
    },
    get: function(path,fn){
      ret.processors.GET.push({
        path: path,
        fn:fn
      })
    },
    post: function(path,fn){
      ret.processors.POST.push({
        path: path,
        fn:fn
      })
    },
    put: function(path,fn){
      ret.processors.PUT.push({
        path: path,
        fn:fn
      })
    },
    delete: function(path,fn){
      ret.processors.DELETE.push({
        path: path,
        fn:fn
      })
    }
  }
  return ret;
}
<|endoftext|>


<commit_before>$(document).ready(function init() {
  var canvas = document.getElementById('easel'),
  stage = new createjs.Stage(canvas),
  initial_triangle_size = 400,
  initial_triangle_x = 250,
  initial_triangle_y = 250,
  vertical_ratio = 0.866,
  t1, t2, t3, t4, t5;

  function createTriangle(size, x, y, upside_down) {
    var shape = new createjs.Shape(),
    g = shape.graphics,
    horizontal_offset = size / 2,
    vertical_offset = size * vertical_ratio / 3;

    shape.x = x;
    shape.y = y;
    shape.upside_down = upside_down ? true : false;

    g.setStrokeStyle(1);
    g.beginStroke("black");

    if (shape.upside_down) {
      g.moveTo(0, 2 * vertical_offset);
      g.lineTo(-1 * horizontal_offset, -1 * vertical_offset);
      g.lineTo(horizontal_offset, -1 * vertical_offset);
      g.lineTo(0, 2 * vertical_offset);
    }
    else {
      g.moveTo(0, -2 * vertical_offset);
      g.lineTo(-1 * horizontal_offset, vertical_offset);
      g.lineTo(horizontal_offset, vertical_offset);
      g.lineTo(0, -2 * vertical_offset);
    }
    return shape;
  }

  // t1 setup
  // static triangle that never changes
  stage.addChild(createTriangle(initial_triangle_size, initial_triangle_x, initial_triangle_y));
  t1 = []
  t1.push(createTriangle(initial_triangle_size, initial_triangle_x, initial_triangle_y));

  // t2 setup
  t2 = [];
  var t2_size = initial_triangle_size / 3;
  var t2_height = initial_triangle_size * vertical_ratio / 3;
  // top
  t2.push(createTriangle(t2_size, initial_triangle_x, initial_triangle_y - (t2_height * 4 / 3)));
  // bottom-left
  t2.push(createTriangle(t2_size, initial_triangle_x - t2_size, initial_triangle_y + (t2_height * 2 / 3)));
  // bottom-right
  t2.push(createTriangle(t2_size, initial_triangle_x + t2_size, initial_triangle_y + (t2_height * 2 / 3)));
  // upside-down triangles
  // top-left
  t2.push(createTriangle(t2_size, initial_triangle_x - t2_size, initial_triangle_y - (t2_height * 2 / 3), true));
  // top-right
  t2.push(createTriangle(t2_size, initial_triangle_x + t2_size, initial_triangle_y - (t2_height * 2 / 3), true));
  // bottom
  t2.push(createTriangle(t2_size, initial_triangle_x, initial_triangle_y + (t2_height * 4 / 3), true));

  function remove_from_stage(child) {
    stage.removeChild(child);
  }

  function t1_rotate() {
    $.each(t1, function(k, v) { stage.addChild(v); });
    createjs.Tween.get(t1[0]).to({rotation: 60}, 500)
      .wait(500)
      .call(t2_rotate);
  }
  function t2_rotate() {
    $.each(t2, function(k, v) { stage.addChild(v); });
    $.each(t2, function(k, v) {
      var direction = !v.upside_down ? 1 : -1;
      createjs.Tween.get(v)
        .to({rotation: direction * 60}, 500);
    });
    createjs.Tween.get(t2[0]).wait(1000).call(t2_reset);
  }
  function t2_reset() {
    $.each(t2, function(k, v) {
      createjs.Tween.get(v)
        .to({rotation: 0}, 500)
        .call(remove_from_stage, [v]);
    });
    createjs.Tween.get(t2[0]).wait(1000).call(t1_reset);
  }
  function t1_reset() {
    createjs.Tween.get(t1[0])
      .to({rotation: 0}, 500)
      .wait(1000)
      .call(t1_rotate);
  }

  // start the party
  t1_rotate();
  createjs.Ticker.setFPS(60);
  createjs.Ticker.addEventListener("tick", stage);

})

<commit_msg>Abstract out rotation_speed.<commit_after>$(document).ready(function init() {
  var canvas = document.getElementById('easel'),
  stage = new createjs.Stage(canvas),
  initial_triangle_size = 400,
  initial_triangle_x = 250,
  initial_triangle_y = 250,
  vertical_ratio = 0.866,
  rotation_speed = 400,
  t1, t2, t3, t4, t5;

  function createTriangle(size, x, y, upside_down) {
    var shape = new createjs.Shape(),
    g = shape.graphics,
    horizontal_offset = size / 2,
    vertical_offset = size * vertical_ratio / 3;

    shape.x = x;
    shape.y = y;
    shape.upside_down = upside_down ? true : false;

    g.setStrokeStyle(1);
    g.beginStroke("black");

    if (shape.upside_down) {
      g.moveTo(0, 2 * vertical_offset);
      g.lineTo(-1 * horizontal_offset, -1 * vertical_offset);
      g.lineTo(horizontal_offset, -1 * vertical_offset);
      g.lineTo(0, 2 * vertical_offset);
    }
    else {
      g.moveTo(0, -2 * vertical_offset);
      g.lineTo(-1 * horizontal_offset, vertical_offset);
      g.lineTo(horizontal_offset, vertical_offset);
      g.lineTo(0, -2 * vertical_offset);
    }
    return shape;
  }

  // t1 setup
  // static triangle that never changes
  stage.addChild(createTriangle(initial_triangle_size, initial_triangle_x, initial_triangle_y));
  t1 = []
  t1.push(createTriangle(initial_triangle_size, initial_triangle_x, initial_triangle_y));

  // t2 setup
  t2 = [];
  var t2_size = initial_triangle_size / 3;
  var t2_height = initial_triangle_size * vertical_ratio / 3;
  // top
  t2.push(createTriangle(t2_size, initial_triangle_x, initial_triangle_y - (t2_height * 4 / 3)));
  // bottom-left
  t2.push(createTriangle(t2_size, initial_triangle_x - t2_size, initial_triangle_y + (t2_height * 2 / 3)));
  // bottom-right
  t2.push(createTriangle(t2_size, initial_triangle_x + t2_size, initial_triangle_y + (t2_height * 2 / 3)));
  // upside-down triangles
  // top-left
  t2.push(createTriangle(t2_size, initial_triangle_x - t2_size, initial_triangle_y - (t2_height * 2 / 3), true));
  // top-right
  t2.push(createTriangle(t2_size, initial_triangle_x + t2_size, initial_triangle_y - (t2_height * 2 / 3), true));
  // bottom
  t2.push(createTriangle(t2_size, initial_triangle_x, initial_triangle_y + (t2_height * 4 / 3), true));

  function remove_from_stage(child) {
    stage.removeChild(child);
  }

  function t1_rotate() {
    $.each(t1, function(k, v) { stage.addChild(v); });
    createjs.Tween.get(t1[0]).to({rotation: 60}, rotation_speed)
      .wait(rotation_speed)
      .call(t2_rotate);
  }
  function t2_rotate() {
    $.each(t2, function(k, v) { stage.addChild(v); });
    $.each(t2, function(k, v) {
      var direction = !v.upside_down ? 1 : -1;
      createjs.Tween.get(v)
        .to({rotation: direction * 60}, rotation_speed);
    });
    createjs.Tween.get(t2[0]).wait(rotation_speed * 2).call(t2_reset);
  }
  function t2_reset() {
    $.each(t2, function(k, v) {
      createjs.Tween.get(v)
        .to({rotation: 0}, rotation_speed)
        .call(remove_from_stage, [v]);
    });
    createjs.Tween.get(t2[0]).wait(rotation_speed * 2).call(t1_reset);
  }
  function t1_reset() {
    createjs.Tween.get(t1[0])
      .to({rotation: 0}, rotation_speed)
      .wait(rotation_speed)
      .call(t1_rotate);
  }

  // start the party
  t1_rotate();
  createjs.Ticker.setFPS(60);
  createjs.Ticker.addEventListener("tick", stage);

})

<|endoftext|>


<commit_before>import { expect } from 'chai';
import { resolve, join, relative, basename, dirname } from 'path';
import { readFileSync } from 'fs';
import gulpUtil from 'gulp-util';
import rimraf from 'rimraf';

describe('babel-plugin-css-modules-transform', () => {
    function transform(path, configuration = {}) {
        // remove css modules transform plugin (simulates clean processes)
        delete require.cache[resolve(__dirname, '../src/index.js')];
        const babel = require('babel-core');
        if (configuration && !('devMode' in configuration)) configuration.devMode = true;

        return babel.transformFileSync(resolve(__dirname, path), {
            babelrc: false,
            presets: [['env', { targets: { node: '6.12' } }]],
            plugins: [
                'transform-object-rest-spread',
                ['@babel/../../src/index.js', configuration]
            ]
        });
    }

    function createBabelStream(configuration = {}) {
        // remove css modules transform plugin (simulates clean processes)
        delete require.cache[resolve(__dirname, '../src/index.js')];
        const gulpBabel = require('gulp-babel');
        // set css-modules-require-hook in dev to clear cache
        if (configuration && !('devMode' in configuration)) configuration.devMode = true;

        return gulpBabel({
            presets: [['env', { targets: { node: '6.12' } }]],
            plugins: [
                'transform-object-rest-spread',
                ['@babel/../../src/index.js', configuration]
            ]
        });
    }

    function readExpected(path) {
        let file = path;

        if (process.env.BABEL_7 && /\.js$/.test(file)) {
            // we load fixture for babel 7, they changed few things so we need to use different fixture
            file = join(dirname(file), `./${basename(file, '.js')}.babel7.js`);
        }
        // We trim the contents of the file so that we don't have
        // to deal with newline issues, since some text editors
        // automatically inserts them. It's easier to do this than to
        // configure the editors to avoid inserting newlines for these
        // particular files.
        return readFileSync(resolve(__dirname, file), 'utf8').trim();
    }

    beforeEach((done) => {
        rimraf(`${__dirname}/output/`, done);
    });

    after((done) => {
        rimraf(`${__dirname}/output/`, done);
    });

    it('should ignore files', () => {
        // run this as first case because css-modules-require-hook will be cached with given options
        expect(transform('fixtures/require.js', {
            ignore: /\.css$/
        }).code).to.be.equal(readExpected('fixtures/require.ignored.expected.js'));
    });

    it('should not throw if we are requiring css module to module scope', () => {
        expect(() => transform('fixtures/global.require.js')).to.not.throw();

        expect(() => transform('fixtures/global.import.js')).to.not.throw();
    });

    it('should replace require call with hash of class name => css class name', () => {
        expect(transform('fixtures/require.js').code).to.be.equal(readExpected('fixtures/require.expected.js'));
        expect(transform('fixtures/import.js').code).to.be.equal(readExpected('fixtures/import.expected.js'));
    });

    it('should replace require call with hash of class name => css class name via gulp', (cb) => {
        const stream = createBabelStream({});

        stream.on('data', (file) => {
            expect(file.contents.toString()).to.be.equal(readExpected('fixtures/import.expected.js'));
        });

        stream.on('end', cb);

        stream.write(new gulpUtil.File({
            cwd: __dirname,
            base: join(__dirname, 'fixtures'),
            path: join(__dirname, 'fixtures/import.js'),
            contents: readFileSync(join(__dirname, 'fixtures/import.js'))
        }));

        stream.end();
    });

    it('should accept file extensions as an array', () => {
        expect(
            transform(
                'fixtures/extensions.js',
                {
                    extensions: ['.scss', '.css']
                }
            ).code
        ).to.be.equal(readExpected('fixtures/extensions.expected.js'));
    });

    it('should write a multiple css files using import', () => {
        expect(transform('fixtures/import.js', {
            extractCss: {
                dir: `${__dirname}/output/`,
                filename: '[name].css',
                relativeRoot: `${__dirname}`
            }
        }).code).to.be.equal(readExpected('fixtures/import.expected.js'));

        expect(readExpected(`${__dirname}/output/parent.css`))
            .to.be.equal(readExpected('fixtures/extractcss.parent.expected.css'));
        expect(readExpected(`${__dirname}/output/styles.css`))
            .to.be.equal(readExpected('fixtures/extractcss.styles.expected.css'));
    });

    it('should write a multiple css files using import preserving directory structure', () => {
        expect(transform('fixtures/import.js', {
            extractCss: {
                dir: `${__dirname}/output/`,
                filename: '[path]/[name].css',
                relativeRoot: `${__dirname}`
            }
        }).code).to.be.equal(readExpected('fixtures/import.expected.js'));

        expect(readExpected(`${__dirname}/output/parent.css`))
            .to.be.equal(readExpected('fixtures/extractcss.parent.expected.css'));
        expect(readExpected(`${__dirname}/output/styles.css`))
            .to.be.equal(readExpected('fixtures/extractcss.styles.expected.css'));
        expect(readExpected(`${__dirname}/output/css/child.css`))
            .to.be.equal(readExpected('fixtures/extractcss.css.child.expected.css'));
    });

    it('should write a multiple css files using require', () => {
        expect(transform('fixtures/require.js', {
            extractCss: {
                dir: `${__dirname}/output/`,
                filename: '[name].css',
                relativeRoot: `${__dirname}`
            }
        }).code).to.be.equal(readExpected('fixtures/require.expected.js'));

        expect(readExpected(`${__dirname}/output/parent.css`))
            .to.be.equal(readExpected('fixtures/extractcss.parent.expected.css'));
        expect(readExpected(`${__dirname}/output/styles.css`))
            .to.be.equal(readExpected('fixtures/extractcss.styles.expected.css'));
    });

    it('should write a single css file using import', () => {
        expect(transform('fixtures/import.js', {
            extractCss: `${__dirname}/output/combined.css`
        }).code).to.be.equal(readExpected('fixtures/import.expected.js'));

        expect(readExpected(`${__dirname}/output/combined.css`))
            .to.be.equal(readExpected('fixtures/extractcss.combined.expected.css'));
    });

    it('should write a single css file using require', () => {
        expect(transform('fixtures/require.js', {
            extractCss: `${__dirname}/output/combined.css`
        }).code).to.be.equal(readExpected('fixtures/require.expected.js'));

        expect(readExpected(`${__dirname}/output/combined.css`))
            .to.be.equal(readExpected('fixtures/extractcss.combined.expected.css'));
    });

    it('should extract styles with a single input file via gulp', (cb) => {
        const stream = createBabelStream({
            extractCss: `${__dirname}/output/combined.css`
        });

        stream.on('data', (file) => {
            expect(file.contents.toString()).to.be.equal(readExpected('fixtures/exctractcss.main.expected.js'));
        });

        stream.on('end', (err) => {
            if (err) return cb(err);
            expect(readExpected(`${__dirname}/output/combined.css`))
                .to.be.equal(readExpected('fixtures/extractcss.parent-combined.expected.css'));

            return cb();
        });

        stream.write(new gulpUtil.File({
            cwd: __dirname,
            base: join(__dirname, 'fixtures'),
            path: join(__dirname, 'fixtures/exctractcss.main.js'),
            contents: readFileSync(join(__dirname, 'fixtures/exctractcss.main.js'))
        }));

        stream.end();
    });

    it('should extract multiple files via gulp', (cb) => {
        const stream = createBabelStream({
            extractCss: {
                dir: `${__dirname}/output/`,
                filename: '[name].css',
                relativeRoot: `${__dirname}`
            }
        });

        // it seems that a data function is required
        stream.on('data', () => {});

        stream.on('end', (err) => {
            if (err) return cb(err);

            expect(readExpected(`${__dirname}/output/parent.css`))
                .to.be.equal(readExpected('fixtures/extractcss.parent.expected.css'));
            expect(readExpected(`${__dirname}/output/styles.css`))
                .to.be.equal(readExpected('fixtures/extractcss.styles.expected.css'));

            return cb();
        });

        stream.write(new gulpUtil.File({
            cwd: __dirname,
            base: join(__dirname, 'fixtures'),
            path: join(__dirname, 'fixtures/exctractcss.main.js'),
            contents: readFileSync(join(__dirname, 'fixtures/exctractcss.main.js'))
        }));

        stream.write(new gulpUtil.File({
            cwd: __dirname,
            base: join(__dirname, 'fixtures'),
            path: join(__dirname, 'fixtures/exctractcss.include.js'),
            contents: readFileSync(join(__dirname, 'fixtures/exctractcss.include.js'))
        }));

        stream.end();
    });

    it('should extract combined files via gulp', (cb) => {
        const stream = createBabelStream({
            extractCss: `${__dirname}/output/combined.css`
        });

        // it seems that a data function is required
        stream.on('data', () => {});

        stream.on('end', (err) => {
            if (err) return cb(err);

            expect(readExpected(`${__dirname}/output/combined.css`))
                .to.be.equal(readExpected('fixtures/extractcss.combined.expected.css'));
            return cb();
        });

        stream.write(new gulpUtil.File({
            cwd: __dirname,
            base: join(__dirname, 'fixtures'),
            path: join(__dirname, 'fixtures/exctractcss.main.js'),
            contents: readFileSync(join(__dirname, 'fixtures/exctractcss.main.js'))
        }));

        stream.write(new gulpUtil.File({
            cwd: __dirname,
            base: join(__dirname, 'fixtures'),
            path: join(__dirname, 'fixtures/exctractcss.include.js'),
            contents: readFileSync(join(__dirname, 'fixtures/exctractcss.include.js'))
        }));

        stream.end();
    });

    it('should call custom preprocess', () => {
        const called = [];
        expect(transform('fixtures/require.js', {
            extractCss: `${__dirname}/output/combined.css`,
            processCss(css, filename) {
                called.push(relative(__dirname, filename));
                return css;
            }
        }).code).to.be.equal(readExpected('fixtures/require.expected.js'));
        expect(called).to.be.deep.equal([
            'css/child.css',
            'parent.css',
            'styles.css'
        ]);
    });

    describe('keepImport option', () => {
        it('keeps requires/imports', () => {
            expect(transform('fixtures/keepImport.js', {
                keepImport: true,
                extensions: ['.scss', '.css']
            }).code).to.be.equal(readExpected('fixtures/keepImport.expected.js'));
        });
    });

    describe('calling without options', () => {
        it('keeps requires/imports', () => {
            delete require.cache[resolve(__dirname, '../src/index.js')];
            const babel = require('babel-core');
            const result = babel.transformFileSync(resolve(__dirname, 'fixtures/import.js'), {
                babelrc: false,
                presets: [['env', { targets: { node: '6.12'} }]],
                plugins: [
                    'transform-object-rest-spread',
                    '@babel/../../src/index.js'
                ]
            });

            expect(result.code).to.be.equal(
                readExpected('fixtures/import.expected.js')
            );
        });
    });
});
<commit_msg>feat: update test cases<commit_after>import { expect } from 'chai';
import { resolve, join, relative, basename, dirname } from 'path';
import { readFileSync } from 'fs';
import gulpUtil from 'gulp-util';
import rimraf from 'rimraf';

describe('babel-plugin-css-modules-transform', () => {
    function transform(path, configuration = {}) {
        // remove css modules transform plugin (simulates clean processes)
        delete require.cache[resolve(__dirname, '../src/index.js')];
        const babel = require('babel-core');
        if (configuration && !('devMode' in configuration)) configuration.devMode = true;

        return babel.transformFileSync(resolve(__dirname, path), {
            babelrc: false,
            presets: [['env', { targets: { node: '6.12' } }]],
            plugins: [
                'transform-object-rest-spread',
                ['@babel/../../src/index.js', configuration]
            ]
        });
    }

    function createBabelStream(configuration = {}) {
        // remove css modules transform plugin (simulates clean processes)
        delete require.cache[resolve(__dirname, '../src/index.js')];
        const gulpBabel = require('gulp-babel');
        // set css-modules-require-hook in dev to clear cache
        if (configuration && !('devMode' in configuration)) configuration.devMode = true;

        return gulpBabel({
            presets: [['env', { targets: { node: '6.12' } }]],
            plugins: [
                'transform-object-rest-spread',
                ['@babel/../../src/index.js', configuration]
            ]
        });
    }

    function readExpected(path) {
        let file = path;

        if (process.env.BABEL_7 && /\.js$/.test(file)) {
            // we load fixture for babel 7, they changed few things so we need to use different fixture
            file = join(dirname(file), `./${basename(file, '.js')}.babel7.js`);
        }
        // We trim the contents of the file so that we don't have
        // to deal with newline issues, since some text editors
        // automatically inserts them. It's easier to do this than to
        // configure the editors to avoid inserting newlines for these
        // particular files.
        return readFileSync(resolve(__dirname, file), 'utf8').trim();
    }

    beforeEach((done) => {
        rimraf(`${__dirname}/output/`, done);
    });

    after((done) => {
        rimraf(`${__dirname}/output/`, done);
    });

    it('should ignore files', () => {
        // run this as first case because css-modules-require-hook will be cached with given options
        expect(transform('fixtures/require.js', {
            ignore: /\.css$/
        }).code).to.be.equal(readExpected('fixtures/require.ignored.expected.js'));
    });

    it('should not throw if we are requiring css module to module scope', () => {
        expect(() => transform('fixtures/global.require.js')).to.not.throw();

        expect(() => transform('fixtures/global.import.js')).to.not.throw();
    });

    it('should replace require call with hash of class name => css class name', () => {
        expect(transform('fixtures/require.js').code).to.be.equal(readExpected('fixtures/require.expected.js'));
        expect(transform('fixtures/import.js').code).to.be.equal(readExpected('fixtures/import.expected.js'));
    });

    it('should replace require call with hash of class name => css class name via gulp', (cb) => {
        const stream = createBabelStream({});

        stream.on('data', (file) => {
            expect(file.contents.toString()).to.be.equal(readExpected('fixtures/import.expected.js'));
        });

        stream.on('end', cb);

        stream.write(new gulpUtil.File({
            cwd: __dirname,
            base: join(__dirname, 'fixtures'),
            path: join(__dirname, 'fixtures/import.js'),
            contents: readFileSync(join(__dirname, 'fixtures/import.js'))
        }));

        stream.end();
    });

    it('should accept file extensions as an array', () => {
        expect(
            transform(
                'fixtures/extensions.js',
                {
                    extensions: ['.scss', '.css']
                }
            ).code
        ).to.be.equal(readExpected('fixtures/extensions.expected.js'));
    });

    it('should write a multiple css files using import', () => {
        expect(transform(`${__dirname}/fixtures/import.js`, {
            extractCss: {
                dir: `${__dirname}/output/`,
                filename: '[path]/[name].css',
                relativeRoot: __dirname
            },
            extensions: ['.scss', '.css']
        }).code).to.be.equal(readExpected('fixtures/import.expected.js'));

        expect(readExpected(`${__dirname}/output/parent.css`))
            .to.be.equal(readExpected('fixtures/extractcss.parent.expected.css'));
        expect(readExpected(`${__dirname}/output/styles.css`))
            .to.be.equal(readExpected('fixtures/extractcss.styles.expected.css'));
    });

    it('should write a multiple css files using import preserving directory structure', () => {
        expect(transform('fixtures/import.js', {
            extractCss: {
                dir: `${__dirname}/output/`,
                filename: '[path]/[name].css',
                relativeRoot: `${__dirname}`
            }
        }).code).to.be.equal(readExpected('fixtures/import.expected.js'));

        expect(readExpected(`${__dirname}/output/parent.css`))
            .to.be.equal(readExpected('fixtures/extractcss.parent.expected.css'));
        expect(readExpected(`${__dirname}/output/styles.css`))
            .to.be.equal(readExpected('fixtures/extractcss.styles.expected.css'));
        expect(readExpected(`${__dirname}/output/css/child.css`))
            .to.be.equal(readExpected('fixtures/extractcss.css.child.expected.css'));
    });

    it('should write a multiple css files using require', () => {
        expect(transform('fixtures/require.js', {
            extractCss: {
                dir: `${__dirname}/output/`,
                filename: '[name].css',
                relativeRoot: `${__dirname}`
            }
        }).code).to.be.equal(readExpected('fixtures/require.expected.js'));

        expect(readExpected(`${__dirname}/output/parent.css`))
            .to.be.equal(readExpected('fixtures/extractcss.parent.expected.css'));
        expect(readExpected(`${__dirname}/output/styles.css`))
            .to.be.equal(readExpected('fixtures/extractcss.styles.expected.css'));
    });

    it('should write a single css file using import', () => {
        expect(transform('fixtures/import.js', {
            extractCss: `${__dirname}/output/combined.css`
        }).code).to.be.equal(readExpected('fixtures/import.expected.js'));

        expect(readExpected(`${__dirname}/output/combined.css`))
            .to.be.equal(readExpected('fixtures/extractcss.combined.expected.css'));
    });

    it('should write a single css file using require', () => {
        expect(transform('fixtures/require.js', {
            extractCss: `${__dirname}/output/combined.css`
        }).code).to.be.equal(readExpected('fixtures/require.expected.js'));

        expect(readExpected(`${__dirname}/output/combined.css`))
            .to.be.equal(readExpected('fixtures/extractcss.combined.expected.css'));
    });

    it('should extract styles with a single input file via gulp', (cb) => {
        const stream = createBabelStream({
            extractCss: `${__dirname}/output/combined.css`
        });

        stream.on('data', (file) => {
            expect(file.contents.toString()).to.be.equal(readExpected('fixtures/exctractcss.main.expected.js'));
        });

        stream.on('end', (err) => {
            if (err) return cb(err);
            expect(readExpected(`${__dirname}/output/combined.css`))
                .to.be.equal(readExpected('fixtures/extractcss.parent-combined.expected.css'));

            return cb();
        });

        stream.write(new gulpUtil.File({
            cwd: __dirname,
            base: join(__dirname, 'fixtures'),
            path: join(__dirname, 'fixtures/exctractcss.main.js'),
            contents: readFileSync(join(__dirname, 'fixtures/exctractcss.main.js'))
        }));

        stream.end();
    });

    it('should extract multiple files via gulp', (cb) => {
        const stream = createBabelStream({
            extractCss: {
                dir: `${__dirname}/output/`,
                filename: '[name].css',
                relativeRoot: `${__dirname}`
            }
        });

        // it seems that a data function is required
        stream.on('data', () => {});

        stream.on('end', (err) => {
            if (err) return cb(err);

            expect(readExpected(`${__dirname}/output/parent.css`))
                .to.be.equal(readExpected('fixtures/extractcss.parent.expected.css'));
            expect(readExpected(`${__dirname}/output/styles.css`))
                .to.be.equal(readExpected('fixtures/extractcss.styles.expected.css'));

            return cb();
        });

        stream.write(new gulpUtil.File({
            cwd: __dirname,
            base: join(__dirname, 'fixtures'),
            path: join(__dirname, 'fixtures/exctractcss.main.js'),
            contents: readFileSync(join(__dirname, 'fixtures/exctractcss.main.js'))
        }));

        stream.write(new gulpUtil.File({
            cwd: __dirname,
            base: join(__dirname, 'fixtures'),
            path: join(__dirname, 'fixtures/exctractcss.include.js'),
            contents: readFileSync(join(__dirname, 'fixtures/exctractcss.include.js'))
        }));

        stream.end();
    });

    it('should extract combined files via gulp', (cb) => {
        const stream = createBabelStream({
            extractCss: `${__dirname}/output/combined.css`
        });

        // it seems that a data function is required
        stream.on('data', () => {});

        stream.on('end', (err) => {
            if (err) return cb(err);

            expect(readExpected(`${__dirname}/output/combined.css`))
                .to.be.equal(readExpected('fixtures/extractcss.combined.expected.css'));
            return cb();
        });

        stream.write(new gulpUtil.File({
            cwd: __dirname,
            base: join(__dirname, 'fixtures'),
            path: join(__dirname, 'fixtures/exctractcss.main.js'),
            contents: readFileSync(join(__dirname, 'fixtures/exctractcss.main.js'))
        }));

        stream.write(new gulpUtil.File({
            cwd: __dirname,
            base: join(__dirname, 'fixtures'),
            path: join(__dirname, 'fixtures/exctractcss.include.js'),
            contents: readFileSync(join(__dirname, 'fixtures/exctractcss.include.js'))
        }));

        stream.end();
    });

    it('should call custom preprocess', () => {
        const called = [];
        expect(transform('fixtures/require.js', {
            extractCss: `${__dirname}/output/combined.css`,
            processCss(css, filename) {
                called.push(relative(__dirname, filename));
                return css;
            }
        }).code).to.be.equal(readExpected('fixtures/require.expected.js'));
        expect(called).to.be.deep.equal([
            'css/child.css',
            'parent.css',
            'styles.css'
        ]);
    });

    describe('keepImport option', () => {
        it('keeps requires/imports', () => {
            expect(transform('fixtures/keepImport.js', {
                keepImport: true,
                extensions: ['.scss', '.css']
            }).code).to.be.equal(readExpected('fixtures/keepImport.expected.js'));
        });
    });

    describe('calling without options', () => {
        it('keeps requires/imports', () => {
            delete require.cache[resolve(__dirname, '../src/index.js')];
            const babel = require('babel-core');
            const result = babel.transformFileSync(resolve(__dirname, 'fixtures/import.js'), {
                babelrc: false,
                presets: [['env', { targets: { node: '6.12'} }]],
                plugins: [
                    'transform-object-rest-spread',
                    '@babel/../../src/index.js'
                ]
            });

            expect(result.code).to.be.equal(
                readExpected('fixtures/import.expected.js')
            );
        });
    });
});
<|endoftext|>


<commit_before>var fs = require('fs');
var path = require('path');
var expect = require('unexpected')
    .clone()
    .installPlugin(require('../index'));

describe('unexpected-fs', function () {
    describe('with fs mocked out', function () {
        var fileContent = function (fileName) {
            return fs.readFileSync('/data/' + fileName, 'utf-8');
        };

        it('should not throw', function () {
            return expect('foobar.txt', 'with fs mocked out', {
                '/data/': {
                    '/foobar.txt': 'Foobar!'
                }
            }, 'when passed as parameter to', fileContent, 'to equal', 'Foobar!');
        });

        it('should mount a directory on /data even if the trailing / is missing', function () {
            return expect('foobar.txt', 'with fs mocked out', {
                '/data': {
                    '/foobar.txt': 'Foobar!'
                }
            }, 'when passed as parameter to', fileContent, 'to equal', 'Foobar!');
        });

        it('should consider relative paths on first level in mock fs to be relative to the mountPath', function () {
            return expect('foobar.txt', 'with fs mocked out', {
                '/data': {
                    'foobar.txt': 'Foobar!'
                }
            }, 'when passed as parameter to', fileContent, 'to equal', 'Foobar!');
        });

        describe('mock.file proxy', function () {
            it('should realise that an object is a file', function () {
                return expect('/foo.txt', 'with fs mocked out', {
                    '/': {
                        '/foo.txt': {
                            _isFile: true,
                            ctime: new Date(1),
                            content: 'foobar!'
                        }
                    }
                }, 'to be a text file satisfying', {
                    content: 'foobar!',
                    ctime: new Date(1),
                    isFile: true
                });
            });
        });
        describe('mock.symlink proxy', function () {
            it('should realise that an object is a symlink', function () {
                return expect(function () {
                    return expect.promise(function (run) {
                        fs.readFile('/bar.txt', 'utf-8', run(function (err, data) {
                            expect(data, 'to satisfy', 'Foobar!');
                        }));
                    });
                }, 'with fs mocked out', {
                    '/': {
                        'foo.txt': 'Foobar!',
                        'bar.txt': {
                            _isSymlink: true,
                            path: 'foo.txt'
                        }
                    }
                }, 'not to error');
            });
        });
        it('should allow reading files on the normal fs', function () {
            return expect(function () {
                var packageJsonPath = path.resolve(__dirname, '..', 'package.json');
                fs.readFileSync(packageJsonPath, 'utf-8');
            }, 'with fs mocked out', {}, 'not to throw');
        });
        it('should allow reading files on different mounted mock fs', function () {
            var mockFs = {};
            mockFs[path.resolve(__dirname, 'wtf') + '/'] = {
                '/FUNNYSTORY.md': 'lol, just kidding.'
            };
            mockFs[path.resolve(__dirname, 'lol') + '/'] = {
                '/SADSTORY.md': 'wtf, just kidding?'
            };
            return expect(function () {
                var funnyStoryPath = path.resolve(__dirname, 'wtf', 'FUNNYSTORY.md');
                var funnyStory = fs.readFileSync(funnyStoryPath, 'utf-8');
                expect(funnyStory, 'to equal', 'lol, just kidding.');
                var sadStoryPath = path.resolve(__dirname, 'lol', 'SADSTORY.md');
                var sadStory = fs.readFileSync(sadStoryPath, 'utf-8');
                expect(sadStory, 'to equal', 'wtf, just kidding?');
            }, 'with fs mocked out', mockFs, 'not to throw');
        });
        it('should allow reading both files on the real fs and the mocked out one', function () {
            var mockFs = {};
            mockFs[path.resolve(__dirname, 'wtf') + '/'] = {
                '/FUNNYSTORY.md': 'lol, just kidding.'
            };
            mockFs[path.resolve(__dirname, 'lol') + '/'] = {
                '/SADSTORY.md': 'wtf, just kidding?'
            };
            return expect(function () {
                var packageJsonPath = path.resolve(__dirname, '..', 'package.json');
                var packageJson = fs.readFileSync(packageJsonPath, 'utf-8');
                expect(packageJson, 'to match', /^{\s+"name":\s"unexpected-fs",/);
                var funnyStoryPath = path.resolve(__dirname, 'wtf', 'FUNNYSTORY.md');
                var funnyStory = fs.readFileSync(funnyStoryPath, 'utf-8');
                expect(funnyStory, 'to equal', 'lol, just kidding.');
                var sadStoryPath = path.resolve(__dirname, 'lol', 'SADSTORY.md');
                var sadStory = fs.readFileSync(sadStoryPath, 'utf-8');
                expect(sadStory, 'to equal', 'wtf, just kidding?');
            }, 'with fs mocked out', mockFs, 'not to throw');
        });
    });
    describe('does it update already exisitng fs modules?', function () {
        it('huh?', function () {
            var someMethod = function (fileName) {
                return fs.readFileSync('/' + fileName, 'utf-8');
            };

            return expect('doesIt.txt', 'with fs mocked out', {
                '/': {
                    '/doesIt.txt': 'Yes it does!'
                }
            }, 'when passed as parameter to', someMethod, 'to equal', 'Yes it does!');
        });
    });

    it('should unpatch fs even when the subsequent assertion fails', function () {
        expect(function () {
            return expect('/highlyUnlikely/foobar.txt', 'with fs mocked out', { '/highlyUnlikely': { 'foobar.txt': 'hey'} }, 'when passed as parameter to', function (fileName) {
                return fs.readFileSync(fileName, 'utf-8');
            }, 'to equal', 'goodbye');
        }, 'to throw',
            "expected '/highlyUnlikely/foobar.txt' when passed as parameter to\n" +
            "function (fileName) {\n" +
            "  return fs.readFileSync(fileName, 'utf-8');\n" +
            "} to equal 'goodbye'\n" +
            "  expected 'hey' to equal 'goodbye'\n" +
            "\n" +
            "  -hey\n" +
            "  +goodbye"
        );
        expect(function () {
            fs.readFileSync('/highlyUnlikely/foobar.txt');
        }, 'to throw', /ENOENT(,|:) no such file or directory(, open)? '\/highlyUnlikely\/foobar.txt'/);
    });

    describe('to be an existing path', function () {
        var existingPath = path.resolve(__dirname, '..', 'test', 'a-path-created-for-testing');

        before(function () {
            fs.mkdirSync(existingPath);
        });

        after(function () {
            fs.rmdirSync(existingPath);
        });

        it('should reject the promise if a path does not exist on disk', function () {
            expect.output.preferredWidth = 80;
            return expect(expect('/i/am/certain/this/path/is/highly/unlikely/to/exist', 'to be an existing path'),
                'to be rejected with', 'expected \'/i/am/certain/this/path/is/highly/unlikely/to/exist\'\nto be an existing path');
        });

        it('should fulfil the promise if a path does exist on disk', function () {
            return expect(expect(existingPath, 'to be an existing path'), 'to be fulfilled');
        });
    });

    describe('not to be an existing path', function () {
        var existingPath = path.resolve(__dirname, '..', 'test', 'a-path-created-for-testing');

        before(function () {
            fs.mkdirSync(existingPath);
        });

        after(function () {
            fs.rmdirSync(existingPath);
        });

        it('should fulfil the promise if a path does not exist on disk', function () {
            return expect(expect('/i/am/certain/this/path/is/highly/unlikely/to/exist', 'not to be an existing path'), 'to be fulfilled');
        });

        it('should reject the promise if a path does exist on disk', function () {
            expect.output.preferredWidth = 80;
            return expect(expect(existingPath, 'not to be an existing path'),
                'to be rejected with', 'expected \'' + existingPath + '\'\nnot to be an existing path');
        });
    });
});
<commit_msg>add failing test for readdir<commit_after>var fs = require('fs');
var path = require('path');
var expect = require('unexpected')
    .clone()
    .installPlugin(require('../index'));

describe('unexpected-fs', function () {
    describe('with fs mocked out', function () {
        var fileContent = function (fileName) {
            return fs.readFileSync('/data/' + fileName, 'utf-8');
        };

        it('should not throw', function () {
            return expect('foobar.txt', 'with fs mocked out', {
                '/data/': {
                    '/foobar.txt': 'Foobar!'
                }
            }, 'when passed as parameter to', fileContent, 'to equal', 'Foobar!');
        });

        it('should mount a directory on /data even if the trailing / is missing', function () {
            return expect('foobar.txt', 'with fs mocked out', {
                '/data': {
                    '/foobar.txt': 'Foobar!'
                }
            }, 'when passed as parameter to', fileContent, 'to equal', 'Foobar!');
        });

        it('should consider relative paths on first level in mock fs to be relative to the mountPath', function () {
            return expect('foobar.txt', 'with fs mocked out', {
                '/data': {
                    'foobar.txt': 'Foobar!'
                }
            }, 'when passed as parameter to', fileContent, 'to equal', 'Foobar!');
        });

        describe('mock.file proxy', function () {
            it('should realise that an object is a file', function () {
                return expect('/foo.txt', 'with fs mocked out', {
                    '/': {
                        '/foo.txt': {
                            _isFile: true,
                            ctime: new Date(1),
                            content: 'foobar!'
                        }
                    }
                }, 'to be a text file satisfying', {
                    content: 'foobar!',
                    ctime: new Date(1),
                    isFile: true
                });
            });
        });
        describe('mock.symlink proxy', function () {
            it('should realise that an object is a symlink', function () {
                return expect(function () {
                    return expect.promise(function (run) {
                        fs.readFile('/bar.txt', 'utf-8', run(function (err, data) {
                            expect(data, 'to satisfy', 'Foobar!');
                        }));
                    });
                }, 'with fs mocked out', {
                    '/': {
                        'foo.txt': 'Foobar!',
                        'bar.txt': {
                            _isSymlink: true,
                            path: 'foo.txt'
                        }
                    }
                }, 'not to error');
            });
        });
        it('should allow reading files on the normal fs', function () {
            return expect(function () {
                var packageJsonPath = path.resolve(__dirname, '..', 'package.json');
                fs.readFileSync(packageJsonPath, 'utf-8');
            }, 'with fs mocked out', {}, 'not to throw');
        });
        it('should allow reading files on different mounted mock fs', function () {
            var mockFs = {};
            mockFs[path.resolve(__dirname, 'wtf') + '/'] = {
                '/FUNNYSTORY.md': 'lol, just kidding.'
            };
            mockFs[path.resolve(__dirname, 'lol') + '/'] = {
                '/SADSTORY.md': 'wtf, just kidding?'
            };
            return expect(function () {
                var funnyStoryPath = path.resolve(__dirname, 'wtf', 'FUNNYSTORY.md');
                var funnyStory = fs.readFileSync(funnyStoryPath, 'utf-8');
                expect(funnyStory, 'to equal', 'lol, just kidding.');
                var sadStoryPath = path.resolve(__dirname, 'lol', 'SADSTORY.md');
                var sadStory = fs.readFileSync(sadStoryPath, 'utf-8');
                expect(sadStory, 'to equal', 'wtf, just kidding?');
            }, 'with fs mocked out', mockFs, 'not to throw');
        });
        it('should allow reading both files on the real fs and the mocked out one', function () {
            var mockFs = {};
            mockFs[path.resolve(__dirname, 'wtf') + '/'] = {
                '/FUNNYSTORY.md': 'lol, just kidding.'
            };
            mockFs[path.resolve(__dirname, 'lol') + '/'] = {
                '/SADSTORY.md': 'wtf, just kidding?'
            };
            return expect(function () {
                var packageJsonPath = path.resolve(__dirname, '..', 'package.json');
                var packageJson = fs.readFileSync(packageJsonPath, 'utf-8');
                expect(packageJson, 'to match', /^{\s+"name":\s"unexpected-fs",/);
                var funnyStoryPath = path.resolve(__dirname, 'wtf', 'FUNNYSTORY.md');
                var funnyStory = fs.readFileSync(funnyStoryPath, 'utf-8');
                expect(funnyStory, 'to equal', 'lol, just kidding.');
                var sadStoryPath = path.resolve(__dirname, 'lol', 'SADSTORY.md');
                var sadStory = fs.readFileSync(sadStoryPath, 'utf-8');
                expect(sadStory, 'to equal', 'wtf, just kidding?');
            }, 'with fs mocked out', mockFs, 'not to throw');
        });
    });

    describe('fs.readdir', function () {
        it('should list only the files specified in mocked fs', function () {
            return expect(function (cb) {
                fs.readdir('/fixtures/', cb);
            }, 'with fs mocked out', {
                '/fixtures': {
                    'foo.txt': 'foobar'
                }
            }, 'to call the callback without error').then(function (files) {
                return expect(files, 'to satisfy', [
                    'foo.txt'
                ]);
            });
        });
    });

    describe('does it update already exisitng fs modules?', function () {
        it('huh?', function () {
            var someMethod = function (fileName) {
                return fs.readFileSync('/' + fileName, 'utf-8');
            };

            return expect('doesIt.txt', 'with fs mocked out', {
                '/': {
                    '/doesIt.txt': 'Yes it does!'
                }
            }, 'when passed as parameter to', someMethod, 'to equal', 'Yes it does!');
        });
    });

    it('should unpatch fs even when the subsequent assertion fails', function () {
        expect(function () {
            return expect('/highlyUnlikely/foobar.txt', 'with fs mocked out', { '/highlyUnlikely': { 'foobar.txt': 'hey'} }, 'when passed as parameter to', function (fileName) {
                return fs.readFileSync(fileName, 'utf-8');
            }, 'to equal', 'goodbye');
        }, 'to throw',
            "expected '/highlyUnlikely/foobar.txt' when passed as parameter to\n" +
            "function (fileName) {\n" +
            "  return fs.readFileSync(fileName, 'utf-8');\n" +
            "} to equal 'goodbye'\n" +
            "  expected 'hey' to equal 'goodbye'\n" +
            "\n" +
            "  -hey\n" +
            "  +goodbye"
        );
        expect(function () {
            fs.readFileSync('/highlyUnlikely/foobar.txt');
        }, 'to throw', /ENOENT(,|:) no such file or directory(, open)? '\/highlyUnlikely\/foobar.txt'/);
    });

    describe('to be an existing path', function () {
        var existingPath = path.resolve(__dirname, '..', 'test', 'a-path-created-for-testing');

        before(function () {
            fs.mkdirSync(existingPath);
        });

        after(function () {
            fs.rmdirSync(existingPath);
        });

        it('should reject the promise if a path does not exist on disk', function () {
            expect.output.preferredWidth = 80;
            return expect(expect('/i/am/certain/this/path/is/highly/unlikely/to/exist', 'to be an existing path'),
                'to be rejected with', 'expected \'/i/am/certain/this/path/is/highly/unlikely/to/exist\'\nto be an existing path');
        });

        it('should fulfil the promise if a path does exist on disk', function () {
            return expect(expect(existingPath, 'to be an existing path'), 'to be fulfilled');
        });
    });

    describe('not to be an existing path', function () {
        var existingPath = path.resolve(__dirname, '..', 'test', 'a-path-created-for-testing');

        before(function () {
            fs.mkdirSync(existingPath);
        });

        after(function () {
            fs.rmdirSync(existingPath);
        });

        it('should fulfil the promise if a path does not exist on disk', function () {
            return expect(expect('/i/am/certain/this/path/is/highly/unlikely/to/exist', 'not to be an existing path'), 'to be fulfilled');
        });

        it('should reject the promise if a path does exist on disk', function () {
            expect.output.preferredWidth = 80;
            return expect(expect(existingPath, 'not to be an existing path'),
                'to be rejected with', 'expected \'' + existingPath + '\'\nnot to be an existing path');
        });
    });
});
<|endoftext|>