<commit_before>import temp from 'temp';
import {Disposable} from 'event-kit';

import {cloneRepository} from '../helpers';

import WorkdirContextPool from '../../lib/models/workdir-context-pool';

describe('WorkdirContextPool', function() {
  let pool;
  let mockWindow, mockWorkspace;

  beforeEach(function() {
    mockWindow = {
      addEventListener: sinon.spy(),
      removeEventListener: sinon.spy(),
    };

    mockWorkspace = {
      observeTextEditors: sinon.stub().returns(new Disposable()),
    };

    pool = new WorkdirContextPool({
      window: mockWindow,
      workspace: mockWorkspace,
    });
  });

  describe('add', function() {
    let workingDirectory;

    beforeEach(async function() {
      workingDirectory = await cloneRepository('three-files');
    });

    it('adds a WorkdirContext for a new working directory', function() {
      assert.equal(pool.size(), 0);
      assert.isFalse(pool.getContext(workingDirectory).isPresent());

      pool.add(workingDirectory);

      assert.equal(pool.size(), 1);
      assert.isTrue(pool.getContext(workingDirectory).isPresent());
    });

    it('is a no-op if the working directory already has a context', function() {
      pool.add(workingDirectory);
      assert.equal(pool.size(), 1);

      const context = pool.getContext(workingDirectory);
      assert.isTrue(context.isPresent());

      pool.add(workingDirectory);
      assert.equal(pool.size(), 1);
    });

    it('begins but does not await the asynchronous initialization process', async function() {
      pool.add(workingDirectory);
      const context = pool.getContext(workingDirectory);
      assert.isTrue(context.getRepository().isLoading());
      assert.isTrue(context.getResolutionProgress().isEmpty());
      assert.isFalse(context.getChangeObserver().isStarted());

      await context.getRepositoryStatePromise('Present');
      assert.isTrue(context.getRepository().isPresent());
    });
  });

  describe('replace', function() {
    it('adds a WorkdirContext if one is absent', function() {
      const directory = temp.mkdirSync();

      assert.equal(pool.size(), 0);
      assert.isFalse(pool.getContext(directory).isPresent());

      pool.replace(directory);

      assert.equal(pool.size(), 1);
      assert.isTrue(pool.getContext(directory).isPresent());
    });

    it('removes an existing WorkdirContext if one is present', async function() {
      const directory = await cloneRepository('three-files');

      pool.add(directory);
      assert.equal(pool.size(), 1);
      const context = pool.getContext(directory);
      assert.isTrue(context.isPresent());
      const original = context.getRepository();

      pool.replace(directory);
      assert.equal(pool.size(), 1);
      assert.isTrue(pool.getContext(directory).isPresent());
      const replaced = pool.getContext(directory).getRepository();

      assert.notStrictEqual(original, replaced);
    });
  });

  describe('remove', function() {
    let existingDirectory, existingContext;

    beforeEach(async function() {
      existingDirectory = await cloneRepository('three-files');
      pool.add(existingDirectory);

      existingContext = pool.getContext(existingDirectory);
    });

    it('removes a WorkdirContext for an existing working directory', function() {
      assert.equal(pool.size(), 1);
      pool.remove(existingDirectory);
      assert.isFalse(pool.getContext(existingDirectory).isPresent());
      assert.equal(pool.size(), 0);
    });

    it('is a no-op if the working directory is not present', function() {
      assert.equal(pool.size(), 1);
      pool.remove('/nope');
      assert.equal(pool.size(), 1);
    });

    it('begins but does not await the termination process', function() {
      const repo = existingContext.getRepository();
      sinon.spy(repo, 'destroy');

      assert.isFalse(existingContext.isDestroyed());
      pool.remove(existingDirectory);
      assert.isTrue(existingContext.isDestroyed());
      assert.isTrue(repo.destroy.called);
    });
  });

  describe('set', function() {
    let dir0, dir1, dir2;

    beforeEach(async function() {
      [dir0, dir1, dir2] = await Promise.all([
        cloneRepository('three-files'),
        cloneRepository('three-files'),
        cloneRepository('three-files'),
      ]);

      pool.add(dir0);
      pool.add(dir1);
    });

    it('adds new directories, removes missing ones, and maintains kept ones', function() {
      const context0 = pool.getContext(dir0);
      const context1 = pool.getContext(dir1);

      pool.set([dir1, dir2]);

      assert.equal(pool.size(), 2);

      assert.isFalse(pool.getContext(dir0).isPresent());
      assert.isTrue(pool.getContext(dir1).isPresent());
      assert.isTrue(pool.getContext(dir2).isPresent());

      assert.isTrue(context0.isDestroyed());
      assert.isFalse(context1.isDestroyed());
    });
  });

  describe('getContext', function() {
    let dir;

    beforeEach(async function() {
      dir = await cloneRepository('three-files');
      pool.add(dir);
    });

    it('returns a context by directory', function() {
      const context = pool.getContext(dir);
      assert.isTrue(context.isPresent());

      const repo = context.getRepository();
      assert.strictEqual(dir, repo.getWorkingDirectoryPath());
    });

    it('returns a null context when missing', function() {
      const context = pool.getContext('/nope');
      assert.isFalse(context.isPresent());
    });
  });

  describe('getMatchingContext', function() {
    let dirs;

    beforeEach(async function() {
      dirs = await Promise.all(
        [1, 2, 3].map(() => cloneRepository()),
      );
    });

    async function addRepoRemote(context, name, url) {
      const repo = context.getRepository();
      await repo.getLoadPromise();
      await repo.addRemote(name, url);
    }

    it('returns a single resident context that has a repository with a matching remote', async function() {
      const matchingContext = pool.add(dirs[0]);
      await addRepoRemote(matchingContext, 'upstream', 'git@github.com:atom/github.git');

      const nonMatchingContext0 = pool.add(dirs[1]);
      await addRepoRemote(nonMatchingContext0, 'up', 'git@github.com:atom/atom.git');

      pool.add(dirs[2]);

      assert.strictEqual(await pool.getMatchingContext('github.com', 'atom', 'github'), matchingContext);
    });

    it('returns a null context when no contexts have suitable repositories', async function() {
      const context0 = pool.add(dirs[0]);
      await addRepoRemote(context0, 'upstream', 'git@github.com:atom/atom.git');

      pool.add(dirs[1]);

      const match = await pool.getMatchingContext('github.com', 'atom', 'github');
      assert.isFalse(match.isPresent());
    });

    it('returns a null context when more than one context has a suitable repository', async function() {
      const context0 = pool.add(dirs[0]);
      await addRepoRemote(context0, 'upstream', 'git@github.com:atom/github.git');

      const context1 = pool.add(dirs[1]);
      await addRepoRemote(context1, 'upstream', 'git@github.com:atom/github.git');

      pool.add(dirs[2]);

      const match = await pool.getMatchingContext('github.com', 'atom', 'github');
      assert.isFalse(match.isPresent());
    });
  });

  describe('clear', function() {
    it('removes all resident contexts', async function() {
      const [dir0, dir1, dir2] = await Promise.all([
        cloneRepository('three-files'),
        cloneRepository('three-files'),
        cloneRepository('three-files'),
      ]);

      pool.add(dir0);
      pool.add(dir1);
      pool.add(dir2);

      assert.equal(pool.size(), 3);

      pool.clear();

      assert.equal(pool.size(), 0);
      assert.isFalse(pool.getContext(dir0).isPresent());
      assert.isFalse(pool.getContext(dir1).isPresent());
      assert.isFalse(pool.getContext(dir2).isPresent());
    });
  });

  describe('emitter', function() {
    describe('did-change-contexts', function() {
      let dir0, dir1, dir2, emitterSpy;

      beforeEach(async function() {
        [dir0, dir1, dir2] = await Promise.all([
          cloneRepository('three-files'),
          cloneRepository('three-files'),
          cloneRepository('three-files'),
        ]);

        pool.add(dir0);

        emitterSpy = sinon.spy();

        pool.onDidChangePoolContexts(emitterSpy);
      });

      it('emits only once for set', function() {
        pool.set(new Set([dir1, dir2]));
        assert.isTrue(emitterSpy.calledOnce);
        assert.deepEqual(
          emitterSpy.getCall(0).args[0],
          {added: new Set([dir1, dir2]), removed: new Set([dir0])},
        );
      });

      it('does not emit for set when no changes are made', function() {
        pool.set(new Set([dir0]));
        assert.isFalse(emitterSpy.called);
      });

      it('emits only once for clear', function() {
        pool.clear();
        assert.isTrue(emitterSpy.calledOnce);
        assert.deepEqual(
          emitterSpy.getCall(0).args[0],
          {removed: new Set([dir0])},
        );
      });

      it('does not emit for clear when no changes are made', function() {
        pool.clear();
        emitterSpy.resetHistory();
        pool.clear(); // Should not emit
        assert.isFalse(emitterSpy.called);
      });

      it('emits only once for replace', function() {
        pool.replace(dir0);
        assert.isTrue(emitterSpy.calledOnce);
        assert.deepEqual(
          emitterSpy.getCall(0).args[0],
          {altered: new Set([dir0])},
        );
      });

      it('emits for every new add', function() {
        pool.remove(dir0);
        emitterSpy.resetHistory();
        pool.add(dir0);
        pool.add(dir1);
        pool.add(dir2);
        assert.isTrue(emitterSpy.calledThrice);
        assert.deepEqual(
          emitterSpy.getCall(0).args[0],
          {added: new Set([dir0])},
        );
        assert.deepEqual(
          emitterSpy.getCall(1).args[0],
          {added: new Set([dir1])},
        );
        assert.deepEqual(
          emitterSpy.getCall(2).args[0],
          {added: new Set([dir2])},
        );
      });

      it('does not emit for add when a context already exists', function() {
        pool.add(dir0);
        assert.isFalse(emitterSpy.called);
      });

      it('emits for every remove', function() {
        pool.add(dir1);
        pool.add(dir2);
        emitterSpy.resetHistory();
        pool.remove(dir0);
        pool.remove(dir1);
        pool.remove(dir2);
        assert.isTrue(emitterSpy.calledThrice);
        assert.deepEqual(
          emitterSpy.getCall(0).args[0],
          {removed: new Set([dir0])},
        );
        assert.deepEqual(
          emitterSpy.getCall(1).args[0],
          {removed: new Set([dir1])},
        );
        assert.deepEqual(
          emitterSpy.getCall(2).args[0],
          {removed: new Set([dir2])},
        );
      });

      it('does not emit for remove when a context did not exist', function() {
        pool.remove(dir1);
        assert.isFalse(emitterSpy.called);
      });
    });
  });
});
<commit_msg>Test for cross-instance cache invalidation<commit_after>import temp from 'temp';
import {Disposable} from 'event-kit';

