<commit_before>import {List, Map, fromJS} from 'immutable';
import {expect} from 'chai';
import {assert} from 'chai';
import diff from 'immutablediff';

import StateWrapper, {initialState} from '../src/StateWrapper.js';

const ActionObjects = {
	screen100: {
		xid: 100,
		width: 800,
		height: 600,
	}
};

/*[{
	actions: b => {
		const d1 = b.addDesktop({});
		return {d1}
	},
	asserts: x => {
		'widgetIdNext': x.d1 + 1],
		'screenIdOrder': [],
		'desktopIdOrder': [d1],
		'windowIdOrder': [],
		'widgetIdChain': [d1],
		'currentScreenId': -1,
		'currentDesktopId': -1,
		'currentWindowId': -1
	],
	children: [{
		actions: b => {

		}
	}]
}];*/

describe('StateWrapper', () => {
	it('empty', () => {
		const builder = new StateWrapper(initialState);
		expect(builder.getState()).to.equal(initialState);
	});

	it('addDesktop', () => {
		const builder = new StateWrapper(initialState);
		const d1 = builder.addDesktop({});

		expect(builder.widgetIdNext, 'widgetIdNext').to.equal(d1 + 1);
		expect(builder.getScreenIdOrder(), 'screen order').to.equal(List([]));
		expect(builder.getDesktopIdOrder(), 'desktop order').to.equal(List([d1]));
		expect(builder.getWindowIdOrder(), 'window order').to.equal(List([]));
		expect(builder.getWidgetIdChain(), 'widget chain').to.equal(List([d1]));
		expect(builder.currentScreenId, 'current screen').to.equal(-1);
		expect(builder.currentDesktopId, 'current desktop').to.equal(-1);
		expect(builder.currentWindowId, 'current window').to.equal(-1);
	});

	it('addDesktop*2', () => {
		const builder = new StateWrapper(initialState);
		const d1 = builder.addDesktop({});
		const d2 = builder.addDesktop({});

		expect(builder.widgetIdNext, 'widgetIdNext').to.equal(d2 + 1);
		expect(builder.getScreenIdOrder(), 'screen order').to.equal(List());
		expect(builder.getDesktopIdOrder(), 'desktop order').to.equal(List.of(d1, d2));
		expect(builder.getWindowIdOrder(), 'window order').to.equal(List());
		expect(builder.getWidgetIdChain(), 'widget chain').to.equal(List.of(d1, d2));
		expect(builder.currentScreenId, 'current screen').to.equal(-1);
		expect(builder.currentDesktopId, 'current desktop').to.equal(-1);
		expect(builder.currentWindowId, 'current window').to.equal(-1);
	});

	it('addScreen: should create a desktop and set it as current', () => {
		const builder = new StateWrapper(initialState);
		const s1 = builder.addScreen(ActionObjects.screen100);
		const d1 = s1 - 1;

		expect(builder.widgetIdNext, 'widgetIdNext').to.equal(s1 + 1);
		expect(builder.getScreenIdOrder(), 'screen order').to.equal(List([s1]));
		expect(builder.getDesktopIdOrder(), 'desktop order').to.equal(List([d1]));
		expect(builder.getWindowIdOrder(), 'window order').to.equal(List());
		expect(builder.getWidgetIdChain(), 'widget chain').to.equal(List([d1, s1]));
		expect(builder.currentScreenId, 'current screen').to.equal(s1);
		expect(builder.currentDesktopId, 'current desktop').to.equal(d1);
		expect(builder.currentWindowId, 'current window').to.equal(-1);
	});

	it('addDesktop, addScreen: should assign the desktop to the new screen and focus it', () => {
		const builder = new StateWrapper(initialState);
		const d1 = builder.addDesktop({});
		const s1 = builder.addScreen(ActionObjects.screen100);

		expect(builder.widgetIdNext, 'widgetIdNext').to.equal(s1 + 1);
		expect(builder.getScreenIdOrder(), 'screen order').to.equal(List([s1]));
		expect(builder.getDesktopIdOrder(), 'desktop order').to.equal(List([d1]));
		expect(builder.getWindowIdOrder(), 'window order').to.equal(List());
		expect(builder.getWidgetIdChain(), 'widget chain').to.equal(List([d1, s1]));
		expect(builder.currentScreenId, 'current screen').to.equal(s1);
		expect(builder.currentDesktopId, 'current desktop').to.equal(d1);
		expect(builder.currentWindowId, 'current window').to.equal(-1);
	});

	it('addDesktop*2, addScreen', () => {
		const builder = new StateWrapper(initialState);
		const d1 = builder.addDesktop({});
		const d2 = builder.addDesktop({});
		const s1 = builder.addScreen(ActionObjects.screen100);

		expect(builder.widgetIdNext, 'widgetIdNext').to.equal(s1 + 1);
		expect(builder.getScreenIdOrder(), 'screen order').to.equal(List([s1]));
		expect(builder.getDesktopIdOrder(), 'desktop order').to.equal(List([d1, d2]));
		expect(builder.getWindowIdOrder(), 'window order').to.equal(List());
		expect(builder.getWidgetIdChain(), 'widget chain').to.equal(List([d1, s1, d2]));
		expect(builder.currentScreenId, 'current screen').to.equal(s1);
		expect(builder.currentDesktopId, 'current desktop').to.equal(d1);
		expect(builder.currentWindowId, 'current window').to.equal(-1);
	});

	it('addWindow', () => {
		const builder = new StateWrapper(initialState);
		const w1 = builder.addWindow({xid: 1000});

		expect(builder.widgetIdNext, 'widgetIdNext').to.equal(w1 + 1);
		expect(builder.getScreenIdOrder(), 'screen order').to.equal(List([]));
		expect(builder.getDesktopIdOrder(), 'desktop order').to.equal(List([]));
		expect(builder.getWindowIdOrder(), 'window order').to.equal(List([w1]));
		expect(builder.getWidgetIdChain(), 'widget chain').to.equal(List([w1]));
		expect(builder.currentScreenId, 'current screen').to.equal(-1);
		expect(builder.currentDesktopId, 'current desktop').to.equal(-1);
		expect(builder.currentWindowId, 'current window').to.equal(-1);
	});

	it('addWindow (s1d2)', () => {
		const builder = new StateWrapper(initialState);
		const d1 = builder.addDesktop({});
		const d2 = builder.addDesktop({});
		const s1 = builder.addScreen(ActionObjects.screen100);
		const w1 = builder.addWindow({xid: 1000});

		expect(builder.widgetIdNext, 'widgetIdNext').to.equal(w1 + 1);
		expect(builder.getScreenIdOrder(), 'screen order').to.equal(List([s1]));
		expect(builder.getDesktopIdOrder(), 'desktop order').to.equal(List([d1, d2]));
		expect(builder.getWindowIdOrder(), 'window order').to.equal(List([w1]));
		expect(builder.getWidgetIdChain(), 'widget chain').to.equal(List([d1, s1, d2, w1]));
		expect(builder.currentScreenId, 'current screen').to.equal(s1);
		expect(builder.currentDesktopId, 'current desktop').to.equal(d1);
		expect(builder.currentWindowId, 'current window').to.equal(-1);
	});

	it('moveWindowToDesktop 1 (s1d2 + addWindow)', () => {
		const builder = new StateWrapper(initialState);
		const d1 = builder.addDesktop({});
		const d2 = builder.addDesktop({});
		const s1 = builder.addScreen(ActionObjects.screen100);
		const w1 = builder.addWindow({xid: 1000});
		builder.moveWindowToDesktop(w1, d1);

		expect(builder.widgetIdNext, 'widgetIdNext').to.equal(w1 + 1);
		expect(builder.getScreenIdOrder(), 'screen order').to.equal(List([s1]));
		expect(builder.getDesktopIdOrder(), 'desktop order').to.equal(List([d1, d2]));
		expect(builder.getWindowIdOrder(), 'window order').to.equal(List([w1]));
		expect(builder.getWidgetIdChain(), 'widget chain').to.equal(List([w1, d1, s1, d2]));
		expect(builder.currentScreenId, 'current screen').to.equal(s1);
		expect(builder.currentDesktopId, 'current desktop').to.equal(d1);
		expect(builder.currentWindowId, 'current window').to.equal(w1);
	});

	it('moveWindowToDesktop 2 (s1d2 + addWindow)', () => {
		const builder = new StateWrapper(initialState);
		const d1 = builder.addDesktop({});
		const d2 = builder.addDesktop({});
		const s1 = builder.addScreen(ActionObjects.screen100);
		const w1 = builder.addWindow({xid: 1000});
		builder.moveWindowToDesktop(w1, d2);

		expect(builder.widgetIdNext, 'widgetIdNext').to.equal(w1 + 1);
		expect(builder.getScreenIdOrder(), 'screen order').to.equal(List([s1]));
		expect(builder.getDesktopIdOrder(), 'desktop order').to.equal(List([d1, d2]));
		expect(builder.getWindowIdOrder(), 'window order').to.equal(List([w1]));
		expect(builder.getWidgetIdChain(), 'widget chain').to.equal(List([d1, s1, d2, w1]));
		expect(builder.currentScreenId, 'current screen').to.equal(s1);
		expect(builder.currentDesktopId, 'current desktop').to.equal(d1);
		expect(builder.currentWindowId, 'current window').to.equal(-1);
	});

	it('activateWindow (s1d2 + addWindow + moveWindowToDesktop 1)', () => {
		const builder = new StateWrapper(initialState);
		const d1 = builder.addDesktop({});
		const d2 = builder.addDesktop({});
		const s1 = builder.addScreen(ActionObjects.screen100);
		const w1 = builder.addWindow({xid: 1000});
		builder.moveWindowToDesktop(w1, d1);
		builder.activateWindow(w1);

		expect(builder.widgetIdNext, 'widgetIdNext').to.equal(w1 + 1);
		expect(builder.getScreenIdOrder(), 'screen order').to.equal(List([s1]));
		expect(builder.getDesktopIdOrder(), 'desktop order').to.equal(List([d1, d2]));
		expect(builder.getWindowIdOrder(), 'window order').to.equal(List([w1]));
		expect(builder.getWidgetIdChain(), 'widget chain').to.equal(List([w1, d1, s1, d2]));
		expect(builder.currentScreenId, 'current screen').to.equal(s1);
		expect(builder.currentDesktopId, 'current desktop').to.equal(d1);
		expect(builder.currentWindowId, 'current window').to.equal(w1);
	});

	it('activateWindow (s1d2 + addWindow + moveWindowToDesktop 2)', () => {
		const builder = new StateWrapper(initialState);
		const d1 = builder.addDesktop({});
		const d2 = builder.addDesktop({});
		const s1 = builder.addScreen(ActionObjects.screen100);
		const w1 = builder.addWindow({xid: 1000});
		builder.moveWindowToDesktop(w1, d2);
		builder.activateWindow(w1);

		expect(builder.widgetIdNext, 'widgetIdNext').to.equal(w1 + 1);
		expect(builder.getScreenIdOrder(), 'screen order').to.equal(List([s1]));
		expect(builder.getDesktopIdOrder(), 'desktop order').to.equal(List([d1, d2]));
		expect(builder.getWindowIdOrder(), 'window order').to.equal(List([w1]));
		expect(builder.getWidgetIdChain(), 'widget chain').to.equal(List([w1, d2, s1, d1]));
		expect(builder.currentScreenId, 'current screen').to.equal(s1);
		expect(builder.currentDesktopId, 'current desktop').to.equal(d2);
		expect(builder.currentWindowId, 'current window').to.equal(w1);
	});

	it('activateDesktop', () => {
		const builder = new StateWrapper(initialState);
		const d1 = builder.addDesktop({});
		const d2 = builder.addDesktop({});
		const s1 = builder.addScreen(ActionObjects.screen100);

		builder.activateDesktop(d2);
		expect(builder.getWidgetIdChain(), 'widget chain #1').to.equal(List([d2, s1, d1]));

		builder.activateDesktop(d1);
		expect(builder.getWidgetIdChain(), 'widget chain #2').to.equal(List([d1, s1, d2]));

		// Add window on desktop 1
		const w1 = builder.addWindow({xid: 1000});
		builder.moveWindowToDesktop(w1, d1);
		expect(builder.getWidgetIdChain(), 'widget chain #3').to.equal(List([w1, d1, s1, d2]));

		builder.activateDesktop(d2);
		expect(builder.getWidgetIdChain(), 'widget chain #4').to.equal(List([d2, s1, w1, d1]));

		// Add window on desktop 2
		builder.activateDesktop(d1);
		const w2 = builder.addWindow({xid: 1001});
		builder.moveWindowToDesktop(w2, d2);
		expect(builder.getWidgetIdChain(), 'widget chain #5').to.equal(List([w1, d1, s1, d2, w2]));

		builder.activateDesktop(d2);
		expect(builder.getWidgetIdChain(), 'widget chain #6').to.equal(List([w2, d2, s1, w1, d1]));
	});

	it('removeWindow', () => {
		const builder = new StateWrapper(initialState);
		const d1 = builder.addDesktop({});
		const d2 = builder.addDesktop({});
		const s1 = builder.addScreen(ActionObjects.screen100);

		const w1 = builder.addWindow({xid: 1000});
		builder.moveWindowToDesktop(w1, d1);
		builder.removeWindow(w1);
		expect(builder.getWindowIdOrder(), 'window order #1').to.equal(List([]));
		expect(builder.getWidgetIdChain(), 'widget chain #1').to.equal(List([d1, s1, d2]));

		const w2 = builder.addWindow({xid: 1000});
		builder.moveWindowToDesktop(w2, d2);
		builder.removeWindow(w2);
		expect(builder.getWindowIdOrder(), 'window order #1').to.equal(List([]));
		expect(builder.getWidgetIdChain(), 'widget chain #1').to.equal(List([d1, s1, d2]));
	});
});
<commit_msg>StateWrapperSpec test for removeWindow<commit_after>import {List, Map, fromJS} from 'immutable';
import {expect} from 'chai';
import {assert} from 'chai';
import diff from 'immutablediff';

