<commit_before>package("kb.Stage", function(exports) {
	"use strict";

	depends("util/SmoothScroll.js");

	depends("Convert.js");
	depends("Stage.js");
	depends("Page.View.js");

	var StageButtons = React.createClass({
		displayName: "StageButtons",

		toggleWidth: function() {
			this.props.onToggleWidth();
		},
		close: function() {
			this.props.stage.close();
		},

		createFactory: function(ev) {
			var item = {
				id: GenerateID(),
				type: "factory",
				text: ""
			};

			ev.dataTransfer.effectAllowed = "copy";
			var data = {
				item: item
			};

			ev.dataTransfer.setData("Text", JSON.stringify(data));
		},

		deletePage: function() {
			var stage = this.props.stage;
			var check = window.prompt("Delete this page?\nType the page link \"" + stage.link + "\" to confirm:");
			if (check === null) {
				return;
			}
			if (check.trim() !== stage.link.trim()) {
				return;
			}

			stage.destroy();
		},

		render: function() {
			var stage = this.props.stage;
			var a = React.DOM.a;
			return React.DOM.div({
					className: "stage-buttons"
				},
				stage.canModify() ? React.DOM.a({
					className: "mdi mdi-playlist-plus",
					title: "Drag to page to add an item.",
					style: {
						cursor: "move"
					},
					draggable: "true",
					href: "#",
					onClick: function(ev) {
						ev = ev || window.event;
						ev.preventDefault();
					},
					onDragStart: this.createFactory
				}) : null,
				stage.canDestroy() ? a({
					className: "mdi mdi-delete",
					title: "Delete this page.",
					onClick: this.deletePage
				}) : null,
				a({
					className: "mdi " + (this.props.isWide ? "mdi-arrow-collapse" : "mdi-arrow-expand"),
					title: "Toggle page width.",
					onClick: this.toggleWidth
				}),
				a({
					className: "mdi mdi-close",
					title: "Close page.",
					onClick: this.close
				})
			);
		}
	});

	var NewPage = React.createClass({
		displayName: "NewPage",
		contextTypes: {
			Session: React.PropTypes.object
		},
		tryCreate: function(ev) {
			var stage = this.props.stage;

			stage.title = this.state.title;
			stage.link = kb.convert.TextToSlug(this.state.owner + "=" + stage.title);
			stage.create();

			ev.preventDefault();
			ev.stopPropagation();
		},

		getInitialState: function() {
			return {
				title: this.props.stage.title,
				owner: kb.convert.LinkToOwner(this.props.stage.link) || "",
				groups: []
			};
		},

		groupsReceived: function(response) {
			if (response.ok) {
				var info = response.json;
				this.setState({
					groups: info.groups || []
				});
			}
		},

		componentDidMount: function() {
			this.context.Session.fetch({
				method: "GET",
				url: "/user=editor-groups",
				ondone: this.groupsReceived,
				headers: {
					"Accept": "application/json"
				}
			});
		},

		ownerChanged: function(ev) {
			this.setState({
				owner: ev.currentTarget.value
			});
		},

		titleChanged: function() {
			this.setState({
				title: this.refs.title.value
			});
		},

		render: function() {
			var self = this;
			var stage = this.props.stage;
			var title = this.state.title,
				owner = this.state.owner,
				link = kb.convert.TextToSlug(owner + "=" + title);

			return React.DOM.div({
					className: "page new-page"
				},
				React.DOM.form({
						onSubmit: this.tryCreate
					},
					React.DOM.label({}, "Link"),
					React.DOM.span({
						className: "link"
					}, link),
					React.DOM.label({
						htmlFor: "new-page-title"
					}, "Title"),
					React.DOM.input({
						id: "new-page-title",
						className: "title",
						ref: "title",
						defaultValue: stage.title,
						onChange: this.titleChanged,
						onKeyUp: this.titleChanged,
						autoFocus: true
					}),
					React.DOM.label({}, "Owner"),
					React.DOM.div({
							className: "group"
						},
						this.state.groups.map(function(group) {
							var checked = owner === group;
							return (
								React.DOM.div({
										key: group,
										className: checked ? "checked" : ""
									},
									React.DOM.input({
										id: "group-" + group,
										type: "radio",
										name: "group",
										value: group,
										onChange: self.ownerChanged,
										checked: checked
									}),
									React.DOM.label({
										htmlFor: "group-" + group
									}, group)
								)
							);
						})
					),
					React.DOM.button({
						type: "submit"
					}, "Create")
				)
			);
		}
	});

	exports.View = React.createClass({
		displayName: "Stage",

		toggleWidth: function() {
			if (this.props.stage.wide) {
				this.props.stage.collapse();
			} else {
				this.props.stage.expand();
			}

			window.setTimeout(this.activate, 100);
		},
		activate: function(ev) {
			if (typeof ev === "undefined") {
				var node = ReactDOM.findDOMNode(this);
				kb.util.SmoothScroll.to(node);
			} else if (!ev.defaultPrevented) {
				var node = ReactDOM.findDOMNode(this);
				kb.util.SmoothScroll.to(node);
			}
		},
		render: function() {
			var stage = this.props.stage;
			if (stage.creating) {
				return React.DOM.div({
						className: "stage",
						onClick: this.activate,
						"data-id": stage.id,

						style: this.props.style
					},
					React.createElement(StageButtons, {
						stage: this.props.stage,
						isWide: stage.wide,
						onToggleWidth: this.toggleWidth
					}),
					React.DOM.div({
							className: "stage-scroll round-scrollbar"
						},
						React.createElement(NewPage, {
							stage: this.props.stage
						})
					)
				);
			}

			return React.DOM.div({
					className: "stage",
					onClick: this.activate,
					"data-id": stage.id,

					style: this.props.style
				},
				React.createElement(StageButtons, {
					stage: this.props.stage,
					isWide: stage.wide,
					onToggleWidth: this.toggleWidth
				}),
				React.DOM.div({
						className: "stage-scroll round-scrollbar"
					},
					React.createElement(kb.Page.View, {
						stage: this.props.stage,
						page: this.props.stage.page
					})
				)
			);
		},

		getInitialState: function() {
			return {
				autoFocus: false,
				autoFocused: false
			};
		},
		// bindings to Stage
		changed: function(ev) {
			if (ev.loaded) {
				this.setState({
					autoFocus: true
				});
			}
			this.forceUpdate();
		},
		componentDidUpdate: function() {
			if (!this.state.autoFocused && this.state.autoFocus) {
				this.setState({
					autoFocused: true,
					autoFocus: false
				});

				var loc = kb.convert.URLToLocation(this.props.stage.link);
				if (loc.fragment !== "") {
					var node = ReactDOM.findDOMNode(this);
					var el = node.querySelector("[data-id=\"" + loc.fragment + "\"]");
					if (el) {
						el.scrollIntoView();
					}
				}
			}
		},
		widthChanged: function() {
			this.props.onWidthChanged();
		},
		componentDidMount: function() {
			this.props.stage.on("changed", this.changed, this);
			this.props.stage.on("widthChanged", this.widthChanged, this);
			this.props.stage.pull();
			this.activate();
		},
		componentWillReceiveProps: function(nextprops) {
			if (this.props.stage !== nextprops.stage) {
				this.props.stage.remove(this);
				nextprops.stage.on("changed", this.changed, this);
				nextprops.stage.on("widthChanged", this.widthChanged, this);
				nextprops.stage.pull();
			}
		},
		componentWillUnmount: function() {
			this.props.stage.remove(this);
		}
	});
});
<commit_msg>Fix fragment handling in focusing to specific item.<commit_after>package("kb.Stage", function(exports) {
	"use strict";

	depends("util/SmoothScroll.js");

	depends("Convert.js");
	depends("Stage.js");
	depends("Page.View.js");

	var StageButtons = React.createClass({
		displayName: "StageButtons",

		toggleWidth: function() {
			this.props.onToggleWidth();
		},
		close: function() {
			this.props.stage.close();
		},

		createFactory: function(ev) {
			var item = {
				id: GenerateID(),
				type: "factory",
				text: ""
			};

			ev.dataTransfer.effectAllowed = "copy";
			var data = {
				item: item
			};

			ev.dataTransfer.setData("Text", JSON.stringify(data));
		},

		deletePage: function() {
			var stage = this.props.stage;
			var check = window.prompt("Delete this page?\nType the page link \"" + stage.link + "\" to confirm:");
			if (check === null) {
				return;
			}
			if (check.trim() !== stage.link.trim()) {
				return;
			}

			stage.destroy();
		},

		render: function() {
			var stage = this.props.stage;
			var a = React.DOM.a;
			return React.DOM.div({
					className: "stage-buttons"
				},
				stage.canModify() ? React.DOM.a({
					className: "mdi mdi-playlist-plus",
					title: "Drag to page to add an item.",
					style: {
						cursor: "move"
					},
					draggable: "true",
					href: "#",
					onClick: function(ev) {
						ev = ev || window.event;
						ev.preventDefault();
					},
					onDragStart: this.createFactory
				}) : null,
				stage.canDestroy() ? a({
					className: "mdi mdi-delete",
					title: "Delete this page.",
					onClick: this.deletePage
				}) : null,
				a({
					className: "mdi " + (this.props.isWide ? "mdi-arrow-collapse" : "mdi-arrow-expand"),
					title: "Toggle page width.",
					onClick: this.toggleWidth
				}),
				a({
					className: "mdi mdi-close",
					title: "Close page.",
					onClick: this.close
				})
			);
		}
	});

	var NewPage = React.createClass({
		displayName: "NewPage",
		contextTypes: {
			Session: React.PropTypes.object
		},
		tryCreate: function(ev) {
			var stage = this.props.stage;

			stage.title = this.state.title;
			stage.link = kb.convert.TextToSlug(this.state.owner + "=" + stage.title);
			stage.create();

			ev.preventDefault();
			ev.stopPropagation();
		},

		getInitialState: function() {
			return {
				title: this.props.stage.title,
				owner: kb.convert.LinkToOwner(this.props.stage.link) || "",
				groups: []
			};
		},

		groupsReceived: function(response) {
			if (response.ok) {
				var info = response.json;
				this.setState({
					groups: info.groups || []
				});
			}
		},

		componentDidMount: function() {
			this.context.Session.fetch({
				method: "GET",
				url: "/user=editor-groups",
				ondone: this.groupsReceived,
				headers: {
					"Accept": "application/json"
				}
			});
		},

		ownerChanged: function(ev) {
			this.setState({
				owner: ev.currentTarget.value
			});
		},

		titleChanged: function() {
			this.setState({
				title: this.refs.title.value
			});
		},

		render: function() {
			var self = this;
			var stage = this.props.stage;
			var title = this.state.title,
				owner = this.state.owner,
				link = kb.convert.TextToSlug(owner + "=" + title);

			return React.DOM.div({
					className: "page new-page"
				},
				React.DOM.form({
						onSubmit: this.tryCreate
					},
					React.DOM.label({}, "Link"),
					React.DOM.span({
						className: "link"
					}, link),
					React.DOM.label({
						htmlFor: "new-page-title"
					}, "Title"),
					React.DOM.input({
						id: "new-page-title",
						className: "title",
						ref: "title",
						defaultValue: stage.title,
						onChange: this.titleChanged,
						onKeyUp: this.titleChanged,
						autoFocus: true
					}),
					React.DOM.label({}, "Owner"),
					React.DOM.div({
							className: "group"
						},
						this.state.groups.map(function(group) {
							var checked = owner === group;
							return (
								React.DOM.div({
										key: group,
										className: checked ? "checked" : ""
									},
									React.DOM.input({
										id: "group-" + group,
										type: "radio",
										name: "group",
										value: group,
										onChange: self.ownerChanged,
										checked: checked
									}),
									React.DOM.label({
										htmlFor: "group-" + group
									}, group)
								)
							);
						})
					),
					React.DOM.button({
						type: "submit"
					}, "Create")
				)
			);
		}
	});

	exports.View = React.createClass({
		displayName: "Stage",

		toggleWidth: function() {
			if (this.props.stage.wide) {
				this.props.stage.collapse();
			} else {
				this.props.stage.expand();
			}

			window.setTimeout(this.activate, 100);
		},
		activate: function(ev) {
			if (typeof ev === "undefined") {
				var node = ReactDOM.findDOMNode(this);
				kb.util.SmoothScroll.to(node);
			} else if (!ev.defaultPrevented) {
				var node = ReactDOM.findDOMNode(this);
				kb.util.SmoothScroll.to(node);
			}
		},
		render: function() {
			var stage = this.props.stage;
			if (stage.creating) {
				return React.DOM.div({
						className: "stage",
						onClick: this.activate,
						"data-id": stage.id,

						style: this.props.style
					},
					React.createElement(StageButtons, {
						stage: this.props.stage,
						isWide: stage.wide,
						onToggleWidth: this.toggleWidth
					}),
					React.DOM.div({
							className: "stage-scroll round-scrollbar"
						},
						React.createElement(NewPage, {
							stage: this.props.stage
						})
					)
				);
			}

			return React.DOM.div({
					className: "stage",
					onClick: this.activate,
					"data-id": stage.id,

					style: this.props.style
				},
				React.createElement(StageButtons, {
					stage: this.props.stage,
					isWide: stage.wide,
					onToggleWidth: this.toggleWidth
				}),
				React.DOM.div({
						className: "stage-scroll round-scrollbar"
					},
					React.createElement(kb.Page.View, {
						stage: this.props.stage,
						page: this.props.stage.page
					})
				)
			);
		},

		getInitialState: function() {
			return {
				autoFocus: false,
				autoFocused: false
			};
		},
		// bindings to Stage
		changed: function(ev) {
			if (ev.loaded) {
				this.setState({
					autoFocus: true
				});
			}
			this.forceUpdate();
		},
		componentDidUpdate: function() {
			if (!this.state.autoFocused && this.state.autoFocus) {
				this.setState({
					autoFocused: true,
					autoFocus: false
				});

				var loc = kb.convert.URLToLocation(this.props.stage.link);
				if (loc.fragment !== "") {
					var id = loc.fragment.substring(1);
					var node = ReactDOM.findDOMNode(this);
					var el = node.querySelector("[data-id=\"" + id + "\"]");
					if (el) {
						el.scrollIntoView();
					}
				}
			}
		},
		widthChanged: function() {
			this.props.onWidthChanged();
		},
		componentDidMount: function() {
			this.props.stage.on("changed", this.changed, this);
			this.props.stage.on("widthChanged", this.widthChanged, this);
			this.props.stage.pull();
			this.activate();
		},
		componentWillReceiveProps: function(nextprops) {
			if (this.props.stage !== nextprops.stage) {
				this.props.stage.remove(this);
				nextprops.stage.on("changed", this.changed, this);
				nextprops.stage.on("widthChanged", this.widthChanged, this);
				nextprops.stage.pull();
			}
		},
		componentWillUnmount: function() {
			this.props.stage.remove(this);
		}
	});
});
<|endoftext|>