import {cloneRepository} from '../helpers';

import WorkdirContextPool from '../../lib/models/workdir-context-pool';

describe('WorkdirContextPool', function() {
  let pool;
  let mockWindow, mockWorkspace;

  beforeEach(function() {
    mockWindow = {
      addEventListener: sinon.spy(),
      removeEventListener: sinon.spy(),
    };

    mockWorkspace = {
      observeTextEditors: sinon.stub().returns(new Disposable()),
    };

    pool = new WorkdirContextPool({
      window: mockWindow,
      workspace: mockWorkspace,
    });
  });

  describe('add', function() {
    let workingDirectory;

    beforeEach(async function() {
      workingDirectory = await cloneRepository('three-files');
    });

    it('adds a WorkdirContext for a new working directory', function() {
      assert.equal(pool.size(), 0);
      assert.isFalse(pool.getContext(workingDirectory).isPresent());

      pool.add(workingDirectory);

      assert.equal(pool.size(), 1);
      assert.isTrue(pool.getContext(workingDirectory).isPresent());
    });

    it('is a no-op if the working directory already has a context', function() {
      pool.add(workingDirectory);
      assert.equal(pool.size(), 1);

      const context = pool.getContext(workingDirectory);
      assert.isTrue(context.isPresent());

      pool.add(workingDirectory);
      assert.equal(pool.size(), 1);
    });

    it('begins but does not await the asynchronous initialization process', async function() {
      pool.add(workingDirectory);
      const context = pool.getContext(workingDirectory);
      assert.isTrue(context.getRepository().isLoading());
      assert.isTrue(context.getResolutionProgress().isEmpty());
      assert.isFalse(context.getChangeObserver().isStarted());

      await context.getRepositoryStatePromise('Present');
      assert.isTrue(context.getRepository().isPresent());
    });
  });

  describe('replace', function() {
    it('adds a WorkdirContext if one is absent', function() {
      const directory = temp.mkdirSync();

      assert.equal(pool.size(), 0);
      assert.isFalse(pool.getContext(directory).isPresent());

      pool.replace(directory);

      assert.equal(pool.size(), 1);
      assert.isTrue(pool.getContext(directory).isPresent());
    });

    it('removes an existing WorkdirContext if one is present', async function() {
      const directory = await cloneRepository('three-files');

      pool.add(directory);
      assert.equal(pool.size(), 1);
      const context = pool.getContext(directory);
      assert.isTrue(context.isPresent());
      const original = context.getRepository();

      pool.replace(directory);
      assert.equal(pool.size(), 1);
      assert.isTrue(pool.getContext(directory).isPresent());
      const replaced = pool.getContext(directory).getRepository();

      assert.notStrictEqual(original, replaced);
    });
  });

  describe('remove', function() {
    let existingDirectory, existingContext;

    beforeEach(async function() {
      existingDirectory = await cloneRepository('three-files');
      pool.add(existingDirectory);

      existingContext = pool.getContext(existingDirectory);
    });

    it('removes a WorkdirContext for an existing working directory', function() {
      assert.equal(pool.size(), 1);
      pool.remove(existingDirectory);
      assert.isFalse(pool.getContext(existingDirectory).isPresent());
      assert.equal(pool.size(), 0);
    });

    it('is a no-op if the working directory is not present', function() {
      assert.equal(pool.size(), 1);
      pool.remove('/nope');
      assert.equal(pool.size(), 1);
    });

    it('begins but does not await the termination process', function() {
      const repo = existingContext.getRepository();
      sinon.spy(repo, 'destroy');

      assert.isFalse(existingContext.isDestroyed());
      pool.remove(existingDirectory);
      assert.isTrue(existingContext.isDestroyed());
      assert.isTrue(repo.destroy.called);
    });
  });

  describe('set', function() {
    let dir0, dir1, dir2;

    beforeEach(async function() {
      [dir0, dir1, dir2] = await Promise.all([
        cloneRepository('three-files'),
        cloneRepository('three-files'),
        cloneRepository('three-files'),
      ]);

      pool.add(dir0);
      pool.add(dir1);
    });

    it('adds new directories, removes missing ones, and maintains kept ones', function() {
      const context0 = pool.getContext(dir0);
      const context1 = pool.getContext(dir1);

      pool.set([dir1, dir2]);

      assert.equal(pool.size(), 2);

      assert.isFalse(pool.getContext(dir0).isPresent());
      assert.isTrue(pool.getContext(dir1).isPresent());
      assert.isTrue(pool.getContext(dir2).isPresent());

      assert.isTrue(context0.isDestroyed());
      assert.isFalse(context1.isDestroyed());
    });
  });

  describe('getContext', function() {
    let dir;

    beforeEach(async function() {
      dir = await cloneRepository('three-files');
      pool.add(dir);
    });

    it('returns a context by directory', function() {
      const context = pool.getContext(dir);
      assert.isTrue(context.isPresent());

      const repo = context.getRepository();
      assert.strictEqual(dir, repo.getWorkingDirectoryPath());
    });

    it('returns a null context when missing', function() {
      const context = pool.getContext('/nope');
      assert.isFalse(context.isPresent());
    });
  });

  describe('getMatchingContext', function() {
    let dirs;

    beforeEach(async function() {
      dirs = await Promise.all(
        [1, 2, 3].map(() => cloneRepository()),
      );
    });

    async function addRepoRemote(context, name, url) {
      const repo = context.getRepository();
      await repo.getLoadPromise();
      await repo.addRemote(name, url);
    }

    it('returns a single resident context that has a repository with a matching remote', async function() {
      const matchingContext = pool.add(dirs[0]);
      await addRepoRemote(matchingContext, 'upstream', 'git@github.com:atom/github.git');

      const nonMatchingContext0 = pool.add(dirs[1]);
      await addRepoRemote(nonMatchingContext0, 'up', 'git@github.com:atom/atom.git');

      pool.add(dirs[2]);

      assert.strictEqual(await pool.getMatchingContext('github.com', 'atom', 'github'), matchingContext);
    });

    it('returns a null context when no contexts have suitable repositories', async function() {
      const context0 = pool.add(dirs[0]);
      await addRepoRemote(context0, 'upstream', 'git@github.com:atom/atom.git');

      pool.add(dirs[1]);

      const match = await pool.getMatchingContext('github.com', 'atom', 'github');
      assert.isFalse(match.isPresent());
    });

    it('returns a null context when more than one context has a suitable repository', async function() {
      const context0 = pool.add(dirs[0]);
      await addRepoRemote(context0, 'upstream', 'git@github.com:atom/github.git');

      const context1 = pool.add(dirs[1]);
      await addRepoRemote(context1, 'upstream', 'git@github.com:atom/github.git');

      pool.add(dirs[2]);

      const match = await pool.getMatchingContext('github.com', 'atom', 'github');
      assert.isFalse(match.isPresent());
    });
  });

  describe('clear', function() {
    it('removes all resident contexts', async function() {
      const [dir0, dir1, dir2] = await Promise.all([
        cloneRepository('three-files'),
        cloneRepository('three-files'),
        cloneRepository('three-files'),
      ]);

      pool.add(dir0);
      pool.add(dir1);
      pool.add(dir2);

      assert.equal(pool.size(), 3);

      pool.clear();

      assert.equal(pool.size(), 0);
      assert.isFalse(pool.getContext(dir0).isPresent());
      assert.isFalse(pool.getContext(dir1).isPresent());
      assert.isFalse(pool.getContext(dir2).isPresent());
    });
  });

  describe('emitter', function() {
    describe('did-change-contexts', function() {
      let dir0, dir1, dir2, emitterSpy;

      beforeEach(async function() {
        [dir0, dir1, dir2] = await Promise.all([
          cloneRepository('three-files'),
          cloneRepository('three-files'),
          cloneRepository('three-files'),
        ]);

        pool.add(dir0);

        emitterSpy = sinon.spy();

        pool.onDidChangePoolContexts(emitterSpy);
      });

      it('emits only once for set', function() {
        pool.set(new Set([dir1, dir2]));
        assert.isTrue(emitterSpy.calledOnce);
        assert.deepEqual(
          emitterSpy.getCall(0).args[0],
          {added: new Set([dir1, dir2]), removed: new Set([dir0])},
        );
      });

      it('does not emit for set when no changes are made', function() {
        pool.set(new Set([dir0]));
        assert.isFalse(emitterSpy.called);
      });

      it('emits only once for clear', function() {
        pool.clear();
        assert.isTrue(emitterSpy.calledOnce);
        assert.deepEqual(
          emitterSpy.getCall(0).args[0],
          {removed: new Set([dir0])},
        );
      });

      it('does not emit for clear when no changes are made', function() {
        pool.clear();
        emitterSpy.resetHistory();
        pool.clear(); // Should not emit
        assert.isFalse(emitterSpy.called);
      });

      it('emits only once for replace', function() {
        pool.replace(dir0);
        assert.isTrue(emitterSpy.calledOnce);
        assert.deepEqual(
          emitterSpy.getCall(0).args[0],
          {altered: new Set([dir0])},
        );
      });

      it('emits for every new add', function() {
        pool.remove(dir0);
        emitterSpy.resetHistory();
        pool.add(dir0);
        pool.add(dir1);
        pool.add(dir2);
        assert.isTrue(emitterSpy.calledThrice);
        assert.deepEqual(
          emitterSpy.getCall(0).args[0],
          {added: new Set([dir0])},
        );
        assert.deepEqual(
          emitterSpy.getCall(1).args[0],
          {added: new Set([dir1])},
        );
        assert.deepEqual(
          emitterSpy.getCall(2).args[0],
          {added: new Set([dir2])},
        );
      });

      it('does not emit for add when a context already exists', function() {
        pool.add(dir0);
        assert.isFalse(emitterSpy.called);
      });

      it('emits for every remove', function() {
        pool.add(dir1);
        pool.add(dir2);
        emitterSpy.resetHistory();
        pool.remove(dir0);
        pool.remove(dir1);
        pool.remove(dir2);
        assert.isTrue(emitterSpy.calledThrice);
        assert.deepEqual(
          emitterSpy.getCall(0).args[0],
          {removed: new Set([dir0])},
        );
        assert.deepEqual(
          emitterSpy.getCall(1).args[0],
          {removed: new Set([dir1])},
        );
        assert.deepEqual(
          emitterSpy.getCall(2).args[0],
          {removed: new Set([dir2])},
        );
      });

      it('does not emit for remove when a context did not exist', function() {
        pool.remove(dir1);
        assert.isFalse(emitterSpy.called);
      });
    });
  });

  describe('cross-instance cache invalidation', function() {
    it('invalidates a config cache key in different instances when a global setting is changed', async function() {
      const value = String(Date.now());

      const repo0 = pool.add(await cloneRepository('three-files')).getRepository();
      const repo1 = pool.add(await cloneRepository('three-files')).getRepository();
      const repo2 = pool.add(temp.mkdirSync()).getRepository();

      await Promise.all([repo0, repo1, repo2].map(repo => repo.getLoadPromise()));

      const [before0, before1, before2] = await Promise.all(
        [repo0, repo1, repo2].map(repo => repo.getConfig('atomGithub.test')),
      );

      assert.notInclude([before0, before1, before2], value);

      await repo2.setConfig('atomGithub.test', value, {global: true});

      const [after0, after1, after2] = await Promise.all(
        [repo0, repo1, repo2].map(repo => repo.getConfig('atomGithub.test')),
      );

      assert.strictEqual(after0, value);
      assert.strictEqual(after1, value);
      assert.strictEqual(after2, value);
    });
  });
});
<|endoftext|>