import StateWrapper, {initialState} from '../src/StateWrapper.js';

const ActionObjects = {
	screen100: {
		xid: 100,
		width: 800,
		height: 600,
	}
};

/*[{
	actions: b => {
		const d1 = b.addDesktop({});
		return {d1}
	},
	asserts: x => {
		'widgetIdNext': x.d1 + 1],
		'screenIdOrder': [],
		'desktopIdOrder': [d1],
		'windowIdOrder': [],
		'widgetIdChain': [d1],
		'currentScreenId': -1,
		'currentDesktopId': -1,
		'currentWindowId': -1
	],
	children: [{
		actions: b => {

		}
	}]
}];*/

describe('StateWrapper', () => {
	it('empty', () => {
		const builder = new StateWrapper(initialState);
		expect(builder.getState()).to.equal(initialState);
	});

	it('addDesktop', () => {
		const builder = new StateWrapper(initialState);
		const d1 = builder.addDesktop({});

		expect(builder.widgetIdNext, 'widgetIdNext').to.equal(d1 + 1);
		expect(builder.getScreenIdOrder(), 'screen order').to.equal(List([]));
		expect(builder.getDesktopIdOrder(), 'desktop order').to.equal(List([d1]));
		expect(builder.getWindowIdOrder(), 'window order').to.equal(List([]));
		expect(builder.getWidgetIdChain(), 'widget chain').to.equal(List([d1]));
		expect(builder.currentScreenId, 'current screen').to.equal(-1);
		expect(builder.currentDesktopId, 'current desktop').to.equal(-1);
		expect(builder.currentWindowId, 'current window').to.equal(-1);
	});

	it('addDesktop*2', () => {
		const builder = new StateWrapper(initialState);
		const d1 = builder.addDesktop({});
		const d2 = builder.addDesktop({});

		expect(builder.widgetIdNext, 'widgetIdNext').to.equal(d2 + 1);
		expect(builder.getScreenIdOrder(), 'screen order').to.equal(List());
		expect(builder.getDesktopIdOrder(), 'desktop order').to.equal(List.of(d1, d2));
		expect(builder.getWindowIdOrder(), 'window order').to.equal(List());
		expect(builder.getWidgetIdChain(), 'widget chain').to.equal(List.of(d1, d2));
		expect(builder.currentScreenId, 'current screen').to.equal(-1);
		expect(builder.currentDesktopId, 'current desktop').to.equal(-1);
		expect(builder.currentWindowId, 'current window').to.equal(-1);
	});

	it('addScreen: should create a desktop and set it as current', () => {
		const builder = new StateWrapper(initialState);
		const s1 = builder.addScreen(ActionObjects.screen100);
		const d1 = s1 - 1;

		expect(builder.widgetIdNext, 'widgetIdNext').to.equal(s1 + 1);
		expect(builder.getScreenIdOrder(), 'screen order').to.equal(List([s1]));
		expect(builder.getDesktopIdOrder(), 'desktop order').to.equal(List([d1]));
		expect(builder.getWindowIdOrder(), 'window order').to.equal(List());
		expect(builder.getWidgetIdChain(), 'widget chain').to.equal(List([d1, s1]));
		expect(builder.currentScreenId, 'current screen').to.equal(s1);
		expect(builder.currentDesktopId, 'current desktop').to.equal(d1);
		expect(builder.currentWindowId, 'current window').to.equal(-1);
	});

	it('addDesktop, addScreen: should assign the desktop to the new screen and focus it', () => {
		const builder = new StateWrapper(initialState);
		const d1 = builder.addDesktop({});
		const s1 = builder.addScreen(ActionObjects.screen100);

		expect(builder.widgetIdNext, 'widgetIdNext').to.equal(s1 + 1);
		expect(builder.getScreenIdOrder(), 'screen order').to.equal(List([s1]));
		expect(builder.getDesktopIdOrder(), 'desktop order').to.equal(List([d1]));
		expect(builder.getWindowIdOrder(), 'window order').to.equal(List());
		expect(builder.getWidgetIdChain(), 'widget chain').to.equal(List([d1, s1]));
		expect(builder.currentScreenId, 'current screen').to.equal(s1);
		expect(builder.currentDesktopId, 'current desktop').to.equal(d1);
		expect(builder.currentWindowId, 'current window').to.equal(-1);
	});

	it('addDesktop*2, addScreen', () => {
		const builder = new StateWrapper(initialState);
		const d1 = builder.addDesktop({});
		const d2 = builder.addDesktop({});
		const s1 = builder.addScreen(ActionObjects.screen100);

		expect(builder.widgetIdNext, 'widgetIdNext').to.equal(s1 + 1);
		expect(builder.getScreenIdOrder(), 'screen order').to.equal(List([s1]));
		expect(builder.getDesktopIdOrder(), 'desktop order').to.equal(List([d1, d2]));
		expect(builder.getWindowIdOrder(), 'window order').to.equal(List());
		expect(builder.getWidgetIdChain(), 'widget chain').to.equal(List([d1, s1, d2]));
		expect(builder.currentScreenId, 'current screen').to.equal(s1);
		expect(builder.currentDesktopId, 'current desktop').to.equal(d1);
		expect(builder.currentWindowId, 'current window').to.equal(-1);
	});

	it('addWindow', () => {
		const builder = new StateWrapper(initialState);
		const w1 = builder.addWindow({xid: 1000});

		expect(builder.widgetIdNext, 'widgetIdNext').to.equal(w1 + 1);
		expect(builder.getScreenIdOrder(), 'screen order').to.equal(List([]));
		expect(builder.getDesktopIdOrder(), 'desktop order').to.equal(List([]));
		expect(builder.getWindowIdOrder(), 'window order').to.equal(List([w1]));
		expect(builder.getWidgetIdChain(), 'widget chain').to.equal(List([w1]));
		expect(builder.currentScreenId, 'current screen').to.equal(-1);
		expect(builder.currentDesktopId, 'current desktop').to.equal(-1);
		expect(builder.currentWindowId, 'current window').to.equal(-1);
	});

	it('addWindow (s1d2)', () => {
		const builder = new StateWrapper(initialState);
		const d1 = builder.addDesktop({});
		const d2 = builder.addDesktop({});
		const s1 = builder.addScreen(ActionObjects.screen100);
		const w1 = builder.addWindow({xid: 1000});

		expect(builder.widgetIdNext, 'widgetIdNext').to.equal(w1 + 1);
		expect(builder.getScreenIdOrder(), 'screen order').to.equal(List([s1]));
		expect(builder.getDesktopIdOrder(), 'desktop order').to.equal(List([d1, d2]));
		expect(builder.getWindowIdOrder(), 'window order').to.equal(List([w1]));
		expect(builder.getWidgetIdChain(), 'widget chain').to.equal(List([d1, s1, d2, w1]));
		expect(builder.currentScreenId, 'current screen').to.equal(s1);
		expect(builder.currentDesktopId, 'current desktop').to.equal(d1);
		expect(builder.currentWindowId, 'current window').to.equal(-1);
	});

	it('moveWindowToDesktop 1 (s1d2 + addWindow)', () => {
		const builder = new StateWrapper(initialState);
		const d1 = builder.addDesktop({});
		const d2 = builder.addDesktop({});
		const s1 = builder.addScreen(ActionObjects.screen100);
		const w1 = builder.addWindow({xid: 1000});
		builder.moveWindowToDesktop(w1, d1);

		expect(builder.widgetIdNext, 'widgetIdNext').to.equal(w1 + 1);
		expect(builder.getScreenIdOrder(), 'screen order').to.equal(List([s1]));
		expect(builder.getDesktopIdOrder(), 'desktop order').to.equal(List([d1, d2]));
		expect(builder.getWindowIdOrder(), 'window order').to.equal(List([w1]));
		expect(builder.getWidgetIdChain(), 'widget chain').to.equal(List([w1, d1, s1, d2]));
		expect(builder.currentScreenId, 'current screen').to.equal(s1);
		expect(builder.currentDesktopId, 'current desktop').to.equal(d1);
		expect(builder.currentWindowId, 'current window').to.equal(w1);
	});

	it('moveWindowToDesktop 2 (s1d2 + addWindow)', () => {
		const builder = new StateWrapper(initialState);
		const d1 = builder.addDesktop({});
		const d2 = builder.addDesktop({});
		const s1 = builder.addScreen(ActionObjects.screen100);
		const w1 = builder.addWindow({xid: 1000});
		builder.moveWindowToDesktop(w1, d2);

		expect(builder.widgetIdNext, 'widgetIdNext').to.equal(w1 + 1);
		expect(builder.getScreenIdOrder(), 'screen order').to.equal(List([s1]));
		expect(builder.getDesktopIdOrder(), 'desktop order').to.equal(List([d1, d2]));
		expect(builder.getWindowIdOrder(), 'window order').to.equal(List([w1]));
		expect(builder.getWidgetIdChain(), 'widget chain').to.equal(List([d1, s1, d2, w1]));
		expect(builder.currentScreenId, 'current screen').to.equal(s1);
		expect(builder.currentDesktopId, 'current desktop').to.equal(d1);
		expect(builder.currentWindowId, 'current window').to.equal(-1);
	});

	it('activateWindow (s1d2 + addWindow + moveWindowToDesktop 1)', () => {
		const builder = new StateWrapper(initialState);
		const d1 = builder.addDesktop({});
		const d2 = builder.addDesktop({});
		const s1 = builder.addScreen(ActionObjects.screen100);
		const w1 = builder.addWindow({xid: 1000});
		builder.moveWindowToDesktop(w1, d1);
		builder.activateWindow(w1);

		expect(builder.widgetIdNext, 'widgetIdNext').to.equal(w1 + 1);
		expect(builder.getScreenIdOrder(), 'screen order').to.equal(List([s1]));
		expect(builder.getDesktopIdOrder(), 'desktop order').to.equal(List([d1, d2]));
		expect(builder.getWindowIdOrder(), 'window order').to.equal(List([w1]));
		expect(builder.getWidgetIdChain(), 'widget chain').to.equal(List([w1, d1, s1, d2]));
		expect(builder.currentScreenId, 'current screen').to.equal(s1);
		expect(builder.currentDesktopId, 'current desktop').to.equal(d1);
		expect(builder.currentWindowId, 'current window').to.equal(w1);
	});

	it('activateWindow (s1d2 + addWindow + moveWindowToDesktop 2)', () => {
		const builder = new StateWrapper(initialState);
		const d1 = builder.addDesktop({});
		const d2 = builder.addDesktop({});
		const s1 = builder.addScreen(ActionObjects.screen100);
		const w1 = builder.addWindow({xid: 1000});
		builder.moveWindowToDesktop(w1, d2);
		builder.activateWindow(w1);

		expect(builder.widgetIdNext, 'widgetIdNext').to.equal(w1 + 1);
		expect(builder.getScreenIdOrder(), 'screen order').to.equal(List([s1]));
		expect(builder.getDesktopIdOrder(), 'desktop order').to.equal(List([d1, d2]));
		expect(builder.getWindowIdOrder(), 'window order').to.equal(List([w1]));
		expect(builder.getWidgetIdChain(), 'widget chain').to.equal(List([w1, d2, s1, d1]));
		expect(builder.currentScreenId, 'current screen').to.equal(s1);
		expect(builder.currentDesktopId, 'current desktop').to.equal(d2);
		expect(builder.currentWindowId, 'current window').to.equal(w1);
	});

	it('activateDesktop', () => {
		const builder = new StateWrapper(initialState);
		const d1 = builder.addDesktop({});
		const d2 = builder.addDesktop({});
		const s1 = builder.addScreen(ActionObjects.screen100);

		builder.activateDesktop(d2);
		expect(builder.getWidgetIdChain(), 'widget chain #1').to.equal(List([d2, s1, d1]));

		builder.activateDesktop(d1);
		expect(builder.getWidgetIdChain(), 'widget chain #2').to.equal(List([d1, s1, d2]));

		// Add window on desktop 1
		const w1 = builder.addWindow({xid: 1000});
		builder.moveWindowToDesktop(w1, d1);
		expect(builder.getWidgetIdChain(), 'widget chain #3').to.equal(List([w1, d1, s1, d2]));

		builder.activateDesktop(d2);
		expect(builder.getWidgetIdChain(), 'widget chain #4').to.equal(List([d2, s1, w1, d1]));

		// Add window on desktop 2
		builder.activateDesktop(d1);
		const w2 = builder.addWindow({xid: 1001});
		builder.moveWindowToDesktop(w2, d2);
		expect(builder.getWidgetIdChain(), 'widget chain #5').to.equal(List([w1, d1, s1, d2, w2]));

		builder.activateDesktop(d2);
		expect(builder.getWidgetIdChain(), 'widget chain #6').to.equal(List([w2, d2, s1, w1, d1]));
	});

	it('removeWindow', () => {
		const builder = new StateWrapper(initialState);
		const d1 = builder.addDesktop({});
		const d2 = builder.addDesktop({});
		const s1 = builder.addScreen(ActionObjects.screen100);

		const w1 = builder.addWindow({xid: 1000});
		builder.moveWindowToDesktop(w1, d1);
		builder.removeWindow(w1);
		expect(builder.getWindowIdOrder(), 'window order #1').to.equal(List([]));
		expect(builder.getWidgetIdChain(), 'widget chain #1').to.equal(List([d1, s1, d2]));

		const w2 = builder.addWindow({xid: 1000});
		builder.moveWindowToDesktop(w2, d2);
		builder.removeWindow(w2);
		expect(builder.getWindowIdOrder(), 'window order #1').to.equal(List([]));
		expect(builder.getWidgetIdChain(), 'widget chain #1').to.equal(List([d1, s1, d2]));

		const w3 = builder.addWindow({xid: 1000});
		const w4 = builder.addWindow({xid: 1000});
		builder.moveWindowToDesktop(w3, d1);
		builder.moveWindowToDesktop(w4, d2);
		builder.removeWindow(w3);
		expect(builder.getWindowIdOrder(), 'window order #1').to.equal(List([w4]));
		expect(builder.getWidgetIdChain(), 'widget chain #1').to.equal(List([d1, s1, d2, w4]));
	});
});
<|endoftext|>