<commit_before>
var app = angular.module('isa');

app.config(['$urlRouterProvider', '$stateProvider', '$locationProvider',
    function($urlRouterProvider, $stateProvider, $locationProvider) {

        $locationProvider.html5Mode(true);

        $stateProvider

            .state('base', {
                abstract : true,
                controller : 'BaseController',
                template: '<ui-view/>',
                data : {
                    anonymous : false
                }
            })

            .state('welcome', {
                url: '/welcome',
                parent: 'base',
                templateUrl: 'client/home/home.ng.html',
                controller: 'HomeController',
                data : {
                    anonymous : true
                }
            })
            .state('login', {
                url: '/login',
                parent: 'base',
                templateUrl: 'client/login/login.ng.html',
                controller : 'LoginController',
                data : {
                    anonymous : true
                }
            })
            .state('overview', {
                url: '/overview',
                parent: 'base',
                templateUrl: 'client/overview/overview.ng.html',
                controller: 'OverviewController'
            })

            /**
             * This is the parent route for all modules. It defines a url with the required
             * organisation and module identifiers.
             */
            .state('module', {
                url : '/organisation/:orgId/module/:moduleId',
                parent: 'base',
                abstract: true,
                template: '<ui-view/>',
                resolve: {
                    module: ['$stateParams', function($stateParams) {
                        return Modules.find({ _id: $stateParams.moduleId });
                    }]
                }
            })

        $urlRouterProvider.otherwise('/welcome');

    }]);
<commit_msg>routes: fixed how the current module is resolved<commit_after>
var app = angular.module('isa');

app.config(['$urlRouterProvider', '$stateProvider', '$locationProvider',
    function($urlRouterProvider, $stateProvider, $locationProvider) {

        $locationProvider.html5Mode(true);

        $stateProvider

            .state('base', {
                abstract : true,
                controller : 'BaseController',
                template: '<ui-view/>',
                data : {
                    anonymous : false
                }
            })

            .state('welcome', {
                url: '/welcome',
                parent: 'base',
                templateUrl: 'client/home/home.ng.html',
                controller: 'HomeController',
                data : {
                    anonymous : true
                }
            })
            .state('login', {
                url: '/login',
                parent: 'base',
                templateUrl: 'client/login/login.ng.html',
                controller : 'LoginController',
                data : {
                    anonymous : true
                }
            })
            .state('overview', {
                url: '/overview',
                parent: 'base',
                templateUrl: 'client/overview/overview.ng.html',
                controller: 'OverviewController'
            })

            /**
             * This is the parent route for all modules. It defines a url with the required
             * organisation and module identifiers.
             */
            .state('module', {
                url : '/organisation/:orgId/module/:moduleId',
                parent: 'base',
                abstract: true,
                template: '<ui-view/>',
                resolve: {
                    module: ['$stateParams', '$meteor', function($stateParams, $meteor) {
                        return $meteor.object(Modules, $stateParams.moduleId);
                    }]
                }
            })

        $urlRouterProvider.otherwise('/welcome');

    }]);
<|endoftext|>


<commit_before><commit_msg>Removed parenthesis around #LEVEL#. They will be added again later<commit_after><|endoftext|>


<commit_before>const connect = require('connect');
const serveStatic = require('serve-static');

const shell = require('shelljs');

const http = require('http');
const path = require('path');
const fs = require('fs');

const Lighthouse = require('lighthouse');
const { ChromeLauncher } = require('lighthouse/lighthouse-cli/chrome-launcher.js');

const packageJson = 'package.json';
const nodeModules = 'node_modules';

run();

function launchChromeAndRunLighthouse(url, flags, config) {
  const launcher = new ChromeLauncher({
    port: 9222,
    autoSelectChrome: true
  });
  return launcher
    .isDebuggerReady()
    .catch(() => {
      if (flags.skipAutolaunch) {
        return;
      }
      return launcher.run();
    })
    .then(() => Lighthouse(url, flags, config))
    .then(results => launcher.kill().then(() => results))
    .catch(err => {
      return launcher.kill().then(() => {
        throw err;
      }, console.error);
    });
}

function getPackageList(dir, rootPathLength, packages = []) {
  const files = fs.readdirSync(dir);

  if (files.includes(packageJson)) {
    packages.push(dir);
    return packages;
  }
  files.forEach(function (file) {
    const filePath = path.join(dir, file);
    const stat = fs.lstatSync(filePath);
    if (stat.isDirectory() && file != nodeModules) {
      packages = getPackageList(filePath, rootPathLength, packages);
    }
  });
  return packages;
}

function getAverageValue(arr) {
  let total = 0;
  for(let i = 0; i < arr.length; i++) {
    total += arr[i];
  }
  return total / arr.length;
}

async function runTestCase(url) {
  const config = require('lighthouse/lighthouse-core/config/perf.json');
  const flags = {maxWaitForLoad: 60000, interactive: true};

  const mountDuration = [];
  const rerenderDuration = [];

  let butch = true;

  for (let i = 0; i < 5; i++) {
    try {
      const currentRes = await launchChromeAndRunLighthouse(`${url}&butch=${butch}`, flags, config);
      const values = currentRes.audits['user-timings'].extendedInfo.value;
      mountDuration.push(values[2].duration);
      let curRerenderDuration = []
      for (let i = 3; i < values.length; i++) {
        if (values[i].duration) {
          curRerenderDuration.push(values[i].duration);
        }
      }
      if (curRerenderDuration.length) {
        rerenderDuration.push(getAverageValue(curRerenderDuration));
      }
      else if (butch) {
        i--;
        butch = false;
      }
    }
    catch (err) {
      console.log(err);
      i--;
    }
  }
  return {
    mountDuration: getAverageValue(mountDuration),
    rerenderDuration: getAverageValue(rerenderDuration)
  };
}

function getIcon(value) {
  return value ? '+' : '-'
}

function arrayToTable (array, cols) {
  const nextLine = '\r\n'
  const nextCol = ' | '

  let table = '## Results:' + nextLine + nextLine
  table += cols.join(nextCol)
  table += nextLine
  table += cols.map(() => ':---').join(nextCol)
  table += nextLine
  array.forEach(item => {
    table += [
      item.name, getIcon(item.useCSS), getIcon(item.useInlineStyles), item.mountDuration, item.rerenderDuration
    ].join(nextCol) + nextLine
  })
  return table
}

function getPackageInfo(path) {
  const json = JSON.parse(fs.readFileSync(path + '/' + packageJson));
  return json.benchmarks;
}

async function run() {
  let res = []

  const port = 3000;
  const rootPath = path.join(__dirname, '../big-table');
  const packages = getPackageList(rootPath, rootPath.length + 1);

  shell.config.verbose = true;

  for (let i = 0; i < packages.length; i++) {
    const app = connect();
    const packageInfo = getPackageInfo(packages[i]);
    const currentPort = port + i;

    if (!process.env.WITHOUT_INSTALL) {
      shell.cd(packages[i]);
      shell.rm('-rf', nodeModules);
      shell.exec('yarn');
      shell.exec('npm run build');
    }

    app.use(serveStatic(packages[i] + '/static', {
      index: ['index.html']
    }));
    const server = http.createServer(app).listen(currentPort);
    console.log('[LOG]: Listen Port:', currentPort);
    const url = `http://localhost:${currentPort}?test=true`;

    const packageRes = await runTestCase(url);
    res.push({
      name: packageInfo.name,
      useInlineStyles: packageInfo.useInlineStyles || false,
      useCSS: packageInfo.useCSS || false,
      rerenderDuration: packageRes.rerenderDuration,
      mountDuration: packageRes.mountDuration
    });

    server.close();
    console.log('[LOG]:', res);
  }

  const table = arrayToTable(res, ['Solution', 'Use CSS', 'Use Inline-Styles', 'Mount Time', 'Rerender time']);
  console.log(table);
  fs.writeFileSync(__dirname + '/../../RESULT.md', table);
}
<commit_msg>add styled jss<commit_after>const connect = require('connect');
const serveStatic = require('serve-static');