<commit_before> $(document).ready(function() {
  var formSelector = ".current form";
  initializeHistory();

  // events
  // get new questions on submit
  $(formSelector).live('submit', function(event) {
    $('input[type=submit]', this).attr('disabled', 'disabled');
    var form = $(this);
    reloadQuestions(form.attr('action'), form.serializeArray());
    event.preventDefault();
    return false;
  });

  // we want to start over with whatever gets provided if someone clicks to change the answer
  $(".undo a").live('click', function() {
    reloadQuestions($(this).attr("href"), "");
    return false;
  });

  // manage next/back by tracking popstate event
  window.onpopstate = function (event) {
    if(event.state != null) {
      updateContent(event.state);
    }
    else if (urlFromHashtag()) {
      $.get(toJsonUrl(urlFromHashtag()), function(data) {
        updateContent(data['html_fragment']);
      });
    } else {
      return false;
    }
  }

  // helper functions
  function urlFromHashtag() {
    return window.location.hash.split('#')[1];
  }

  function toJsonUrl(url) {
    var parts = url.split('?');
    return parts[0] + ".json";
  }

  function fromJsonUrl(url) {
    return url.replace(/\.json$/, "");
  }

  // replace all the questions currently in the page with whatever is returned for given url
  function reloadQuestions(url, params) {
    $.get(toJsonUrl(url), params, function(data) {
      addToHistory(data);
      updateContent(data['html_fragment']);
    });
  };

  // manage the URL
  function addToHistory(data) {
    var url = data['url'];
    if (history && history.pushState) {
      history.pushState(data, data['title'], url);
    }
    else {
      window.location.hash = url;
      $(formSelector).attr("action", url);
    };
  };

  // update the content (i.e. plonk in the html fragment)
  function updateContent(fragment){
    $('.smart_answer section').html(fragment);

  //  $('.next-question input[type=submit]').attr('disabled');
    // check if value or selected
    // if that
    // undisable
    // else
    // set event listener for change in value or selected
    //$(formSelector+' input[type=submit]').attr('disabled', 'disabled');
  };

  function initializeHistory(data) {
    // if hashed, means it's a non-pushstated URL that we need to generate the content for
    if (urlFromHashtag()) {
      reloadQuestions(urlFromHashtag(), "");
    }

    if (history && history.replaceState) {
      history.replaceState(
				$('.smart_answer section').html(),
				"Question",
				window.location.toString()
			);
    }
  }
});<commit_msg>Fix browser back/forward handling.<commit_after> $(document).ready(function() {
  var formSelector = ".current form";
  initializeHistory();

  // events
  // get new questions on submit
  $(formSelector).live('submit', function(event) {
    $('input[type=submit]', this).attr('disabled', 'disabled');
    var form = $(this);
    reloadQuestions(form.attr('action'), form.serializeArray());
    event.preventDefault();
    return false;
  });

  // we want to start over with whatever gets provided if someone clicks to change the answer
  $(".undo a").live('click', function() {
    reloadQuestions($(this).attr("href"), "");
    return false;
  });

  // manage next/back by tracking popstate event
  window.onpopstate = function (event) {
    if(event.state != null) {
      updateContent(event.state['html_fragment']);
    }
    else if (urlFromHashtag()) {
      $.get(toJsonUrl(urlFromHashtag()), function(data) {
        updateContent(data['html_fragment']);
      });
    } else {
      return false;
    }
  }

  // helper functions
  function urlFromHashtag() {
    return window.location.hash.split('#')[1];
  }

  function toJsonUrl(url) {
    var parts = url.split('?');
    return parts[0] + ".json";
  }

  function fromJsonUrl(url) {
    return url.replace(/\.json$/, "");
  }

  // replace all the questions currently in the page with whatever is returned for given url
  function reloadQuestions(url, params) {
    $.get(toJsonUrl(url), params, function(data) {
      addToHistory(data);
      updateContent(data['html_fragment']);
    });
  };

  // manage the URL
  function addToHistory(data) {
    if (history && history.pushState) {
      history.pushState(data, data['title'], data['url']);
    }
    else {
      window.location.hash = data['url'];
      $(formSelector).attr("action", data['url']);
    };
  };

  // update the content (i.e. plonk in the html fragment)
  function updateContent(fragment){
    $('.smart_answer section').html(fragment);

  //  $('.next-question input[type=submit]').attr('disabled');
    // check if value or selected
    // if that
    // undisable
    // else
    // set event listener for change in value or selected
    //$(formSelector+' input[type=submit]').attr('disabled', 'disabled');
  };

  function initializeHistory(data) {
    // if hashed, means it's a non-pushstated URL that we need to generate the content for
    if (urlFromHashtag()) {
      reloadQuestions(urlFromHashtag(), "");
    }

    if (history && history.replaceState) {
      data = {
        html_fragment: $('.smart_answer section').html(),
        title: "Question",
        url: window.location.toString()
      };
      history.replaceState(data, data['title'], data['url']);
    }
  }
});<|endoftext|>