<commit_before>/*global expect*/
describe('addType', function () {
    var clonedExpect;
    beforeEach(function () {
        clonedExpect = expect.clone();
    });

    it('throws an expection if the type has an empty or undefined name', function () {
        expect(function () {
            clonedExpect.addType({});
        }, 'to throw', 'A type must be given a non-empty name and must match ^[a-z_](?:|[a-z0-9_.-]*[_a-z0-9])$');
    });

    it('throws an expection if the type has a name of "assertion"', function () {
        expect(function () {
            clonedExpect.addType({ name: 'assertion', identify: false });
        }, 'to throw', 'The type with the name assertion already exists');
    });

    it('throw an expection if the type does not specify a correct identify field', function () {
        expect(function () {
            clonedExpect.addType({ name: 'wat' });
        }, 'to throw', 'Type wat must specify an identify function or be declared abstract by setting identify to false');

        expect(function () {
            clonedExpect.addType({ name: 'wat', identify: true });
        }, 'to throw', 'Type wat must specify an identify function or be declared abstract by setting identify to false');

        expect(function () {
            clonedExpect.addType({ name: 'wat', identify: 'wat' });
        }, 'to throw', 'Type wat must specify an identify function or be declared abstract by setting identify to false');
    });

    it('throws an expection if a type of that name already exists', function () {
        expect(function () {
            clonedExpect.addType({ name: 'Promise', identify: false });
        }, 'to throw', 'The type with the name Promise already exists');
    });

    it('throws an expection if the type starts with .', function () {
        expect(function () {
            clonedExpect.addType({name: '.foo'});
        }, 'to throw', 'A type must be given a non-empty name and must match ^[a-z_](?:|[a-z0-9_.-]*[_a-z0-9])$');
    });

    it('throws an expection if the type ends with .', function () {
        expect(function () {
            clonedExpect.addType({name: 'foo.'});
        }, 'to throw', 'A type must be given a non-empty name and must match ^[a-z_](?:|[a-z0-9_.-]*[_a-z0-9])$');
    });

    it('throws an expection if the type contains non-alphanumeric chars', function () {
        expect(function () {
            clonedExpect.addType({name: 'ø'});
        }, 'to throw', 'A type must be given a non-empty name and must match ^[a-z_](?:|[a-z0-9_.-]*[_a-z0-9])$');
    });

    describe('with a custom box type', function () {
        function box(value) {
            return {
                isBox: true,
                value: value
            };
        }

        describe('added with a base type of any', function () {
            beforeEach(function () {
                clonedExpect.addType({
                    name: 'box',
                    identify: function (obj) {
                        return obj && typeof obj === 'object' && obj.isBox;
                    },
                    equal: function (a, b, equal) {
                        return a === b || equal(a.value, b.value);
                    },
                    inspect: function (obj, depth, output, inspect) {
                        return output
                            .text('box(')
                            .append(inspect(obj.value))
                            .text(')');
                    },
                    diff: function (actual, expected, output, diff) {
                        output = output.text('box(').append(diff({ value: actual.value }, { value: expected.value })).text(')');
                        output.inline = true;
                        return output;
                    }
                });
            });

            it('should use the equal defined by the type', function () {
                clonedExpect(box(123), 'to equal', box(123));
                clonedExpect(box(123), 'not to equal', box(321));
            });

            it('shows a diff in case of a mismatch', function () {
                expect(function () {
                    clonedExpect(box(box(123)), 'to equal', box(box(456)));
                }, 'to throw', "expected box(box(123)) to equal box(box(456))\n" +
                       "\n" +
                       "box({\n" +
                       "  value: box({\n" +
                       "    value: 123 // should equal 456\n" +
                       "  })\n" +
                       "})");
            });
        });

        describe('added with a base type of wrapperObject', function () {
            beforeEach(function () {
                clonedExpect.addType({
                    name: 'box',
                    base: 'wrapperObject',
                    identify: function (obj) {
                        return obj && typeof obj === 'object' && obj.isBox;
                    },
                    unwrap: function (box) {
                        return box.value;
                    },
                    prefix: function (output) {
                        return output.text('box(');
                    },
                    suffix: function (output) {
                        return output.text(')');
                    }
                });
            });

            it('should use the equal defined by the type', function () {
                clonedExpect(box(123), 'to equal', box(123));
                clonedExpect(box(123), 'not to equal', box(321));
            });

            it('shows a diff in case of a mismatch', function () {
                expect(function () {
                    clonedExpect(box(box(123)), 'to equal', box(box(456)));
                }, 'to throw', "expected box(box(123)) to equal box(box(456))\n" +
                       "\n" +
                       "box(box(\n" +
                       "  123 // should equal 456\n" +
                       "))");
            });

            it('should include the diff when one is available', function () {
                expect(function () {
                    clonedExpect(box('abc'), 'to equal', box('abe'));
                }, 'to throw',
                       "expected box('abc') to equal box('abe')\n" +
                       "\n" +
                       "box(\n" +
                       "  'abc' // should equal 'abe'\n" +
                       "        //\n" +
                       "        // -abc\n" +
                       "        // +abe\n" +
                       ")"
                );
            });
        });

        it('allows adding a type whose diff method returns an old-style { inline: <boolean>, diff: <magicpen> } object', function () {
            clonedExpect.addType({
                name: 'box',
                identify: function (obj) {
                    return obj && typeof obj === 'object' && obj.isBox;
                },
                equal: function (a, b, equal) {
                    return a === b || equal(a.value, b.value);
                },
                inspect: function (obj, depth, output, inspect) {
                    return output
                        .text('box(')
                        .append(inspect(obj.value))
                        .text(')');
                },
                diff: function (actual, expected, output, diff) {
                    return {
                        inline: true,
                        diff: output.text('box(').append(diff({ value: actual.value }, { value: expected.value })).text(')')
                    };
                }
            });

            expect(function () {
                clonedExpect(box('abc'), 'to equal', box('abe'));
            }, 'to throw',
                   "expected box('abc') to equal box('abe')\n" +
                   "\n" +
                   "box({\n" +
                   "  value: 'abc' // should equal 'abe'\n" +
                   "               //\n" +
                   "               // -abc\n" +
                   "               // +abe\n" +
                   "})"
            );
        });
    });
});
<commit_msg>Increase coverage of addType.<commit_after>/*global expect*/
describe('addType', function () {
    var clonedExpect;
    beforeEach(function () {
        clonedExpect = expect.clone();
    });

    it('throws an expection if the type has an empty or undefined name', function () {
        expect(function () {
            clonedExpect.addType({});
        }, 'to throw', 'A type must be given a non-empty name and must match ^[a-z_](?:|[a-z0-9_.-]*[_a-z0-9])$');
    });

    it('throws an expection if the base type does not exist', function () {
        expect(function () {
            clonedExpect.addType({name: 'foo', base: 'barquux', identify: function () { return false; }});
        }, 'to throw', 'Unknown base type: barquux');
    });

    it('throws an expection if the type has a name of "assertion"', function () {
        expect(function () {
            clonedExpect.addType({ name: 'assertion', identify: false });
        }, 'to throw', 'The type with the name assertion already exists');
    });

    it('throw an expection if the type does not specify a correct identify field', function () {
        expect(function () {
            clonedExpect.addType({ name: 'wat' });
        }, 'to throw', 'Type wat must specify an identify function or be declared abstract by setting identify to false');

        expect(function () {
            clonedExpect.addType({ name: 'wat', identify: true });
        }, 'to throw', 'Type wat must specify an identify function or be declared abstract by setting identify to false');

        expect(function () {
            clonedExpect.addType({ name: 'wat', identify: 'wat' });
        }, 'to throw', 'Type wat must specify an identify function or be declared abstract by setting identify to false');
    });

    it('throws an expection if a type of that name already exists', function () {
        expect(function () {
            clonedExpect.addType({ name: 'Promise', identify: false });
        }, 'to throw', 'The type with the name Promise already exists');
    });

    it('throws an expection if the type starts with .', function () {
        expect(function () {
            clonedExpect.addType({name: '.foo'});
        }, 'to throw', 'A type must be given a non-empty name and must match ^[a-z_](?:|[a-z0-9_.-]*[_a-z0-9])$');
    });

    it('throws an expection if the type ends with .', function () {
        expect(function () {
            clonedExpect.addType({name: 'foo.'});
        }, 'to throw', 'A type must be given a non-empty name and must match ^[a-z_](?:|[a-z0-9_.-]*[_a-z0-9])$');
    });

    it('throws an expection if the type contains non-alphanumeric chars', function () {
        expect(function () {
            clonedExpect.addType({name: 'ø'});
        }, 'to throw', 'A type must be given a non-empty name and must match ^[a-z_](?:|[a-z0-9_.-]*[_a-z0-9])$');
    });

    describe('with a custom box type', function () {
        function box(value) {
            return {
                isBox: true,
                value: value
            };
        }

        describe('added with a base type of any', function () {
            beforeEach(function () {
                clonedExpect.addType({
                    name: 'box',
                    identify: function (obj) {
                        return obj && typeof obj === 'object' && obj.isBox;
                    },
                    equal: function (a, b, equal) {
                        return a === b || equal(a.value, b.value);
                    },
                    inspect: function (obj, depth, output, inspect) {
                        return output
                            .text('box(')
                            .append(inspect(obj.value))
                            .text(')');
                    },
                    diff: function (actual, expected, output, diff) {
                        output = output.text('box(').append(diff({ value: actual.value }, { value: expected.value })).text(')');
                        output.inline = true;
                        return output;
                    }
                });
            });

            it('should use the equal defined by the type', function () {
                clonedExpect(box(123), 'to equal', box(123));
                clonedExpect(box(123), 'not to equal', box(321));
            });

            it('shows a diff in case of a mismatch', function () {
                expect(function () {
                    clonedExpect(box(box(123)), 'to equal', box(box(456)));
                }, 'to throw', "expected box(box(123)) to equal box(box(456))\n" +
                       "\n" +
                       "box({\n" +
                       "  value: box({\n" +
                       "    value: 123 // should equal 456\n" +
                       "  })\n" +
                       "})");
            });
        });

        describe('added with a base type of wrapperObject', function () {
            beforeEach(function () {
                clonedExpect.addType({
                    name: 'box',
                    base: 'wrapperObject',
                    identify: function (obj) {
                        return obj && typeof obj === 'object' && obj.isBox;
                    },
                    unwrap: function (box) {
                        return box.value;
                    },
                    prefix: function (output) {
                        return output.text('box(');
                    },
                    suffix: function (output) {
                        return output.text(')');
                    }
                });
            });

            it('should use the equal defined by the type', function () {
                clonedExpect(box(123), 'to equal', box(123));
                clonedExpect(box(123), 'not to equal', box(321));
            });

            it('shows a diff in case of a mismatch', function () {
                expect(function () {
                    clonedExpect(box(box(123)), 'to equal', box(box(456)));
                }, 'to throw', "expected box(box(123)) to equal box(box(456))\n" +
                       "\n" +
                       "box(box(\n" +
                       "  123 // should equal 456\n" +
                       "))");
            });

            it('should include the diff when one is available', function () {
                expect(function () {
                    clonedExpect(box('abc'), 'to equal', box('abe'));
                }, 'to throw',
                       "expected box('abc') to equal box('abe')\n" +
                       "\n" +
                       "box(\n" +
                       "  'abc' // should equal 'abe'\n" +
                       "        //\n" +
                       "        // -abc\n" +
                       "        // +abe\n" +
                       ")"
                );
            });
        });

        it('allows adding a type whose diff method returns an old-style { inline: <boolean>, diff: <magicpen> } object', function () {
            clonedExpect.addType({
                name: 'box',
                identify: function (obj) {
                    return obj && typeof obj === 'object' && obj.isBox;
                },
                equal: function (a, b, equal) {
                    return a === b || equal(a.value, b.value);
                },
                inspect: function (obj, depth, output, inspect) {
                    return output
                        .text('box(')
                        .append(inspect(obj.value))
                        .text(')');
                },
                diff: function (actual, expected, output, diff) {
                    return {
                        inline: true,
                        diff: output.text('box(').append(diff({ value: actual.value }, { value: expected.value })).text(')')
                    };
                }
            });

            expect(function () {
                clonedExpect(box('abc'), 'to equal', box('abe'));
            }, 'to throw',
                   "expected box('abc') to equal box('abe')\n" +
                   "\n" +
                   "box({\n" +
                   "  value: 'abc' // should equal 'abe'\n" +
                   "               //\n" +
                   "               // -abc\n" +
                   "               // +abe\n" +
                   "})"
            );
        });
    });
});
<|endoftext|>