const shell = require('shelljs');

const http = require('http');
const path = require('path');
const fs = require('fs');

const Lighthouse = require('lighthouse');
const { ChromeLauncher } = require('lighthouse/lighthouse-cli/chrome-launcher.js');

const packageJson = 'package.json';
const nodeModules = 'node_modules';

run();

function launchChromeAndRunLighthouse(url, flags, config) {
  const launcher = new ChromeLauncher({
    port: 9222,
    autoSelectChrome: true
  });
  return launcher
    .isDebuggerReady()
    .catch(() => {
      if (flags.skipAutolaunch) {
        return;
      }
      return launcher.run();
    })
    .then(() => Lighthouse(url, flags, config))
    .then(results => launcher.kill().then(() => results))
    .catch(err => {
      return launcher.kill().then(() => {
        throw err;
      }, console.error);
    });
}

function getPackageList(dir, rootPathLength, packages = []) {
  const files = fs.readdirSync(dir);

  if (files.includes(packageJson)) {
    packages.push(dir);
    return packages;
  }
  files.forEach(function (file) {
    const filePath = path.join(dir, file);
    const stat = fs.lstatSync(filePath);
    if (stat.isDirectory() && file != nodeModules) {
      packages = getPackageList(filePath, rootPathLength, packages);
    }
  });
  return packages;
}

function getAverageValue(arr) {
  let total = 0;
  for(let i = 0; i < arr.length; i++) {
    total += arr[i];
  }
  return total / arr.length;
}

async function runTestCase(url) {
  const config = require('lighthouse/lighthouse-core/config/perf.json');
  const flags = {maxWaitForLoad: 60000, interactive: true};

  const mountDuration = [];
  const rerenderDuration = [];

  let butch = true;

  for (let i = 0; i < 5; i++) {
    try {
      const currentRes = await launchChromeAndRunLighthouse(`${url}&butch=${butch}`, flags, config);
      const values = currentRes.audits['user-timings'].extendedInfo.value;
      mountDuration.push(values[2].duration);
      let curRerenderDuration = []
      for (let i = 3; i < values.length; i++) {
        if (values[i].duration) {
          curRerenderDuration.push(values[i].duration);
        }
      }
      if (curRerenderDuration.length) {
        rerenderDuration.push(getAverageValue(curRerenderDuration));
      }
      else if (butch) {
        i--;
        butch = false;
      }
    }
    catch (err) {
      console.log(err);
      i--;
    }
  }
  return {
    mountDuration: getAverageValue(mountDuration),
    rerenderDuration: getAverageValue(rerenderDuration)
  };
}

function getIcon(value) {
  return value ? '+' : '-'
}

function arrayToTable (array, cols) {
  const nextLine = '\r\n'
  const nextCol = ' | '

  let table = '## Results:' + nextLine + nextLine
  table += cols.join(nextCol)
  table += nextLine
  table += cols.map(() => ':---').join(nextCol)
  table += nextLine
  array.forEach(item => {
    table += [
      item.name, getIcon(item.useCSS), getIcon(item.useInlineStyles), item.mountDuration, item.rerenderDuration
    ].join(nextCol) + nextLine
  })
  return table
}

function getPackageInfo(path) {
  const json = JSON.parse(fs.readFileSync(path + '/' + packageJson));
  return json.benchmarks;
}

async function run() {
  let res = []

  const port = 3000;
  const rootPath = path.join(__dirname, '../big-table');
  const packages = getPackageList(rootPath, rootPath.length + 1);

  shell.config.verbose = true;

  for (let i = 0; i < packages.length; i++) {
    const app = connect();
    const packageInfo = getPackageInfo(packages[i]);
    const currentPort = port + i;

    if (!process.env.WITHOUT_INSTALL) {
      shell.cd(packages[i]);
      shell.rm('-rf', nodeModules);
      shell.exec('yarn');
      shell.exec('npm run build');
    }

    app.use(serveStatic(packages[i] + '/static', {
      index: ['index.html']
    }));
    const server = http.createServer(app).listen(currentPort);
    console.log('[LOG]: Listen Port:', currentPort);
    const url = `http://localhost:${currentPort}?test=true`;

    const packageRes = await runTestCase(url);
    res.push({
      name: packageInfo.name,
      useInlineStyles: packageInfo.useInlineStyles || false,
      useCSS: packageInfo.useCSS || false,
      rerenderDuration: packageRes.rerenderDuration,
      mountDuration: packageRes.mountDuration
    });

    server.close();
    console.log('[LOG]:', res);
  }

  const sortRes = res.sort((a, b) => a.rerenderDuration - b.rerenderDuration)
  const table = arrayToTable(
    sortRes,
    ['Solution', 'Use CSS', 'Use Inline-Styles', 'Mount Time', 'Rerender time']
  );

  console.log(table);

  fs.writeFileSync(__dirname + '/../../RESULT.md', table);
}
<|endoftext|>


<commit_before>/*
 @author Zakai Hamilton
 @component AppLibrary
 */