<commit_before>var data;
var colors = ["#1abc9c","#2ecc71","#3498db","#9b59b6","#34495e","#95a6a6"];

var l = 250; // left margin
var r = 150; // right margin
var w = 500; // width of drawing area
var h = 36;  // bar height
var s = 2;   // spacing between bars

// construct query string
var params = d3.select("h1#api_key");
if (!params.empty()) {
  var api_key = params.attr('data-api_key');
  var query = encodeURI("/api/v5/sources?api_key=" + api_key);
};

// load the data from the ALM API
if (query) {
  d3.json(query, function(error, json) {
    if (error) return console.warn(error);
    data = json["data"];

    articlesViz(data);
    eventsViz(data);
  });
}

// articles bar chart
function articlesViz(data) {

  // remove source not needed for the following visualizations
  data = data.filter(function(d) { return d.name != "relativemetric"; });

  // Articles tab
  var chart = d3.select("div#articles").append("svg")
    .attr("width", w + l + r)
    .attr("height", data.length * (h + 2 * s) + 30)
    .attr("class", "chart")
    .append("g")
    .attr("transform", "translate(330,20)");

  var x = d3.scale.linear()
    .domain([0, d3.max(data, function(d) { return d.article_count; })])
    .range([0, w]);
  var y = d3.scale.ordinal()
    .domain(data.map(function(d) { return d.display_name; }))
    .rangeBands([0, (h + 2 * s) * data.length]);
  var z = d3.scale.ordinal()
    .domain(data.map(function(d) { return d.group; }))
    .range(colors);

  chart.selectAll("text.labels")
    .data(data)
    .enter().append("a").attr("xlink:href", function(d) { return "/sources/" + d.name; }).append("text")
    .attr("x", 0)
    .attr("y", function(d) { return y(d.display_name) + y.rangeBand() / 2; })
    .attr("dx", -330) // padding-right
    .attr("dy", ".35em") // vertical-align: middle
    .text(function(d) { return d.display_name; });
  chart.selectAll("rect")
    .data(data)
    .enter().append("rect")
    .attr("fill", function(d) { return z(d.group); })
    .attr("y", function(d,i) { return y(d.display_name); })
    .attr("height", h)
    .attr("width", function(d) { return x(d.article_count); });
  chart.selectAll("text.values")
    .data(data)
    .enter().append("text")
    .attr("x", function(d) { return x(d.article_count); })
    .attr("y", function(d) { return y(d.display_name) + y.rangeBand() / 2; })
    .attr("dx", 5) // padding-right
    .attr("dy", ".35em") // vertical-align: middle
    .text(function(d) { return numberWithDelimiter(d.article_count); });
}

// events bar chart
function eventsViz(data) {

  // remove source not needed for the following visualizations
  data = data.filter(function(d) { return d.name != "relativemetric"; });

  // Events tab
  var chart = d3.select("div#events").append("svg")
    .attr("width", w + l + r)
    .attr("height", data.length * (h + 2 * s) + 30)
    .attr("class", "chart")
    .append("g")
    .attr("transform", "translate(330,20)");

  var x = d3.scale.log()
    .domain([0.1, d3.max(data, function(d) { return d.event_count; })])
    .range([1, w]);
  var y = d3.scale.ordinal()
    .domain(data.map(function(d) { return d.display_name; }))
    .rangeBands([0, (h + 2 * s) * data.length]);
  var z = d3.scale.ordinal()
    .domain(data.map(function(d) { return d.group; }))
    .range(colors);

  chart.selectAll("text.labels")
    .data(data)
    .enter().append("a").attr("xlink:href", function(d) { return "/sources/" + d.name; }).append("text")
    .attr("x", 0)
    .attr("y", function(d) { return y(d.display_name) + y.rangeBand() / 2; })
    .attr("dx", -330) // padding-right
    .attr("dy", ".35em") // vertical-align: middle
    .text(function(d) { return d.display_name; });
  chart.selectAll("rect")
    .data(data)
    .enter().append("rect")
    .attr("fill", function(d) { return z(d.group); })
    .attr("y", function(d) { return y(d.display_name); })
    .attr("height", h)
    .attr("width", function(d) { return x(d.event_count); });
  chart.selectAll("text.values")
    .data(data)
    .enter().append("text")
    .attr("x", function(d) { return x(d.event_count); })
    .attr("y", function(d) { return y(d.display_name) + y.rangeBand() / 2; })
    .attr("dx", 5) // padding-right
    .attr("dy", ".35em") // vertical-align: middle
    .text(function(d) { return numberWithDelimiter(d.event_count); });
}

// d3 helper functions
var formatFixed = d3.format(",.0f");

function numberWithDelimiter(number) {
  if(number !== 0) {
    return formatFixed(number);
  } else {
    return null;
  }
}
<commit_msg>give more space for number label<commit_after>var data;
var colors = ["#1abc9c","#2ecc71","#3498db","#9b59b6","#34495e","#95a6a6"];

var l = 250; // left margin
var r = 170; // right margin
var w = 480; // width of drawing area
var h = 36;  // bar height
var s = 2;   // spacing between bars

// construct query string
var params = d3.select("h1#api_key");
if (!params.empty()) {
  var api_key = params.attr('data-api_key');
  var query = encodeURI("/api/v5/sources?api_key=" + api_key);
};

// load the data from the ALM API
if (query) {
  d3.json(query, function(error, json) {
    if (error) return console.warn(error);
    data = json["data"];

    articlesViz(data);
    eventsViz(data);
  });
}

// articles bar chart
function articlesViz(data) {

  // remove source not needed for the following visualizations
  data = data.filter(function(d) { return d.name != "relativemetric"; });

  // Articles tab
  var chart = d3.select("div#articles").append("svg")
    .attr("width", w + l + r)
    .attr("height", data.length * (h + 2 * s) + 30)
    .attr("class", "chart")
    .append("g")
    .attr("transform", "translate(330,20)");

  var x = d3.scale.linear()
    .domain([0, d3.max(data, function(d) { return d.article_count; })])
    .range([0, w]);
  var y = d3.scale.ordinal()
    .domain(data.map(function(d) { return d.display_name; }))
    .rangeBands([0, (h + 2 * s) * data.length]);
  var z = d3.scale.ordinal()
    .domain(data.map(function(d) { return d.group; }))
    .range(colors);

  chart.selectAll("text.labels")
    .data(data)
    .enter().append("a").attr("xlink:href", function(d) { return "/sources/" + d.name; }).append("text")
    .attr("x", 0)
    .attr("y", function(d) { return y(d.display_name) + y.rangeBand() / 2; })
    .attr("dx", -330) // padding-right
    .attr("dy", ".35em") // vertical-align: middle
    .text(function(d) { return d.display_name; });
  chart.selectAll("rect")
    .data(data)
    .enter().append("rect")
    .attr("fill", function(d) { return z(d.group); })
    .attr("y", function(d,i) { return y(d.display_name); })
    .attr("height", h)
    .attr("width", function(d) { return x(d.article_count); });
  chart.selectAll("text.values")
    .data(data)
    .enter().append("text")
    .attr("x", function(d) { return x(d.article_count); })
    .attr("y", function(d) { return y(d.display_name) + y.rangeBand() / 2; })
    .attr("dx", 5) // padding-right
    .attr("dy", ".35em") // vertical-align: middle
    .text(function(d) { return numberWithDelimiter(d.article_count); });
}

