<commit_before>// This module helps setting up FOSSASIA's GCI15 website repo
// Also checks if origin and upstream remotes are configured correctly

const git = require('./git');
const Git = require('nodegit');
const fs = require('fs');
const ipcRenderer = require('electron').ipcRenderer;

const gciWebButton = document.querySelector('#gci-website__button');
gciWebButton.mode = 'clone';
gciWebButton.innerHTML = 'Clone';

const pathField = document.querySelector('#clone-path');

pathField.value = __dirname;
updateStatuses(); // Update the statuses for the default value of the path

function updateStatuses() {
  const path = pathField.value;

  // Set default submit button's values
  gciWebButton.mode = 'clone';
  gciWebButton.innerHTML = 'Clone';

  const statusDirIcon = document.querySelectorAll('#gci-website__status-dir > span')[0];
  const statusDirText = document.querySelectorAll('#gci-website__status-dir > span')[1];
  const statusRepoIcon = document.querySelectorAll('#gci-website__status-repo > span')[0];
  const statusRepoText = document.querySelectorAll('#gci-website__status-repo > span')[1];
  const statusUpstreamIcon = document.querySelectorAll('#gci-website__status-upstream > span')[0];
  const statusUpstreamText = document.querySelectorAll('#gci-website__status-upstream > span')[1];
  const statusOriginIcon = document.querySelectorAll('#gci-website__status-origin > span')[0];
  const statusOriginText = document.querySelectorAll('#gci-website__status-origin > span')[1];

  // Set all statuses as 'no' by default
  statusDirIcon.className = 'material-icons gci-website__status-no';
  statusDirIcon.innerHTML = 'clear';
  statusDirText.className = 'gci-website__status gci-website__status-no';
  statusDirText.innerHTML = 'doesn\'t exist';
  statusRepoIcon.className = 'material-icons gci-website__status-no';
  statusRepoIcon.innerHTML = 'clear';
  statusRepoText.className = 'gci-website__status gci-website__status-no';
  statusRepoText.innerHTML = 'isn\'t';
  statusUpstreamIcon.className = 'material-icons gci-website__status-no';
  statusUpstreamIcon.innerHTML = 'clear';
  statusUpstreamText.className = 'gci-website__status gci-website__status-no';
  statusUpstreamText.innerHTML = 'isn\'t';
  statusOriginIcon.className = 'material-icons gci-website__status-no';
  statusOriginIcon.innerHTML = 'clear';
  statusOriginText.className = 'gci-website__status gci-website__status-no';
  statusOriginText.innerHTML = 'isn\'t';

  fs.stat(path, function(err, stat) {
    if(err === null) {  // Path already exists
      statusDirIcon.className = 'material-icons gci-website__status-yes';
      statusDirIcon.innerHTML = 'done';
      statusDirText.className = 'gci-website__status gci-website__status-yes';
      statusDirText.innerHTML = 'exists';
      Git.Repository.open(path)
      .then(function(repo) {
        repo.getCommit('03850094869f142934e924a3cbb294993f005d44') // Verify this is gci15.fossasia.org, and not any other git repository (that's the very first commit on gh-pages)
        .then(function(commit) {
          gciWebButton.mode = 'remote';
          statusRepoIcon.className = 'material-icons gci-website__status-yes';
          statusRepoIcon.innerHTML = 'done';
          statusRepoText.className = 'gci-website__status gci-website__status-yes';
          statusRepoText.innerHTML = 'is';
          repo.getRemote('upstream')
          .then(function(remote) {
            if(remote.url() === 'https://github.com/fossasia/gci15.fossasia.org.git') { // "upstream" is set to FOSSASIA's repo
              gciWebButton.mode += '-origin';
              statusUpstreamIcon.className = 'material-icons gci-website__status-yes';
              statusUpstreamIcon.innerHTML = 'done';
              statusUpstreamText.className = 'gci-website__status gci-website__status-yes';
              statusUpstreamText.innerHTML = 'is';
              Git.Remote.create(repo, 'upstream', 'https://github.com/fossasia/gci15.fossasia.org.git');
            }
            repo.getRemote('origin')
            .then(function(remote) {
              if(remote.url() !== 'https://github.com/fossasia/gci15.fossasia.org.git') { // "origin" is set to a custom repo
                gciWebButton.mode += '-upstream';
                statusOriginIcon.className = 'material-icons gci-website__status-yes';
                statusOriginIcon.innerHTML = 'done';
                statusOriginText.className = 'gci-website__status gci-website__status-yes';
                statusOriginText.innerHTML = 'is';
              }
              switch(gciWebButton.mode) {
                // Everything is properly configured
                case 'remote-upstream-origin':
                case 'remote-origin-upstream':
                  gciWebButton.disabled = true;
                  gciWebButton.innerHTML = 'All set!';
                  break;
                // Either "upstream" or none of the remotes aren't configured
                case 'remote':
                case 'remote-upstream':
                  gciWebButton.innerHTML = 'Configure "upstream"';
                  break;
                // The remote "origin" isn't correctly configured
                case 'remote-origin':
                  gciWebButton.innerHTML = 'Configure "origin"';
                  break;
              }
            });
          });
        });
    });
  } else if(err.code !== 'ENOENT') {  // Something went wrong (excluding path not found)
      console.log(err);
    }
  });
}

pathField.onclick = function(e) {
  e.preventDefault();

  // Set up dialog for opening repo's path
  const options = {
    title: 'Choose the directory where open/save the repo',
    properties: [ 'openDirectory' ]
  };

  // Got the path from the dialog
  ipcRenderer.on('openDialogReply', function(event, paths) {
    if(paths !== null) {  // Check the dialog hasn't been cancelled
      // Set the chosen path as pathField's value
      pathField.value = paths[0];
      // Update the statuses (changing the value won't trigger pathfield's oninput
      // event)
      updateStatuses();
    }
  });

  // Display the dialog
  ipcRenderer.send('openDialog', options);
}

pathField.oninput = function(e) {
  e.preventDefault();

  updateStatuses();
}

gciWebButton.onclick = function(e) {
  e.preventDefault();

  const path = pathField.value;

  switch(gciWebButton.mode) {
    // Either "upstream" or none of the remotes aren't configured
    case 'remote':
    case 'remote-upstream':
      gciWebButton.disabled = true;
      gciWebButton.style.cursor = 'not-allowed';
      gciWebButton.innerHTML = 'Loading...';

      document.querySelector('#gci-website__loading').className += ' is-active'; // Display the loading spinner

      Git.Repository.open(path)
      .then(function(repo) {
        Git.Remote.create(repo, 'upstream', 'https://github.com/fossasia/gci15.fossasia.org.git');
        gciWebButton.innerHTML = 'Done!';
        updateStatuses();
        document.querySelector('#gci-website__loading').className = 'mdl-spinner mdl-spinner--single-color mdl-js-spinner';  // Hide the loading spinner (by removing the 'is-active' class)
        setTimeout(function() { // Keep the button disabled with the "Done!" message for a moment
          gciWebButton.disabled = false;
          gciWebButton.style.cursor = 'default';
          gciWebButton.innerHTML = 'Clone';
        }, 1500);
      });
      break;

    // The remote "origin" isn't correctly configured
    case 'remote-origin':
      // TO IMPLEMENT WITH USER'S USERNAME, ONCE #9 IS MERGED
      /*
      Git.Repository.open(path)
      .then(function(repo) {
          Git.Remote.create(repo, 'upstream', customRemote);
      });
      */
      break;

    // The repo isn't cloned yet
    default:
      gciWebButton.disabled = true;
      gciWebButton.style.cursor = 'not-allowed';
      gciWebButton.innerHTML = 'Loading...';

      document.querySelector('#gci-website__loading').className += ' is-active'; // Display the loading spinner

      Git.Clone.clone('https://github.com/fossasia/gci15.fossasia.org.git', path, null)
      .then(function(repo, err) {
        if(err) { // Something went wrong
          console.log(err);
          gciWebButton.innerHTML = 'Error!';
        } else {
          Git.Remote.create(repo, 'upstream', 'https://github.com/fossasia/gci15.fossasia.org.git');
          gciWebButton.innerHTML = 'Done!';
        }
        updateStatuses();
        document.querySelector('#gci-website__loading').className = 'mdl-spinner mdl-spinner--single-color mdl-js-spinner';  // Hide the loading spinner (by removing the 'is-active' class)
        setTimeout(function() { // Keep the button disabled with the "Done!" message for a moment
          gciWebButton.disabled = false;
          gciWebButton.style.cursor = 'default';
          gciWebButton.innerHTML = 'Clone';
        }, 1500);
      });
  }
}
<commit_msg>Consider FOSSASIA's remote with or w/o .git at the end<commit_after>// This module helps setting up FOSSASIA's GCI15 website repo
// Also checks if origin and upstream remotes are configured correctly

const git = require('./git');
const Git = require('nodegit');
const fs = require('fs');
const ipcRenderer = require('electron').ipcRenderer;

const gciWebButton = document.querySelector('#gci-website__button');
gciWebButton.mode = 'clone';
gciWebButton.innerHTML = 'Clone';

const pathField = document.querySelector('#clone-path');

pathField.value = __dirname;
updateStatuses(); // Update the statuses for the default value of the path