<commit_before>/**
 * Copyright 2018 Google Inc. All rights reserved.
 * Modifications copyright (c) Microsoft Corporation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

const {FFOX, CHROMIUM, WEBKIT, USES_HOOKS} = testOptions;

describe('Auto waiting', () => {
  it('should await navigation when clicking anchor', async({page, server}) => {
    const messages = [];
    server.setRoute('/empty.html', async (req, res) => {
      messages.push('route');
      res.setHeader('Content-Type', 'text/html');
      res.end(`<link rel='stylesheet' href='./one-style.css'>`);
    });

    await page.setContent(`<a href="${server.EMPTY_PAGE}">empty.html</a>`);

    await Promise.all([
      page.click('a').then(() => messages.push('click')),
      page.waitForEvent('framenavigated').then(() => messages.push('navigated')),
    ]);
    expect(messages.join('|')).toBe('route|navigated|click');
  });
  it('should await cross-process navigation when clicking anchor', async({page, server}) => {
    const messages = [];
    server.setRoute('/empty.html', async (req, res) => {
      messages.push('route');
      res.setHeader('Content-Type', 'text/html');
      res.end(`<link rel='stylesheet' href='./one-style.css'>`);
    });

    await page.setContent(`<a href="${server.CROSS_PROCESS_PREFIX + '/empty.html'}">empty.html</a>`);

    await Promise.all([
      page.click('a').then(() => messages.push('click')),
      page.waitForEvent('framenavigated').then(() => messages.push('navigated')),
    ]);
    expect(messages.join('|')).toBe('route|navigated|click');
  });
  it('should await form-get on click', async({page, server}) => {
    const messages = [];
    server.setRoute('/empty.html?foo=bar', async (req, res) => {
      messages.push('route');
      res.setHeader('Content-Type', 'text/html');
      res.end(`<link rel='stylesheet' href='./one-style.css'>`);
    });

    await page.setContent(`
      <form action="${server.EMPTY_PAGE}" method="get">
        <input name="foo" value="bar">
        <input type="submit" value="Submit">
      </form>`);

    await Promise.all([
      page.click('input[type=submit]').then(() => messages.push('click')),
      page.waitForEvent('framenavigated').then(() => messages.push('navigated')),
    ]);
    expect(messages.join('|')).toBe('route|navigated|click');
  });
  it('should await form-post on click', async({page, server}) => {
    const messages = [];
    server.setRoute('/empty.html', async (req, res) => {
      messages.push('route');
      res.setHeader('Content-Type', 'text/html');
      res.end(`<link rel='stylesheet' href='./one-style.css'>`);
    });

    await page.setContent(`
      <form action="${server.EMPTY_PAGE}" method="post">
        <input name="foo" value="bar">
        <input type="submit" value="Submit">
      </form>`);

    await Promise.all([
      page.click('input[type=submit]').then(() => messages.push('click')),
      page.waitForEvent('framenavigated').then(() => messages.push('navigated')),
    ]);
    expect(messages.join('|')).toBe('route|navigated|click');
  });
  it('should await navigation when assigning location', async({page, server}) => {
    const messages = [];
    server.setRoute('/empty.html', async (req, res) => {
      messages.push('route');
      res.setHeader('Content-Type', 'text/html');
      res.end(`<link rel='stylesheet' href='./one-style.css'>`);
    });
    await Promise.all([
      page.evaluate(`window.location.href = "${server.EMPTY_PAGE}"`).then(() => messages.push('evaluate')),
      page.waitForEvent('framenavigated').then(() => messages.push('navigated')),
    ]);
    expect(messages.join('|')).toBe('route|navigated|evaluate');
  });
  it('should await navigation when assigning location twice', async({page, server}) => {
    const messages = [];
    server.setRoute('/empty.html?cancel', async (req, res) => { res.end('done'); });
    server.setRoute('/empty.html?override', async (req, res) => { messages.push('routeoverride'); res.end('done'); });
    await Promise.all([
      page.evaluate(`
        window.location.href = "${server.EMPTY_PAGE}?cancel";
        window.location.href = "${server.EMPTY_PAGE}?override";
      `).then(() => messages.push('evaluate')),
    ]);
    expect(messages.join('|')).toBe('routeoverride|evaluate');
  });
  it('should await navigation when evaluating reload', async({page, server}) => {
    const messages = [];
    await page.goto(server.EMPTY_PAGE);
    server.setRoute('/empty.html', async (req, res) => {
      messages.push('route');
      res.setHeader('Content-Type', 'text/html');
      res.end(`<link rel='stylesheet' href='./one-style.css'>`);
    });

    await Promise.all([
      page.evaluate(`window.location.reload()`).then(() => messages.push('evaluate')),
      page.waitForEvent('framenavigated').then(() => messages.push('navigated')),
    ]);
    expect(messages.join('|')).toBe('route|navigated|evaluate');
  });
  it('should await navigating specified target', async({page, server}) => {
    const messages = [];
    server.setRoute('/empty.html', async (req, res) => {
      messages.push('route');
      res.setHeader('Content-Type', 'text/html');
      res.end(`<link rel='stylesheet' href='./one-style.css'>`);
    });

    await page.setContent(`
      empty.html

    `);
    const frame = page.frame({ name: 'target' });
    await Promise.all([
      page.click('a').then(() => messages.push('click')),
      page.waitForEvent('framenavigated').then(() => messages.push('navigated')),
    ]);
    expect(frame.url()).toBe(server.EMPTY_PAGE);
    expect(messages.join('|')).toBe('route|navigated|click');
  });
  it('should work with noWaitAfter: true', async({page, server}) => {
    server.setRoute('/empty.html', async () => {});
    await page.setContent(`<a href="${server.EMPTY_PAGE}">empty.html</a>`);
    await page.click('a', { noWaitAfter: true });
  });
  it('should work with waitForLoadState(load)', async({page, server}) => {
    const messages = [];
    server.setRoute('/empty.html', async (req, res) => {
      messages.push('route');
      res.setHeader('Content-Type', 'text/html');
      res.end(`<link rel='stylesheet' href='./one-style.css'>`);
    });

    await page.setContent(`<a href="${server.EMPTY_PAGE}">empty.html</a>`);
    await Promise.all([
      page.click('a').then(() => page.waitForLoadState('load')).then(() => messages.push('clickload')),
      page.waitForEvent('framenavigated').then(() => page.waitForLoadState('domcontentloaded')).then(() => messages.push('domcontentloaded')),
    ]);
    expect(messages.join('|')).toBe('route|domcontentloaded|clickload');
  });
  it('should work with goto following click', async({page, server}) => {
    server.setRoute('/login.html', async (req, res) => {
      messages.push('route');
      res.setHeader('Content-Type', 'text/html');
      res.end(`You are logged in`);
    });

    await page.setContent(`
      <form action="${server.PREFIX}/login.html" method="get">
        <input type="text">
        <input type="submit" value="Submit">
      </form>`);

    await page.fill('input[type=text]', 'admin');
    await page.click('input[type=submit]');
    await page.goto(server.EMPTY_PAGE);
  });
  it.skip(USES_HOOKS)('should report navigation in the log when clicking anchor', async({page, server}) => {
    await page.setContent(`<a href="${server.PREFIX + '/frames/one-frame.html'}">click me</a>`);
    const __testHookAfterPointerAction = () => new Promise(f => setTimeout(f, 6000));
    const error = await page.click('a', { timeout: 5000, __testHookAfterPointerAction }).catch(e => e);
    expect(error.message).toContain('page.click: Timeout 5000ms exceeded.');
    expect(error.message).toContain('waiting for scheduled navigations to finish');
    expect(error.message).toContain(`navigated to "${server.PREFIX + '/frames/one-frame.html'}"`);
  });
});

describe('Auto waiting should not hang when', () => {
  it('clicking on links which do not commit navigation', async({page, server, httpsServer}) => {
    await page.goto(server.EMPTY_PAGE);
    await page.setContent(`<a href='${httpsServer.EMPTY_PAGE}'>foobar</a>`);
    await page.click('a');
  });
  it('calling window.stop async', async({page, server, httpsServer}) => {
    server.setRoute('/empty.html', async (req, res) => {});
    await page.evaluate((url) => {
        window.location.href = url;
        setTimeout(() => window.stop(), 100);
      }, server.EMPTY_PAGE);
  });
  it('calling window.stop sync', async({page, server, httpsServer}) => {
    await page.evaluate((url) => {
        window.location.href = url;
        window.stop();
      }, server.EMPTY_PAGE);
  });
  it('assigning location to about:blank', async({page, server}) => {
    await page.goto(server.EMPTY_PAGE);
    await page.evaluate(`window.location.href = "about:blank";`);
  });
  it('assigning location to about:blank after non-about:blank', async({page, server}) => {
    server.setRoute('/empty.html', async (req, res) => {});
    await page.evaluate(`
        window.location.href = "${server.EMPTY_PAGE}";
        window.location.href = "about:blank";`);
  });
  it('calling window.open and window.close', async function({page, server}) {
    await page.goto(server.EMPTY_PAGE);
    await page.evaluate(() => {
      const popup = window.open(window.location.href);
      popup.close();
    });
  });
  it('opening a popup', async function({page, server}) {
    await page.goto(server.EMPTY_PAGE);
    await Promise.all([
      page.waitForEvent('popup'),
      page.evaluate(() => window._popup = window.open(window.location.href)),
    ]);
  });
});

<commit_msg>test: improve autowaiting tests (#3168)<commit_after>/**
 * Copyright 2018 Google Inc. All rights reserved.
 * Modifications copyright (c) Microsoft Corporation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

const {FFOX, CHROMIUM, WEBKIT, USES_HOOKS} = testOptions;

describe('Auto waiting', () => {
  it('should await navigation when clicking anchor', async({page, server}) => {
    const messages = [];
    server.setRoute('/empty.html', async (req, res) => {
      messages.push('route');
      res.setHeader('Content-Type', 'text/html');
      res.end(`<link rel='stylesheet' href='./one-style.css'>`);
    });

    await page.setContent(`<a href="${server.EMPTY_PAGE}">empty.html</a>`);

    await Promise.all([
      page.click('a').then(() => messages.push('click')),
      page.waitForEvent('framenavigated').then(() => messages.push('navigated')),
    ]);
    expect(messages.join('|')).toBe('route|navigated|click');
  });
  it('should await cross-process navigation when clicking anchor', async({page, server}) => {
    const messages = [];
    server.setRoute('/empty.html', async (req, res) => {
      messages.push('route');
      res.setHeader('Content-Type', 'text/html');
      res.end(`<link rel='stylesheet' href='./one-style.css'>`);
    });

    await page.setContent(`<a href="${server.CROSS_PROCESS_PREFIX + '/empty.html'}">empty.html</a>`);

    await Promise.all([
      page.click('a').then(() => messages.push('click')),
      page.waitForEvent('framenavigated').then(() => messages.push('navigated')),
    ]);
    expect(messages.join('|')).toBe('route|navigated|click');
  });
  it('should await form-get on click', async({page, server}) => {
    const messages = [];
    server.setRoute('/empty.html?foo=bar', async (req, res) => {
      messages.push('route');
      res.setHeader('Content-Type', 'text/html');
      res.end(`<link rel='stylesheet' href='./one-style.css'>`);
    });

    await page.setContent(`
      <form action="${server.EMPTY_PAGE}" method="get">
        <input name="foo" value="bar">
        <input type="submit" value="Submit">
      </form>`);

    await Promise.all([
      page.click('input[type=submit]').then(() => messages.push('click')),
      page.waitForEvent('framenavigated').then(() => messages.push('navigated')),
    ]);
    expect(messages.join('|')).toBe('route|navigated|click');
  });
  it('should await form-post on click', async({page, server}) => {
    const messages = [];
    server.setRoute('/empty.html', async (req, res) => {
      messages.push('route');
      res.setHeader('Content-Type', 'text/html');
      res.end(`<link rel='stylesheet' href='./one-style.css'>`);
    });

    await page.setContent(`
      <form action="${server.EMPTY_PAGE}" method="post">
        <input name="foo" value="bar">
        <input type="submit" value="Submit">
      </form>`);

    await Promise.all([
      page.click('input[type=submit]').then(() => messages.push('click')),
      page.waitForEvent('framenavigated').then(() => messages.push('navigated')),
    ]);
    expect(messages.join('|')).toBe('route|navigated|click');
  });
  it('should await navigation when assigning location', async({page, server}) => {
    const messages = [];
    server.setRoute('/empty.html', async (req, res) => {
      messages.push('route');
      res.setHeader('Content-Type', 'text/html');
      res.end(`<link rel='stylesheet' href='./one-style.css'>`);
    });
    await Promise.all([
      page.evaluate(`window.location.href = "${server.EMPTY_PAGE}"`).then(() => messages.push('evaluate')),
      page.waitForEvent('framenavigated').then(() => messages.push('navigated')),
    ]);
    expect(messages.join('|')).toBe('route|navigated|evaluate');
  });
  it('should await navigation when assigning location twice', async({page, server}) => {
    const messages = [];
    server.setRoute('/empty.html?cancel', async (req, res) => { res.end('done'); });
    server.setRoute('/empty.html?override', async (req, res) => { messages.push('routeoverride'); res.end('done'); });
    await page.evaluate(`
        window.location.href = "${server.EMPTY_PAGE}?cancel";
        window.location.href = "${server.EMPTY_PAGE}?override";
      `);
    messages.push('evaluate');
    expect(messages.join('|')).toBe('routeoverride|evaluate');
  });
  it('should await navigation when evaluating reload', async({page, server}) => {
    const messages = [];
    await page.goto(server.EMPTY_PAGE);
    server.setRoute('/empty.html', async (req, res) => {
      messages.push('route');
      res.setHeader('Content-Type', 'text/html');
      res.end(`<link rel='stylesheet' href='./one-style.css'>`);
    });

    await Promise.all([
      page.evaluate(`window.location.reload()`).then(() => messages.push('evaluate')),
      page.waitForEvent('framenavigated').then(() => messages.push('navigated')),
    ]);
    expect(messages.join('|')).toBe('route|navigated|evaluate');
  });
  it('should await navigating specified target', async({page, server}) => {
    const messages = [];
    server.setRoute('/empty.html', async (req, res) => {
      messages.push('route');
      res.setHeader('Content-Type', 'text/html');
      res.end(`<link rel='stylesheet' href='./one-style.css'>`);
    });

    await page.setContent(`
      empty.html

    `);
    const frame = page.frame({ name: 'target' });
    await Promise.all([
      page.click('a').then(() => messages.push('click')),
      page.waitForEvent('framenavigated').then(() => messages.push('navigated')),
    ]);
    expect(frame.url()).toBe(server.EMPTY_PAGE);
    expect(messages.join('|')).toBe('route|navigated|click');
  });
  it('should work with noWaitAfter: true', async({page, server}) => {
    server.setRoute('/empty.html', async () => {});
    await page.setContent(`<a href="${server.EMPTY_PAGE}">empty.html</a>`);
    await page.click('a', { noWaitAfter: true });
  });
  it('should work with waitForLoadState(load)', async({page, server}) => {
    const messages = [];
    server.setRoute('/empty.html', async (req, res) => {
      messages.push('route');
      res.setHeader('Content-Type', 'text/html');
      res.end(`<link rel='stylesheet' href='./one-style.css'>`);
    });

    await page.setContent(`<a href="${server.EMPTY_PAGE}">empty.html</a>`);
    await Promise.all([
      page.click('a').then(() => page.waitForLoadState('load')).then(() => messages.push('clickload')),
      page.waitForEvent('framenavigated').then(() => page.waitForLoadState('domcontentloaded')).then(() => messages.push('domcontentloaded')),
    ]);
    expect(messages.join('|')).toBe('route|domcontentloaded|clickload');
  });
  it('should work with goto following click', async({page, server}) => {
    server.setRoute('/login.html', async (req, res) => {
      res.setHeader('Content-Type', 'text/html');
      res.end(`You are logged in`);
    });

    await page.setContent(`
      <form action="${server.PREFIX}/login.html" method="get">
        <input type="text">
        <input type="submit" value="Submit">
      </form>`);

    await page.fill('input[type=text]', 'admin');
    await page.click('input[type=submit]');
    await page.goto(server.EMPTY_PAGE);
  });
  it.skip(USES_HOOKS)('should report navigation in the log when clicking anchor', async({page, server}) => {
    await page.setContent(`<a href="${server.PREFIX + '/frames/one-frame.html'}">click me</a>`);
    const __testHookAfterPointerAction = () => new Promise(f => setTimeout(f, 6000));
    const error = await page.click('a', { timeout: 5000, __testHookAfterPointerAction }).catch(e => e);
    expect(error.message).toContain('page.click: Timeout 5000ms exceeded.');
    expect(error.message).toContain('waiting for scheduled navigations to finish');
    expect(error.message).toContain(`navigated to "${server.PREFIX + '/frames/one-frame.html'}"`);
  });
});

describe('Auto waiting should not hang when', () => {
  it('clicking on links which do not commit navigation', async({page, server, httpsServer}) => {
    await page.goto(server.EMPTY_PAGE);
    await page.setContent(`<a href='${httpsServer.EMPTY_PAGE}'>foobar</a>`);
    await page.click('a');
  });
  it('calling window.stop async', async({page, server, httpsServer}) => {
    server.setRoute('/empty.html', async (req, res) => {});
    await page.evaluate((url) => {
        window.location.href = url;
        setTimeout(() => window.stop(), 100);
      }, server.EMPTY_PAGE);
  });
  it('calling window.stop sync', async({page, server, httpsServer}) => {
    await page.evaluate((url) => {
        window.location.href = url;
        window.stop();
      }, server.EMPTY_PAGE);
  });
  it('assigning location to about:blank', async({page, server}) => {
    await page.goto(server.EMPTY_PAGE);
    await page.evaluate(`window.location.href = "about:blank";`);
  });
  it('assigning location to about:blank after non-about:blank', async({page, server}) => {
    server.setRoute('/empty.html', async (req, res) => {});
    await page.evaluate(`
        window.location.href = "${server.EMPTY_PAGE}";
        window.location.href = "about:blank";`);
  });
  it('calling window.open and window.close', async function({page, server}) {
    await page.goto(server.EMPTY_PAGE);
    await page.evaluate(() => {
      const popup = window.open(window.location.href);
      popup.close();
    });
  });
  it('opening a popup', async function({page, server}) {
    await page.goto(server.EMPTY_PAGE);
    await Promise.all([
      page.waitForEvent('popup'),
      page.evaluate(() => window._popup = window.open(window.location.href)),
    ]);
  });
});

<|endoftext|>


<commit_before>describe("base64", function()
{
    var assert = chai.assert;

    describe("sanity", function()
    {
        var str = 'abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123';
        var expected = 'YWJjMTIzYWJjMTIzYWJjMTIzYWJjMTIzYWJjMTIzYWJjMTIzYWJjMTIzYWJjMTIzYWJjMTIzYWJjMTIz';
        var encoded;

        it("should result in expected base64 value after encoding", function()
        {
            encoded = cyphrd.crypto.base64.encode(str);
            assert.equal(encoded, expected);
        });

        it("should result in original value after decoding", function()
        {
            assert.equal(cyphrd.crypto.base64.decode(encoded), str);
        });
    });

    describe("truism tests", function()
    {
        it("should match values", function()
        {
            assert.equal(cyphrd.crypto.base64.encode('abc123'), 'YWJjMTIz');
        });
    });
});<commit_msg>Added browser test, test against the browser's base64 (assuming that the browser is correct).<commit_after>describe("base64", function()
{
    var assert = chai.assert;

    describe("sanity", function()
    {
        var str = 'abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123';
        var expected = 'YWJjMTIzYWJjMTIzYWJjMTIzYWJjMTIzYWJjMTIzYWJjMTIzYWJjMTIzYWJjMTIzYWJjMTIzYWJjMTIz';
        var encoded;

        it("should result in expected base64 value after encoding", function()
        {
            encoded = cyphrd.crypto.base64.encode(str);
            assert.equal(encoded, expected);
        });

        it("should result in original value after decoding", function()
        {
            assert.equal(cyphrd.crypto.base64.decode(encoded), str);
        });
    });

    describe("truism tests", function()
    {
        it("should match values", function()
        {
            assert.equal(cyphrd.crypto.base64.encode('abc123'), 'YWJjMTIz');
        });
    });

    describe("browser truism tests", function()
    {
        it("browser should support base64 natively", function()
        {
            assert.notEqual(window.btoa, cyphrd.crypto.base64.encode);
        });

        it("should match", function()
        {
            assert.equal(window.btoa('hello world'), cyphrd.crypto.base64.encode('hello world'));
            assert.equal(window.btoa('8247198571298571928'), cyphrd.crypto.base64.encode('8247198571298571928'));
            assert.equal(window.btoa('{hello: true, this: false, that: "muahaha"}'), cyphrd.crypto.base64.encode('{hello: true, this: false, that: "muahaha"}'));
        });

        it("utf8 test", function()
        {
            assert.equal(window.btoa('©'), cyphrd.crypto.base64.encode('©'));
        });
    });
});<|endoftext|>


<commit_before>const assert = require('assert');
const Compiler = require('../../src/compile/compiler');
const defaults = require('../../src/compile/defaults');
const ruleNative = require('../../src/compile/adapter/rule.native');

const compressor = ({ source }) => {
    return source
        .replace(/\s+/g, ` `)
        .replace(//g, ``);
};

module.exports = {
    before: () => {
        console.log('#compile/index');
    },

    'getVariables': {
        'basic': ()=>{
            const test = (code, result) => {
                const tokens = Compiler.prototype.getEsTokens(code);
                const variables = Compiler.prototype.getVariables(tokens);
                assert.deepEqual(result, variables);
            };

            test('var', []);
            test('var a', ['a']);
            test('a', ['a']);
            test('a.b', ['a']);
            test('a.b;c', ['a', 'c']);
            test('a.b\nd', ['a', 'd']);
            test('0.99 + a', ['a']);
            test('0.99 + a + b.c', ['a', 'b']);
            test('a /*.*/. b /**/; c', ['a', 'c']);
            test('a ".b.c; d;" /*e*/ f', ['a', 'f']);

            test('a[b]', ['a', 'b']);
            test('a[b].c[d]', ['a', 'b', 'd']);
            test('a["b"]', ['a']);
        }
    },

    'importContext': {

        'basic': () => {
            const test = (code, result, options) => {
                options = defaults.$extend(options);
                options.source = '';
                const compiler = new Compiler(options);
                compiler.importContext(code);
                result.$out = '""';
                assert.deepEqual(result, compiler.context);
            };

            test('value', {
                value: '$data.value'
            });

            test('if', {});
            test('for', {});
            test('$data', {});
            test('$imports', {});

            test('print', { print: "function(){$out+=''.concat.apply('',arguments)}" });
            test('include', { include: "function(src,data){$out+=$imports.$include(src,data||$data,$options)}" })

            test('$escape', { $escape: '$imports.$escape' });
            test('$include', { $include: '$imports.$include' });

        },

        'imports': () => {
            const options = defaults.$extend({});
            options.imports.Math = Math;
            options.source = '';
            const compiler = new Compiler(options);
            compiler.importContext('Math');
            assert.deepEqual({
                $out: '""',
                Math: '$imports.Math'
            }, compiler.context);
        }
    },

    'addSource': {
        basic: () => {
            const test = (code, result, options) => {
                options = defaults.$extend(options);
                options.source = code;
                const compiler = new Compiler(options);
                assert.deepEqual(result, compiler.scripts.map(script => script.code));
            };

            test('hello', ['$out+="hello"']);
            test('<%=value%>', ['$out+=$escape(value)']);

            test('hello<%=value%>', ['$out+="hello"', '$out+=$escape(value)']);
            test('hello\n<%=value%>', ['$out+="hello\\n"', '$out+=$escape(value)']);

            test('<% if (value) { %>\nhello\n<% } %>', ['if (value) {', '$out+="\\nhello\\n"', '}']);
        }
    },

    'parseString': {
        'basic': () => {
            const test = (code, result, options) => {
                it(code, () => {
                    options = defaults.$extend(options);
                    options.source = '';
                    const compiler = new Compiler(options);
                    const token = compiler.getTplTokens(code, [ruleNative]);
                    compiler.parseString(token[0]);
                    assert.deepEqual(result, compiler.scripts.map(script => script.code));
                });
            };

            // raw
            test('hello', ['$out+="hello"']);
            test('\'hello\'', ['$out+="\'hello\'"']);
            test('"hello    world"', ['$out+="\\"hello    world\\""']);
            test('
hello
', ['$out+="
hello
"']);
            test('
hello
', ['$out+="
hello
"']);

            // compressor
            test('  hello  ', ['$out+=" hello "'], { compressor });
            test('\n  hello  \n\n.', ['$out+=" hello ."'], { compressor });
            test('"hello    world"', ['$out+="\\"hello world\\""'], { compressor });
            test('\'hello    world\'', ['$out+="\'hello world\'"'], { compressor });
        },

        'parseExpression': () => {
            const test = (code, result, options) => {
                it(code, () => {
                    options = defaults.$extend(options);
                    options.source = '';
                    const compiler = new Compiler(options);
                    const token = compiler.getTplTokens(code, [ruleNative]);
                    compiler.parseExpression(token[0]);
                    assert.deepEqual(result, compiler.scripts.map(script => script.code));
                });
            };

            // v3 compat
            test('<%=value%>', ['$out+=$escape(value)']);
            test('<%=#value%>', ['$out+=value']);

            // v4
            test('<%-value%>', ['$out+=value']);
            test('<%- value %>', ['$out+= value']);

            test('<%=value%>', ['$out+=value'], { escape: false });
            test('<%-value%>', ['$out+=value'], { escape: false });

            test('<%if (value) {%>', ['if (value) {']);
            test('<% if (value) { %>', [' if (value) { ']);
            test('<%    if ( value ) {    %>', ['    if ( value ) {    '], {
                compressor
            });
        }
    },

    'checkExpression': {
        'basic': () => {
            const test = (code, result, options) => {
                options = defaults.$extend(options);
                options.source = code;
                const compiler = new Compiler(options);
                assert.deepEqual(result, compiler.checkExpression(code));
            };

            test('if(a){', true);
            test('for(var i in d){', true);
            test('list.forEach(function(a,b){', true);
            test('list.forEach((a,b)=>{', true);
            test('$each(user.tags,function($value,$index){;', true);
            test('}else if(a){', true);
            test('}else{', true);
            test('}', true);

            test('if(a){}', true);
            test('for(var i in d){}', true);
            test('list.forEach(function(a,b){})', true);
            test('list.forEach((a,b)=>{})', true);

            test('@if(a){', false);
            test('@for(var i in d){', false);
            test('@list.forEach(function(a,b){', false);
            test('@list.forEach((a,b)=>{', false);
        }
    },

    'build': {
        basic: () => {
            const test = (code, result, options) => {
                options = defaults.$extend(options);
                options.source = code;
                const compiler = new Compiler(options);
                compiler.build();
                assert.deepEqual(result, compiler.scripts.map(script => script.code));
            };

            test('hello', ['$out+="hello"']);
            test('<%=value%>', ['$out+=$escape(value)']);
            test('hello <%=value%>.', ['$out+="hello "', '$out+=$escape(value)', '$out+="."']);
            test('<%-value%>', ['$out+=value']);
            test('hello <%-value%>.', ['$out+="hello "', '$out+=value', '$out+="."']);

            test('hello<%=value%>', ['$out+="hello"', '$out+=$escape(value)']);
            test('hello\n<%=value%>', ['$out+="hello\\n"', '$out+=$escape(value)']);

            test('<% if (value) { %>\nhello\n<% } %>', ['if (value) {', '$out+="\\nhello\\n"', '}']);

            // compileDebug
            test('<%-value%>', ['$line=[0,0,\"<%-value%>\"]', '$out+=value'], {
                compileDebug: true
            });
            // CompileError
        },

        'CompileError': {
            'throw': () => {
                const options = Object.create(defaults);
                options.source = 'hello\n\n<% a b c d %>';
                const compiler = new Compiler(options);

                try {
                    compiler.build();
                } catch (e) {
                    assert.deepEqual('CompileError', e.name);
                    assert.deepEqual(3, e.line);
                }
            }
        }

    }
};<commit_msg>添加测试用例<commit_after>const assert = require('assert');
const Compiler = require('../../src/compile/compiler');
const defaults = require('../../src/compile/defaults');
const ruleNative = require('../../src/compile/adapter/rule.native');

const compressor = ({ source }) => {
    return source
        .replace(/\s+/g, ` `)
        .replace(//g, ``);
};

module.exports = {
    before: () => {
        console.log('#compile/index');
    },

    'getVariables': {
        'basic': ()=>{
            const test = (code, result) => {
                const tokens = Compiler.prototype.getEsTokens(code);
                const variables = Compiler.prototype.getVariables(tokens);
                assert.deepEqual(result, variables);
            };

            test('var', []);
            test('var a', ['a']);
            test('a', ['a']);
            test('a.b', ['a']);
            test('a.b;c', ['a', 'c']);
            test('a.b\nd', ['a', 'd']);
            test('0.99 + a', ['a']);
            test('0.99 + a + b.c', ['a', 'b']);
            test('a /*.*/. b /**/; c', ['a', 'c']);
            test('a ".b.c; d;" /*e*/ f', ['a', 'f']);

            test('a[b]', ['a', 'b']);
            test('a[b].c[d]', ['a', 'b', 'd']);
            test('a["b"]', ['a']);
            test('a["b"].c', ['a']);

            test(`var a, b, c`, ['a', 'b', 'c']);
            test(`function a(b,c){d}`, ['a', 'b', 'c', 'd']);
            test(`try{a}catch(b){c}`, ['a', 'b', 'c']);
        }
    },

    'importContext': {

        'basic': () => {
            const test = (code, result, options) => {
                options = defaults.$extend(options);
                options.source = '';
                const compiler = new Compiler(options);
                compiler.importContext(code);
                result.$out = '""';
                assert.deepEqual(result, compiler.context);
            };

            test('value', {
                value: '$data.value'
            });

            test('if', {});
            test('for', {});
            test('$data', {});
            test('$imports', {});

            test('print', { print: "function(){$out+=''.concat.apply('',arguments)}" });
            test('include', { include: "function(src,data){$out+=$imports.$include(src,data||$data,$options)}" })

            test('$escape', { $escape: '$imports.$escape' });
            test('$include', { $include: '$imports.$include' });

        },

        'imports': () => {
            const options = defaults.$extend({});
            options.imports.Math = Math;
            options.source = '';
            const compiler = new Compiler(options);
            compiler.importContext('Math');
            assert.deepEqual({
                $out: '""',
                Math: '$imports.Math'
            }, compiler.context);
        }
    },

    'addSource': {
        basic: () => {
            const test = (code, result, options) => {
                options = defaults.$extend(options);
                options.source = code;
                const compiler = new Compiler(options);
                assert.deepEqual(result, compiler.scripts.map(script => script.code));
            };

            test('hello', ['$out+="hello"']);
            test('<%=value%>', ['$out+=$escape(value)']);

            test('hello<%=value%>', ['$out+="hello"', '$out+=$escape(value)']);
            test('hello\n<%=value%>', ['$out+="hello\\n"', '$out+=$escape(value)']);

            test('<% if (value) { %>\nhello\n<% } %>', ['if (value) {', '$out+="\\nhello\\n"', '}']);
        }
    },

    'parseString': {
        'basic': () => {
            const test = (code, result, options) => {
                it(code, () => {
                    options = defaults.$extend(options);
                    options.source = '';
                    const compiler = new Compiler(options);
                    const token = compiler.getTplTokens(code, [ruleNative]);
                    compiler.parseString(token[0]);
                    assert.deepEqual(result, compiler.scripts.map(script => script.code));
                });
            };

            // raw
            test('hello', ['$out+="hello"']);
            test('\'hello\'', ['$out+="\'hello\'"']);
            test('"hello    world"', ['$out+="\\"hello    world\\""']);
            test('
hello
', ['$out+="
hello
"']);
            test('
hello
', ['$out+="
hello
"']);

            // compressor
            test('  hello  ', ['$out+=" hello "'], { compressor });
            test('\n  hello  \n\n.', ['$out+=" hello ."'], { compressor });
            test('"hello    world"', ['$out+="\\"hello world\\""'], { compressor });
            test('\'hello    world\'', ['$out+="\'hello world\'"'], { compressor });
        },

        'parseExpression': () => {
            const test = (code, result, options) => {
                it(code, () => {
                    options = defaults.$extend(options);
                    options.source = '';
                    const compiler = new Compiler(options);
                    const token = compiler.getTplTokens(code, [ruleNative]);
                    compiler.parseExpression(token[0]);
                    assert.deepEqual(result, compiler.scripts.map(script => script.code));
                });
            };

            // v3 compat
            test('<%=value%>', ['$out+=$escape(value)']);
            test('<%=#value%>', ['$out+=value']);

            // v4
            test('<%-value%>', ['$out+=value']);
            test('<%- value %>', ['$out+= value']);

            test('<%=value%>', ['$out+=value'], { escape: false });
            test('<%-value%>', ['$out+=value'], { escape: false });

            test('<%if (value) {%>', ['if (value) {']);
            test('<% if (value) { %>', [' if (value) { ']);
            test('<%    if ( value ) {    %>', ['    if ( value ) {    '], {
                compressor
            });
        }
    },

    'checkExpression': {
        'basic': () => {
            const test = (code, result, options) => {
                options = defaults.$extend(options);
                options.source = code;
                const compiler = new Compiler(options);
                assert.deepEqual(result, compiler.checkExpression(code));
            };

            test('if(a){', true);
            test('for(var i in d){', true);
            test('list.forEach(function(a,b){', true);
            test('list.forEach((a,b)=>{', true);
            test('$each(user.tags,function($value,$index){;', true);
            test('}else if(a){', true);
            test('}else{', true);
            test('}', true);

            test('if(a){}', true);
            test('for(var i in d){}', true);
            test('list.forEach(function(a,b){})', true);
            test('list.forEach((a,b)=>{})', true);

            test('@if(a){', false);
            test('@for(var i in d){', false);
            test('@list.forEach(function(a,b){', false);
            test('@list.forEach((a,b)=>{', false);
        }
    },

    'build': {
        basic: () => {
            const test = (code, result, options) => {
                options = defaults.$extend(options);
                options.source = code;
                const compiler = new Compiler(options);
                compiler.build();
                assert.deepEqual(result, compiler.scripts.map(script => script.code));
            };

            test('hello', ['$out+="hello"']);
            test('<%=value%>', ['$out+=$escape(value)']);
            test('hello <%=value%>.', ['$out+="hello "', '$out+=$escape(value)', '$out+="."']);
            test('<%-value%>', ['$out+=value']);
            test('hello <%-value%>.', ['$out+="hello "', '$out+=value', '$out+="."']);

            test('hello<%=value%>', ['$out+="hello"', '$out+=$escape(value)']);
            test('hello\n<%=value%>', ['$out+="hello\\n"', '$out+=$escape(value)']);

            test('<% if (value) { %>\nhello\n<% } %>', ['if (value) {', '$out+="\\nhello\\n"', '}']);

            // compileDebug
            test('<%-value%>', ['$line=[0,0,\"<%-value%>\"]', '$out+=value'], {
                compileDebug: true
            });
            // CompileError
        },

        'CompileError': {
            'throw': () => {
                const options = Object.create(defaults);
                options.source = 'hello\n\n<% a b c d %>';
                const compiler = new Compiler(options);

                try {
                    compiler.build();
                } catch (e) {
                    assert.deepEqual('CompileError', e.name);
                    assert.deepEqual(3, e.line);
                }
            }
        }

    }
};<|endoftext|>


<commit_before>/**
 * Created by Mihail on 10/2/2016.
 */
'use strict';

import assert from 'assert';
import Ball from '../../src/dauber/ball';
import { expect } from 'chai';
import jsdom  from 'mocha-jsdom';

describe('Ball module', () => {

	jsdom();
	/*const ball = new Ball(34);

	it('Should create a ball object', (done) => {
		expect(ball).not.to.be.undefined;
		done();
	});

	it('Should create a ball object with given number', (done) => {
		expect(ball.number).not.to.be.undefined;
		expect(ball.number).to.be.equal(34);
		done();
	});

	it('Should create a ball object with given color', (done) => {
		expect(ball.color).not.to.be.undefined;
		expect(ball.color).to.be.equal('radial-gradient(circle, #660099, #fff)');
		done();
	});

	it('Should be able to draw itself', (done) => {
		expect(ball.draw).not.to.be.undefined;
		const el = document.createElement('div');
		el.setAttribute('id', 'tube');
		ball.draw(el);
		expect(document.querySelector('#tube')).to.have.children;
		done();
	});*/
});<commit_msg>Fixed Ball unit tests.<commit_after>/**
 * Created by Mihail on 10/2/2016.
 */
'use strict';

import assert from 'assert';
import Ball from '../../src/dauber/ball';
import PubSub from '../../src/events/pubsub-service';
import { expect } from 'chai';
import jsdom  from 'mocha-jsdom';

describe('Ball module', () => {

	jsdom();

	it('Should create a ball object', (done) => {
		const pb = new PubSub();
		const ball = new Ball(34, pb);
		expect(ball).not.to.be.undefined;
		done();
	});

	it('Should create a ball object with given number', (done) => {
		const pb = new PubSub();
		const ball = new Ball(34, pb);
		expect(ball.elNumber.innerText).not.to.be.undefined;
		expect(ball.elNumber.innerText).to.be.equal(34);
		done();
	});

	it('Should create a ball object with given color', (done) => {
		const pb = new PubSub();
		const ball = new Ball(34, pb);
		expect(ball.elBall.style.backgroundImage).not.to.be.undefined;
		expect(ball.elBall.style.borderColor).to.be.equal('#660099');
		done();
	});

	it('Should be able to draw itself', (done) => {
		const pb = new PubSub();
		const ball = new Ball(34, pb);
		expect(ball.draw).not.to.be.undefined;
		const el = document.createElement('div');
		el.setAttribute('id', 'tube');
		ball.draw(el);
		expect(document.querySelector('#tube')).to.have.children;
		done();
	});

	it('Should have methods move, animate, bounce and quad', (done) => {
		const pb = new PubSub();
		const ball = new Ball(34, pb);
		expect(ball.move).not.to.be.undefined;
		expect(ball.animate).not.to.be.undefined;
		expect(Ball.bounce).not.to.be.undefined;
		expect(Ball.quad).not.to.be.undefined;
		done();
	});
});<|endoftext|>


<commit_before>'use strict';

const test = require('blue-tape');
const fs = require('fs');
const path = require('path');
const writer = require('../lib/file-writer.js');

const xmlObject = {
  dependencies: {
    dependency: [
      {
        packageName: 'testProject',
        version: '1.0.0',
        licenses: {
          license: [
            {name: 'MIT', url: '...'}
          ]
        }
      },
      {
        packageName: 'notApproved',
        version: '2.0.0',
        licenses: {
          license: [
            {name: '9wm License (Original)', url: '...'}
          ]
        }
      }
    ]
  }
};

test('Should create foo.xml.', (t) => {
  writer.createXml({file: 'foo.xml', silent: true}, xmlObject);
  t.equal(fs.existsSync('foo.xml'), true, 'foo.xml file created.');
  fs.unlinkSync('foo.xml');
  t.end();
});

test('Should create HTML file.', (t) => {
  const options = {css: path.join(__dirname, '../lib/resources/licenses.css')};
  options.directory = process.cwd();
  return Promise.resolve(writer.createHtml(options, xmlObject))
  .then(() => {
    t.equal(fs.existsSync('license.html'), true, 'HTML file created.');
    fs.unlink('license.html', () => {});
    fs.unlink('licenses.css', () => {});
  });
});
<commit_msg>src: test merge xmls<commit_after>'use strict';

const test = require('blue-tape');
const fs = require('fs');
const path = require('path');
const writer = require('../lib/file-writer.js');

const xmlObject = {
  dependencies: {
    dependency: [
      {
        packageName: 'testProject',
        version: '1.0.0',
        licenses: {
          license: [
            {name: 'MIT', url: '...'}
          ]
        }
      },
      {
        packageName: 'notApproved',
        version: '2.0.0',
        licenses: {
          license: [
            {name: '9wm License (Original)', url: '...'}
          ]
        }
      }
    ]
  }
};

test('Should create foo.xml.', (t) => {
  writer.createXml({file: 'foo.xml', silent: true}, xmlObject);
  t.equal(fs.existsSync('foo.xml'), true, 'foo.xml file created.');
  fs.unlinkSync('foo.xml');
  t.end();
});

test('Should create HTML file.', (t) => {
  const options = {css: path.join(__dirname, '../lib/resources/licenses.css')};
  options.directory = process.cwd();
  return Promise.resolve(writer.createHtml(options, xmlObject))
  .then(() => {
    t.equal(fs.existsSync('license.html'), true, 'HTML file created.');
    fs.unlink('license.html', () => {});
    fs.unlink('licenses.css', () => {});
  });
});

test('Should merge XMLs.', (t) => {
  writer.createXml({file: 'foo.xml', silent: true}, xmlObject);
  writer.createXml({file: 'bar.xml', silent: true}, xmlObject);
  const options = {mergeProductName: 'fooBar', mergeXmls: 'foo.xml,bar.xml', mergeOutput: 'fooBar.xml'};
  return Promise.resolve(writer.mergeXmls(options))
  .then(() => {
    t.equal(fs.access('fooBar.xml', (err) => { if (!err) return true; }, true));
    fs.unlink('foo.xml', () => {});
    fs.unlink('bar.xml', () => {});
    setTimeout(() => fs.unlink('fooBar.xml', () => {}), 1000);
  });
});
<|endoftext|>


<commit_before>const gs = require('./../src/ghostscript');
const rimraf = require('rimraf');
const assert = require('assert');

describe('ghostscript-js', function () {
  it('should convert some pdf to tiff', function (done) {
    gs.exec([
      '-q',
      '-dNOPAUSE',
      '-dBATCH',
      '-sDEVICE=tiff24nc',
      '-r300',
      `-sOutputFile=${__dirname}/output-%03d.tiff`,
      `${__dirname}/test.pdf`
    ], (codeError) => {
      if (codeError) return done(err);
      done();
    });
  });
  it('should return an code error fatal', function (done) {
    gs.exec([
      '-q',
      '-dNOPAUSE',
      '-dBATCH',
      '-sDEVICE=tiff24nc',
      '-r300',
      `-sOutputFile=${__dirname}/output-%03d.tiff`,
      `${__dirname}/no-test.pdf`
    ], (codeError) => {
      assert.equal(codeError, -100);
      done();
    });
  });
  after(function () {
    rimraf.sync(`${__dirname}/output-*.tiff`);
  });
});
<commit_msg>bugfix<commit_after>const gs = require('./../src/ghostscript');
const rimraf = require('rimraf');
const assert = require('assert');

describe('ghostscript-js', function () {
  it('should convert some pdf to tiff', function (done) {
    gs.exec([
      '-q',
      '-dNOPAUSE',
      '-dBATCH',
      '-sDEVICE=tiff24nc',
      '-r300',
      `-sOutputFile=${__dirname}/output-%03d.tiff`,
      `${__dirname}/test.pdf`
    ], (codeError) => {
      if (codeError) return done(codeError);
      done();
    });
  });
  it('should return an code error fatal', function (done) {
    gs.exec([
      '-q',
      '-dNOPAUSE',
      '-dBATCH',
      '-sDEVICE=tiff24nc',
      '-r300',
      `-sOutputFile=${__dirname}/output-%03d.tiff`,
      `${__dirname}/no-test.pdf`
    ], (codeError) => {
      assert.equal(codeError, -100);
      done();
    });
  });
  after(function () {
    rimraf.sync(`${__dirname}/output-*.tiff`);
  });
});
<|endoftext|>


<commit_before>/**
 * Integration tests using server-start.sh script
 */
'use strict';

var vows = require('vows'),
	assert = require('assert'),
	phantomas = require('..');

// see start-server.sh
var WEBROOT = 'http://127.0.0.1:8888';

// run the test
vows.describe('Integration tests').addBatch({
	'/dom.html': {
		topic: function() {
			phantomas(WEBROOT + '/dom.html', this.callback);
		},
		'metrics should match': function(err, data, results) {
			assert.equal(err, null);

			var metrics = {
				requests: 3,
				cssCount: 1,
				jsCount: 1,
				domains: 2,
				DOMqueries: 10,
				DOMqueriesById: 3,
				DOMqueriesByClassName: 1,
				DOMqueriesByTagName: 5,
				DOMqueriesByQuerySelectorAll: 1,
				DOMinserts: 2,
				DOMqueriesDuplicated: 3,
			};

			Object.keys(metrics).forEach(function(name) {
				assert.equal(results.getMetric(name), metrics[name], name + ' should be = ' + metrics[name]);
			});
		}
	},
}).export(module);
<commit_msg>Check that the server is up and running<commit_after>/**
 * Integration tests using server-start.sh script
 */
'use strict';

var vows = require('vows'),
	assert = require('assert'),
	phantomas = require('..');

// see start-server.sh
var WEBROOT = 'http://127.0.0.1:8888';

// run the test
vows.describe('Integration tests').addBatch({
	'server': {
		topic: function() {
			var http = require('http'),
				self = this;

			http.get(WEBROOT + '/', function(res) {
				self.callback(null, res);
			}).on('error', self.callback);
		},
		'should be up and running': function(err, res) {
			assert.equal(typeof res !== 'undefined', true);
			assert.equal(res.statusCode, 200);
		}
	},
	'/dom.html': {
		topic: function() {
			phantomas(WEBROOT + '/dom.html', this.callback);
		},
		'metrics should match': function(err, data, results) {
			assert.equal(err, null);

			var metrics = {
				requests: 3,
				cssCount: 1,
				jsCount: 1,
				domains: 2,
				DOMqueries: 10,
				DOMqueriesById: 3,
				DOMqueriesByClassName: 1,
				DOMqueriesByTagName: 5,
				DOMqueriesByQuerySelectorAll: 1,
				DOMinserts: 2,
				DOMqueriesDuplicated: 3,
			};

			Object.keys(metrics).forEach(function(name) {
				assert.equal(results.getMetric(name), metrics[name], name + ' should be = ' + metrics[name]);
			});
		}
	},
}).export(module);
<|endoftext|>


<commit_before>var should = require("should");

describe('ErrorHandler', function () {
	var ErrorHandler = require('../../lib/ErrorHandler');
	var msg = 'fresh peaches';

	describe('#()', function () {
		var errorHandler = new ErrorHandler();

		describe('.options', function () {
			describe('.logger', function () {
				it('should be equal to console.log() by default', function () {
					errorHandler.options.logger.should.equal(console.log);
				});
			});

			describe('.strict', function () {
				it('should be equal to true by default', function () {
					errorHandler.options.strict.should.equal(true);
				});
			});

			describe('.verbose', function () {
				it('should be equal to true by default', function () {
					errorHandler.options.verbose.should.equal(true);
				});
			});
		});
	});

	describe('#({ strict: true })', function () {
		var errorHandler = new ErrorHandler({ strict: true, logger: function() { /* silence the logger */ } });

		describe('.options', function () {
			describe('.strict', function () {
				it('should be equal to true ', function () {
					errorHandler.options.strict.should.equal(true);
				});
			});
		});

		describe('#log()', function () {
			it('should throw an error', function () {
				(function(){
					errorHandler.log(msg);
				}).should.throw();
			});

			it('should throw an error labeled exactly like the log message', function () {
				(function(){
					errorHandler.log(msg);
				}).should.throw(msg);
			});
		});
	});

	describe('#({ strict: false })', function () {
		var errorHandler = new ErrorHandler({ strict: false, logger: function() { /* silence the logger */ } });

		describe('.options', function () {
			describe('.strict', function () {
				it('should be equal to false ', function () {
					errorHandler.options.strict.should.equal(false);
				});
			});
		});

		describe('#log()', function () {
			it('should throw not an error', function () {
				(function(){
					errorHandler.log(msg);
				}).should.not.throw();
			});
		});
	});

	describe('#({ verbose: true })', function () {
		describe('.options', function () {
			describe('.verbose', function () {
				var errorHandler = new ErrorHandler({ verbose: true });

				it('should be equal to true ', function () {
					errorHandler.options.verbose.should.equal(true);
				});
			});
		});

		describe('#log()', function () {

			it('should call the logger function', function (done) {
				var errorHandler = new ErrorHandler({
					strict: false, // Silence error-throwing
					verbose: true,
					logger: function (m) {
						if(msg == m) {
							done();
						}
						else {
							done(new Error());
						}
					}
				});

				errorHandler.log(msg);
			});
		});
	});

	describe('#({ verbose: false })', function () {
		describe('.options', function () {
			describe('.verbose', function () {
				var errorHandler = new ErrorHandler({ verbose: false });

				it('should be equal to false ', function () {
					errorHandler.options.verbose.should.equal(false);
				});
			});
		});

		describe('#log()', function () {
			it('should not call the logger function', function () {
				var errorHandler = new ErrorHandler({
					strict: false, // Silence error-throwing
					verbose: false,
					logger: function (m) {
						done(new Error());
					}
				});

				errorHandler.log(msg);
			});
		});
	});
});<commit_msg>Minor: Fixed grammar<commit_after>var should = require("should");

describe('ErrorHandler', function () {
	var ErrorHandler = require('../../lib/ErrorHandler');
	var msg = 'fresh peaches';

	describe('#()', function () {
		var errorHandler = new ErrorHandler();

		describe('.options', function () {
			describe('.logger', function () {
				it('should be equal to console.log() by default', function () {
					errorHandler.options.logger.should.equal(console.log);
				});
			});

			describe('.strict', function () {
				it('should be equal to true by default', function () {
					errorHandler.options.strict.should.equal(true);
				});
			});

			describe('.verbose', function () {
				it('should be equal to true by default', function () {
					errorHandler.options.verbose.should.equal(true);
				});
			});
		});
	});

	describe('#({ strict: true })', function () {
		var errorHandler = new ErrorHandler({ strict: true, logger: function() { /* silence the logger */ } });

		describe('.options', function () {
			describe('.strict', function () {
				it('should be equal to true ', function () {
					errorHandler.options.strict.should.equal(true);
				});
			});
		});

		describe('#log()', function () {
			it('should throw an error', function () {
				(function(){
					errorHandler.log(msg);
				}).should.throw();
			});

			it('should throw an error labeled exactly like the log message', function () {
				(function(){
					errorHandler.log(msg);
				}).should.throw(msg);
			});
		});
	});

	describe('#({ strict: false })', function () {
		var errorHandler = new ErrorHandler({ strict: false, logger: function() { /* silence the logger */ } });

		describe('.options', function () {
			describe('.strict', function () {
				it('should be equal to false ', function () {
					errorHandler.options.strict.should.equal(false);
				});
			});
		});

		describe('#log()', function () {
			it('should not throw an error', function () {
				(function(){
					errorHandler.log(msg);
				}).should.not.throw();
			});
		});
	});

	describe('#({ verbose: true })', function () {
		describe('.options', function () {
			describe('.verbose', function () {
				var errorHandler = new ErrorHandler({ verbose: true });

				it('should be equal to true ', function () {
					errorHandler.options.verbose.should.equal(true);
				});
			});
		});

		describe('#log()', function () {

			it('should call the logger function', function (done) {
				var errorHandler = new ErrorHandler({
					strict: false, // Silence error-throwing
					verbose: true,
					logger: function (m) {
						if(msg == m) {
							done();
						}
						else {
							done(new Error());
						}
					}
				});

				errorHandler.log(msg);
			});
		});
	});

	describe('#({ verbose: false })', function () {
		describe('.options', function () {
			describe('.verbose', function () {
				var errorHandler = new ErrorHandler({ verbose: false });

				it('should be equal to false ', function () {
					errorHandler.options.verbose.should.equal(false);
				});
			});
		});

		describe('#log()', function () {
			it('should not call the logger function', function () {
				var errorHandler = new ErrorHandler({
					strict: false, // Silence error-throwing
					verbose: false,
					logger: function (m) {
						done(new Error());
					}
				});

				errorHandler.log(msg);
			});
		});
	});
});<|endoftext|>


<commit_before>const should = require('should');
const passwordHash = require('./../../lib/passwordHash');

describe('passwordHash', () => {
  describe('.generate(password, [options])', () => {
    it('should throw an error if the password is not a valid string', () => {
      const invalid = [
        null,
        undefined,
        true,
        false,
        123,
        456.78,
        new Date(),
        {},
        [],
        function empty() {},
      ];

      invalid.forEach((value) => {
        let err;
        try {
          passwordHash.generate(value);
        } catch (e) {
          err = e;
        }
        should(err).be.instanceof(Error);
        should(err.message).equal('Invalid password');
      });
    });
  });
});
<commit_msg>should throw an error if an invalid message digest algorithm is specified<commit_after>const should = require('should');
const passwordHash = require('./../../lib/passwordHash');

describe('passwordHash', () => {
  describe('.generate(password, [options])', () => {
    it('should throw an error if the password is not a valid string', () => {
      const invalid = [
        null,
        undefined,
        true,
        false,
        123,
        456.78,
        new Date(),
        {},
        [],
        function empty() {},
      ];

      invalid.forEach((value) => {
        let err;
        try {
          passwordHash.generate(value);
        } catch (e) {
          err = e;
        }
        should(err).be.instanceof(Error);
        should(err.message).equal('Invalid password');
      });
    });

    it('should throw an error if an invalid message digest algorithm is specified', () => {
      let err;
      try {
        passwordHash.generate('password123', { algorithm: 'foo' });
      } catch (e) {
        err = e;
      }
      should(err).be.instanceof(Error);
      should(err.message).equal('Invalid message digest algorithm');
    });
  });
});
<|endoftext|>