// events bar chart
function eventsViz(data) {

  // remove source not needed for the following visualizations
  data = data.filter(function(d) { return d.name != "relativemetric"; });

  // Events tab
  var chart = d3.select("div#events").append("svg")
    .attr("width", w + l + r)
    .attr("height", data.length * (h + 2 * s) + 30)
    .attr("class", "chart")
    .append("g")
    .attr("transform", "translate(330,20)");

  var x = d3.scale.log()
    .domain([0.1, d3.max(data, function(d) { return d.event_count; })])
    .range([1, w]);
  var y = d3.scale.ordinal()
    .domain(data.map(function(d) { return d.display_name; }))
    .rangeBands([0, (h + 2 * s) * data.length]);
  var z = d3.scale.ordinal()
    .domain(data.map(function(d) { return d.group; }))
    .range(colors);

  chart.selectAll("text.labels")
    .data(data)
    .enter().append("a").attr("xlink:href", function(d) { return "/sources/" + d.name; }).append("text")
    .attr("x", 0)
    .attr("y", function(d) { return y(d.display_name) + y.rangeBand() / 2; })
    .attr("dx", -330) // padding-right
    .attr("dy", ".35em") // vertical-align: middle
    .text(function(d) { return d.display_name; });
  chart.selectAll("rect")
    .data(data)
    .enter().append("rect")
    .attr("fill", function(d) { return z(d.group); })
    .attr("y", function(d) { return y(d.display_name); })
    .attr("height", h)
    .attr("width", function(d) { return x(d.event_count); });
  chart.selectAll("text.values")
    .data(data)
    .enter().append("text")
    .attr("x", function(d) { return x(d.event_count); })
    .attr("y", function(d) { return y(d.display_name) + y.rangeBand() / 2; })
    .attr("dx", 5) // padding-right
    .attr("dy", ".35em") // vertical-align: middle
    .text(function(d) { return numberWithDelimiter(d.event_count); });
}

// d3 helper functions
var formatFixed = d3.format(",.0f");

function numberWithDelimiter(number) {
  if(number !== 0) {
    return formatFixed(number);
  } else {
    return null;
  }
}
<|endoftext|>


<commit_before>#!/usr/bin/env node

var fs = require('fs'),
    program = require('commander'),
    async = require('async'),
    child = require('child_process'),
    cwd = process.cwd();

program.command('test')
    .description('Run functional tests')
    .option('-u, --unit', 'Run unit tests')
    .option('-f, --func', 'Run functional tests')
    .option('-b, --no-build', 'Don\'t build the apps')
    .option('-d, --no-deploy', 'Don\'t deploy the apps')
    .option('-s, --no-selenium', 'Don\'t run arrow_selenium')
    .option('-a, --no-arrow', 'Don\'t run arrow_server')
    .action(test);

program.command('deploy')
    .description('Deploy all apps')
    .action(deploy);

program.parse(process.argv);

function test (cmd) {
    var series = [];
    // Default to all tests
    if (!cmd.unit && !cmd.func) {
        cmd.unit = true;
        cmd.func = true;
    }
    if (cmd.unit) {
        if (cmd.arrow) {
            series.push(startArrowServer);
        }
        series.push(runUnitTests);
    }
    if (cmd.func) {
        if (cmd.build) {
            series.push(build);
        }
        if (cmd.selenium) {
            series.push(startArrowSelenium);
        }
        if (cmd.deploy) {
            series.push(deploy);
        }
        series.push(runFuncTests);
    }
    async.series(series, finalize);
}

function startArrowServer (callback) {
    console.log("---Starting Arrow Server---");
    var p = runCommand(cwd, "arrow_server");
    setTimeout(function () {
        callback(null, [p.pid]);
    }, 5000);
}

function runUnitTests (callback) {
    console.log('---Running Unit Tests---');
    var arrowReportDir = cwd + '/arrowreport/unit/';
    runCommand(cwd, "mkdir", [cwd + '/arrowreport/'], function () {
        runCommand(cwd, "mkdir", [arrowReportDir], function () {
            var cmd = runCommand(
                cwd + '/unit',
                "arrow",
                ["**/*_descriptor.json", "--browser=phantomjs", "--report=true", "--reportFolder=" + arrowReportDir],
                callback
            );
            cmd.stdout.on('data', function (data) {
                process.stdout.write(data);
            });
        });
    });
}

function build (callback) {
    console.log('---Building Apps---');
    runCommand(
        cwd + '/func/applications/frameworkapp/common',
        "mojito",
        ['build', 'html5app', cwd + '/func/applications/frameworkapp/flatfile'],
        callback
    );
}

function deploy (callback) {
    console.log('---Deploying Apps---');
    var appSeries = [],
        appsConfig = JSON.parse(fs.readFileSync(cwd + '/func/applications/apps.json', 'utf8')),
        apps = appsConfig.applications;

    for (var i=0; i<apps.length; i++) {
        (function () {
            var app = apps[i],
                port = app.port ? parseInt(app.port) : null;

            if (app.tests) {
                var mytests = app.tests;
                for(var j=0; j<mytests.length; j++) {
                    (function () {
                        var test = mytests[j],
                            port = test.port ? parseInt(test.port) : null;
                        appSeries.push(function (callback) {
                            runApp(cwd + '/func/applications', app.path, port, test.param, callback);
                        });
                    })();
                }
            } else if (app.enabled === "true" && app.path && port) {
                appSeries.push(function (callback) {
                    runApp(cwd + '/func/applications', app.path, port, app.param, callback);
                });
            }
        })();
    }
    async.series(appSeries, callback);
}

function startArrowSelenium (callback) {
    console.log("---Starting Arrow Selenium---");
    var p = runCommand(cwd+"/func/applications/frameworkapp/common", "arrow_selenium", ["--open=firefox"]);
    setTimeout(function () {
        callback(null, [p.pid]);
    }, 10000);
}

function runFuncTests (callback) {
    console.log('---Running Functional Tests---');
    var arrowReportDir = cwd + '/arrowreport/func/';
    runCommand(cwd, "mkdir", [arrowReportDir], function () {
        var cmd = runCommand(
            cwd + '/func/',
            "arrow",
            ["**/*_descriptor.json", "--browser=firefox", "--reuseSession", "--report=true", "--reportFolder=" + arrowReportDir],
            callback
        );
        cmd.stdout.on('data', function (data) {
            process.stdout.write(data);
        });
    });
}

function finalize (err, results) {
    if (results && results[0] && results[0].length) {
        for(var i=0; i < results[0].length; i++) {
            console.log('Shutting down pid ' + results[0][i]);
            process.kill(results[0][i]);
        }
    }
    if (err) {
        console.log(err);
        console.log('FAILED');
        process.exit(1);
        return;
    }
    console.log(results);
    console.log('Completed');
    process.exit(0);

}

function runCommand (path, command, argv, callback) {
    callback = callback || function () {};
    process.chdir(path);
    var cmd = child.spawn(command, argv, {
        cwd: path,
        env: process.env
    });

    cmd.stdout.on('data', function (data) {
        // Don't care generally. But, specific commands may want a listener for this.
    });

    cmd.stderr.on('data', function (data) {
        process.stdout.write(data);
    });

    cmd.on('exit', function (code) {
        cmd.stdin.end();
        if (0 !== code) {
            callback('exit: child process exited with code ' + code);
            return;
        }
        callback();
    });

    cmd.on('uncaughtException', function (err) {
        process.stderr.write('uncaught exception: ' + err+'\n');
        callback(1);
    });

    return cmd;
}

function runApp (basePath, path, port, params, callback) {
    params = params || '';
    console.log('Starting ' + path + ' at port ' + port + ' with params ' + (params || 'empty'));
    var p = runCommand(basePath + '/' + path, "mojito", ["start", port, "--context", params], function () {});
    // Give each app a second to start
    setTimeout(function () { callback(null, [p.pid]) }, 1000);
}<commit_msg>Added unit tests to the description<commit_after>#!/usr/bin/env node

var fs = require('fs'),
    program = require('commander'),
    async = require('async'),
    child = require('child_process'),
    cwd = process.cwd();

program.command('test')
    .description('Run unit and functional tests')
    .option('-u, --unit', 'Run unit tests')
    .option('-f, --func', 'Run functional tests')
    .option('-b, --no-build', 'Don\'t build the apps')
    .option('-d, --no-deploy', 'Don\'t deploy the apps')
    .option('-s, --no-selenium', 'Don\'t run arrow_selenium')
    .option('-a, --no-arrow', 'Don\'t run arrow_server')
    .action(test);

program.command('deploy')
    .description('Deploy all apps')
    .action(deploy);

program.parse(process.argv);

function test (cmd) {
    var series = [];
    // Default to all tests
    if (!cmd.unit && !cmd.func) {
        cmd.unit = true;
        cmd.func = true;
    }
    if (cmd.unit) {
        if (cmd.arrow) {
            series.push(startArrowServer);
        }
        series.push(runUnitTests);
    }
    if (cmd.func) {
        if (cmd.build) {
            series.push(build);
        }
        if (cmd.selenium) {
            series.push(startArrowSelenium);
        }
        if (cmd.deploy) {
            series.push(deploy);
        }
        series.push(runFuncTests);
    }
    async.series(series, finalize);
}

function startArrowServer (callback) {
    console.log("---Starting Arrow Server---");
    var p = runCommand(cwd, "arrow_server");
    setTimeout(function () {
        callback(null, [p.pid]);
    }, 5000);
}

function runUnitTests (callback) {
    console.log('---Running Unit Tests---');
    var arrowReportDir = cwd + '/arrowreport/unit/';
    runCommand(cwd, "mkdir", [cwd + '/arrowreport/'], function () {
        runCommand(cwd, "mkdir", [arrowReportDir], function () {
            var cmd = runCommand(
                cwd + '/unit',
                "arrow",
                ["**/*_descriptor.json", "--browser=phantomjs", "--report=true", "--reportFolder=" + arrowReportDir],
                callback
            );
            cmd.stdout.on('data', function (data) {
                process.stdout.write(data);
            });
        });
    });
}