function updateStatuses() {
  const path = pathField.value;

  // Set default submit button's values
  gciWebButton.mode = 'clone';
  gciWebButton.innerHTML = 'Clone';

  const statusDirIcon = document.querySelectorAll('#gci-website__status-dir > span')[0];
  const statusDirText = document.querySelectorAll('#gci-website__status-dir > span')[1];
  const statusRepoIcon = document.querySelectorAll('#gci-website__status-repo > span')[0];
  const statusRepoText = document.querySelectorAll('#gci-website__status-repo > span')[1];
  const statusUpstreamIcon = document.querySelectorAll('#gci-website__status-upstream > span')[0];
  const statusUpstreamText = document.querySelectorAll('#gci-website__status-upstream > span')[1];
  const statusOriginIcon = document.querySelectorAll('#gci-website__status-origin > span')[0];
  const statusOriginText = document.querySelectorAll('#gci-website__status-origin > span')[1];

  // Set all statuses as 'no' by default
  statusDirIcon.className = 'material-icons gci-website__status-no';
  statusDirIcon.innerHTML = 'clear';
  statusDirText.className = 'gci-website__status gci-website__status-no';
  statusDirText.innerHTML = 'doesn\'t exist';
  statusRepoIcon.className = 'material-icons gci-website__status-no';
  statusRepoIcon.innerHTML = 'clear';
  statusRepoText.className = 'gci-website__status gci-website__status-no';
  statusRepoText.innerHTML = 'isn\'t';
  statusUpstreamIcon.className = 'material-icons gci-website__status-no';
  statusUpstreamIcon.innerHTML = 'clear';
  statusUpstreamText.className = 'gci-website__status gci-website__status-no';
  statusUpstreamText.innerHTML = 'isn\'t';
  statusOriginIcon.className = 'material-icons gci-website__status-no';
  statusOriginIcon.innerHTML = 'clear';
  statusOriginText.className = 'gci-website__status gci-website__status-no';
  statusOriginText.innerHTML = 'isn\'t';

  fs.stat(path, function(err, stat) {
    if(err === null) {  // Path already exists
      statusDirIcon.className = 'material-icons gci-website__status-yes';
      statusDirIcon.innerHTML = 'done';
      statusDirText.className = 'gci-website__status gci-website__status-yes';
      statusDirText.innerHTML = 'exists';
      Git.Repository.open(path)
      .then(function(repo) {
        repo.getCommit('03850094869f142934e924a3cbb294993f005d44') // Verify this is gci15.fossasia.org, and not any other git repository (that's the very first commit on gh-pages)
        .then(function(commit) {
          gciWebButton.mode = 'remote';
          statusRepoIcon.className = 'material-icons gci-website__status-yes';
          statusRepoIcon.innerHTML = 'done';
          statusRepoText.className = 'gci-website__status gci-website__status-yes';
          statusRepoText.innerHTML = 'is';
          repo.getRemote('upstream')
          .then(function(remote) {
            if(remote.url() === 'https://github.com/fossasia/gci15.fossasia.org.git' || remote.url() === 'https://github.com/fossasia/gci15.fossasia.org') { // "upstream" is set to FOSSASIA's repo
              gciWebButton.mode += '-origin';
              statusUpstreamIcon.className = 'material-icons gci-website__status-yes';
              statusUpstreamIcon.innerHTML = 'done';
              statusUpstreamText.className = 'gci-website__status gci-website__status-yes';
              statusUpstreamText.innerHTML = 'is';
              Git.Remote.create(repo, 'upstream', 'https://github.com/fossasia/gci15.fossasia.org.git');
            }
            repo.getRemote('origin')
            .then(function(remote) {
              if(remote.url() !== 'https://github.com/fossasia/gci15.fossasia.org.git' && remote.url() !== 'https://github.com/fossasia/gci15.fossasia.org') { // "origin" is set to a custom repo
                gciWebButton.mode += '-upstream';
                statusOriginIcon.className = 'material-icons gci-website__status-yes';
                statusOriginIcon.innerHTML = 'done';
                statusOriginText.className = 'gci-website__status gci-website__status-yes';
                statusOriginText.innerHTML = 'is';
              }
              switch(gciWebButton.mode) {
                // Everything is properly configured
                case 'remote-upstream-origin':
                case 'remote-origin-upstream':
                  gciWebButton.disabled = true;
                  gciWebButton.innerHTML = 'All set!';
                  break;
                // Either "upstream" or none of the remotes aren't configured
                case 'remote':
                case 'remote-upstream':
                  gciWebButton.innerHTML = 'Configure "upstream"';
                  break;
                // The remote "origin" isn't correctly configured
                case 'remote-origin':
                  gciWebButton.innerHTML = 'Configure "origin"';
                  break;
              }
            });
          });
        });
    });
  } else if(err.code !== 'ENOENT') {  // Something went wrong (excluding path not found)
      console.log(err);
    }
  });
}

pathField.onclick = function(e) {
  e.preventDefault();

  // Set up dialog for opening repo's path
  const options = {
    title: 'Choose the directory where open/save the repo',
    properties: [ 'openDirectory' ]
  };

  // Got the path from the dialog
  ipcRenderer.on('openDialogReply', function(event, paths) {
    if(paths !== null) {  // Check the dialog hasn't been cancelled
      // Set the chosen path as pathField's value
      pathField.value = paths[0];
      // Update the statuses (changing the value won't trigger pathfield's oninput
      // event)
      updateStatuses();
    }
  });

  // Display the dialog
  ipcRenderer.send('openDialog', options);
}

pathField.oninput = function(e) {
  e.preventDefault();

  updateStatuses();
}

gciWebButton.onclick = function(e) {
  e.preventDefault();

  const path = pathField.value;

  switch(gciWebButton.mode) {
    // Either "upstream" or none of the remotes aren't configured
    case 'remote':
    case 'remote-upstream':
      gciWebButton.disabled = true;
      gciWebButton.style.cursor = 'not-allowed';
      gciWebButton.innerHTML = 'Loading...';

      document.querySelector('#gci-website__loading').className += ' is-active'; // Display the loading spinner

      Git.Repository.open(path)
      .then(function(repo) {
        Git.Remote.create(repo, 'upstream', 'https://github.com/fossasia/gci15.fossasia.org.git');
        gciWebButton.innerHTML = 'Done!';
        updateStatuses();
        document.querySelector('#gci-website__loading').className = 'mdl-spinner mdl-spinner--single-color mdl-js-spinner';  // Hide the loading spinner (by removing the 'is-active' class)
        setTimeout(function() { // Keep the button disabled with the "Done!" message for a moment
          gciWebButton.disabled = false;
          gciWebButton.style.cursor = 'default';
          gciWebButton.innerHTML = 'Clone';
        }, 1500);
      });
      break;

    // The remote "origin" isn't correctly configured
    case 'remote-origin':
      // TO IMPLEMENT WITH USER'S USERNAME, ONCE #9 IS MERGED
      /*
      Git.Repository.open(path)
      .then(function(repo) {
          Git.Remote.create(repo, 'upstream', customRemote);
      });
      */
      break;

    // The repo isn't cloned yet
    default:
      gciWebButton.disabled = true;
      gciWebButton.style.cursor = 'not-allowed';
      gciWebButton.innerHTML = 'Loading...';

      document.querySelector('#gci-website__loading').className += ' is-active'; // Display the loading spinner

      Git.Clone.clone('https://github.com/fossasia/gci15.fossasia.org.git', path, null)
      .then(function(repo, err) {
        if(err) { // Something went wrong
          console.log(err);
          gciWebButton.innerHTML = 'Error!';
        } else {
          Git.Remote.create(repo, 'upstream', 'https://github.com/fossasia/gci15.fossasia.org.git');
          gciWebButton.innerHTML = 'Done!';
        }
        updateStatuses();
        document.querySelector('#gci-website__loading').className = 'mdl-spinner mdl-spinner--single-color mdl-js-spinner';  // Hide the loading spinner (by removing the 'is-active' class)
        setTimeout(function() { // Keep the button disabled with the "Done!" message for a moment
          gciWebButton.disabled = false;
          gciWebButton.style.cursor = 'default';
          gciWebButton.innerHTML = 'Clone';
        }, 1500);
      });
  }
}
<|endoftext|>


<commit_before>// Note:
//   window.MacMessengerVersion will be defined to a string e.g. to "0.1.2"
//   window.MacMessengerGitRev will be defined to a string e.g. "abc917"

window.MacMessenger = {
  openGearMenu: function() {
    this.gearButton.firstElementChild.dispatchEvent(
      new MouseEvent('click', {view:window, bubbles:true, cancelable:true})
    );
  },

  logOut: function() {
    // TODO: Actually "log out" instead of showing the menu
    this.openGearMenu();
  },

  showSettings: function() {
    this.openGearMenu();
    document.querySelector(
      'div.uiLayer.uiContextualLayerPositioner#js_1 > div.uiContextualLayer a'
    ).dispatchEvent(
      new MouseEvent('click', {view:window, bubbles:true, cancelable:true})
    );
  },

  composeNewMessage: function() {
    document.querySelector('a[href="/new"]').dispatchEvent(
      new MouseEvent('click', {view:window, bubbles:true, cancelable:true})
    );
  },

  focusSearchField: function() {
    document.querySelector('input[placeholder~="Search"]').focus();
  },

  focusComposer: function() {
    document.querySelector('div[contenteditable="true"]').focus();
  },

  selectConversationAtIndex: function(index) {
    document.querySelector('li:nth-child('+index+') > [data-reactid]:first-child').click();
  },

};

// Things that need the DOM to be loaded
(function () {
  var onDocumentLoaded = function() {
    if (document.readyState === "loading") {
      return; // still loading
    }
    document.removeEventListener('readystatechange', onDocumentLoaded);

    // This fixes an annoying "beep" sound
    document.body.onkeypress = function (e) {
      var target = e.target.contentEditable && e.target.querySelector('[data-block]');
      if (target && window.getSelection().baseOffset === 0 && !e.metaKey) {
        var textEvent = document.createEvent('TextEvent');
        textEvent.initTextEvent('textInput', true, true, null, String.fromCharCode(e.which));
        target.dispatchEvent(textEvent);
        return false;
      }
    };

    // Find settings gear
    var tryFindSettingsGear = function() {
      var e = document.querySelector('[aria-owns="js_1"]');
      if (e) {
        e = e.parentNode;
        e.style.visibility = 'hidden';
        window.MacMessenger.gearButton = e;
        return true;
      }
    };
    if (!tryFindSettingsGear()) {
      var observer = new MutationObserver(function(mutations) {
        if (tryFindSettingsGear()) {
          observer.disconnect();
        }
      });
      observer.observe(document.body, { attributes: false, childList: true, characterData: false });
    }

    // The following two statements enable drag-and-drop file sending
    document.addEventListener('dragover', function(ev) {
      ev.stopPropagation();
      ev.preventDefault();
      ev.dataTransfer.dropEffect = 'copy';
    });
    document.addEventListener('drop', function(ev) {
      ev.stopPropagation();
      ev.preventDefault();
      document.querySelector('input[type="file"][name="attachment[]"]').files =
        ev.dataTransfer.files;
    });

  };
  document.addEventListener('readystatechange', onDocumentLoaded);
  onDocumentLoaded();
})();

console.log('app/main.js loaded');
<commit_msg>always trigger manual text events<commit_after>// Note:
//   window.MacMessengerVersion will be defined to a string e.g. to "0.1.2"
//   window.MacMessengerGitRev will be defined to a string e.g. "abc917"

window.MacMessenger = {
  openGearMenu: function() {
    this.gearButton.firstElementChild.dispatchEvent(
      new MouseEvent('click', {view:window, bubbles:true, cancelable:true})
    );
  },

  logOut: function() {
    // TODO: Actually "log out" instead of showing the menu
    this.openGearMenu();
  },

  showSettings: function() {
    this.openGearMenu();
    document.querySelector(
      'div.uiLayer.uiContextualLayerPositioner#js_1 > div.uiContextualLayer a'
    ).dispatchEvent(
      new MouseEvent('click', {view:window, bubbles:true, cancelable:true})
    );
  },

  composeNewMessage: function() {
    document.querySelector('a[href="/new"]').dispatchEvent(
      new MouseEvent('click', {view:window, bubbles:true, cancelable:true})
    );
  },

  focusSearchField: function() {
    document.querySelector('input[placeholder~="Search"]').focus();
  },

  focusComposer: function() {
    document.querySelector('div[contenteditable="true"]').focus();
  },

  selectConversationAtIndex: function(index) {
    document.querySelector('li:nth-child('+index+') > [data-reactid]:first-child').click();
  },

};