screens.app.library = function AppLibrary(me) {
    me.launch = function (args) {
        if (me.core.property.get(me.singleton, "ui.node.parent")) {
            me.core.property.set(me.singleton, "widget.window.show", true);
            return me.singleton;
        }
        me.singleton = me.ui.element(__json__, "workspace", "self");
    };
    me.init = async function () {
        me.tagList = me.db.library.tags.list();
        me.core.property.link("widget.transform.clear", "app.library.clear", true);
    };
    me.refresh = async function () {
        me.tagList = me.db.library.tags.list();
    };
    me.initOptions = async function (object) {
        var window = me.widget.window(object);
        me.ui.options.load(me, window, {
            editMode: false,
            structuredMode: false
        });
        me.ui.options.toggleSet(me, window, "editMode", me.updateEditMode);
        me.ui.options.toggleSet(me, window, "structuredMode", me.updateMode);
        window.showResults = true;
        me.updateMode(window);
        me.reset(object);
    };
    me.updateEditMode = function(object) {
        me.updateMode(object);
        me.updateText(object);
    };
    me.updateMode = function(object) {
        var window = me.widget.window(object);
        var showResults = window.showResults;
        var editMode = window.options.editMode && !showResults;
        var structuredMode = window.options.structuredMode;
        me.core.property.set(window.var.transform, "ui.style.opacity", showResults || editMode ? "0" : "");
        me.core.property.set([window.var.editor, window.var.editorContainer, window.var.delete, window.var.update], "ui.basic.show", editMode);
        me.core.property.set(window.var.process, "ui.basic.show", !structuredMode && editMode);
        me.core.property.set(window.var.showResults, "ui.basic.show", !showResults);
        me.core.property.set(window.var.resultsContainer, "ui.basic.show", showResults);
    };
    me.menuList = function (object, list, group) {
        var window = me.widget.window.window(object);
        var parseItems = (items) => {
            var names = new Set();
            if (!items) {
                items = [];
            }
            for (var item of items) {
                for (var key in item) {
                    if (key === "_id" || key === "user") {
                        continue;
                    }
                    names.add(key + ":" + item[key]);
                }
            }
            names = Array.from(names).sort().map((name) => {
                var result = [
                    name,
                    async function () {
                        var search = me.core.property.get(window.var.search, "ui.basic.text");
                        var insert = true;
                        if (search) {
                            var [nameKey, nameValue] = name.split(":");
                            nameKey = nameKey.trim().toLowerCase();
                            search = search.split(" AND ").map((item) => {
                                if(item.includes(":")) {
                                    var [itemKey] = item.split(":");
                                    itemKey = itemKey.trim().toLowerCase();
                                    if(itemKey == nameKey) {
                                        insert = false;
                                        return name;
                                    }
                                    return item;
                                }
                            }).join(" AND ")
                            if(insert) {
                                search += " AND ";
                            }
                        }
                        if(insert) {
                            search += name;
                        }
                        me.core.property.set(window.var.search, "ui.basic.text", search);
                        me.changedSearch(window.var.search);
                    },
                    null,
                    {
                        "group": group
                    }
                ];
                return result;
            });
            return names;
        }
        if (list.then) {
            return [[
                "",
                null,
                {
                    "visible": false
                },
                {
                    "group": group,
                    "promise": { promise: list, callback: parseItems }
                }
            ]];
        }
        else {
            items = parseItems(items);
        }
        return items;
    };
    me.tagMenuList = {
        get: function (object) {
            return me.menuList(object, me.tagList, "public");
        }
    };
    me.changedSearch = function (object) {
        if (me.searchTimer) {
            clearTimeout(me.searchTimer);
        }
        me.searchTimer = setTimeout(() => {
            me.searchTimer = null;
            me.search(object);
        }, 2000);
    };
    me.clear = function (object) {
        var window = me.widget.window.window(object);
        me.core.property.set(window.var.search, "ui.basic.text", "");
        me.reset(object);
    };
    me.reset = function (object) {
        var window = me.widget.window.window(object);
        me.core.property.set(window.var.editor, "text", "");
        me.core.property.set(window.var.transform, "text", "");
        me.core.property.set(window.var.transform, "transform");
        window.searchText = "";
    };
    me.reSearch = function(object) {
        window.searchText = "";
        me.search(object);
    };
    me.search = async function (object) {
        var window = me.widget.window.window(object);
        var search = me.core.property.get(window.var.search, "ui.basic.text");
        if (search === window.searchText) {
            return;
        }
        me.reset(object);
        window.searchText = search;
        clearTimeout(me.searchTimer);
        var records = null;
        if (search) {
            me.core.property.set(window.var.resultsContainer, "ui.basic.show", false);
            me.core.property.set(window.var.resultsSpinner, "ui.style.visibility", "visible");
            records = await me.db.library.find(0, search);
            me.core.property.set(window.var.resultsSpinner, "ui.style.visibility", "hidden");
        }
        me.updateResults(object, records);
    };
    me.updateText = function (object) {
        var window = me.widget.window.window(object);
        var records = me.parseRecordsFromText(window);
        me.updateTextFromRecords(object, records);
    };
    me.removeExtra = function (json) {
        json = Object.assign({}, json);
        delete json._id
        delete json.id
        delete json.user
        return json;
    };
    me.addExtra = function (json, record) {
        json = Object.assign({}, json);
        delete json.id
        json._id = record.id || record._id;
        json.user = record.user || 0;
        return json;
    };
    me.updateTextFromRecords = function (object, records) {
        var window = me.widget.window.window(object);
        if(!Array.isArray(records)) {
            records = me.toRecordArray(records);
        }
        var structuredMode = window.options.structuredMode;
        var text = "";
        if (structuredMode) {
            text = JSON.stringify(records, null, 4);
        }
        else {
            var tags = {};
            for (var item of records) {
                if (text) {
                    text += "\n";
                }
                if (item.id) {
                    text += "#id:" + item.id;
                }
                else if(item._id) {
                    text += "#id:" + item._id;
                }
                else if(item.tags && item.tags._id) {
                    text += "#id:" + item.tags._id;
                }
                else {
                    text += "#id:";
                }
                var diff = [];
                if (item.tags) {
                    for (var tag in item.tags) {
                        if (tag in tags && tags[tag] === item.tags[tag]) {
                            continue;
                        }
                        if(tag === "id" || tag === "_id") {
                            continue;
                        }
                        if (text) {
                            text += "\n";
                        }
                        text += "#" + tag + ":" + item.tags[tag]
                        tags[tag] = item.tags[tag]
                    }
                    diff = Object.keys(tags).filter((i) => Object.keys(item.tags).indexOf(i) < 0);
                }
                else {
                    diff = Object.keys(tags);
                    tags = {};
                }
                for (var tag of diff) {
                    if (text) {
                        text += "\n";
                    }
                    text += "#" + tag + ":"
                }
                if (item.content && item.content.text) {
                    if (text) {
                        text += "\n";
                    }
                    text += item.content.text;
                }
            }
        }
        var transformText = "";
        for(var record of records) {
            if(transformText) {
                transformText += "<article>";
            }
            if(record.tags) {
                var getTag = (tag, prefix="") => { if(tag in record.tags) { return prefix + record.tags[tag] + "\n"} else {return ""}};
                transformText += getTag("article");
                transformText += getTag("title");
                transformText += getTag("chapter", "Chapter ");
                transformText += getTag("part", "Part ");
                transformText += getTag("volume");
                transformText += getTag("book");
                transformText += getTag("author");
            }
            transformText += record.content.text;
        };
        if (records.content) {
            transformText = records.content.map(record => record.text).join("<article>");
        }
        me.core.property.set(window.var.editor, "text", text);
        me.core.property.set(window.var.transform, "text", transformText);
        if (!window.options.editMode) {
            me.core.property.set(window.var.transform, "transform");
        }
    };
    me.parseRecordsFromText = function (object) {
        var window = me.widget.window.window(object);
        var text = me.core.property.get(window.var.editor, "text");
        var records = {};
        var array = [];
        if (text) {
            if (text[0] === "[") {
                array = JSON.parse(text);
            }
            else {
                var tags = {};
                for (line of text.split("\n")) {
                    var last = array[array.length - 1];
                    if (line[0] === "#") {
                        var [key, value] = line.substring(1).split(":").map(string => string.trim());
                        if (key === "id") {
                            if (last) {
                                last.tags = Object.assign({}, tags);
                            }
                            array.push({ id: value });
                        }
                        else {
                            if (!last) {
                                array.push({});
                                last = array[array.length - 1];
                            }
                            if (value) {
                                tags[key] = value;
                            }
                            else {
                                delete tags[key]
                            }
                        }
                    }
                    else {
                        if (!last) {
                            array.push({});
                            last = array[array.length - 1];
                        }
                        if (last.content && last.content.text) {
                            last.content.text += "\n" + line;
                        }
                        else {
                            last.content = { text: line };
                        }
                    }
                }
                if (last) {
                    last.tags = Object.assign({}, tags);
                }
            }
            records = me.fromRecordArray(array);
        }
        return records;
    };
    me.toRecordArray = function (json) {
        var array = [];
        if (json.content) {
            for (var index = 0; index < json.content.length; index++) {
                var id = 0;
                var tags = json.tags[index];
                var content = json.content[index];
                if(json.ids) {
                    id = json.ids[index];
                }
                else {
                    id = content._id || content.id;
                }
                array.push({
                    id: id,
                    tags: me.removeExtra(tags),
                    content: me.removeExtra(content)
                });
            }
        }
        return array;
    };
    me.fromRecordArray = function (array) {
        var dict = { tags: [], content: [], ids: [] };
        for (record of array) {
            dict.tags.push(me.addExtra(record.tags, record));
            dict.content.push(me.addExtra(record.content, record));
            dict.ids.push(record.id);
        }
        return dict;
    };
    me.updateRecord = async function (object) {
        var records = me.parseRecordsFromText(object);
        if (records.content) {
            records.content = await me.db.library.content.set(records.content);
            records.ids = records.content.map(item => item._id);
        }
        if (records.tags) {
            for (var index = 0; index < records.tags.length; index++) {
                records.tags[index] = me.addExtra(records.tags[index], records.content[index]);
            }
            records.tags = await me.db.library.tags.set(records.tags);
            records.ids = records.tags.map(item => item._id);
        }
        me.updateTextFromRecords(object, records);
        me.refresh();
    };
    me.deleteRecord = async function (object) {
        var records = me.parseRecordsFromText(object);
        if (records.ids) {
            await me.db.library.tags.remove(records.ids);
            await me.db.library.content.remove(records.ids);
        }
    };
    me.process = function(object) {
        var window = me.widget.window.window(object);
        var text = me.core.property.get(window.var.editor, "text");
        var prevLine = "";
        text = text.split("\n").map(line => {
            if(line.startsWith("#")) {
                return line;
            }
            if(line.match(/[^.?!:;,\\\"'”…\\)’]$/)) {
                if(line.startsWith("Items")) {
                    return "";
                }
                if(prevLine.includes("article")) {
                    line = "#title:" + line;
                }
                else {
                    line = "#id:\n#article:" + line;
                }
            }
            prevLine = line;
            return line;
        }).join("\n");
        me.core.property.set(window.var.editor, "text", text);
        me.updateText(object);
    };
    me.gotoArticle = async function(object, tags) {
        var window = me.widget.window.window(object);
        me.core.property.set(window.var.resultsContainer, "ui.basic.show", false);
        me.core.property.set(window.var.resultsSpinner, "ui.style.visibility", "visible");
        var content = await me.db.library.content.get(tags._id);
        me.core.property.set(window.var.resultsSpinner, "ui.style.visibility", "hidden");
        var records = [{content:content,tags:tags}];
        me.updateTextFromRecords(window, records);
        window.showResults = false;
        me.updateMode(window);
    };
    me.showResults = function(object) {
        var window = me.widget.window.window(object);
        window.showResults = true;
        me.updateMode(window);
    };
    me.updateResults = function(object, results) {
        var window = me.widget.window.window(object);
        window.showResults = true;
        me.updateMode(window);
        if(!results) {
            results = [];
        }
        var gotoArticle = function(info) {
            me.gotoArticle(object, info.item);
        };
        var fields = Object.keys(Object.assign({}, ...results)).filter(name => name !== 'user' && name !== '_id').map(name => {
            return { name: name, title: me.core.string.title(name), type: "text"};
        });
        $(window.var.resultsGrid).jsGrid("clearFilter");
        $(window.var.resultsGrid).jsGrid({
            width: "100%",
            height: "100%",

            inserting: false,
            filtering: true,
            clearFilterButton: true,
            noDataContent: "No Results Found",
            editing: false,
            sorting: true,

            fields: fields,
            autoload: true,
            rowClick: gotoArticle,
            controller: {
                data:results,
                loadData: function (filter) {
                    var filterCount = 0;
                    for(var key in filter) {
                        if(filter[key]) {
                            filterCount++;
                        }
                    }
                    if(!filterCount) {
                        return this.data;
                    }
                    return $.grep(this.data, function (item) {
                        var filterIndex = 0;
                        for(key in filter) {
                            var filterValue = filter[key];
                            var itemValue = item[key];
                            if(filterValue && itemValue) {
                                if(itemValue.toLowerCase().includes(filterValue.toLowerCase())) {
                                    filterIndex++;
                                }
                            }
                        }
                        return filterIndex === filterCount;
                    });
                },
            }
        });
    };
};
<commit_msg>bug fix<commit_after>/*
 @author Zakai Hamilton
 @component AppLibrary
 */

screens.app.library = function AppLibrary(me) {
    me.launch = function (args) {
        if (me.core.property.get(me.singleton, "ui.node.parent")) {
            me.core.property.set(me.singleton, "widget.window.show", true);
            return me.singleton;
        }
        me.singleton = me.ui.element(__json__, "workspace", "self");
    };
    me.init = async function () {
        me.tagList = me.db.library.tags.list();
        me.core.property.link("widget.transform.clear", "app.library.clear", true);
    };
    me.refresh = async function () {
        me.tagList = me.db.library.tags.list();
    };
    me.initOptions = async function (object) {
        var window = me.widget.window(object);
        me.ui.options.load(me, window, {
            editMode: false,
            structuredMode: false
        });
        me.ui.options.toggleSet(me, window, "editMode", me.updateEditMode);
        me.ui.options.toggleSet(me, window, "structuredMode", me.updateMode);
        window.showResults = true;
        me.updateMode(window);
        me.reset(object);
    };
    me.updateEditMode = function(object) {
        me.updateMode(object);
        me.updateText(object);
    };
    me.updateMode = function(object) {
        var window = me.widget.window(object);
        var showResults = window.showResults;
        var editMode = window.options.editMode && !showResults;
        var structuredMode = window.options.structuredMode;
        me.core.property.set(window.var.transform, "ui.style.opacity", showResults || editMode ? "0" : "");
        me.core.property.set([window.var.editor, window.var.editorContainer, window.var.delete, window.var.update], "ui.basic.show", editMode);
        me.core.property.set(window.var.process, "ui.basic.show", !structuredMode && editMode);
        me.core.property.set(window.var.showResults, "ui.basic.show", !showResults);
        me.core.property.set(window.var.resultsContainer, "ui.basic.show", showResults);
    };
    me.menuList = function (object, list, group) {
        var window = me.widget.window.window(object);
        var parseItems = (items) => {
            var names = new Set();
            if (!items) {
                items = [];
            }
            for (var item of items) {
                for (var key in item) {
                    if (key === "_id" || key === "user") {
                        continue;
                    }
                    names.add(key + ":" + item[key]);
                }
            }
            names = Array.from(names).sort().map((name) => {
                var result = [
                    name,
                    async function () {
                        var search = me.core.property.get(window.var.search, "ui.basic.text");
                        var insert = true;
                        if (search) {
                            var [nameKey, nameValue] = name.split(":");
                            nameKey = nameKey.trim().toLowerCase();
                            search = search.split(" AND ").map((item) => {
                                if(item.includes(":")) {
                                    var [itemKey] = item.split(":");
                                    itemKey = itemKey.trim().toLowerCase();
                                    if(itemKey == nameKey) {
                                        insert = false;
                                        return name;
                                    }
                                    return item;
                                }
                            }).join(" AND ")
                            if(insert) {
                                search += " AND ";
                            }
                        }
                        if(insert) {
                            search += name;
                        }
                        me.core.property.set(window.var.search, "ui.basic.text", search);
                        me.changedSearch(window.var.search);
                    },
                    null,
                    {
                        "group": group
                    }
                ];
                return result;
            });
            return names;
        }
        if (list.then) {
            return [[
                "",
                null,
                {
                    "visible": false
                },
                {
                    "group": group,
                    "promise": { promise: list, callback: parseItems }
                }
            ]];
        }
        else {
            items = parseItems(items);
        }
        return items;
    };
    me.tagMenuList = {
        get: function (object) {
            return me.menuList(object, me.tagList, "public");
        }
    };
    me.changedSearch = function (object) {
        if (me.searchTimer) {
            clearTimeout(me.searchTimer);
        }
        me.searchTimer = setTimeout(() => {
            me.searchTimer = null;
            me.search(object);
        }, 2000);
    };
    me.clear = function (object) {
        var window = me.widget.window.window(object);
        me.core.property.set(window.var.search, "ui.basic.text", "");
        me.reset(object);
    };
    me.reset = function (object) {
        var window = me.widget.window.window(object);
        me.core.property.set(window.var.editor, "text", "");
        me.core.property.set(window.var.transform, "text", "");
        me.core.property.set(window.var.transform, "transform");
        window.searchText = "";
    };
    me.reSearch = function(object) {
        window.searchText = "";
        me.search(object);
    };
    me.search = async function (object) {
        var window = me.widget.window.window(object);
        var search = me.core.property.get(window.var.search, "ui.basic.text");
        if (search === window.searchText) {
            return;
        }
        me.reset(object);
        window.searchText = search;
        clearTimeout(me.searchTimer);
        var records = null;
        if (search) {
            me.core.property.set(window.var.resultsContainer, "ui.basic.show", false);
            me.core.property.set(window.var.resultsSpinner, "ui.style.visibility", "visible");
            records = await me.db.library.find(0, search);
            me.core.property.set(window.var.resultsSpinner, "ui.style.visibility", "hidden");
        }
        me.updateResults(object, records);
    };
    me.updateText = function (object) {
        var window = me.widget.window.window(object);
        var records = me.parseRecordsFromText(window);
        me.updateTextFromRecords(object, records);
    };
    me.removeExtra = function (json) {
        json = Object.assign({}, json);
        delete json._id
        delete json.id
        delete json.user
        return json;
    };
    me.addExtra = function (json, record) {
        json = Object.assign({}, json);
        delete json.id
        json._id = record.id || record._id;
        json.user = record.user || 0;
        return json;
    };
    me.updateTextFromRecords = function (object, records) {
        var window = me.widget.window.window(object);
        if(!Array.isArray(records)) {
            records = me.toRecordArray(records);
        }
        var structuredMode = window.options.structuredMode;
        var text = "";
        if (structuredMode) {
            text = JSON.stringify(records, null, 4);
        }
        else {
            var tags = {};
            for (var item of records) {
                if (text) {
                    text += "\n";
                }
                if (item.id) {
                    text += "#id:" + item.id;
                }
                else if(item._id) {
                    text += "#id:" + item._id;
                }
                else if(item.tags && item.tags._id) {
                    text += "#id:" + item.tags._id;
                }
                else {
                    text += "#id:";
                }
                var diff = [];
                if (item.tags) {
                    for (var tag in item.tags) {
                        if (tag in tags && tags[tag] === item.tags[tag]) {
                            continue;
                        }
                        if(tag === "id" || tag === "_id") {
                            continue;
                        }
                        if (text) {
                            text += "\n";
                        }
                        text += "#" + tag + ":" + item.tags[tag]
                        tags[tag] = item.tags[tag]
                    }
                    diff = Object.keys(tags).filter((i) => Object.keys(item.tags).indexOf(i) < 0);
                }
                else {
                    diff = Object.keys(tags);
                    tags = {};
                }
                for (var tag of diff) {
                    if (text) {
                        text += "\n";
                    }
                    text += "#" + tag + ":"
                }
                if (item.content && item.content.text) {
                    if (text) {
                        text += "\n";
                    }
                    text += item.content.text;
                }
            }
        }
        var transformText = "";
        for(var record of records) {
            if(transformText) {
                transformText += "<article>";
            }
            if(record.tags) {
                var getTag = (tag, prefix="") => { if(tag in record.tags) { return prefix + record.tags[tag] + "\n"} else {return ""}};
                transformText += getTag("article");
                transformText += getTag("title");
                transformText += getTag("chapter", "Chapter ");
                transformText += getTag("part", "Part ");
                transformText += getTag("volume");
                transformText += getTag("book");
                transformText += getTag("author");
            }
            transformText += record.content.text;
        };
        if (records.content) {
            transformText = records.content.map(record => record.text).join("<article>");
        }
        me.core.property.set(window.var.editor, "text", text);
        me.core.property.set(window.var.transform, "text", transformText);
        if (!window.options.editMode) {
            me.core.property.set(window.var.transform, "transform");
        }
    };
    me.parseRecordsFromText = function (object) {
        var window = me.widget.window.window(object);
        var text = me.core.property.get(window.var.editor, "text");
        var records = {};
        var array = [];
        if (text) {
            if (text[0] === "[") {
                array = JSON.parse(text);
            }
            else {
                var tags = {};
                for (line of text.split("\n")) {
                    var last = array[array.length - 1];
                    if (line[0] === "#") {
                        var [key, value] = line.substring(1).split(":").map(string => string.trim());
                        if (key === "id") {
                            if (last) {
                                last.tags = Object.assign({}, tags);
                            }
                            array.push({ id: value });
                        }
                        else {
                            if (!last) {
                                array.push({});
                                last = array[array.length - 1];
                            }
                            if (value) {
                                tags[key] = value;
                            }
                            else {
                                delete tags[key]
                            }
                        }
                    }
                    else {
                        if (!last) {
                            array.push({});
                            last = array[array.length - 1];
                        }
                        if (last.content && last.content.text) {
                            last.content.text += "\n" + line;
                        }
                        else {
                            last.content = { text: line };
                        }
                    }
                }
                if (last) {
                    last.tags = Object.assign({}, tags);
                }
            }
            records = me.fromRecordArray(array);
        }
        return records;
    };
    me.toRecordArray = function (json) {
        var array = [];
        if (json.content) {
            for (var index = 0; index < json.content.length; index++) {
                var id = 0;
                var tags = json.tags[index];
                var content = json.content[index];
                if(json.ids) {
                    id = json.ids[index];
                }
                else {
                    id = content._id || content.id;
                }
                array.push({
                    id: id,
                    tags: me.removeExtra(tags),
                    content: me.removeExtra(content)
                });
            }
        }
        return array;
    };
    me.fromRecordArray = function (array) {
        var dict = { tags: [], content: [], ids: [] };
        for (record of array) {
            dict.tags.push(me.addExtra(record.tags, record));
            dict.content.push(me.addExtra(record.content, record));
            dict.ids.push(record.id);
        }
        return dict;
    };
    me.updateRecord = async function (object) {
        var records = me.parseRecordsFromText(object);
        if (records.content) {
            records.content = await me.db.library.content.set(records.content);
            records.ids = records.content.map(item => item._id);
        }
        if (records.tags) {
            for (var index = 0; index < records.tags.length; index++) {
                records.tags[index] = me.addExtra(records.tags[index], records.content[index]);
            }
            records.tags = await me.db.library.tags.set(records.tags);
            records.ids = records.tags.map(item => item._id);
        }
        me.updateTextFromRecords(object, records);
        me.refresh();
    };
    me.deleteRecord = async function (object) {
        var records = me.parseRecordsFromText(object);
        if (records.ids) {
            await me.db.library.tags.remove(records.ids);
            await me.db.library.content.remove(records.ids);
        }
    };
    me.process = function(object) {
        var window = me.widget.window.window(object);
        var text = me.core.property.get(window.var.editor, "text");
        var prevLine = "";
        text = text.split("\n").map(line => {
            if(line.startsWith("#")) {
                return line;
            }
            if(line.match(/[^.?!:;,\\\"'”…\\)’]$/)) {
                if(line.startsWith("Items")) {
                    return "";
                }
                if(prevLine.includes("article")) {
                    line = "#title:" + line;
                }
                else {
                    line = "#id:\n#article:" + line;
                }
            }
            prevLine = line;
            return line;
        }).join("\n");
        me.core.property.set(window.var.editor, "text", text);
        me.updateText(object);
    };
    me.gotoArticle = async function(object, tags) {
        var window = me.widget.window.window(object);
        me.core.property.set(window.var.resultsContainer, "ui.basic.show", false);
        me.core.property.set(window.var.resultsSpinner, "ui.style.visibility", "visible");
        var content = await me.db.library.content.get(tags._id);
        me.core.property.set(window.var.resultsSpinner, "ui.style.visibility", "hidden");
        var records = [{content:content,tags:tags}];
        me.updateTextFromRecords(window, records);
        window.showResults = false;
        me.updateMode(window);
    };
    me.showResults = function(object) {
        var window = me.widget.window.window(object);
        window.showResults = true;
        me.updateMode(window);
    };
    me.updateResults = function(object, results) {
        var window = me.widget.window.window(object);
        window.showResults = true;
        me.updateMode(window);
        var noSearch = false;
        if(!results) {
            results = [];
            noSearch = true;
        }
        var gotoArticle = function(info) {
            me.gotoArticle(object, info.item);
        };
        var fields = Object.keys(Object.assign({}, ...results)).filter(name => name !== 'user' && name !== '_id').map(name => {
            return { name: name, title: me.core.string.title(name), type: "text"};
        });
        $(window.var.resultsGrid).jsGrid("clearFilter");
        $(window.var.resultsGrid).jsGrid({
            width: "100%",
            height: "100%",

            inserting: false,
            filtering: true,
            clearFilterButton: true,
            noDataContent: noSearch ? "": "No Results Found",
            editing: false,
            sorting: true,

            fields: fields,
            autoload: true,
            rowClick: gotoArticle,
            controller: {
                data:results,
                loadData: function (filter) {
                    var filterCount = 0;
                    for(var key in filter) {
                        if(filter[key]) {
                            filterCount++;
                        }
                    }
                    if(!filterCount) {
                        return this.data;
                    }
                    return $.grep(this.data, function (item) {
                        var filterIndex = 0;
                        for(key in filter) {
                            var filterValue = filter[key];
                            var itemValue = item[key];
                            if(filterValue && itemValue) {
                                if(itemValue.toLowerCase().includes(filterValue.toLowerCase())) {
                                    filterIndex++;
                                }
                            }
                        }
                        return filterIndex === filterCount;
                    });
                },
            }
        });
    };
};
<|endoftext|>


<commit_before>import React from "react";
import { Link } from "gatsby";
import { prepareTitle } from "../common.js";
import Layout from "../components/layout";
import styled from "@emotion/styled";

const VolumeWrapper = styled.div`
  border-top: 1px solid #faf9f3;
`;

const Volume = styled.div`
  max-width: 960px;
  margin: 0 auto;
  font-size: 0.92rem;
`;

const DiscourseList = styled.div`
  -moz-border-radius: 2px;
  -webkit-border-radius: 2px;
  border-bottom: 1px solid #e3e1ce;
  border-left: 1px solid #e3e1ce;
  border-spacing: 0;
  border-top: 1px solid #e3e1ce;
  clear: both;
  width: 100%;
  background-color: white;
  margin-bottom: 16px;
`;
const DiscourseListItem = styled.div`
  display: flex;
  margin-top: 8px;
  margin-bottom: 8px;
`;

const Pages = styled.div`
  width: 80px;
  padding: 4px 8px;
  padding-left: 12px;
`;

const DateComponent = styled.div`
  width: 145px;
  padding: 4px 8px;
`;

const Speaker = styled.div`
  width: 130px;
  padding: 4px 8px;
`;
const Title = styled.div`
  flex: 1;
  padding: 4px 8px;
  padding-right: 12px;
`;

export default ({
  pageContext: { volumeNumbers, volumeNumber, discourses }
}) => {
  return (
    <Layout volumeNumbers={volumeNumbers} volumeNumber={volumeNumber}>
      <VolumeWrapper>
        <Volume>

Volume {volumeNumber}

          <DiscourseList>
            {discourses.map(discourse => {
              const event = new Date();
              if (discourse.date) {
                event.setFullYear(parseInt(discourse.date.substr(0, 4), 10));
                event.setMonth(parseInt(discourse.date.substr(5, 7), 10) - 1);
                event.setDate(parseInt(discourse.date.substr(8, 10), 10));
                event.setUTCHours(0);
              }
              const dateOptions = {
                year: "numeric",
                month: "long",
                day: "numeric"
              };
              return (
                <DiscourseListItem key={discourse.id}>
                  <Pages>
                    pp. {discourse.start_page}-{discourse.end_page}
                  </Pages>
                  <DateComponent title={discourse.date}>
                    {discourse.date &&
                      event.toLocaleDateString("default", dateOptions)}
                  </DateComponent>
                  <Speaker>{discourse.speaker}</Speaker>
                  <Title>
                    <Link
                      to={`/${discourse.volume}/${discourse.start_page}`}
                      dangerouslySetInnerHTML={{
                        __html: prepareTitle(discourse.title)
                      }}
                    />
                  </Title>
                </DiscourseListItem>
              );
            })}
          </DiscourseList>
        </Volume>
      </VolumeWrapper>
    </Layout>
  );
};
<commit_msg>Volume title<commit_after>import React from "react";
import { Link } from "gatsby";
import { prepareTitle } from "../common.js";
import Layout from "../components/layout";
import styled from "@emotion/styled";
import SEO from "../components/seo";

const VolumeWrapper = styled.div`
  border-top: 1px solid #faf9f3;
`;

const Volume = styled.div`
  max-width: 960px;
  margin: 0 auto;
  font-size: 0.92rem;
`;

const DiscourseList = styled.div`
  -moz-border-radius: 2px;
  -webkit-border-radius: 2px;
  border-bottom: 1px solid #e3e1ce;
  border-left: 1px solid #e3e1ce;
  border-spacing: 0;
  border-top: 1px solid #e3e1ce;
  clear: both;
  width: 100%;
  background-color: white;
  margin-bottom: 16px;
`;
const DiscourseListItem = styled.div`
  display: flex;
  margin-top: 8px;
  margin-bottom: 8px;
`;

const Pages = styled.div`
  width: 80px;
  padding: 4px 8px;
  padding-left: 12px;
`;

const DateComponent = styled.div`
  width: 145px;
  padding: 4px 8px;
`;

const Speaker = styled.div`
  width: 130px;
  padding: 4px 8px;
`;
const Title = styled.div`
  flex: 1;
  padding: 4px 8px;
  padding-right: 12px;
`;

export default ({
  pageContext: { volumeNumbers, volumeNumber, discourses }
}) => {
  const seoTitle = "";
  return (
    <Layout volumeNumbers={volumeNumbers} volumeNumber={volumeNumber}>
      <SEO title={`Journal of Discourses, vol. ${volumeNumber}`} />
      <VolumeWrapper>
        <Volume>

Volume {volumeNumber}

          <DiscourseList>
            {discourses.map(discourse => {
              const event = new Date();
              if (discourse.date) {
                event.setFullYear(parseInt(discourse.date.substr(0, 4), 10));
                event.setMonth(parseInt(discourse.date.substr(5, 7), 10) - 1);
                event.setDate(parseInt(discourse.date.substr(8, 10), 10));
                event.setUTCHours(0);
              }
              const dateOptions = {
                year: "numeric",
                month: "long",
                day: "numeric"
              };
              return (
                <DiscourseListItem key={discourse.id}>
                  <Pages>
                    pp. {discourse.start_page}-{discourse.end_page}
                  </Pages>
                  <DateComponent title={discourse.date}>
                    {discourse.date &&
                      event.toLocaleDateString("default", dateOptions)}
                  </DateComponent>
                  <Speaker>{discourse.speaker}</Speaker>
                  <Title>
                    <Link
                      to={`/${discourse.volume}/${discourse.start_page}`}
                      dangerouslySetInnerHTML={{
                        __html: prepareTitle(discourse.title)
                      }}
                    />
                  </Title>
                </DiscourseListItem>
              );
            })}
          </DiscourseList>
        </Volume>
      </VolumeWrapper>
    </Layout>
  );
};
<|endoftext|>


<commit_before>
import test from 'tape'
import parser from '../parser'
import moment from 'moment'

test('simple am times: 8am-10am', t => {
  let {start, end} = parser('8am-10am')
  t.equals(start.getHours(), 8, 'start is 8am')
  t.equals(end.getHours(), 10, 'end is 10am')

  t.end()
})

test('simple am to pm times: 9am-2pm', t => {
  let {start, end} = parser('9am-2pm')
  t.equals(start.getHours(), 9, 'start is 9am')
  t.equals(end.getHours(), 14, 'end is 2pm (14)')

  t.end()
})

test('simple pm times: 1pm-4pm', t => {
  let {start, end} = parser('1pm-4pm')
  t.equals(start.getHours(), 13, 'start is 1pm (13)')
  t.equals(end.getHours(), 16, 'end is 4pm (16)')

  t.end()
})

test('infer meridiem: 1-3pm', t => {
  let {start, end} = parser('1-3pm')
  t.equals(start.getHours(), 13, 'infer start is 1pm (13)')
  t.equals(end.getHours(), 15, 'end is 3pm (15)')

  t.end()
})

// Test is skipped because it currently doesn't pass
// Please see this issue: https://github.com/wanasit/chrono/issues/76
test.skip('infer meridiem: 1pm-3', t => {
  let today = new Date()
  let {start, end} = parser('1pm-3')
  t.equals(start.getHours(), 13, 'start is 1pm (13)')
  t.equals(end.getHours(), 15, 'infer end is 3pm (15)')
  t.ok(moment(start).isSame(today, 'day'), 'start is same as today')
  t.ok(moment(end).isSame(today, 'day'), 'end is same as today')

  t.end()
})

test.skip('infer meridiem: 11pm-2', t => {
  let today = new Date()
  let {start, end} = parser('11pm-2')

  t.equals(start.getHours(), 23, 'start is 11pm (23)')
  t.equals(end.getHours(), 2, 'end is 2am')
  t.ok(moment(start).isSame(moment(today).subtract(1, 'day'), 'day'), 'start is same as yesterday')
  t.ok(moment(end).isSame(today, 'day'), 'end is same as today')
})

test('minutes: 9:15am-2:30pm', t => {
  let {start, end} = parser('9:15am-2:30pm')
  t.equals(start.getHours(), 9, 'start is 9am')
  t.equals(start.getMinutes(), 15, 'start is 9:15am')
  t.equals(end.getHours(), 14, 'end is 2pm (14)')
  t.equals(end.getMinutes(), 30, 'end is 2:30pm')

  t.end()
})

test('colon segmented 24 times: 08:000-13:00', t => {
  let {start, end} = parser('0800-1330')
  t.equals(start.getHours(), 8, 'start is 8am')
  t.equals(end.getHours(), 13, 'end is 1pm (13)')
  t.equals(end.getMinutes(), 30, 'end is 1:30pm')

  t.end()
})

test('proper 24h times: 0800-1330', t => {
  let {start, end} = parser('0800-1330')
  t.equals(start.getHours(), 8, 'start is 8am')
  t.equals(end.getHours(), 13, 'end is 1pm (13)')
  t.equals(end.getMinutes(), 30, 'end is 1:30pm')

  t.end()
})

test('no leading zero 24h times: 800-1300', t => {
  let {start, end} = parser('800-1300')
  t.equals(start.getHours(), 8, 'start is 8am')
  t.equals(end.getHours(), 13, 'end is 1pm (13)')

  t.end()
})

const anchor  = new Date('Jan 25, 2015 0:00:00')
const anchor2 = new Date('April 2, 2015 0:00:00')

test('anchored: dates relative to anchor', t => {
  let {start, end} = parser('8am-1pm', anchor)

  t.ok(moment(start).isSame(anchor, 'day'), 'start is same day as anchor')
  t.ok(moment(end).isSame(anchor, 'day'), 'end is same day as anchor')

  t.end()
})

test('anchored: dates relative to anchor2', t => {
  let {start, end} = parser('8am-1pm', anchor2)

  t.ok(moment(start).isSame(anchor2, 'day'), 'start is same day as anchor2')
  t.ok(moment(end).isSame(anchor2, 'day'), 'end is same day as anchor2')

  t.end()
})

test('overlapping times: 11pm-2am', t => {
  let {start, end} = parser('11pm-2am', anchor)

  t.ok(moment(start).isSame(anchor, 'day'), 'start is same day as anchor')
  t.ok(moment(end).isSame(moment(anchor).add(1, 'day'), 'day'), 'end is day after anchor')

  t.end()
})

// Test is skipped because it currently doesn't pass
// Please see this issue: https://github.com/MemoryLeaf/tickbin/issues/26
test.skip('overlapping times for current day: 11pm-2am', t => {
  const today = new Date()
  let {start, end} = parser('11pm-2am')

  t.ok(moment(start).isSame(moment(today).subtract(1, 'day')), 'start is day before today')
  t.ok(moment(end).isSame(today), 'end is same as today')

  t.end()
})

test('matching text is returned', t => {
  let {text} = parser('1-3pm')
  let {text: only} = parser('1-3pm did some things')
  t.equals(text, '1-3pm', 'parser returns matching text')
  t.equals(only, '1-3pm', 'parser returns only matching text')

  t.end()
})

//  Test impliedPMStartRefiner
//  See https://github.com/MemoryLeaf/tickbin/issues/96
test('10-4pm should be implied as 10am-4pm', t => {
  const today = new Date()
  let {start, end} = parser('10-4pm')

  t.equals(start.getHours(), 10, 'start is 10am')
  t.equals(end.getHours(), 16, 'end is 4pm (16)')
  t.ok(moment(start).isSame(today, 'day'), 'start is same as today')
  t.ok(moment(end).isSame(today, 'day'), 'end is same as today')

  t.end()
})

//  See https://github.com/MemoryLeaf/tickbin/issues/42
test('9:30-12pm should be implied as 9:30am-12pm', t => {
  const today = new Date()
  let {start, end} = parser('9:30-12pm')

  t.equals(start.getHours(), 9, 'start is 9am')
  t.equals(start.getMinutes(), 30, 'start is 30 minutes')
  t.equals(end.getHours(), 12, 'end is 12pm')
  t.ok(moment(start).isSame(today, 'day'), 'start is same as today')
  t.ok(moment(end).isSame(today, 'day'), 'end is same as today')

  t.end()
})
<commit_msg>Add test for parsing day overlap with ref date<commit_after>
import test from 'tape'
import parser from '../parser'
import moment from 'moment'

test('simple am times: 8am-10am', t => {
  let {start, end} = parser('8am-10am')
  t.equals(start.getHours(), 8, 'start is 8am')
  t.equals(end.getHours(), 10, 'end is 10am')

  t.end()
})

test('simple am to pm times: 9am-2pm', t => {
  let {start, end} = parser('9am-2pm')
  t.equals(start.getHours(), 9, 'start is 9am')
  t.equals(end.getHours(), 14, 'end is 2pm (14)')

  t.end()
})

test('simple pm times: 1pm-4pm', t => {
  let {start, end} = parser('1pm-4pm')
  t.equals(start.getHours(), 13, 'start is 1pm (13)')
  t.equals(end.getHours(), 16, 'end is 4pm (16)')

  t.end()
})

test('infer meridiem: 1-3pm', t => {
  let {start, end} = parser('1-3pm')
  t.equals(start.getHours(), 13, 'infer start is 1pm (13)')
  t.equals(end.getHours(), 15, 'end is 3pm (15)')

  t.end()
})

// Test is skipped because it currently doesn't pass
// Please see this issue: https://github.com/wanasit/chrono/issues/76
test.skip('infer meridiem: 1pm-3', t => {
  let today = new Date()
  let {start, end} = parser('1pm-3')
  t.equals(start.getHours(), 13, 'start is 1pm (13)')
  t.equals(end.getHours(), 15, 'infer end is 3pm (15)')
  t.ok(moment(start).isSame(today, 'day'), 'start is same as today')
  t.ok(moment(end).isSame(today, 'day'), 'end is same as today')

  t.end()
})

test.skip('infer meridiem: 11pm-2', t => {
  let today = new Date()
  let {start, end} = parser('11pm-2')

  t.equals(start.getHours(), 23, 'start is 11pm (23)')
  t.equals(end.getHours(), 2, 'end is 2am')
  t.ok(moment(start).isSame(moment(today).subtract(1, 'day'), 'day'), 'start is same as yesterday')
  t.ok(moment(end).isSame(today, 'day'), 'end is same as today')
})

test('minutes: 9:15am-2:30pm', t => {
  let {start, end} = parser('9:15am-2:30pm')
  t.equals(start.getHours(), 9, 'start is 9am')
  t.equals(start.getMinutes(), 15, 'start is 9:15am')
  t.equals(end.getHours(), 14, 'end is 2pm (14)')
  t.equals(end.getMinutes(), 30, 'end is 2:30pm')

  t.end()
})

test('colon segmented 24 times: 08:000-13:00', t => {
  let {start, end} = parser('0800-1330')
  t.equals(start.getHours(), 8, 'start is 8am')
  t.equals(end.getHours(), 13, 'end is 1pm (13)')
  t.equals(end.getMinutes(), 30, 'end is 1:30pm')

  t.end()
})

test('proper 24h times: 0800-1330', t => {
  let {start, end} = parser('0800-1330')
  t.equals(start.getHours(), 8, 'start is 8am')
  t.equals(end.getHours(), 13, 'end is 1pm (13)')
  t.equals(end.getMinutes(), 30, 'end is 1:30pm')

  t.end()
})

test('no leading zero 24h times: 800-1300', t => {
  let {start, end} = parser('800-1300')
  t.equals(start.getHours(), 8, 'start is 8am')
  t.equals(end.getHours(), 13, 'end is 1pm (13)')

  t.end()
})

const anchor  = new Date('Jan 25, 2015 0:00:00')
const anchor2 = new Date('April 2, 2015 0:00:00')

test('anchored: dates relative to anchor', t => {
  let {start, end} = parser('8am-1pm', anchor)

  t.ok(moment(start).isSame(anchor, 'day'), 'start is same day as anchor')
  t.ok(moment(end).isSame(anchor, 'day'), 'end is same day as anchor')

  t.end()
})

test('anchored: dates relative to anchor2', t => {
  let {start, end} = parser('8am-1pm', anchor2)

  t.ok(moment(start).isSame(anchor2, 'day'), 'start is same day as anchor2')
  t.ok(moment(end).isSame(anchor2, 'day'), 'end is same day as anchor2')

  t.end()
})

test('overlapping times: 11pm-2am', t => {
  let {start, end} = parser('11pm-2am', anchor)

  t.ok(moment(start).isSame(anchor, 'day'), 'start is same day as anchor')
  t.ok(moment(end).isSame(moment(anchor).add(1, 'day'), 'day'), 'end is day after anchor')

  t.end()
})

// Test is skipped because it currently doesn't pass
// Please see this issue: https://github.com/MemoryLeaf/tickbin/issues/26
test.skip('overlapping times for current day: 11pm-2am', t => {
  const today = new Date()
  let {start, end} = parser('11pm-2am')

  t.ok(moment(start).isSame(moment(today).subtract(1, 'day')), 'start is day before today')
  t.ok(moment(end).isSame(today), 'end is same as today')

  t.end()
})

test('overlapping time for specified day: 11pm-2am', t => {
  const refDate = new Date('January 15, 2016 0:00:00') //  Jan 16, 2016
  let {start, end} = parser('11pm-2am', refDate)

  t.ok(moment(start).isSame(refDate, 'day'))
  t.ok(moment(end).isSame(moment(refDate).add(1, 'day'), 'day'))

  t.end()
})

test('matching text is returned', t => {
  let {text} = parser('1-3pm')
  let {text: only} = parser('1-3pm did some things')
  t.equals(text, '1-3pm', 'parser returns matching text')
  t.equals(only, '1-3pm', 'parser returns only matching text')

  t.end()
})

//  Test impliedPMStartRefiner
//  See https://github.com/MemoryLeaf/tickbin/issues/96
test('10-4pm should be implied as 10am-4pm', t => {
  const today = new Date()
  let {start, end} = parser('10-4pm')

  t.equals(start.getHours(), 10, 'start is 10am')
  t.equals(end.getHours(), 16, 'end is 4pm (16)')
  t.ok(moment(start).isSame(today, 'day'), 'start is same as today')
  t.ok(moment(end).isSame(today, 'day'), 'end is same as today')

  t.end()
})

//  See https://github.com/MemoryLeaf/tickbin/issues/42
test('9:30-12pm should be implied as 9:30am-12pm', t => {
  const today = new Date()
  let {start, end} = parser('9:30-12pm')

  t.equals(start.getHours(), 9, 'start is 9am')
  t.equals(start.getMinutes(), 30, 'start is 30 minutes')
  t.equals(end.getHours(), 12, 'end is 12pm')
  t.ok(moment(start).isSame(today, 'day'), 'start is same as today')
  t.ok(moment(end).isSame(today, 'day'), 'end is same as today')

  t.end()
})
<|endoftext|>


<commit_before>'use strict'

const state = require('../src/extensions/state/state')

test('should return null value', () => {
    expect(state.populate('((null))')).toBe('((null))')
})

test('should return undefined value', () => {
    expect(state.populate('((undefined))')).toBe('((undefined))')
})

test('should populate value with state data', () => {
    state.clear()
    state.set('key1', '1')
    expect(state.populate('{{key1}}')).toBe('1')
    expect(state.populate('{{key1}}((number))')).toBe('1((number))')
})

test('should returned complete object populated with the state data', () => {
    state.clear()
    state.set('key1', 'value1')
    state.set('key2', '2')

    const object = {
        field1: '{{key1}}',
        object2: {
            field1: '1((number))',
            field2: '{{key2}}((number))'
        }
    }

    const expectedObject = {
        field1: 'value1',
        object2: {
            field1: '1((number))',
            field2: '2((number))'
        }
    }

    expect(state.populateObject(object)).toEqual(expectedObject)
})<commit_msg>fix(format): add missing formatting<commit_after>'use strict'

const state = require('../src/extensions/state/state')

test('should return null value', () => {
    expect(state.populate('((null))')).toBe('((null))')
})

test('should return undefined value', () => {
    expect(state.populate('((undefined))')).toBe('((undefined))')
})

test('should populate value with state data', () => {
    state.clear()
    state.set('key1', '1')
    expect(state.populate('{{key1}}')).toBe('1')
    expect(state.populate('{{key1}}((number))')).toBe('1((number))')
})

test('should returned complete object populated with the state data', () => {
    state.clear()
    state.set('key1', 'value1')
    state.set('key2', '2')

    const object = {
        field1: '{{key1}}',
        object2: {
            field1: '1((number))',
            field2: '{{key2}}((number))'
        }
    }

    const expectedObject = {
        field1: 'value1',
        object2: {
            field1: '1((number))',
            field2: '2((number))'
        }
    }

    expect(state.populateObject(object)).toEqual(expectedObject)
})
<|endoftext|>


<commit_before>"use strict";

module.exports = describe("Task", function(){
    after(require("./cleanup"));

  describe("#initModel", function(){
    it("should validate data", function(){
      var task = new Task();
      var model = "cars";

      task.initModel(model, {
        make: {type: String, required: true}
        , year: {type: Number, required: true}
      });

      task.save(model, {name: "John"});

      return expect(task.run()).to.eventually.be.rejectedWith(/validation failed/);
    });
  });

  describe("#save", function(){
    it("should save successfully", function(){
      var emmanuel = new TestMdlA({name: "Emmanuel Olaojo", age: 20});
      var brian = new TestMdlB({name: "Brian Griffin", age: 18});

      task.save(TEST_COLLECTION_B, {name: "T-REX", age: 50000000});
      task.save(emmanuel);
      task.save(TEST_COLLECTION_A, {name: "John Damos", age: 26});
      task.save(brian);

      return task.run();
    });

    it("should have Emmanuel Olaojo in " + TEST_COLLECTION_A, function(){
      return expect(TestMdlA.find({name: "Emmanuel Olaojo", age: 20}).exec()).to.eventually.have.length(1);
    });

    it("should have John Damos in " + TEST_COLLECTION_A, function(){
      return expect(TestMdlA.find({name: "John Damos", age: 26}).exec()).to.eventually.have.length(1);
    });

    it("should have T-REX in " + TEST_COLLECTION_B, function(){
      return expect(TestMdlB.find({name: "T-REX", age: 50000000}).exec()).to.eventually.have.length(1);
    });

    it("should have Brian Griffin in " + TEST_COLLECTION_B, function(){
      return expect(TestMdlB.find({name: "Brian Griffin", age: 18}).exec()).to.eventually.have.length(1);
    });

    it(TEST_COLLECTION_A + " should have length 2", function(){
      return expect(TestMdlA.find().exec()).to.eventually.have.length(2);
    });

    it(TEST_COLLECTION_B + " should have length 2", function(){
      return expect(TestMdlB.find().exec()).to.eventually.have.length(2);
    });
  });

  describe("#update", function(){
    it("should update successfully", function(){
      return TestMdlB.findOne({name: "Brian Griffin"})
        .exec()
        .then(function(brian){
          task.update(TEST_COLLECTION_A, {name: "John Damos"}, {name: "John Snow"});
          task.update(brian, {name: "Yo momma", $inc: {age: 20}});

          return task.run()
        });
    });

    it("should have Emmanuel Olaojo in " + TEST_COLLECTION_A, function(){
      return expect(TestMdlA.find({name: "Emmanuel Olaojo"}).exec()).to.eventually.have.length(1);
    });

    it("should have John Snow in " + TEST_COLLECTION_A, function(){
      return expect(TestMdlA.find({name: "John Snow"}).exec()).to.eventually.have.length(1);
    });

    it("should have Yo momma in " + TEST_COLLECTION_B + " with age 38", function(){
      return expect(TestMdlB.find({name: "Yo momma", age: 38}).exec()).to.eventually.have.length(1);
    });

    it("should have T-REX in " + TEST_COLLECTION_B, function(){
      return expect(TestMdlB.find({name: "T-REX"}).exec()).to.eventually.have.length(1);
    });

    it(TEST_COLLECTION_A + " should have length 2", function(){
      return expect(TestMdlA.find().exec()).to.eventually.have.length(2);
    });

    it(TEST_COLLECTION_B + " should have length 2", function(){
      return expect(TestMdlB.find().exec()).to.eventually.have.length(2);
    });
  });

  describe("#remove", function(){
    it("should remove successfully", function(){
      return TestMdlB.findOne({name: "Yo momma"})
        .exec()
        .then(function(yoMomma){
          task.remove(TEST_COLLECTION_A, {name: "John Snow"});
          task.remove(yoMomma);

          return task.run();
        });
    });

    it("should not have John Snow in " + TEST_COLLECTION_A, function(){
      return expect(TestMdlA.find({name: "John Snow"}).exec()).to.eventually.have.length(0);
    });

    it("should have Emmanuel Olaojo in " + TEST_COLLECTION_A, function(){
      return expect(TestMdlA.find({name: "Emmanuel Olaojo"}).exec()).to.eventually.have.length(1);
    });

    it("should not have Yo momma in " + TEST_COLLECTION_B, function(){
      return expect(TestMdlB.find({name: "Yo momma"}).exec()).to.eventually.have.length(0);
    });

    it("should have T-REX in " + TEST_COLLECTION_B, function(){
      return expect(TestMdlB.find({name: "T-REX"}).exec()).to.eventually.have.length(1);
    });

    it(TEST_COLLECTION_A + " should have length 1", function(){
      return expect(TestMdlA.find().exec()).to.eventually.have.length(1);
    });

    it(TEST_COLLECTION_B + " should have length 1", function(){
      return expect(TestMdlB.find().exec()).to.eventually.have.length(1);
    });
  });

  describe("allTogetherNow", function(){
    it("should save, update and remove successfully", function(){
      var brian = new TestMdlB({name: "Brian Griffin", age: 18});

      return task.save(TEST_COLLECTION_A, {name: "John Snow", age: 26})
        .update(TestMdlB, {name: "T-REX"}, {name: "Pegasus"})
        .update(TEST_COLLECTION_A, {name: "Emmanuel Olaojo"}, {name: "OJ"})
        .save(TestMdlA, {name: "unimportant", age: 50})
        .remove(TEST_COLLECTION_A, {name: "unimportant"})
        .save(brian)
        .save(TEST_COLLECTION_B, {name: "Yo momma", age: 18})
        .remove(TestMdlB, {name: "Yo momma"})
        .run();
    });

    it("should have John Snow in " + TEST_COLLECTION_A, function(){
      return expect(TestMdlA.find({name: "John Snow"}).exec()).to.eventually.have.length(1);
    });

    it("should have OJ in " + TEST_COLLECTION_A, function(){
      return expect(TestMdlA.find({name: "OJ"}).exec()).to.eventually.have.length(1);
    });

    it("should have Pegasus in " + TEST_COLLECTION_B, function(){
      return expect(TestMdlB.find({name: "Pegasus"}).exec()).to.eventually.have.length(1);
    });

    it("should have Brian Griffin in " + TEST_COLLECTION_B, function(){
      return expect(TestMdlB.find({name: "Brian Griffin"}).exec()).to.eventually.have.length(1);
    });

    it(TEST_COLLECTION_A + " should have length 2", function(){
      return expect(TestMdlA.find().exec()).to.eventually.have.length(2);
    });

    it(TEST_COLLECTION_B + " should have length 2", function(){
      return expect(TestMdlB.find().exec()).to.eventually.have.length(2);
    });
  });
});<commit_msg>indent change<commit_after>"use strict";

module.exports = describe("Task", function(){
  after(require("./cleanup"));

  describe("#initModel", function(){
    it("should validate data", function(){
      var task = new Task();
      var model = "cars";

      task.initModel(model, {
        make: {type: String, required: true}
        , year: {type: Number, required: true}
      });

      task.save(model, {name: "John"});

      return expect(task.run()).to.eventually.be.rejectedWith(/validation failed/);
    });
  });

  describe("#save", function(){
    it("should save successfully", function(){
      var emmanuel = new TestMdlA({name: "Emmanuel Olaojo", age: 20});
      var brian = new TestMdlB({name: "Brian Griffin", age: 18});

      task.save(TEST_COLLECTION_B, {name: "T-REX", age: 50000000});
      task.save(emmanuel);
      task.save(TEST_COLLECTION_A, {name: "John Damos", age: 26});
      task.save(brian);

      return task.run();
    });

    it("should have Emmanuel Olaojo in " + TEST_COLLECTION_A, function(){
      return expect(TestMdlA.find({name: "Emmanuel Olaojo", age: 20}).exec()).to.eventually.have.length(1);
    });

    it("should have John Damos in " + TEST_COLLECTION_A, function(){
      return expect(TestMdlA.find({name: "John Damos", age: 26}).exec()).to.eventually.have.length(1);
    });

    it("should have T-REX in " + TEST_COLLECTION_B, function(){
      return expect(TestMdlB.find({name: "T-REX", age: 50000000}).exec()).to.eventually.have.length(1);
    });

    it("should have Brian Griffin in " + TEST_COLLECTION_B, function(){
      return expect(TestMdlB.find({name: "Brian Griffin", age: 18}).exec()).to.eventually.have.length(1);
    });

    it(TEST_COLLECTION_A + " should have length 2", function(){
      return expect(TestMdlA.find().exec()).to.eventually.have.length(2);
    });

    it(TEST_COLLECTION_B + " should have length 2", function(){
      return expect(TestMdlB.find().exec()).to.eventually.have.length(2);
    });
  });

  describe("#update", function(){
    it("should update successfully", function(){
      return TestMdlB.findOne({name: "Brian Griffin"})
        .exec()
        .then(function(brian){
          task.update(TEST_COLLECTION_A, {name: "John Damos"}, {name: "John Snow"});
          task.update(brian, {name: "Yo momma", $inc: {age: 20}});

          return task.run()
        });
    });

    it("should have Emmanuel Olaojo in " + TEST_COLLECTION_A, function(){
      return expect(TestMdlA.find({name: "Emmanuel Olaojo"}).exec()).to.eventually.have.length(1);
    });

    it("should have John Snow in " + TEST_COLLECTION_A, function(){
      return expect(TestMdlA.find({name: "John Snow"}).exec()).to.eventually.have.length(1);
    });

    it("should have Yo momma in " + TEST_COLLECTION_B + " with age 38", function(){
      return expect(TestMdlB.find({name: "Yo momma", age: 38}).exec()).to.eventually.have.length(1);
    });

    it("should have T-REX in " + TEST_COLLECTION_B, function(){
      return expect(TestMdlB.find({name: "T-REX"}).exec()).to.eventually.have.length(1);
    });

    it(TEST_COLLECTION_A + " should have length 2", function(){
      return expect(TestMdlA.find().exec()).to.eventually.have.length(2);
    });

    it(TEST_COLLECTION_B + " should have length 2", function(){
      return expect(TestMdlB.find().exec()).to.eventually.have.length(2);
    });
  });

  describe("#remove", function(){
    it("should remove successfully", function(){
      return TestMdlB.findOne({name: "Yo momma"})
        .exec()
        .then(function(yoMomma){
          task.remove(TEST_COLLECTION_A, {name: "John Snow"});
          task.remove(yoMomma);

          return task.run();
        });
    });

    it("should not have John Snow in " + TEST_COLLECTION_A, function(){
      return expect(TestMdlA.find({name: "John Snow"}).exec()).to.eventually.have.length(0);
    });

    it("should have Emmanuel Olaojo in " + TEST_COLLECTION_A, function(){
      return expect(TestMdlA.find({name: "Emmanuel Olaojo"}).exec()).to.eventually.have.length(1);
    });

    it("should not have Yo momma in " + TEST_COLLECTION_B, function(){
      return expect(TestMdlB.find({name: "Yo momma"}).exec()).to.eventually.have.length(0);
    });

    it("should have T-REX in " + TEST_COLLECTION_B, function(){
      return expect(TestMdlB.find({name: "T-REX"}).exec()).to.eventually.have.length(1);
    });

    it(TEST_COLLECTION_A + " should have length 1", function(){
      return expect(TestMdlA.find().exec()).to.eventually.have.length(1);
    });

    it(TEST_COLLECTION_B + " should have length 1", function(){
      return expect(TestMdlB.find().exec()).to.eventually.have.length(1);
    });
  });

  describe("allTogetherNow", function(){
    it("should save, update and remove successfully", function(){
      var brian = new TestMdlB({name: "Brian Griffin", age: 18});

      return task.save(TEST_COLLECTION_A, {name: "John Snow", age: 26})
        .update(TestMdlB, {name: "T-REX"}, {name: "Pegasus"})
        .update(TEST_COLLECTION_A, {name: "Emmanuel Olaojo"}, {name: "OJ"})
        .save(TestMdlA, {name: "unimportant", age: 50})
        .remove(TEST_COLLECTION_A, {name: "unimportant"})
        .save(brian)
        .save(TEST_COLLECTION_B, {name: "Yo momma", age: 18})
        .remove(TestMdlB, {name: "Yo momma"})
        .run();
    });

    it("should have John Snow in " + TEST_COLLECTION_A, function(){
      return expect(TestMdlA.find({name: "John Snow"}).exec()).to.eventually.have.length(1);
    });

    it("should have OJ in " + TEST_COLLECTION_A, function(){
      return expect(TestMdlA.find({name: "OJ"}).exec()).to.eventually.have.length(1);
    });

    it("should have Pegasus in " + TEST_COLLECTION_B, function(){
      return expect(TestMdlB.find({name: "Pegasus"}).exec()).to.eventually.have.length(1);
    });

    it("should have Brian Griffin in " + TEST_COLLECTION_B, function(){
      return expect(TestMdlB.find({name: "Brian Griffin"}).exec()).to.eventually.have.length(1);
    });

    it(TEST_COLLECTION_A + " should have length 2", function(){
      return expect(TestMdlA.find().exec()).to.eventually.have.length(2);
    });

    it(TEST_COLLECTION_B + " should have length 2", function(){
      return expect(TestMdlB.find().exec()).to.eventually.have.length(2);
    });
  });
});<|endoftext|>


<commit_before>/*jslint white: true */
/*global module, String, require, console */

/**
 * @author brian@bevey.org
 * @fileoverview Unit test runner.
 */

module.exports = (function () {
  var reporter = require('nodeunit').reporters.default;

  reporter.run(['tests/unit/lib/loadControllerTest.js',
                'tests/unit/lib/loadMarkupTest.js']);
}());
<commit_msg>Add files to testRunner.js.  Ill do something smarter here later<commit_after>/*jslint white: true */
/*global module, String, require, console */

/**
 * @author brian@bevey.org
 * @fileoverview Unit test runner.
 */

module.exports = (function () {
  var reporter = require('nodeunit').reporters.default;

  reporter.run(['tests/unit/lib/loadControllerTest.js',
                'tests/unit/lib/loadMarkupTest.js',
                'tests/unit/lib/runCommandTest.js',
                'tests/unit/lib/staticAssetsTest.js',
                'tests/unit/controllers/ps3ControllerTest.js',
                'tests/unit/controllers/rokuControllerTest.js',
                'tests/unit/controllers/samsungControllerTest.js',
                'tests/unit/controllers/speechControllerTest.js']);
}());
<|endoftext|>