function build (callback) {
    console.log('---Building Apps---');
    runCommand(
        cwd + '/func/applications/frameworkapp/common',
        "mojito",
        ['build', 'html5app', cwd + '/func/applications/frameworkapp/flatfile'],
        callback
    );
}

function deploy (callback) {
    console.log('---Deploying Apps---');
    var appSeries = [],
        appsConfig = JSON.parse(fs.readFileSync(cwd + '/func/applications/apps.json', 'utf8')),
        apps = appsConfig.applications;

    for (var i=0; i<apps.length; i++) {
        (function () {
            var app = apps[i],
                port = app.port ? parseInt(app.port) : null;

            if (app.tests) {
                var mytests = app.tests;
                for(var j=0; j<mytests.length; j++) {
                    (function () {
                        var test = mytests[j],
                            port = test.port ? parseInt(test.port) : null;
                        appSeries.push(function (callback) {
                            runApp(cwd + '/func/applications', app.path, port, test.param, callback);
                        });
                    })();
                }
            } else if (app.enabled === "true" && app.path && port) {
                appSeries.push(function (callback) {
                    runApp(cwd + '/func/applications', app.path, port, app.param, callback);
                });
            }
        })();
    }
    async.series(appSeries, callback);
}

function startArrowSelenium (callback) {
    console.log("---Starting Arrow Selenium---");
    var p = runCommand(cwd+"/func/applications/frameworkapp/common", "arrow_selenium", ["--open=firefox"]);
    setTimeout(function () {
        callback(null, [p.pid]);
    }, 10000);
}

function runFuncTests (callback) {
    console.log('---Running Functional Tests---');
    var arrowReportDir = cwd + '/arrowreport/func/';
    runCommand(cwd, "mkdir", [arrowReportDir], function () {
        var cmd = runCommand(
            cwd + '/func/',
            "arrow",
            ["**/*_descriptor.json", "--browser=firefox", "--reuseSession", "--report=true", "--reportFolder=" + arrowReportDir],
            callback
        );
        cmd.stdout.on('data', function (data) {
            process.stdout.write(data);
        });
    });
}

function finalize (err, results) {
    if (results && results[0] && results[0].length) {
        for(var i=0; i < results[0].length; i++) {
            console.log('Shutting down pid ' + results[0][i]);
            process.kill(results[0][i]);
        }
    }
    if (err) {
        console.log(err);
        console.log('FAILED');
        process.exit(1);
        return;
    }
    console.log(results);
    console.log('Completed');
    process.exit(0);

}

function runCommand (path, command, argv, callback) {
    callback = callback || function () {};
    process.chdir(path);
    var cmd = child.spawn(command, argv, {
        cwd: path,
        env: process.env
    });

    cmd.stdout.on('data', function (data) {
        // Don't care generally. But, specific commands may want a listener for this.
    });

    cmd.stderr.on('data', function (data) {
        process.stdout.write(data);
    });

    cmd.on('exit', function (code) {
        cmd.stdin.end();
        if (0 !== code) {
            callback('exit: child process exited with code ' + code);
            return;
        }
        callback();
    });

    cmd.on('uncaughtException', function (err) {
        process.stderr.write('uncaught exception: ' + err+'\n');
        callback(1);
    });

    return cmd;
}

function runApp (basePath, path, port, params, callback) {
    params = params || '';
    console.log('Starting ' + path + ' at port ' + port + ' with params ' + (params || 'empty'));
    var p = runCommand(basePath + '/' + path, "mojito", ["start", port, "--context", params], function () {});
    // Give each app a second to start
    setTimeout(function () { callback(null, [p.pid]) }, 1000);
}<|endoftext|>


<commit_before>var mockAws = {
	S3: function(){
		return {
			createBucket: function(params, callback){
				callback(null, "test");
			},
			listObjectsV2: function (params, callback) {
				callback(null, "test");
			},
			getSignedUrl: function (params, callback) {
				callback(null, "test");
			},
			headObject: function (params, callback) {
				callback(null, "test");
			},
			deleteFile: function (params, callback) {
				callback(null, "test");
			}
		};
	},
	Config: function () {
		return {};
	},
	Endpoint: function () {
		return {};
	}
};

module.exports = mockAws;
<commit_msg>improve test coverage for fileStorage<commit_after>const testListObjectsReturn = {
	Contents: [
		{key: "testFile"}
	]
};

const testHeadObjectReturn = {
	Metadata: { name: "testName", thumbnail: "testThumbnail" },
	LastModified: "test",
	ContentLength: 5,
	ContentType: "mime/image"
};

var mockAws = {
	S3: function(){
		return {
			createBucket: function(params, callback){
				callback(null, "test");
			},
			listObjectsV2: function (params, callback) {
				callback(null, testListObjectsReturn);
			},
			getSignedUrl: function (params, callback) {
				callback(null, "test");
			},
			headObject: function (params, callback) {
				callback(null, testHeadObjectReturn);
			},
			deleteFile: function (params, callback) {
				callback(null, "test");
			}
		};
	},
	Config: function () {
		return {};
	},
	Endpoint: function () {
		return {};
	}
};

module.exports = mockAws;
<|endoftext|>


<commit_before>/*global jQuery:true*/

'use strict';

require('angular');
require('angular-mocks');

describe('Directive: Code Descriptions', function () {

    beforeEach(angular.mock.module('hmdaPilotApp'));

    var element,
        scope,
        $el,
        HMDAEngine,
        ngDialog,
        mockFileSpec = {
            transmittalSheet: {
                agencyCode: {
                    label: 'Agency Code',
                    validation: {
                        type: 'number',
                        values: {
                            '1': 'OCC',
                            '2': 'FRS',
                            '3': 'FDIC',
                            '5': 'NCUA',
                            '7': 'HUD',
                            '9': 'CFPB'
                        }
                    }
                }
            },
            loanApplicationRegister: {
                loanType: {
                    label: 'Loan Type',
                    validation: {
                        type: 'number',
                        values: {
                            '1': 'Conventional (any loan other than FHA, VA, FSA, or RHS loans)',
                            '2': 'FHA-insured (Federal Housing Administration)',
                            '3': 'VA-guaranteed (Veterans Administration)',
                            '4': 'FSA/RHS (Farm Service Agency or Rural Housing Service)'
                         }
                     }
                }
            }
        };

    beforeEach(inject(function(_ngDialog_) {
        HMDAEngine = { getFileSpec: function() { return mockFileSpec; } };
        ngDialog = _ngDialog_;
        spyOn(ngDialog, 'open');
    }));

    beforeEach(inject(function($templateCache) {
        var directiveTemplate = null;
        var templateId = 'partials/codeDescriptions.html';
        var req = new XMLHttpRequest();
        req.onload = function() {
            directiveTemplate = this.responseText;
        };
        req.open('get', '/base/app/'+templateId, false);
        req.send();
        $templateCache.put(templateId, directiveTemplate);
    }));

    beforeEach(inject(function ($rootScope, $compile) {
        scope = $rootScope.$new();
        element = angular.element('<code-descriptions></code-descriptions>');
        element = $compile(element)(scope);
        scope.$digest();
        $el = jQuery(element);
    }));

    describe('open', function() {
        it('should display a definition list', function () {
            expect($el.find('dl')).toBeDefined();
        });
    });
});
<commit_msg>working tests<commit_after>/*global jQuery:true*/

'use strict';

require('angular');
require('angular-mocks');