// Things that need the DOM to be loaded
(function () {
  var onDocumentLoaded = function() {
    if (document.readyState === "loading") {
      return; // still loading
    }
    document.removeEventListener('readystatechange', onDocumentLoaded);

    // This fixes an annoying "beep" sound
    document.body.onkeypress = function (e) {
      var target = e.target.contentEditable && e.target.querySelector('[data-block]');
      if (target && !e.metaKey) {
        var textEvent = document.createEvent('TextEvent');
        textEvent.initTextEvent('textInput', true, true, null, String.fromCharCode(e.which));
        target.dispatchEvent(textEvent);
        return false;
      }
    };

    // Find settings gear
    var tryFindSettingsGear = function() {
      var e = document.querySelector('[aria-owns="js_1"]');
      if (e) {
        e = e.parentNode;
        e.style.visibility = 'hidden';
        window.MacMessenger.gearButton = e;
        return true;
      }
    };
    if (!tryFindSettingsGear()) {
      var observer = new MutationObserver(function(mutations) {
        if (tryFindSettingsGear()) {
          observer.disconnect();
        }
      });
      observer.observe(document.body, { attributes: false, childList: true, characterData: false });
    }

    // The following two statements enable drag-and-drop file sending
    document.addEventListener('dragover', function(ev) {
      ev.stopPropagation();
      ev.preventDefault();
      ev.dataTransfer.dropEffect = 'copy';
    });
    document.addEventListener('drop', function(ev) {
      ev.stopPropagation();
      ev.preventDefault();
      document.querySelector('input[type="file"][name="attachment[]"]').files =
        ev.dataTransfer.files;
    });

  };
  document.addEventListener('readystatechange', onDocumentLoaded);
  onDocumentLoaded();
})();

console.log('app/main.js loaded');
<|endoftext|>


<commit_before>function draw_graph(json_data){
	var data = json_data;
	var links = []; // dict = {source: , target: , value: ,}
	for (var n= 0; n < data.length; n++){
		var cluster_nodes = data[n].nodes;
		var neighbors = data[n].neighbors;
		for (var i= 0; i < cluster_nodes.length; i++){
			var node = cluster_nodes[i];
			var name = node.name;
			var requests = node.requests;
			var node_neighbors = neighbors[name];
			if (node_neighbors.length == 0){
				var similarity = 0;
				links.push({"source": [name, requests], "target": [name, requests], "value": similarity});
			} else {
				for (var m= 0; m < node_neighbors.length; m++){
					var neighbor = node_neighbors[m];
					var source = [name, requests];
					for (var t = 0; t < cluster_nodes.length; t++){
						if (cluster_nodes[t].name == neighbor.node){
							var target = [cluster_nodes[t].name, cluster_nodes[t].requests];
							var similarity = neighbor.similarity;
							break;
						}
					}
					links.push({"source": source, "target": target, "value": similarity});
				}
			}

		}
	}
//	console.log(links);
	var nodes = {};

	// Compute the distinct nodes from the links.
	links.forEach(function(link) {
		link.source = nodes[link.source] ||
			(nodes[link.source] = {name: link.source});
		link.target = nodes[link.target] ||
			(nodes[link.target] = {name: link.target});
		link.value = +link.value;
	});

//	console.log(nodes);

	var graph_div = document.getElementById("graph");
	var width = window.innerWidth;
	var	height = window.innerHeight;
	var width_button, height_panels = 150;
	var side_bar_height = document.getElementById('side_bar').clientHeight;
	var graph_width = document.getElementById('graph').clientWidth;

	var force = d3.layout.force()
		.nodes(d3.values(nodes))
		.links(links)
		.size([width / 2 , height/ 1.5])
		.linkDistance(100)
		.charge(-500)
		.on("tick", tick)
		.start();

	// remove if anything was already drawn on the screen
	d3.select("body").select("#container").select("#parent").select("#graph").select("svg").remove();
	// draw new graph

	var svg = d3.select("body").select("#container").select("#parent").select("#graph").append("svg")
		.attr("width", graph_width)
		.attr("height", side_bar_height);

	// build the arrow.
	svg.append("svg:defs").selectAll("marker")
		.data(["end"])      // Different link/path types can be defined here
	.enter().append("svg:marker")    // This section adds in the arrows
		.attr("id", String)
		.attr("viewBox", "0 -5 10 10")
		.attr("refX", 15)
		.attr("refY", -1.5)
		.attr("fill", "darkgrey")
		.attr("markerWidth", 6)
		.attr("markerHeight", 6)
		.attr("orient", "auto")
	.append("svg:path")
		.attr("d", "M0,-5L10,0L0,5");

	// add the links and the arrows
	var path_index = 0
	var path = svg.append("svg:g").selectAll("path")
		.data(force.links())
	.enter().append("svg:path")
	    .attr("class", function(d) { return "link " + d.type; })
		.attr("class", "link")
		.attr("id", function(){
			path_index = path_index + 1;
			return path_index;
		} )
		.on("mouseover", function(d){
			var g = d3.select(this); // The node
			console.log(g);
			// The class is used to remove the additional text later
//			if (d3.select(this).select('text.info')[0][0] == null){
			var info = g.append('text')
				.classed('info', true)
//				.attr('x', 20)
//				.attr('y', 10)
				.attr("font-size","30px")
				.append("textPath")
        		.attr("xlink:href", function (d,i) {
					var path_id = g[0][0].id;
					return path_id; })
				.text(function(d) {
					return d.value; });
		})
		.on("mouseout", function() {
		// Remove the info text on mouse out.
			//d3.select(this).select('text.info').remove();
		})
		.attr("marker-end", function(d) {if (d.value == 0){
											return "";
										} else {
											return "url(#end)"}});

	// define the nodes
	var node = svg.selectAll(".node")
		.data(force.nodes())
	.enter().append("g")
		.attr("class", "node")
		.on("click", function(d) {
			var g = d3.select(this); // The node
			// The class is used to remove the additional text later
			if (d3.select(this).select('text.info')[0][0] == null){
				var info = g.append('text')
					.classed('info', true)
					.attr('x', 20)
					.attr('y', 10)
					.attr("font-size","30px")
					.text(function(d) { console.log(d); });
			} else {
				d3.select(this).select('text.info').remove();
			}
		})
/*		.on("mouseout", function() {
			// Remove the info text on mouse out.
			d3.select(this).select('text.info').remove();
		})*/
		.call(force.drag);

	// add the nodes
	node.append("circle")
		.attr("r", function(d){
			return 5});

	// add the text
	node.append("text")
		.attr("x", 12)
		.attr("dy", ".35em")
		.attr("font-size", "10xp")
		.text(function(d) { return d.name[0]; });

	resize();
  	d3.select(window).on("resize", resize);
	// add the curvy lines
	function tick() {
		path.attr("d", function(d) {
			var dx = d.target.x - d.source.x,
				dy = d.target.y - d.source.y,
				dr = Math.sqrt(dx * dx + dy * dy);
			return "M" +
				d.source.x + "," +
				d.source.y + "A" +
				dr + "," + dr + " 0 0,1 " +
				d.target.x + "," +
				d.target.y;
		});

		node
			.attr("transform", function(d) {
			return "translate(" + d.x + "," + d.y + ")"; });
	}

	function resize(){
		var side_bar_height = document.getElementById('side_bar').clientHeight;
		var graph_width = document.getElementById('graph').clientWidth;
		svg.attr("width", graph_width).attr("height", height - height_panels);
		force.size([width / 2, height / 1.5]).resume();
	}

}

//Get the distance to use between nodes depending on the screen size
function getOptimalDistance(sreenHeight){

}

// Returns a list of all nodes under the root.
function flatten(root) {
  var nodes = [], i = 0;

  function recurse(node) {
    if (node.children) node.children.forEach(recurse);
    if (!node.id) node.id = ++i;
    nodes.push(node);
  }

  recurse(root);
  return nodes;
}
<commit_msg>Corrected some mistakes following jshint<commit_after>function draw_graph(json_data){
	var data = json_data;
	var links = []; // dict = {source: , target: , value: ,}
	for (var n= 0; n < data.length; n++){
		var cluster_nodes = data[n].nodes;
		var neighbors = data[n].neighbors;
		for (var i= 0; i < cluster_nodes.length; i++){
			var node = cluster_nodes[i];
			var name = node.name;
			var requests = node.requests;
			var node_neighbors = neighbors[name];
			if (node_neighbors.length === 0){
				var similarity = 0;
				links.push({"source": [name, requests], "target": [name, requests], "value": similarity});
			} else {
				for (var m= 0; m < node_neighbors.length; m++){
					var neighbor = node_neighbors[m];
					var source = [name, requests];
					for (var t = 0; t < cluster_nodes.length; t++){
						if (cluster_nodes[t].name == neighbor.node){
							var target = [cluster_nodes[t].name, cluster_nodes[t].requests];
							var similarity = neighbor.similarity;
							break;
						}
					}
					links.push({"source": source, "target": target, "value": similarity});
				}
			}

		}
	}
//	console.log(links);
	var nodes = {};

	// Compute the distinct nodes from the links.
	links.forEach(function(link) {
		link.source = nodes[link.source] ||
			(nodes[link.source] = {name: link.source});
		link.target = nodes[link.target] ||
			(nodes[link.target] = {name: link.target});
		link.value = +link.value;
	});

//	console.log(nodes);

	var graph_div = document.getElementById("graph");
	var width = window.innerWidth;
	var	height = window.innerHeight;
	var width_button, height_panels = 150;
	var side_bar_height = document.getElementById('side_bar').clientHeight;
	var graph_width = document.getElementById('graph').clientWidth;

	var force = d3.layout.force()
		.nodes(d3.values(nodes))
		.links(links)
		.size([width / 2 , height/ 1.5])
		.linkDistance(100)
		.charge(-500)
		.on("tick", tick)
		.start();

	// remove if anything was already drawn on the screen
	d3.select("body").select("#container").select("#parent").select("#graph").select("svg").remove();
	// draw new graph

	var svg = d3.select("body").select("#container").select("#parent").select("#graph").append("svg")
		.attr("width", graph_width)
		.attr("height", side_bar_height);

	// build the arrow.
	svg.append("svg:defs").selectAll("marker")
		.data(["end"])      // Different link/path types can be defined here
	.enter().append("svg:marker")    // This section adds in the arrows
		.attr("id", String)
		.attr("viewBox", "0 -5 10 10")
		.attr("refX", 15)
		.attr("refY", -1.5)
		.attr("fill", "darkgrey")
		.attr("markerWidth", 6)
		.attr("markerHeight", 6)
		.attr("orient", "auto")
	.append("svg:path")
		.attr("d", "M0,-5L10,0L0,5");

	// add the links and the arrows
	var path_index = 0;
	var path = svg.append("svg:g").selectAll("path")
		.data(force.links())
	.enter().append("svg:path")
	    .attr("class", function(d) { return "link " + d.type; })
		.attr("class", "link")
		.attr("id", function(){
			path_index = path_index + 1;
			return path_index;
		} )
		.on("mouseover", function(d){
			var g = d3.select(this); // The node
			console.log(g);
			// The class is used to remove the additional text later
//			if (d3.select(this).select('text.info')[0][0] == null){
			var info = g.append('text')
				.classed('info', true)
//				.attr('x', 20)
//				.attr('y', 10)
				.attr("font-size","30px")
				.append("textPath")
        		.attr("xlink:href", function (d,i) {
					var path_id = g[0][0].id;
					return path_id; })
				.text(function(d) {
					return d.value; });
		})
		.on("mouseout", function() {
		// Remove the info text on mouse out.
			//d3.select(this).select('text.info').remove();
		})
		.attr("marker-end", function(d) {if (d.value === 0){
											return "";
										} else {
											return "url(#end)";}});

	// define the nodes
	var node = svg.selectAll(".node")
		.data(force.nodes())
	.enter().append("g")
		.attr("class", "node")
		.on("click", function(d) {
			var g = d3.select(this); // The node
			// The class is used to remove the additional text later
			if (d3.select(this).select('text.info')[0][0] === null){
				var info = g.append('text')
					.classed('info', true)
					.attr('x', 20)
					.attr('y', 10)
					.attr("font-size","30px")
					.text(function(d) { console.log(d); });
			} else {
				d3.select(this).select('text.info').remove();
			}
		})
/*		.on("mouseout", function() {
			// Remove the info text on mouse out.
			d3.select(this).select('text.info').remove();
		})*/
		.call(force.drag);

	// add the nodes
	node.append("circle")
		.attr("r", function(d){
			return 5;});

	// add the text
	node.append("text")
		.attr("x", 12)
		.attr("dy", ".35em")
		.attr("font-size", "10xp")
		.text(function(d) { return d.name[0]; });

	resize();
  	d3.select(window).on("resize", resize);
	// add the curvy lines
	function tick() {
		path.attr("d", function(d) {
			var dx = d.target.x - d.source.x,
				dy = d.target.y - d.source.y,
				dr = Math.sqrt(dx * dx + dy * dy);
			return "M" +
				d.source.x + "," +
				d.source.y + "A" +
				dr + "," + dr + " 0 0,1 " +
				d.target.x + "," +
				d.target.y;
		});

		node
			.attr("transform", function(d) {
			return "translate(" + d.x + "," + d.y + ")"; });
	}

	function resize(){
		var side_bar_height = document.getElementById('side_bar').clientHeight;
		var graph_width = document.getElementById('graph').clientWidth;
		svg.attr("width", graph_width).attr("height", height - height_panels);
		force.size([width / 2, height / 1.5]).resume();
	}

}

//Get the distance to use between nodes depending on the screen size
function getOptimalDistance(sreenHeight){

}

// Returns a list of all nodes under the root.
function flatten(root) {
  var nodes = [], i = 0;

  function recurse(node) {
    if (node.children) node.children.forEach(recurse);
    if (!node.id) node.id = ++i;
    nodes.push(node);
  }

  recurse(root);
  return nodes;
}
<|endoftext|>


<commit_before>// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
//
// This software (Documize Community Edition) is licensed under
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
//
// You can operate outside the AGPL restrictions by purchasing
// Documize Enterprise Edition and obtaining a commercial license
// by contacting <sales@documize.com>.
//
// https://documize.com

import { computed } from '@ember/object';
import { inject as service } from '@ember/service';
import Component from '@ember/component';

export default Component.extend({
	localStorage: service('localStorage'),
	resultPhrase: '',
	searchQuery: computed('keywords', function() {
		return encodeURIComponent(this.get('keywords'));
	}),
	// eslint-disable-next-line ember/avoid-leaking-state-in-ember-objects
	sortBy: {
		name: true,
		created: false,
		updated: false,
		asc: true,
		desc: false,
	},

	didReceiveAttrs() {
		this._super(...arguments);

		let docs = this.get('results');
		let duped = [];
		let phrase = 'Nothing found';

		if (docs.length > 0) {
			duped = _.uniq(docs, function (item) {
				return item.get('documentId');
			});

			let references = docs.length === 1 ? "reference" : "references";
			let docLabel = duped.length === 1 ? "document" : "documents";
			let i = docs.length;
			let j = duped.length;
			phrase = `${i} ${references} in ${j} ${docLabel}`;
		}

		this.set('resultPhrase', phrase);

		let sortBy = this.get('localStorage').getSessionItem('search.sortBy');
		if (!_.isNull(sortBy) && !_.isUndefined(sortBy)) {
			this.send('onSetSort', sortBy);
		}

		let sortOrder = this.get('localStorage').getSessionItem('search.sortOrder');
		if (!_.isNull(sortOrder) && !_.isUndefined(sortOrder)) {
			this.send('onSetSort', sortOrder);
		}

		this.sortResults(duped);
	},

	sortResults(docs) {
		let ls = this.get('localStorage');
		let sortBy = this.get('sortBy');

		if (_.isNull(docs)) return;

		if (sortBy.name) {
			docs = docs.sortBy('document');
			ls.storeSessionItem('search.sortBy', 'name');
		}
		if (sortBy.created) {
			docs = docs.sortBy('created');
			ls.storeSessionItem('search.sortBy', 'created');
		}
		if (sortBy.updated) {
			docs = docs.sortBy('revised');
			ls.storeSessionItem('search.sortBy', 'updated');
		}
		if (sortBy.desc) {
			docs = docs.reverseObjects();
			ls.storeSessionItem('search.sortOrder', 'desc');
		} else {
			ls.storeSessionItem('search.sortOrder', 'asc');
		}

		this.set('documents', docs);
	},

	actions: {
		onSetSort(val) {
			switch (val) {
				case 'name':
					this.set('sortBy.name', true);
					this.set('sortBy.created', false);
					this.set('sortBy.updated', false);
					break;
				case 'created':
					this.set('sortBy.name', false);
					this.set('sortBy.created', true);
					this.set('sortBy.updated', false);
					break;
				case 'updated':
					this.set('sortBy.name', false);
					this.set('sortBy.created', false);
					this.set('sortBy.updated', true);
					break;
				case 'asc':
					this.set('sortBy.asc', true);
					this.set('sortBy.desc', false);
					break;
				case 'desc':
					this.set('sortBy.asc', false);
					this.set('sortBy.desc', true);
					break;
			}
		},

		// eslint-disable-next-line no-unused-vars
		onSortBy(attacher) {
			this.sortResults(this.get('documents'));
		},
	}
});
<commit_msg>Fixed an issue with duplicate search results<commit_after>// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
//
// This software (Documize Community Edition) is licensed under
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
//
// You can operate outside the AGPL restrictions by purchasing
// Documize Enterprise Edition and obtaining a commercial license
// by contacting <sales@documize.com>.
//
// https://documize.com

import { computed } from '@ember/object';
import { inject as service } from '@ember/service';
import Component from '@ember/component';

export default Component.extend({
	localStorage: service('localStorage'),
	resultPhrase: '',
	searchQuery: computed('keywords', function() {
		return encodeURIComponent(this.get('keywords'));
	}),
	// eslint-disable-next-line ember/avoid-leaking-state-in-ember-objects
	sortBy: {
		name: true,
		created: false,
		updated: false,
		asc: true,
		desc: false,
	},

	didReceiveAttrs() {
		this._super(...arguments);

		let docs = this.get('results');
		let duped = [];
		let phrase = 'Nothing found';

		if (docs.length > 0) {
			duped = _.uniqBy(docs, function(item) {
				return item.get('documentId');
			});

			let references = docs.length === 1 ? "reference" : "references";
			let docLabel = duped.length === 1 ? "document" : "documents";
			let i = docs.length;
			let j = duped.length;
			phrase = `${i} ${references} in ${j} ${docLabel}`;
		}

		this.set('resultPhrase', phrase);

		let sortBy = this.get('localStorage').getSessionItem('search.sortBy');
		if (!_.isNull(sortBy) && !_.isUndefined(sortBy)) {
			this.send('onSetSort', sortBy);
		}

		let sortOrder = this.get('localStorage').getSessionItem('search.sortOrder');
		if (!_.isNull(sortOrder) && !_.isUndefined(sortOrder)) {
			this.send('onSetSort', sortOrder);
		}

		this.sortResults(duped);
	},

	sortResults(docs) {
		let ls = this.get('localStorage');
		let sortBy = this.get('sortBy');

		if (_.isNull(docs)) return;

		if (sortBy.name) {
			docs = docs.sortBy('document');
			ls.storeSessionItem('search.sortBy', 'name');
		}
		if (sortBy.created) {
			docs = docs.sortBy('created');
			ls.storeSessionItem('search.sortBy', 'created');
		}
		if (sortBy.updated) {
			docs = docs.sortBy('revised');
			ls.storeSessionItem('search.sortBy', 'updated');
		}
		if (sortBy.desc) {
			docs = docs.reverseObjects();
			ls.storeSessionItem('search.sortOrder', 'desc');
		} else {
			ls.storeSessionItem('search.sortOrder', 'asc');
		}

		this.set('documents', docs);
	},

	actions: {
		onSetSort(val) {
			switch (val) {
				case 'name':
					this.set('sortBy.name', true);
					this.set('sortBy.created', false);
					this.set('sortBy.updated', false);
					break;
				case 'created':
					this.set('sortBy.name', false);
					this.set('sortBy.created', true);
					this.set('sortBy.updated', false);
					break;
				case 'updated':
					this.set('sortBy.name', false);
					this.set('sortBy.created', false);
					this.set('sortBy.updated', true);
					break;
				case 'asc':
					this.set('sortBy.asc', true);
					this.set('sortBy.desc', false);
					break;
				case 'desc':
					this.set('sortBy.asc', false);
					this.set('sortBy.desc', true);
					break;
			}
		},

		// eslint-disable-next-line no-unused-vars
		onSortBy(attacher) {
			this.sortResults(this.get('documents'));
		},
	}
});
<|endoftext|>


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

"use strict";