describe('Directive: Code Descriptions', function () {

    beforeEach(angular.mock.module('hmdaPilotApp'));

    var element,
        scope,
        $el,
        HMDAEngine,
        ngDialog,
        mockFileSpec = {
            transmittalSheet: {
                recordID: {
                    label: 'Record Identifier',
                    validation: {
                        type: 'number',
                        canBeBlank: false,
                        canBeNA: false
                    }
                },
                respondentID: {
                    label: 'Respondent-ID',
                    validation: {
                        type: 'string',
                        canBeBlank: false,
                        canBeNA: false
                    }
                },
                agencyCode: {
                    label: 'Agency Code',
                    validation: {
                        type: 'number',
                        values: {
                            '1': 'OCC',
                            '2': 'FRS',
                            '3': 'FDIC',
                            '5': 'NCUA',
                            '7': 'HUD',
                            '9': 'CFPB'
                        }
                    }
                }
            },
            loanApplicationRegister: {
                loanType: {
                    label: 'Loan Type',
                    validation: {
                        type: 'number',
                        values: {
                            '1': 'Conventional (any loan other than FHA, VA, FSA, or RHS loans)',
                            '2': 'FHA-insured (Federal Housing Administration)',
                            '3': 'VA-guaranteed (Veterans Administration)',
                            '4': 'FSA/RHS (Farm Service Agency or Rural Housing Service)'
                         }
                     }
                }
            }
        };

    beforeEach(inject(function(_HMDAEngine_, _ngDialog_) {
        HMDAEngine = _HMDAEngine_;
        HMDAEngine.getFileSpec = function() { return mockFileSpec; };
        HMDAEngine.getRuleYear = function() { return '2013'; };
        ngDialog = _ngDialog_;
        spyOn(ngDialog, 'open');
    }));

    beforeEach(inject(function($templateCache) {
        var directiveTemplate = null;
        var templateId = 'partials/codeDescriptions.html';
        var req = new XMLHttpRequest();
        req.onload = function() {
            directiveTemplate = this.responseText;
        };
        req.open('get', '/base/app/'+templateId, false);
        req.send();
        $templateCache.put(templateId, directiveTemplate);
    }));

    beforeEach(inject(function ($rootScope, $compile) {
        scope = $rootScope.$new();
        element = angular.element('<code-descriptions></code-descriptions>');
        element = $compile(element)(scope);
        scope.$digest();
        $el = jQuery(element);
    }));

    describe('template', function() {
        it('should display a clickable span', function() {
            var $span = $el.find('span');
            expect($span.hasClass('pointer')).toBeTruthy();
            $span.click();
            expect(ngDialog.open).toHaveBeenCalled();
        });
    });

    describe('open', function() {
        it('should display a definition list', function() {
            jQuery('span', element).click();
            expect($el.find('dl')).toBeDefined();
        });
    });
});
<|endoftext|>


<commit_before>M.wrap('github/jillix/i18n-sync/v0.3.0/client/i18n.js', function (require, module, exports) {
module.exports = function(config) {

    var self = this;
    self._config = config;

    // set default value for translations
    config.translations = config.translations || {};

    /**
     * translate
     * Translates the message passed in the first parameter.
     *
     * @name translate
     * @function
     * @param {String} messageToTranslate The message that should be translated.
     * @param {String (Optional)} locale The locale of translated string.
     * @return
     */
    self.translate = self.t = function (messageToTranslate, locale, callback) {

        // set locale
        locale = locale || M.getLocale();

        // translate message
        var translatedMessage = (
            config.translations[messageToTranslate] || {}
        )[locale] || messageToTranslate;

        return translatedMessage;
    };

    self.emit("ready", config);
};

return module; });
<commit_msg>Comments and minor changes<commit_after>/**
 * i18n-sync
 * The sync version of i18n module.
 *
 * @name exports
 * @function
 * @param {Object} config The module config
 */
module.exports = function(config) {

    var self = this;
    self._config = config;

    // set default value for translations
    config.translations = config.translations || {};

    /**
     * translate
     * Translates the message passed in the first parameter.
     *
     * @name translate
     * @function
     * @param {String} messageToTranslate The message that should be translated.
     * @param {String (Optional)} locale The locale of translated string.
     * @return
     */
    self.translate = self.t = function(messageToTranslate, locale, callback) {

        // set locale
        locale = locale || M.getLocale();

        // translate message
        var translatedMessage = (
            config.translations[messageToTranslate] || {}
        )[locale] || messageToTranslate;

        return translatedMessage;
    };

    // Emit "ready" event
    self.emit("ready", config);
};
<|endoftext|>


<commit_before>import {
  init,
  requestBidsHook,
  setTargetsAfterRequestBids,
  deepMerge
} from 'modules/rtdModule/index.js';
import {
  init as browsiInit,
  addBrowsiTag,
  isIdMatchingAdUnit,
  setData
} from 'modules/browsiRtdProvider.js';
import {
  init as audigentInit,
  setData as setAudigentData
} from 'modules/audigentRtdProvider.js';
import {config} from 'src/config.js';
import {makeSlot} from '../integration/faker/googletag.js';

let expect = require('chai').expect;

describe('Real time module', function() {
  const conf = {
    'realTimeData': {
      'auctionDelay': 250,
      dataProviders: [{
        'name': 'browsi',
        'params': {
          'url': 'testUrl.com',
          'siteKey': 'testKey',
          'pubKey': 'testPub',
          'keyName': 'bv'
        }
      }, {
        'name': 'audigent'
      }]
    }
  };

  const predictions =
    {p: {
      'browsiAd_2': {
        'w': [
          '/57778053/Browsi_Demo_Low',
          '/57778053/Browsi_Demo_300x250'
        ],
        'p': 0.07
      },
      'browsiAd_1': {
        'w': [],
        'p': 0.06
      },
      'browsiAd_3': {
        'w': [],
        'p': 0.53
      },
      'browsiAd_4': {
        'w': [
          '/57778053/Browsi_Demo'
        ],
        'p': 0.85
      }
    }
    };

  const audigentSegments = {
    audigent_segments: {'a': 1, 'b': 2}
  }

  function getAdUnitMock(code = 'adUnit-code') {
    return {
      code,
      mediaTypes: {banner: {}, native: {}},
      sizes: [[300, 200], [300, 600]],
      bids: [{bidder: 'sampleBidder', params: {placementId: 'banner-only-bidder'}}]
    };
  }

  function createSlots() {
    const slot1 = makeSlot({code: '/57778053/Browsi_Demo_300x250', divId: 'browsiAd_1'});
    return [slot1];
  }

  describe('Real time module with browsi provider', function() {
    afterEach(function () {
      $$PREBID_GLOBAL$$.requestBids.removeAll();
    });

    it('check module using bidsBackCallback', function () {
      let adUnits1 = [getAdUnitMock('browsiAd_1')];
      let targeting = [];
      init(config);
      browsiInit(config);
      config.setConfig(conf);
      setData(predictions);

      // set slot
      const slots = createSlots();
      window.googletag.pubads().setSlots(slots);

      function afterBidHook() {
        slots.map(s => {
          targeting = [];
          s.getTargeting().map(value => {
            targeting.push(Object.keys(value).toString());
          });
        });
      }
      setTargetsAfterRequestBids(afterBidHook, adUnits1, true);

      setTimeout(() => {
        expect(targeting.indexOf('bv')).to.be.greaterThan(-1);
      }, 200);
    });

    it('check module using requestBidsHook', function () {
      let adUnits1 = [getAdUnitMock('browsiAd_1')];
      let targeting = [];
      let dataReceived = null;

      // set slot
      const slotsB = createSlots();
      window.googletag.pubads().setSlots(slotsB);

      function afterBidHook(data) {
        dataReceived = data;
        slotsB.map(s => {
          targeting = [];
          s.getTargeting().map(value => {
            targeting.push(Object.keys(value).toString());
          });
        });
      }
      requestBidsHook(afterBidHook, {adUnits: adUnits1});
      setTimeout(() => {
        expect(targeting.indexOf('bv')).to.be.greaterThan(-1);
        dataReceived.adUnits.forEach(unit => {
          unit.bids.forEach(bid => {
            expect(bid.realTimeData).to.have.property('bv');
          });
        });
      }, 200);
    });

    it('check object deep merge', function () {
      const obj1 = {
        id1: {
          key: 'value',
          key2: 'value2'
        },
        id2: {
          k: 'v'
        }
      };
      const obj2 = {
        id1: {
          key3: 'value3'
        }
      };
      const obj3 = {
        id3: {
          key: 'value'
        }
      };
      const expected = {
        id1: {
          key: 'value',
          key2: 'value2',
          key3: 'value3'
        },
        id2: {
          k: 'v'
        },
        id3: {
          key: 'value'
        }
      };

      const merged = deepMerge([obj1, obj2, obj3]);
      assert.deepEqual(expected, merged);
    });

    it('check browsi sub module', function () {
      const script = addBrowsiTag('scriptUrl.com');
      expect(script.getAttribute('data-sitekey')).to.equal('testKey');
      expect(script.getAttribute('data-pubkey')).to.equal('testPub');
      expect(script.async).to.equal(true);

      const slots = createSlots();
      const test1 = isIdMatchingAdUnit('browsiAd_1', slots[0], ['/57778053/Browsi_Demo_300x250']); // true
      const test2 = isIdMatchingAdUnit('browsiAd_1', slots[0], ['/57778053/Browsi_Demo_300x250', '/57778053/Browsi']); // true
      const test3 = isIdMatchingAdUnit('browsiAd_1', slots[0], ['/57778053/Browsi_Demo_Low']); // false
      const test4 = isIdMatchingAdUnit('browsiAd_1', slots[0], []); // true

      expect(test1).to.equal(true);
      expect(test2).to.equal(true);
      expect(test3).to.equal(false);
      expect(test4).to.equal(true);
    })
  });

  describe('Real time module with Audigent provider', function() {
    afterEach(function () {
      $$PREBID_GLOBAL$$.requestBids.removeAll();
    });

    let targeting = [];
    init(config);
    audigentInit(config);
    config.setConfig(conf);
    setAudigentData(audigentSegments);

    it('check module using requestBidsHook', function () {
      let adUnits1 = [getAdUnitMock('audigentAd_1')];
      let targeting = [];
      let dataReceived = null;

      // set slot
      const slotsB = createSlots();
      window.googletag.pubads().setSlots(slotsB);

      function afterBidHook(data) {
        dataReceived = data;
        slotsB.map(s => {
          targeting = [];
          s.getTargeting().map(value => {
            targeting.push(Object.keys(value).toString());
          });
        });
      }

      requestBidsHook(afterBidHook, {adUnits: adUnits1});
      setTimeout(() => {
        dataReceived.adUnits.forEach(unit => {
          unit.bids.forEach(bid => {
            expect(bid.realTimeData).to.have.property('audigent_segments');
            expect(bid.realTimeData.audigent_segments).to.deep.equal(audigentSegments.audigent_segments);
          });
        });
      }, 200);
    });
  });
});
<commit_msg>update audigent tests to fix larger test suite issue (#4952)<commit_after>import {
  init,
  requestBidsHook,
  setTargetsAfterRequestBids,
  deepMerge
} from 'modules/rtdModule/index.js';
import {
  init as browsiInit,
  addBrowsiTag,
  isIdMatchingAdUnit,
  setData
} from 'modules/browsiRtdProvider.js';
import {
  init as audigentInit,
  setData as setAudigentData
} from 'modules/audigentRtdProvider.js';
import { config } from 'src/config.js';
import { makeSlot } from '../integration/faker/googletag.js';