describe('Lifecycle', () => {
    it("Connection Lifecycle Promises", function () {
        const client = require("./setup").client();
        expect(client.status.created).toBeGreaterThan(0);
        expect(client.status.lastopen).toBe(0);
        expect(client.status.lastcall).toBe(0);
        expect(client.status.lastclose).toBe(0);

        return (async function () {
            await client.open();
            expect(client.status.created).toBeGreaterThan(0);
            expect(client.status.lastopen).toBeGreaterThan(client.status.created);
            expect(client.status.lastcall).toBe(0);
            expect(client.status.lastclose).toBe(0);

            let result = await client.call('STFC_CONNECTION', {
                REQUTEXT: 'H€llö SAP!'
            });
            expect(client.status.created).toBeGreaterThan(0);
            expect(client.status.lastopen).toBeGreaterThan(client.status.created);
            expect(client.status.lastcall).toBeGreaterThan(client.status.lastopen);
            expect(client.status.lastclose).toBe(0);

            await client.close();
            expect(client.status.created).toBeGreaterThan(0);
            expect(client.status.lastopen).toBeGreaterThan(client.status.created);
            expect(client.status.lastcall).toBeGreaterThan(client.status.lastopen)
            expect(client.status.lastclose).toBeGreaterThan(client.status.lastcall);
        })()
    });

    it("Connection Lifecycle Callbacks", function (done) {

        const client = require("./setup").client();
        expect(client.status.created).toBeGreaterThan(0);
        expect(client.status.lastopen).toBe(0);
        expect(client.status.lastcall).toBe(0);
        expect(client.status.lastclose).toBe(0);

        client.connect(err => {
            if (err) done(err);
            expect(client.status.created).toBeGreaterThan(0);
            expect(client.status.lastopen).toBeGreaterThan(client.status.created);
            expect(client.status.lastcall).toBe(0);
            expect(client.status.lastclose).toBe(0);;

            client.invoke('STFC_CONNECTION', {
                REQUTEXT: 'H€llö SAP!',
            }, (err, res) => {
                if (err) done(err);
                expect(client.status.created).toBeGreaterThan(0);
                expect(client.status.lastopen).toBeGreaterThan(client.status.created);
                expect(client.status.lastcall).toBeGreaterThan(client.status.lastopen);
                expect(client.status.lastclose).toBe(0);

                client.close(() => {
                    expect(client.status.created).toBeGreaterThan(0);
                    expect(client.status.lastopen).toBeGreaterThan(client.status.created);
                    expect(client.status.lastcall).toBeGreaterThan(client.status.lastopen)
                    expect(client.status.lastclose).toBeGreaterThan(client.status.lastcall);
                    done();
                })
            });
        });
    });
})
<commit_msg>Unit tests Lifecycle<commit_after>// Copyright 2014 SAP AG.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http: //www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// either express or implied. See the License for the specific
// language governing permissions and limitations under the License.

"use strict";

describe('Lifecycle', () => {
    it("Connection Lifecycle Promises", function () {
        const client = require("./setup").client();
        expect(client.status.created).toBeGreaterThan(0);
        expect(client.status.lastopen).toBe(0);
        expect(client.status.lastcall).toBe(0);
        expect(client.status.lastclose).toBe(0);

        return (async function () {
            await client.open();
            expect(client.status.created).toBeGreaterThan(0);
            expect(client.status.lastopen).toBeGreaterThan(client.status.created);
            expect(client.status.lastcall).toBe(0);
            expect(client.status.lastclose).toBe(0);

            let result = await client.call('/COE/RBP_FE_WAIT', {
                IV_SECONDS: 1
            });
            expect(client.status.created).toBeGreaterThan(0);
            expect(client.status.lastopen).toBeGreaterThan(client.status.created);
            expect(client.status.lastcall).toBeGreaterThan(client.status.lastopen);
            expect(client.status.lastclose).toBe(0);

            await client.close();
            expect(client.status.created).toBeGreaterThan(0);
            expect(client.status.lastopen).toBeGreaterThan(client.status.created);
            expect(client.status.lastcall).toBeGreaterThan(client.status.lastopen)
            expect(client.status.lastclose).toBeGreaterThan(client.status.lastcall);
        })()
    });

    it("Connection Lifecycle Callbacks", function (done) {

        const client = require("./setup").client();
        expect(client.status.created).toBeGreaterThan(0);
        expect(client.status.lastopen).toBe(0);
        expect(client.status.lastcall).toBe(0);
        expect(client.status.lastclose).toBe(0);

        client.connect(err => {
            if (err) done(err);
            expect(client.status.created).toBeGreaterThan(0);
            expect(client.status.lastopen).toBeGreaterThan(client.status.created);
            expect(client.status.lastcall).toBe(0);
            expect(client.status.lastclose).toBe(0);;

            client.invoke('/COE/RBP_FE_WAIT', {
                IV_SECONDS: 1
            }, (err, res) => {
                if (err) done(err);
                expect(client.status.created).toBeGreaterThan(0);
                expect(client.status.lastopen).toBeGreaterThan(client.status.created);
                expect(client.status.lastcall).toBeGreaterThan(client.status.lastopen);
                expect(client.status.lastclose).toBe(0);

                client.close(() => {
                    expect(client.status.created).toBeGreaterThan(0);
                    expect(client.status.lastopen).toBeGreaterThan(client.status.created);
                    expect(client.status.lastcall).toBeGreaterThan(client.status.lastopen)
                    expect(client.status.lastclose).toBeGreaterThan(client.status.lastcall);
                    done();
                })
            });
        });
    });
})
<|endoftext|>


<commit_before>/* eslint-env mocha */

import { List as ImList } from 'immutable'
import chai from 'chai'
import chaiBytes from 'chai-bytes'
import dirtyChai from 'dirty-chai'

import struct from '../../src/lowlevel/struct'
import union from '../../src/lowlevel/union'
import std from '../../src/std'
import { isExonumObject } from '../../src/lowlevel/common'

const expect = chai
  .use(chaiBytes)
  .use(dirtyChai)
  .expect

describe('union', () => {
  const StrOrInt = union([
    { name: 'str', type: std.Str },
    { name: 'int', type: std.Uint32 }
  ])

  // Not actually a list
  const ListRecord = struct([
    { name: 'head', type: std.Uint32 },
    { name: 'tail', type: std.Str }
  ])
  const List = union([
    { name: 'none', type: std.None },
    { name: 'some', type: ListRecord }
  ])

  const EmbeddedUnion = union([
    { name: 'union', type: StrOrInt },
    { name: 'bool', type: std.Bool }
  ])

  const UnionWithMarker = union({
    marker: 'kind',
    variants: [
      { name: 'int', type: std.Int32 },
      { name: 'bool', type: std.Bool }
    ]
  })

  describe('constructor', () => {
    it('should parse spec', () => {
      expect(StrOrInt).to.be.a('function')
      expect(StrOrInt.int).to.be.a('function')
      expect(StrOrInt.str).to.be.a('function')
    })

    it('should calculate byteLength', () => {
      expect(StrOrInt.typeLength()).to.be.undefined()
    })

    it('should instantiate from an object', () => {
      const x = new StrOrInt({ str: 'Hello world' })
      expect(x.type).to.equal('str')
      expect(x.str).to.equal('Hello world')
    })

    it('should instantiate from a variant shortcut', () => {
      const x = StrOrInt.str('Hello world')
      expect(x.type).to.equal('str')
      expect(x.str).to.equal('Hello world')
    })

    it('should instantiate from an object with embedded type declaration', () => {
      const x = new List({
        type: 'some',
        head: 15,
        tail: 'not actually a tail'
      })

      expect(x.some.toJSON()).to.deep.equal({ head: 15, tail: 'not actually a tail' })
    })

    it('should instantiate from an object with custom marker', () => {
      const x = UnionWithMarker.from({ kind: 'int', hex: 'ff' })
      expect(x.int).to.equal(255)
    })

    it('should throw if an object does not contain allowed variant tags', () => {
      expect(() => new StrOrInt({ bool: false })).to.throw(TypeError, /invalid/i)
    })

    it('should throw if a marker declaration does not have allowed variant tag', () => {
      expect(() => new StrOrInt({ type: 'bool', dec: '1' })).to.throw(TypeError, /invalid/i)
    })

    it('should throw if the custom marker is not specified', () => {
      // The marker is `kind`, but we have supplied default `type`
      expect(() => UnionWithMarker.from({ type: 'int', hex: 'ffffffff' })).to.throw(/invalid.*init/i)
    })
  })

  describe('byteLength', () => {
    it('should work in the basic case', () => {
      let x = new StrOrInt({ str: 'Hello world' })
      expect(x.byteLength()).to.equal(1 + 11)
      x = StrOrInt.int(123)
      expect(x.byteLength()).to.equal(1 + 4)
    })

    it('should work for union with embedded sequence', () => {
      const lst = {
        type: 'some',
        head: 15,
        tail: 'not actually a tail'
      }
      const x = new List(lst)
      expect(x.byteLength()).to.equal(1 + 4 + 8 + lst.tail.length)
      // 8 is for the segment pointer for the string
    })

    it('should work for union with embedded union', () => {
      const x = new EmbeddedUnion({
        union: {
          int: {
            dec: '1020304'
          }
        }
      })

      expect(x.byteLength()).to.equal(1 + 1 + 4)
    })
  })

  describe('value', () => {
    it('should return raw value for integers', () => {
      const x = StrOrInt.int(123)
      expect(x.int).to.be.a('number')
    })

    it('should return raw value for strings', () => {
      const x = StrOrInt.str('123')
      expect(x.str).to.be.a('string')
    })

    it('should return raw value for buffers', () => {
      const BufferUnion = std.resolve({
        union: [
          { name: 'buf', type: { fixedBuffer: 8 } },
          { name: 'u64', type: std.Uint64 }
        ]
      })

      const x = BufferUnion.buf('0011223344556677')
      expect(x.buf).to.be.a('uint8array')
      expect(x.buf[1]).to.equal(0x11)
    })

    it('should return unmodified value for structs', () => {
      const StructUnion = union([
        {
          name: 'point',
          type: struct([
            { name: 'x', type: std.Int32 },
            { name: 'y', type: std.Int32 }
          ])
        },
        { name: 'u64', type: std.Uint64 }
      ])

      const x = new StructUnion({ point: [5, -3] })
      expect(x.point).to.satisfy(isExonumObject)
      expect(x.point.get('x')).to.equal(5)
    })
  })

  describe('get', () => {
    it('should return raw value for integers', () => {
      const x = StrOrInt.int(123)
      expect(x.get('int')).to.be.a('number')
    })

    it('should return raw value for strings', () => {
      const x = StrOrInt.str('123')
      expect(x.get('str')).to.be.a('string')
    })

    it('should return `undefined` for unspecified variants', () => {
      let x = StrOrInt.int(123)
      expect(x.get('str')).to.be.undefined()
      x = StrOrInt.str('123')
      expect(x.get('int')).to.be.undefined()
    })

    it('should return unmodified value for structs', () => {
      const StructUnion = union([
        {
          name: 'point',
          type: struct([
            { name: 'x', type: std.Int32 },
            { name: 'y', type: std.Int32 }
          ])
        },
        { name: 'u64', type: std.Uint64 }
      ])

      const x = new StructUnion({ point: [5, -3] })
      expect(x.get('point')).to.satisfy(isExonumObject)
    })
  })

  describe('getOriginal', () => {
    it('should return original value for integers', () => {
      const x = StrOrInt.int(123)
      expect(x.getOriginal('int')).to.satisfy(isExonumObject)
      expect(+x.getOriginal('int')).to.equal(123)
    })

    it('should return original value for strings', () => {
      const x = StrOrInt.str('123')
      expect(x.getOriginal('str')).to.satisfy(isExonumObject)
      expect(x.getOriginal('str').toString()).to.equal('123')
    })

    it('should return undefined for other variants', () => {
      const x = StrOrInt.str('123')
      expect(x.getOriginal('int')).to.be.undefined()
    })
  })

  describe('match', () => {
    it('should throw if invoked not with an object', () => {
      let x = StrOrInt.str('123')

      const invalidMatchers = [ false, 5, 'abcd', null ]
      invalidMatchers.forEach(invalid => {
        expect(() => x.match(invalid)).to.throw(/matcher should be an object/i)
      })
    })

    it('should not try to invoke the variant handle if it is not a function', () => {
      let x = StrOrInt.str('123')
      expect(x.match({
        str: 123,
        int: () => { throw new Error('This should not be invoked!') }
      })).to.be.undefined()
    })

    it('should not try to invoke the sink handle if it is not a function', () => {
      let x = StrOrInt.str('123')
      expect(x.match({
        str: 123,
        int: () => { throw new Error('This should not be invoked!') },
        _: 'bar'
      })).to.be.undefined()
    })

    it('should invoke the matching method handle', (done) => {
      let x = StrOrInt.str('123')
      x.match({
        str (str) { expect(str).to.equal('123'); done() },
        int () { throw new Error('This should not be invoked!') }
      })
    })

    it('should be usable for descructuring variants', (done) => {
      const x = List.some({ head: 42, tail: '...' })
      x.match({
        some ({ head, tail }) {
          expect(head).to.equal(42)
          expect(tail).to.equal('...')
          done()
        },
        none () { throw new Error('not as planned') }
      })
    })

    it('should invoke the sink handle if there is no matching variant', (done) => {
      const x = new StrOrInt({ int: 25 })
      x.match({
        str (str) { throw new Error('This should not be invoked!') },
        _ (int) { expect(int).to.equal(25); done() }
      })
    })

    it('should return a value', () => {
      const RealList = std.resolver.addTypes([{
        name: 'List',
        union: [
          { name: 'none', type: 'None' },
          {
            name: 'some',
            type: {
              struct: [
                { name: 'head', type: 'Str' },
                { name: 'tail', type: 'List' }
              ]
            }
          }
        ]
      }]).resolve('List')

      let lst = RealList.from({ some: ['foo', { some: ['bar', { none: null }] }] })
      let elems = []
      while (lst) {
        lst = lst.match({
          some: ({ head, tail }) => { elems.push(head); return tail }
        })
      }
      expect(elems).to.deep.equal(['foo', 'bar'])
      expect(lst).to.be.undefined()
    })
  })

  describe('matchOriginal', () => {
    it('should invoke the matching method handle with original Exonum-typed object', (done) => {
      let x = StrOrInt.int(123)
      x.matchOriginal({
        str (str) { throw new Error('This should not be invoked!') },
        int (int) {
          expect(int).to.satisfy(isExonumObject)
          expect(+int).to.equal(123)
          done()
        }
      })
    })
  })

  describe('serialize', () => {
    it('should serialize as a marker + variant in the basic case', () => {
      const x = new StrOrInt({ int: 255 })
      expect(x.serialize()).to.equalBytes('01ff000000')
    })

    it('should serialize in the basic case for var-length variant', () => {
      const x = new StrOrInt({ str: 'ABC' })
      expect(x.serialize()).to.equalBytes('00414243')
    })

    it('should serialize as a marker + variant for embedded types', () => {
      let x = new List({ some: [ 256, 'ABC' ] })
      expect(x.serialize()).to.equalBytes('01' + // marker
        '00010000' + // head
        '0c000000' + '03000000' + // segment pointer to the tail
        '414243' // tail
      )

      x = new List({ none: null })
      expect(x.serialize()).to.equalBytes('00')
    })
  })

  describe('toJSON', () => {
    it('should work in the basic case', () => {
      let x = new StrOrInt({ str: 'Hello world' })
      expect(x.toJSON()).to.deep.equal({ str: 'Hello world' })
      x = StrOrInt.int(123)
      expect(x.toJSON()).to.deep.equal({ int: 123 })
    })

    it('should work for union with embedded union', () => {
      const lst = {
        some: {
          head: 15,
          tail: 'not actually a tail'
        }
      }
      const x = new List(lst)
      expect(x.toJSON()).to.deep.equal(lst)
    })

    it('should work for union with embedded union', () => {
      const x = new EmbeddedUnion({
        union: {
          int: {
            dec: '1020304'
          }
        }
      })
      expect(x.toJSON()).to.deep.equal({
        union: { int: 1020304 }
      })
    })
  })

  describe('toString', () => {
    it('should work in basic case', () => {
      let x = new StrOrInt({ str: 'Hello world' })
      expect(x.toString()).to.equal('str(Hello world)')
      x = StrOrInt.int(123)
      expect(x.toString()).to.equal('int(123)')
    })

    it('should work with complex variants', () => {
      const x = new EmbeddedUnion({
        union: {
          int: {
            dec: '1020304'
          }
        }
      })
      expect(x.toString()).to.equal('union(int(1020304))')
    })
  })

  describe('typeTag', () => {
    it('should be defined', () => {
      expect(StrOrInt.typeTag).to.be.a('function')
    })

    it('should be an immutable list', () => {
      const lst = ImList.of('union',
        ImList.of('str', std.Str, 'int', std.Uint32))
      expect(lst.equals(StrOrInt.typeTag())).to.be.true()
    })
  })

  describe('static hashCode', () => {
    it('should proxy typeTag hashCode', () => {
      expect(StrOrInt.hashCode()).to.equal(StrOrInt.typeTag().hashCode())
    })
  })

  describe('static equals', () => {
    it('should structurally determine type equality', () => {
      expect(StrOrInt.equals(StrOrInt)).to.be.true()
      expect(StrOrInt.equals(ListRecord)).to.be.false()

      let OtherStrOrInt = std.resolve({
        union: [
          { name: 'str', type: 'Str' },
          { name: 'int', type: 'Uint32' }
        ]
      })
      expect(OtherStrOrInt.equals(StrOrInt)).to.be.true()

      OtherStrOrInt = std.resolve({
        union: [
          { name: 'str', type: 'Str' },
          { name: 'int', type: 'Uint16' }
        ]
      })
      expect(OtherStrOrInt.equals(StrOrInt)).to.be.false()

      OtherStrOrInt = std.resolve({
        union: [
          { name: 'str', type: 'Str' },
          { name: 'int', type: { uinteger: 4 } }
        ]
      })
      expect(OtherStrOrInt.equals(StrOrInt)).to.be.true()
    })
  })
})
<commit_msg>Fix test using outdated API<commit_after>/* eslint-env mocha */

import { List as ImList } from 'immutable'
import chai from 'chai'
import chaiBytes from 'chai-bytes'
import dirtyChai from 'dirty-chai'

import struct from '../../src/lowlevel/struct'
import union from '../../src/lowlevel/union'
import std from '../../src/std'
import { isExonumObject } from '../../src/lowlevel/common'

const expect = chai
  .use(chaiBytes)
  .use(dirtyChai)
  .expect