let expect = require('chai').expect;

describe('Real time module', function () {
  const conf = {
    'realTimeData': {
      'auctionDelay': 250,
      dataProviders: [{
        'name': 'browsi',
        'params': {
          'url': 'testUrl.com',
          'siteKey': 'testKey',
          'pubKey': 'testPub',
          'keyName': 'bv'
        }
      }, {
        'name': 'audigent'
      }]
    }
  };

  const predictions = {
    p: {
      'browsiAd_2': {
        'w': [
          '/57778053/Browsi_Demo_Low',
          '/57778053/Browsi_Demo_300x250'
        ],
        'p': 0.07
      },
      'browsiAd_1': {
        'w': [],
        'p': 0.06
      },
      'browsiAd_3': {
        'w': [],
        'p': 0.53
      },
      'browsiAd_4': {
        'w': [
          '/57778053/Browsi_Demo'
        ],
        'p': 0.85
      }
    }
  };

  const audigentSegments = {
    audigent_segments: { 'a': 1, 'b': 2 }
  }

  function getAdUnitMock(code = 'adUnit-code') {
    return {
      code,
      mediaTypes: { banner: {}, native: {} },
      sizes: [[300, 200], [300, 600]],
      bids: [{ bidder: 'sampleBidder', params: { placementId: 'banner-only-bidder' } }]
    };
  }

  function createSlots() {
    const slot1 = makeSlot({ code: '/57778053/Browsi_Demo_300x250', divId: 'browsiAd_1' });
    return [slot1];
  }

  describe('Real time module with browsi provider', function () {
    afterEach(function () {
      $$PREBID_GLOBAL$$.requestBids.removeAll();
    });

    after(function () {
      config.resetConfig();
    });

    it('check module using bidsBackCallback', function () {
      let adUnits1 = [getAdUnitMock('browsiAd_1')];
      let targeting = [];
      init(config);
      browsiInit(config);
      config.setConfig(conf);
      setData(predictions);

      // set slot
      const slots = createSlots();
      window.googletag.pubads().setSlots(slots);

      function afterBidHook() {
        slots.map(s => {
          targeting = [];
          s.getTargeting().map(value => {
            targeting.push(Object.keys(value).toString());
          });
        });

        expect(targeting.indexOf('bv')).to.be.greaterThan(-1);
      }
      setTargetsAfterRequestBids(afterBidHook, adUnits1, true);
    });

    it('check module using requestBidsHook', function () {
      let adUnits1 = [getAdUnitMock('browsiAd_1')];
      let targeting = [];
      let dataReceived = null;

      // set slot
      const slotsB = createSlots();
      window.googletag.pubads().setSlots(slotsB);

      function afterBidHook(data) {
        dataReceived = data;
        slotsB.map(s => {
          targeting = [];
          s.getTargeting().map(value => {
            targeting.push(Object.keys(value).toString());
          });
        });

        expect(targeting.indexOf('bv')).to.be.greaterThan(-1);
        dataReceived.adUnits.forEach(unit => {
          unit.bids.forEach(bid => {
            expect(bid.realTimeData).to.have.property('bv');
          });
        });
      }
      requestBidsHook(afterBidHook, { adUnits: adUnits1 });
    });

    it('check object deep merge', function () {
      const obj1 = {
        id1: {
          key: 'value',
          key2: 'value2'
        },
        id2: {
          k: 'v'
        }
      };
      const obj2 = {
        id1: {
          key3: 'value3'
        }
      };
      const obj3 = {
        id3: {
          key: 'value'
        }
      };
      const expected = {
        id1: {
          key: 'value',
          key2: 'value2',
          key3: 'value3'
        },
        id2: {
          k: 'v'
        },
        id3: {
          key: 'value'
        }
      };

      const merged = deepMerge([obj1, obj2, obj3]);
      assert.deepEqual(expected, merged);
    });

    it('check browsi sub module', function () {
      const script = addBrowsiTag('scriptUrl.com');
      expect(script.getAttribute('data-sitekey')).to.equal('testKey');
      expect(script.getAttribute('data-pubkey')).to.equal('testPub');
      expect(script.async).to.equal(true);

      const slots = createSlots();
      const test1 = isIdMatchingAdUnit('browsiAd_1', slots[0], ['/57778053/Browsi_Demo_300x250']); // true
      const test2 = isIdMatchingAdUnit('browsiAd_1', slots[0], ['/57778053/Browsi_Demo_300x250', '/57778053/Browsi']); // true
      const test3 = isIdMatchingAdUnit('browsiAd_1', slots[0], ['/57778053/Browsi_Demo_Low']); // false
      const test4 = isIdMatchingAdUnit('browsiAd_1', slots[0], []); // true

      expect(test1).to.equal(true);
      expect(test2).to.equal(true);
      expect(test3).to.equal(false);
      expect(test4).to.equal(true);
    })
  });

  describe('Real time module with Audigent provider', function () {
    before(function () {
      init(config);
      audigentInit(config);
      config.setConfig(conf);
      setAudigentData(audigentSegments);
    });

    afterEach(function () {
      $$PREBID_GLOBAL$$.requestBids.removeAll();
      config.resetConfig();
    });

    it('check module using requestBidsHook', function () {
      let adUnits1 = [getAdUnitMock('audigentAd_1')];
      let targeting = [];
      let dataReceived = null;

      // set slot
      const slotsB = createSlots();
      window.googletag.pubads().setSlots(slotsB);

      function afterBidHook(data) {
        dataReceived = data;
        slotsB.map(s => {
          targeting = [];
          s.getTargeting().map(value => {
            targeting.push(Object.keys(value).toString());
          });
        });

        dataReceived.adUnits.forEach(unit => {
          unit.bids.forEach(bid => {
            expect(bid.realTimeData).to.have.property('audigent_segments');
            expect(bid.realTimeData.audigent_segments).to.deep.equal(audigentSegments.audigent_segments);
          });
        });
      }

      requestBidsHook(afterBidHook, { adUnits: adUnits1 });
    });
  });
});
<|endoftext|>


<commit_before>function opt() {
    for (let i = 0; i < 100; i++) {
        let j = i - 2;
        switch (i) {
            case 2:
            case 4:
            case 6:
            case 8:
            case 10:
            case 12:
            case 14:
            case 16:
            case 18:
            case 20:
            case 22:
            case 24:
            case 26:
            case 28:
            case 30:
            case 32:
            case 34:
            case 36:
            case 38:
                break;
        }

        if (i == 90) {
            i = 'x';
        }
    }
}

function main() {
    for (let i = 0; i < 100; i++) {
        opt();
    }
}

main();

WScript.Echo('pass');
<commit_msg>Add copyright notice to test case<commit_after>//-------------------------------------------------------------------------------------------------------
// Copyright (C) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
//-------------------------------------------------------------------------------------------------------

function opt() {
    for (let i = 0; i < 100; i++) {
        let j = i - 2;
        switch (i) {
            case 2:
            case 4:
            case 6:
            case 8:
            case 10:
            case 12:
            case 14:
            case 16:
            case 18:
            case 20:
            case 22:
            case 24:
            case 26:
            case 28:
            case 30:
            case 32:
            case 34:
            case 36:
            case 38:
                break;
        }

        if (i == 90) {
            i = 'x';
        }
    }
}

function main() {
    for (let i = 0; i < 100; i++) {
        opt();
    }
}

main();

WScript.Echo('pass');
<|endoftext|>