describe('union', () => {
  const StrOrInt = union([
    { name: 'str', type: std.Str },
    { name: 'int', type: std.Uint32 }
  ])

  // Not actually a list
  const ListRecord = struct([
    { name: 'head', type: std.Uint32 },
    { name: 'tail', type: std.Str }
  ])
  const List = union([
    { name: 'none', type: std.None },
    { name: 'some', type: ListRecord }
  ])

  const EmbeddedUnion = union([
    { name: 'union', type: StrOrInt },
    { name: 'bool', type: std.Bool }
  ])

  const UnionWithMarker = union({
    marker: 'kind',
    variants: [
      { name: 'int', type: std.Int32 },
      { name: 'bool', type: std.Bool }
    ]
  })

  describe('constructor', () => {
    it('should parse spec', () => {
      expect(StrOrInt).to.be.a('function')
      expect(StrOrInt.int).to.be.a('function')
      expect(StrOrInt.str).to.be.a('function')
    })

    it('should calculate byteLength', () => {
      expect(StrOrInt.typeLength()).to.be.undefined()
    })

    it('should instantiate from an object', () => {
      const x = new StrOrInt({ str: 'Hello world' })
      expect(x.type).to.equal('str')
      expect(x.str).to.equal('Hello world')
    })

    it('should instantiate from a variant shortcut', () => {
      const x = StrOrInt.str('Hello world')
      expect(x.type).to.equal('str')
      expect(x.str).to.equal('Hello world')
    })

    it('should instantiate from an object with embedded type declaration', () => {
      const x = new List({
        type: 'some',
        head: 15,
        tail: 'not actually a tail'
      })

      expect(x.some.toJSON()).to.deep.equal({ head: 15, tail: 'not actually a tail' })
    })

    it('should instantiate from an object with custom marker', () => {
      const x = UnionWithMarker.from({ kind: 'int', hex: 'ff' })
      expect(x.int).to.equal(255)
    })

    it('should throw if an object does not contain allowed variant tags', () => {
      expect(() => new StrOrInt({ bool: false })).to.throw(TypeError, /invalid/i)
    })

    it('should throw if a marker declaration does not have allowed variant tag', () => {
      expect(() => new StrOrInt({ type: 'bool', dec: '1' })).to.throw(TypeError, /invalid/i)
    })

    it('should throw if the custom marker is not specified', () => {
      // The marker is `kind`, but we have supplied default `type`
      expect(() => UnionWithMarker.from({ type: 'int', hex: 'ffffffff' })).to.throw(/invalid.*init/i)
    })
  })

  describe('byteLength', () => {
    it('should work in the basic case', () => {
      let x = new StrOrInt({ str: 'Hello world' })
      expect(x.byteLength()).to.equal(1 + 11)
      x = StrOrInt.int(123)
      expect(x.byteLength()).to.equal(1 + 4)
    })

    it('should work for union with embedded sequence', () => {
      const lst = {
        type: 'some',
        head: 15,
        tail: 'not actually a tail'
      }
      const x = new List(lst)
      expect(x.byteLength()).to.equal(1 + 4 + 8 + lst.tail.length)
      // 8 is for the segment pointer for the string
    })

    it('should work for union with embedded union', () => {
      const x = new EmbeddedUnion({
        union: {
          int: {
            dec: '1020304'
          }
        }
      })

      expect(x.byteLength()).to.equal(1 + 1 + 4)
    })
  })

  describe('value', () => {
    it('should return raw value for integers', () => {
      const x = StrOrInt.int(123)
      expect(x.int).to.be.a('number')
    })

    it('should return raw value for strings', () => {
      const x = StrOrInt.str('123')
      expect(x.str).to.be.a('string')
    })

    it('should return raw value for buffers', () => {
      const BufferUnion = std.resolve({
        union: [
          { name: 'buf', type: { fixedBuffer: 8 } },
          { name: 'u64', type: std.Uint64 }
        ]
      })

      const x = BufferUnion.buf('0011223344556677')
      expect(x.buf).to.be.a('uint8array')
      expect(x.buf[1]).to.equal(0x11)
    })

    it('should return unmodified value for structs', () => {
      const StructUnion = union([
        {
          name: 'point',
          type: struct([
            { name: 'x', type: std.Int32 },
            { name: 'y', type: std.Int32 }
          ])
        },
        { name: 'u64', type: std.Uint64 }
      ])

      const x = new StructUnion({ point: [5, -3] })
      expect(x.point).to.satisfy(isExonumObject)
      expect(x.point.get('x')).to.equal(5)
    })
  })

  describe('get', () => {
    it('should return raw value for integers', () => {
      const x = StrOrInt.int(123)
      expect(x.get('int')).to.be.a('number')
    })

    it('should return raw value for strings', () => {
      const x = StrOrInt.str('123')
      expect(x.get('str')).to.be.a('string')
    })

    it('should return `undefined` for unspecified variants', () => {
      let x = StrOrInt.int(123)
      expect(x.get('str')).to.be.undefined()
      x = StrOrInt.str('123')
      expect(x.get('int')).to.be.undefined()
    })

    it('should return unmodified value for structs', () => {
      const StructUnion = union([
        {
          name: 'point',
          type: struct([
            { name: 'x', type: std.Int32 },
            { name: 'y', type: std.Int32 }
          ])
        },
        { name: 'u64', type: std.Uint64 }
      ])

      const x = new StructUnion({ point: [5, -3] })
      expect(x.get('point')).to.satisfy(isExonumObject)
    })
  })

  describe('getOriginal', () => {
    it('should return original value for integers', () => {
      const x = StrOrInt.int(123)
      expect(x.getOriginal('int')).to.satisfy(isExonumObject)
      expect(+x.getOriginal('int')).to.equal(123)
    })

    it('should return original value for strings', () => {
      const x = StrOrInt.str('123')
      expect(x.getOriginal('str')).to.satisfy(isExonumObject)
      expect(x.getOriginal('str').toString()).to.equal('123')
    })

    it('should return undefined for other variants', () => {
      const x = StrOrInt.str('123')
      expect(x.getOriginal('int')).to.be.undefined()
    })
  })

  describe('match', () => {
    it('should throw if invoked not with an object', () => {
      let x = StrOrInt.str('123')

      const invalidMatchers = [ false, 5, 'abcd', null ]
      invalidMatchers.forEach(invalid => {
        expect(() => x.match(invalid)).to.throw(/matcher should be an object/i)
      })
    })

    it('should not try to invoke the variant handle if it is not a function', () => {
      let x = StrOrInt.str('123')
      expect(x.match({
        str: 123,
        int: () => { throw new Error('This should not be invoked!') }
      })).to.be.undefined()
    })

    it('should not try to invoke the sink handle if it is not a function', () => {
      let x = StrOrInt.str('123')
      expect(x.match({
        str: 123,
        int: () => { throw new Error('This should not be invoked!') },
        _: 'bar'
      })).to.be.undefined()
    })

    it('should invoke the matching method handle', (done) => {
      let x = StrOrInt.str('123')
      x.match({
        str (str) { expect(str).to.equal('123'); done() },
        int () { throw new Error('This should not be invoked!') }
      })
    })

    it('should be usable for descructuring variants', (done) => {
      const x = List.some({ head: 42, tail: '...' })
      x.match({
        some ({ head, tail }) {
          expect(head).to.equal(42)
          expect(tail).to.equal('...')
          done()
        },
        none () { throw new Error('not as planned') }
      })
    })

    it('should invoke the sink handle if there is no matching variant', (done) => {
      const x = new StrOrInt({ int: 25 })
      x.match({
        str (str) { throw new Error('This should not be invoked!') },
        _ (int) { expect(int).to.equal(25); done() }
      })
    })

    it('should return a value', () => {
      const RealList = std.resolver.add([{
        name: 'List',
        union: [
          { name: 'none', type: 'None' },
          {
            name: 'some',
            type: {
              struct: [
                { name: 'head', type: 'Str' },
                { name: 'tail', type: 'List' }
              ]
            }
          }
        ]
      }]).resolve('List')

      let lst = RealList.from({ some: ['foo', { some: ['bar', { none: null }] }] })
      let elems = []
      while (lst) {
        lst = lst.match({
          some: ({ head, tail }) => { elems.push(head); return tail }
        })
      }
      expect(elems).to.deep.equal(['foo', 'bar'])
      expect(lst).to.be.undefined()
    })
  })

  describe('matchOriginal', () => {
    it('should invoke the matching method handle with original Exonum-typed object', (done) => {
      let x = StrOrInt.int(123)
      x.matchOriginal({
        str (str) { throw new Error('This should not be invoked!') },
        int (int) {
          expect(int).to.satisfy(isExonumObject)
          expect(+int).to.equal(123)
          done()
        }
      })
    })
  })

  describe('serialize', () => {
    it('should serialize as a marker + variant in the basic case', () => {
      const x = new StrOrInt({ int: 255 })
      expect(x.serialize()).to.equalBytes('01ff000000')
    })

    it('should serialize in the basic case for var-length variant', () => {
      const x = new StrOrInt({ str: 'ABC' })
      expect(x.serialize()).to.equalBytes('00414243')
    })

    it('should serialize as a marker + variant for embedded types', () => {
      let x = new List({ some: [ 256, 'ABC' ] })
      expect(x.serialize()).to.equalBytes('01' + // marker
        '00010000' + // head
        '0c000000' + '03000000' + // segment pointer to the tail
        '414243' // tail
      )

      x = new List({ none: null })
      expect(x.serialize()).to.equalBytes('00')
    })
  })

  describe('toJSON', () => {
    it('should work in the basic case', () => {
      let x = new StrOrInt({ str: 'Hello world' })
      expect(x.toJSON()).to.deep.equal({ str: 'Hello world' })
      x = StrOrInt.int(123)
      expect(x.toJSON()).to.deep.equal({ int: 123 })
    })

    it('should work for union with embedded union', () => {
      const lst = {
        some: {
          head: 15,
          tail: 'not actually a tail'
        }
      }
      const x = new List(lst)
      expect(x.toJSON()).to.deep.equal(lst)
    })

    it('should work for union with embedded union', () => {
      const x = new EmbeddedUnion({
        union: {
          int: {
            dec: '1020304'
          }
        }
      })
      expect(x.toJSON()).to.deep.equal({
        union: { int: 1020304 }
      })
    })
  })

  describe('toString', () => {
    it('should work in basic case', () => {
      let x = new StrOrInt({ str: 'Hello world' })
      expect(x.toString()).to.equal('str(Hello world)')
      x = StrOrInt.int(123)
      expect(x.toString()).to.equal('int(123)')
    })

    it('should work with complex variants', () => {
      const x = new EmbeddedUnion({
        union: {
          int: {
            dec: '1020304'
          }
        }
      })
      expect(x.toString()).to.equal('union(int(1020304))')
    })
  })

  describe('typeTag', () => {
    it('should be defined', () => {
      expect(StrOrInt.typeTag).to.be.a('function')
    })

    it('should be an immutable list', () => {
      const lst = ImList.of('union',
        ImList.of('str', std.Str, 'int', std.Uint32))
      expect(lst.equals(StrOrInt.typeTag())).to.be.true()
    })
  })

  describe('static hashCode', () => {
    it('should proxy typeTag hashCode', () => {
      expect(StrOrInt.hashCode()).to.equal(StrOrInt.typeTag().hashCode())
    })
  })

  describe('static equals', () => {
    it('should structurally determine type equality', () => {
      expect(StrOrInt.equals(StrOrInt)).to.be.true()
      expect(StrOrInt.equals(ListRecord)).to.be.false()

      let OtherStrOrInt = std.resolve({
        union: [
          { name: 'str', type: 'Str' },
          { name: 'int', type: 'Uint32' }
        ]
      })
      expect(OtherStrOrInt.equals(StrOrInt)).to.be.true()

      OtherStrOrInt = std.resolve({
        union: [
          { name: 'str', type: 'Str' },
          { name: 'int', type: 'Uint16' }
        ]
      })
      expect(OtherStrOrInt.equals(StrOrInt)).to.be.false()

      OtherStrOrInt = std.resolve({
        union: [
          { name: 'str', type: 'Str' },
          { name: 'int', type: { uinteger: 4 } }
        ]
      })
      expect(OtherStrOrInt.equals(StrOrInt)).to.be.true()
    })
  })
})
<|endoftext|>


<commit_before>var uuid = require('uuid');
var expect = require('expect.js');
var accountManagement = require('../Exchange/accountManagement.js');
var orderLog = require('../DB/InMemory/orderLog.js');
var testModules = {
  orderLog: orderLog
};
var exchange = require('../Exchange/exchange.js')(testModules);
var mockOrders = require('./fixtures/orders.js').MockOrders;

var account = null;

describe('Matching engine', function() {
  it('should be able to add an account', function(done){
    account = accountManagement.CreateAccount();
    done();
  });
  it('should be able to add a bid', function(done) {
    exchange.SubmitNewOrderForMatching(mockOrders[0], function(res){
      expect(res.submitted).to.equal(true);
      exchange.GetBidsAndAsks(1, function(bidsAndAsks){
        expect(bidsAndAsks.bids.length).to.be(1);
        expect(bidsAndAsks.asks.length).to.be(0);
        expect(bidsAndAsks.bids[0].timestamp).to.equal(1481536182349);
        expect(bidsAndAsks.bids[0].id).to.equal('4e367fd0-c050-11e6-992a-730712547a2a');
        expect(bidsAndAsks.bids[0].accountId).to.equal(0);
        expect(bidsAndAsks.bids[0].type).to.equal('bid');
        expect(Number(bidsAndAsks.bids[0].price)).to.equal(750);
        expect(Number(bidsAndAsks.bids[0].amount)).to.equal(100);
        done();
      });
    });
  });
  it('should be able to add an ask', function(done) {
    exchange.SubmitNewOrderForMatching(mockOrders[1], function(res){
      expect(res.submitted).to.equal(true);
      exchange.GetBidsAndAsks(1, function(bidsAndAsks){
        expect(bidsAndAsks.bids.length).to.be(1);
        expect(bidsAndAsks.asks.length).to.be(1);
        expect(bidsAndAsks.asks[0].timestamp).to.equal(1481536182350);
        expect(bidsAndAsks.asks[0].id).to.equal('4e374320-c050-11e6-992a-730712547a2a');
        expect(bidsAndAsks.asks[0].accountId).to.equal(0);
        expect(bidsAndAsks.asks[0].type).to.equal('ask');
        expect(Number(bidsAndAsks.asks[0].price)).to.equal(751);
        expect(Number(bidsAndAsks.asks[0].amount)).to.equal(100);
        done();
      });
    });
  });
  it('should be able to add a matcing bid', function(done) {
    exchange.SubmitNewOrderForMatching(mockOrders[2], function(res){
      expect(res.submitted).to.equal(true);
      exchange.GetBidsAndAsks(1, function(bidsAndAsks){
        expect(bidsAndAsks.bids.length).to.be(1);
        expect(bidsAndAsks.asks.length).to.be(1);
        expect(bidsAndAsks.asks[0].timestamp).to.equal(1481536182350);
        expect(bidsAndAsks.asks[0].id).to.equal('4e374320-c050-11e6-992a-730712547a2a');
        expect(bidsAndAsks.asks[0].accountId).to.equal(0);
        expect(bidsAndAsks.asks[0].type).to.equal('ask');
        expect(Number(bidsAndAsks.asks[0].price)).to.equal(751);
        expect(Number(bidsAndAsks.asks[0].amount)).to.equal(10);
        done();
      });
    });
  });
  it('should be able to add a matching ask', function(done) {
    exchange.SubmitNewOrderForMatching(mockOrders[3], function(res){
      expect(res.submitted).to.equal(true);
      exchange.GetBidsAndAsks(2, function(bidsAndAsks){
        expect(bidsAndAsks.bids.length).to.be(1);
        expect(bidsAndAsks.asks.length).to.be(1);
        expect(bidsAndAsks.bids[0].timestamp).to.equal(1481536182349);
        expect(bidsAndAsks.bids[0].id).to.equal('4e367fd0-c050-11e6-992a-730712547a2a');
        expect(bidsAndAsks.bids[0].accountId).to.equal(0);
        expect(bidsAndAsks.bids[0].type).to.equal('bid');
        expect(Number(bidsAndAsks.bids[0].price)).to.equal(750);
        expect(Number(bidsAndAsks.bids[0].amount)).to.equal(10);
        done();
      });
    });
  });
  it('should be able to add a few asks', function(done) {
    exchange.SubmitNewOrderForMatching(mockOrders[4], function(res){
    exchange.SubmitNewOrderForMatching(mockOrders[5], function(res){
    exchange.SubmitNewOrderForMatching(mockOrders[6], function(res){
      expect(res.submitted).to.equal(true);
      exchange.GetBidsAndAsks(10, function(bidsAndAsks){
        expect(bidsAndAsks.bids.length).to.be(1);
        expect(bidsAndAsks.asks.length).to.be(4);
        done();
      });
    });
    });
    });
  });
  it('one bid should be able to partially take two asks', function(done) {
    exchange.SubmitNewOrderForMatching(mockOrders[7], function(res){
      expect(res.submitted).to.equal(true);
      exchange.GetBidsAndAsks(10, function(bidsAndAsks){
        expect(bidsAndAsks.bids.length).to.be(1);
        expect(bidsAndAsks.asks.length).to.be(3);
        expect(bidsAndAsks.asks[0].id).to.equal('4e374324-c050-11e6-992a-730712547a2a');
        expect(Number(bidsAndAsks.bids[0].amount)).to.equal(10);
        done();
      });
    });
  });
  it('a bid should be able to be partially fulfilled', function(done) {
    exchange.SubmitNewOrderForMatching(mockOrders[8], function(res){
      expect(res.submitted).to.equal(true);
      exchange.GetBidsAndAsks(10, function(bidsAndAsks){
        expect(bidsAndAsks.bids.length).to.be(2);
        expect(bidsAndAsks.asks.length).to.be(2);
        expect(bidsAndAsks.bids[0].id).to.equal('4e374328-c050-11e6-992a-730712547a2a');
        expect(bidsAndAsks.asks[0].id).to.equal('4e374325-c050-11e6-992a-730712547a2a');
        expect(Number(bidsAndAsks.bids[0].amount)).to.equal(40);
        expect(Number(bidsAndAsks.asks[0].amount)).to.equal(50);
        done();
      });
    });
  });
});
<commit_msg>Moved test for adding an account to account tests<commit_after>var uuid = require('uuid');
var expect = require('expect.js');
var accountManagement = require('../Exchange/accountManagement.js');
var orderLog = require('../DB/InMemory/orderLog.js');
var testModules = {
  orderLog: orderLog
};
var exchange = require('../Exchange/exchange.js')(testModules);
var mockOrders = require('./fixtures/orders.js').MockOrders;

var account = null;

describe('Matching engine', function() {
  it('should be able to add a bid', function(done) {
    account = accountManagement.CreateAccount();
    exchange.SubmitNewOrderForMatching(mockOrders[0], function(res){
      expect(res.submitted).to.equal(true);
      exchange.GetBidsAndAsks(1, function(bidsAndAsks){
        expect(bidsAndAsks.bids.length).to.be(1);
        expect(bidsAndAsks.asks.length).to.be(0);
        expect(bidsAndAsks.bids[0].timestamp).to.equal(1481536182349);
        expect(bidsAndAsks.bids[0].id).to.equal('4e367fd0-c050-11e6-992a-730712547a2a');
        expect(bidsAndAsks.bids[0].accountId).to.equal(0);
        expect(bidsAndAsks.bids[0].type).to.equal('bid');
        expect(Number(bidsAndAsks.bids[0].price)).to.equal(750);
        expect(Number(bidsAndAsks.bids[0].amount)).to.equal(100);
        done();
      });
    });
  });
  it('should be able to add an ask', function(done) {
    exchange.SubmitNewOrderForMatching(mockOrders[1], function(res){
      expect(res.submitted).to.equal(true);
      exchange.GetBidsAndAsks(1, function(bidsAndAsks){
        expect(bidsAndAsks.bids.length).to.be(1);
        expect(bidsAndAsks.asks.length).to.be(1);
        expect(bidsAndAsks.asks[0].timestamp).to.equal(1481536182350);
        expect(bidsAndAsks.asks[0].id).to.equal('4e374320-c050-11e6-992a-730712547a2a');
        expect(bidsAndAsks.asks[0].accountId).to.equal(0);
        expect(bidsAndAsks.asks[0].type).to.equal('ask');
        expect(Number(bidsAndAsks.asks[0].price)).to.equal(751);
        expect(Number(bidsAndAsks.asks[0].amount)).to.equal(100);
        done();
      });
    });
  });
  it('should be able to add a matcing bid', function(done) {
    exchange.SubmitNewOrderForMatching(mockOrders[2], function(res){
      expect(res.submitted).to.equal(true);
      exchange.GetBidsAndAsks(1, function(bidsAndAsks){
        expect(bidsAndAsks.bids.length).to.be(1);
        expect(bidsAndAsks.asks.length).to.be(1);
        expect(bidsAndAsks.asks[0].timestamp).to.equal(1481536182350);
        expect(bidsAndAsks.asks[0].id).to.equal('4e374320-c050-11e6-992a-730712547a2a');
        expect(bidsAndAsks.asks[0].accountId).to.equal(0);
        expect(bidsAndAsks.asks[0].type).to.equal('ask');
        expect(Number(bidsAndAsks.asks[0].price)).to.equal(751);
        expect(Number(bidsAndAsks.asks[0].amount)).to.equal(10);
        done();
      });
    });
  });
  it('should be able to add a matching ask', function(done) {
    exchange.SubmitNewOrderForMatching(mockOrders[3], function(res){
      expect(res.submitted).to.equal(true);
      exchange.GetBidsAndAsks(2, function(bidsAndAsks){
        expect(bidsAndAsks.bids.length).to.be(1);
        expect(bidsAndAsks.asks.length).to.be(1);
        expect(bidsAndAsks.bids[0].timestamp).to.equal(1481536182349);
        expect(bidsAndAsks.bids[0].id).to.equal('4e367fd0-c050-11e6-992a-730712547a2a');
        expect(bidsAndAsks.bids[0].accountId).to.equal(0);
        expect(bidsAndAsks.bids[0].type).to.equal('bid');
        expect(Number(bidsAndAsks.bids[0].price)).to.equal(750);
        expect(Number(bidsAndAsks.bids[0].amount)).to.equal(10);
        done();
      });
    });
  });
  it('should be able to add a few asks', function(done) {
    exchange.SubmitNewOrderForMatching(mockOrders[4], function(res){
    exchange.SubmitNewOrderForMatching(mockOrders[5], function(res){
    exchange.SubmitNewOrderForMatching(mockOrders[6], function(res){
      expect(res.submitted).to.equal(true);
      exchange.GetBidsAndAsks(10, function(bidsAndAsks){
        expect(bidsAndAsks.bids.length).to.be(1);
        expect(bidsAndAsks.asks.length).to.be(4);
        done();
      });
    });
    });
    });
  });
  it('one bid should be able to partially take two asks', function(done) {
    exchange.SubmitNewOrderForMatching(mockOrders[7], function(res){
      expect(res.submitted).to.equal(true);
      exchange.GetBidsAndAsks(10, function(bidsAndAsks){
        expect(bidsAndAsks.bids.length).to.be(1);
        expect(bidsAndAsks.asks.length).to.be(3);
        expect(bidsAndAsks.asks[0].id).to.equal('4e374324-c050-11e6-992a-730712547a2a');
        expect(Number(bidsAndAsks.bids[0].amount)).to.equal(10);
        done();
      });
    });
  });
  it('a bid should be able to be partially fulfilled', function(done) {
    exchange.SubmitNewOrderForMatching(mockOrders[8], function(res){
      expect(res.submitted).to.equal(true);
      exchange.GetBidsAndAsks(10, function(bidsAndAsks){
        expect(bidsAndAsks.bids.length).to.be(2);
        expect(bidsAndAsks.asks.length).to.be(2);
        expect(bidsAndAsks.bids[0].id).to.equal('4e374328-c050-11e6-992a-730712547a2a');
        expect(bidsAndAsks.asks[0].id).to.equal('4e374325-c050-11e6-992a-730712547a2a');
        expect(Number(bidsAndAsks.bids[0].amount)).to.equal(40);
        expect(Number(bidsAndAsks.asks[0].amount)).to.equal(50);
        done();
      });
    });
  });
});
<|endoftext|>