<commit_before>
'use strict';

const os = require('os');
const https = require('https');
const proc = require('child_process');
const StateController = require('../../lib/state-controller');
const OSXSupport = require('../../lib/support/osx');

const {
  fakeProcesses, fakeKiteInstallPaths, fakeResponse,
  withKiteInstalled, withKiteRunning, withKiteNotRunning,
  withFakeServer, withKiteEnterpriseInstalled, withBothKiteInstalled,
  withKiteEnterpriseRunning, withKiteEnterpriseNotRunning,
} = require('../spec-helpers.js');

describe('StateController - OSX Support', () => {
  beforeEach(() => {
    spyOn(os, 'platform').andReturn('darwin');
    spyOn(os, 'release').andReturn('14.0.0');
  });

  fakeKiteInstallPaths();

  describe('.isKiteSupported()', () => {
    it('returns a resolved promise', () => {
      waitsForPromise(() => StateController.isKiteSupported());
    });

    describe('when the os release is below 10.10', () => {
      beforeEach(() => {
        os.release.andReturn('13.0.0');
      });

      it('returns a rejected promise', () => {
        waitsForPromise({shouldReject: true}, () => StateController.isKiteSupported());
      });
    });
  });

  describe('.isKiteInstalled()', () => {
    withKiteInstalled(() => {
      it('returns a resolved promise', () => {
        waitsForPromise(() => StateController.isKiteInstalled());
      });
    });

    describe('when kite is not installed', () => {
      it('returns a rejected promise', () => {
        waitsForPromise({
          shouldReject: true,
        }, () => StateController.isKiteInstalled());
      });
    });

    withKiteEnterpriseInstalled(() => {
      it('returns a rejected promise', () => {
        waitsForPromise({shouldReject: true}, () =>
          StateController.isKiteInstalled());
      });
    });
  });

  describe('.isKiteEnterpriseInstalled()', () => {
    describe('when kite enterprise is not installed', () => {
      it('returns a rejected promise', () => {
        waitsForPromise({shouldReject: true}, () =>
          StateController.isKiteEnterpriseInstalled());
      });
    });

    withKiteInstalled(() => {
      it('returns a rejected promise', () => {
        waitsForPromise({shouldReject: true}, () =>
          StateController.isKiteEnterpriseInstalled());
      });
    });

    withKiteEnterpriseInstalled(() => {
      it('returns a resolved promise', () => {
        waitsForPromise(() => StateController.isKiteEnterpriseInstalled());
      });
    });
  });

  describe('.hasBothKiteInstalled()', () => {
    describe('when no kite is installed', () => {
      it('returns a rejected promise', () => {
        waitsForPromise({shouldReject: true}, () =>
        StateController.hasBothKiteInstalled());
      });
    });

    describe('when kite enterprise is not installed', () => {
      withKiteInstalled(() => {
        it('returns a rejected promise', () => {
          waitsForPromise({shouldReject: true}, () =>
          StateController.hasBothKiteInstalled());
        });
      });
    });

    describe('when kite is not installed', () => {
      withKiteEnterpriseInstalled(() => {
        it('returns a rejected promise', () => {
          waitsForPromise({shouldReject: true}, () =>
          StateController.hasBothKiteInstalled());
        });
      });
    });

    withBothKiteInstalled(() => {
      it('returns a resolved promise', () => {
        waitsForPromise(() => StateController.hasBothKiteInstalled());
      });
    });
  });

  describe('.installKite()', () => {
    describe('when every command succeeds', () => {
      beforeEach(() => {
        fakeProcesses({
          hdiutil: () => 0,
          cp: () => 0,
          rm: () => 0,
          mdfind: (ps, args) => {
            const [, key] = args[0].split(/\s=\s/);
            key === '"com.kite.Kite"'
              ? ps.stdout('/Applications/Kite.app')
              : ps.stdout('');
            return 0;
          },
        });
      });

      it('returns a resolved promise', () => {
        const options = {
          onInstallStart: jasmine.createSpy(),
          onMount: jasmine.createSpy(),
          onCopy: jasmine.createSpy(),
          onUnmount: jasmine.createSpy(),
          onRemove: jasmine.createSpy(),
        };

        waitsForPromise(() => StateController.installKite(options));
        runs(() => {
          expect(proc.spawn).toHaveBeenCalledWith('hdiutil', [
            'attach', '-nobrowse',
            OSXSupport.KITE_DMG_PATH,
          ]);
          expect(proc.spawn).toHaveBeenCalledWith('cp', [
            '-r',
            OSXSupport.KITE_APP_PATH.mounted,
            OSXSupport.APPS_PATH,
          ]);
          expect(proc.spawn).toHaveBeenCalledWith('hdiutil', [
            'detach',
            OSXSupport.KITE_VOLUME_PATH,
          ]);
          expect(proc.spawn).toHaveBeenCalledWith('rm', [
            OSXSupport.KITE_DMG_PATH,
          ]);
          expect(proc.spawn).toHaveBeenCalledWith('mdfind', [
            'kMDItemCFBundleIdentifier = "com.kite.Kite"',
          ]);

          expect(options.onInstallStart).toHaveBeenCalled();
          expect(options.onMount).toHaveBeenCalled();
          expect(options.onCopy).toHaveBeenCalled();
          expect(options.onUnmount).toHaveBeenCalled();
          expect(options.onRemove).toHaveBeenCalled();
        });
      });
    });

    describe('when mounting the archive fails', () => {
      beforeEach(() => {
        fakeProcesses({
          hdiutil: () => 1,
          cp: () => 0,
          rm: () => 0,
        });
      });

      it('returns a rejected promise', () => {
        waitsForPromise({shouldReject: true}, () => StateController.installKite());
      });
    });

    describe('when copying the archive content fails', () => {
      beforeEach(() => {
        fakeProcesses({
          hdiutil: () => 0,
          cp: () => 1,
          rm: () => 0,
        });
      });

      it('returns a rejected promise', () => {
        waitsForPromise({shouldReject: true}, () => StateController.installKite());
      });
    });

    describe('when unmounting the archive fails', () => {
      beforeEach(() => {
        fakeProcesses({
          hdiutil: (ps, [command]) => command === 'attach' ? 0 : 1,
          cp: () => 0,
          rm: () => 0,
        });
      });

      it('returns a rejected promise', () => {
        waitsForPromise({shouldReject: true}, () => StateController.installKite());
      });
    });

    describe('when removing the downloaded archive fails', () => {
      beforeEach(() => {
        fakeProcesses({
          hdiutil: () => 0,
          cp: () => 0,
          rm: () => 1,
        });
      });

      it('returns a rejected promise', () => {
        waitsForPromise({shouldReject: true}, () => StateController.installKite());
      });
    });
  });

  describe('.downloadKite()', () => {
    withFakeServer([
      [
        o => /^http:\/\/kite\.com/.test(o),
        o => fakeResponse(303, '', {headers: {location: 'https://download.kite.com'}}),
      ], [
        o => /^https:\/\/download\.kite\.com/.test(o),
        o => fakeResponse(200, 'foo'),
      ],
    ], () => {
      describe('when the download succeeds', () => {
        beforeEach(() => {
          fakeProcesses({
            hdiutil: () => 0,
            cp: () => 0,
            rm: () => 0,
            mdfind: (ps) => {
              ps.stdout('');
              return 0;
            },
          });
        });

        describe('with the install option', () => {
          it('returns a promise resolved after the install', () => {
            const options = {
              install: true,
              onDownload: jasmine.createSpy(),
              onInstallStart: jasmine.createSpy(),
              onMount: jasmine.createSpy(),
              onCopy: jasmine.createSpy(),
              onUnmount: jasmine.createSpy(),
              onRemove: () => {
                fakeProcesses({
                  mdfind: (ps, args) => {
                    const [, key] = args[0].split(/\s=\s/);
                    key === '"com.kite.Kite"'
                      ? ps.stdout('/Applications/Kite.app')
                      : ps.stdout('');
                    return 0;
                  },
                });
              },
            };
            spyOn(options, 'onRemove').and.callFake((ps, args) => {
              const [, key] = args[0].split(/\s=\s/);
              key === '"com.kite.Kite"'
                ? ps.stdout('/Applications/Kite.app')
                : ps.stdout('');
              return 0;
            });
            const url = 'http://kite.com/download';

            waitsForPromise(() => StateController.downloadKite(url, options));
            runs(() => {
              expect(https.request).toHaveBeenCalledWith('http://kite.com/download');
              expect(proc.spawn).toHaveBeenCalledWith('hdiutil', [
                'attach', '-nobrowse',
                OSXSupport.KITE_DMG_PATH,
              ]);
              expect(proc.spawn).toHaveBeenCalledWith('cp', [
                '-r',
                OSXSupport.KITE_APP_PATH.mounted,
                OSXSupport.APPS_PATH,
              ]);
              expect(proc.spawn).toHaveBeenCalledWith('hdiutil', [
                'detach',
                OSXSupport.KITE_VOLUME_PATH,
              ]);
              expect(proc.spawn).toHaveBeenCalledWith('rm', [
                OSXSupport.KITE_DMG_PATH,
              ]);

              expect(options.onDownload).toHaveBeenCalled();
              expect(options.onInstallStart).toHaveBeenCalled();
              expect(options.onMount).toHaveBeenCalled();
              expect(options.onCopy).toHaveBeenCalled();
              expect(options.onUnmount).toHaveBeenCalled();
              expect(options.onRemove).toHaveBeenCalled();
            });
          });
        });
      });
    });
  });

  describe('.isKiteRunning()', () => {
    describe('when kite is not installed', () => {
      it('returns a rejected promise', () => {
        waitsForPromise({shouldReject: true}, () => StateController.isKiteRunning());
      });
    });

    withKiteInstalled(() => {
      describe('but not running', () => {
        beforeEach(() => {
          fakeProcesses({
            '/bin/ps': (ps) => {
              ps.stdout('');
              return 0;
            },
          });
        });

        it('returns a rejected promise', () => {
          waitsForPromise({shouldReject: true}, () => StateController.isKiteRunning());
        });
      });

      withKiteRunning(() => {
        it('returns a resolved promise', () => {
          waitsForPromise(() => StateController.isKiteRunning());
        });
      });
    });
  });

  describe('.canRunKite()', () => {
    describe('when kite is not installed', () => {
      it('returns a rejected function', () => {
        waitsForPromise({shouldReject: true}, () => StateController.canRunKite());
      });
    });

    withKiteNotRunning(() => {
      it('returns a resolved promise', () => {
        waitsForPromise(() => StateController.canRunKite());
      });
    });

    withKiteRunning(() => {
      it('returns a rejected function', () => {
        waitsForPromise({shouldReject: true}, () => StateController.canRunKite());
      });
    });
  });

  describe('.runKite()', () => {
    describe('when kite is not installed', () => {
      it('returns a rejected function', () => {
        waitsForPromise({shouldReject: true}, () => StateController.runKite());
      });
    });

    withKiteRunning(() => {
      it('returns a resolved function', () => {
        waitsForPromise(() => StateController.runKite());
      });
    });

    withKiteNotRunning(() => {
      it('returns a resolved promise', () => {
        waitsForPromise(() => StateController.runKite());
        runs(() => {
          expect(proc.spawn).toHaveBeenCalledWith('defaults', [
            'write', 'com.kite.Kite', 'shouldReopenSidebar', '0',
          ]);

          expect(proc.spawn).toHaveBeenCalledWith('open', [
            '-a', OSXSupport.installPath,
          ]);
        });
      });
    });
  });

  describe('.isKiteEnterpriseRunning()', () => {
    describe('when kite is not installed', () => {
      it('returns a rejected promise', () => {
        waitsForPromise({shouldReject: true}, () => StateController.isKiteEnterpriseRunning());
      });
    });

    withKiteEnterpriseInstalled(() => {
      describe('but not running', () => {
        beforeEach(() => {
          fakeProcesses({
            '/bin/ps': (ps) => {
              ps.stdout('');
              return 0;
            },
          });
        });

        it('returns a rejected promise', () => {
          waitsForPromise({shouldReject: true}, () => StateController.isKiteEnterpriseRunning());
        });
      });

      withKiteEnterpriseRunning(() => {
        it('returns a resolved promise', () => {
          waitsForPromise(() => StateController.isKiteEnterpriseRunning());
        });
      });
    });
  });

  describe('.canRunKiteEnterprise()', () => {
    describe('when kite is not installed', () => {
      it('returns a rejected function', () => {
        waitsForPromise({shouldReject: true}, () => StateController.canRunKiteEnterprise());
      });
    });

    withKiteEnterpriseNotRunning(() => {
      it('returns a resolved promise', () => {
        waitsForPromise(() => StateController.canRunKiteEnterprise());
      });
    });

    withKiteEnterpriseRunning(() => {
      it('returns a rejected function', () => {
        waitsForPromise({shouldReject: true}, () => StateController.canRunKiteEnterprise());
      });
    });
  });

  describe('.runKiteEnterprise()', () => {
    describe('when kite is not installed', () => {
      it('returns a rejected function', () => {
        waitsForPromise({shouldReject: true}, () => StateController.runKiteEnterprise());
      });
    });

    withKiteEnterpriseRunning(() => {
      it('returns a resolved function', () => {
        waitsForPromise(() => StateController.runKiteEnterprise());
      });
    });

    withKiteEnterpriseNotRunning(() => {
      it('returns a resolved promise', () => {
        waitsForPromise(() => StateController.runKiteEnterprise());
        runs(() => {
          expect(proc.spawn).toHaveBeenCalledWith('defaults', [
            'write', 'enterprise.kite.Kite', 'shouldReopenSidebar', '0',
          ]);

          expect(proc.spawn).toHaveBeenCalledWith('open', [
            '-a', OSXSupport.enterpriseInstallPath,
          ]);
        });
      });
    });
  });
});
<commit_msg>revert<commit_after>
'use strict';

const os = require('os');
const https = require('https');
const proc = require('child_process');
const StateController = require('../../lib/state-controller');
const OSXSupport = require('../../lib/support/osx');

const {
  fakeProcesses, fakeKiteInstallPaths, fakeResponse,
  withKiteInstalled, withKiteRunning, withKiteNotRunning,
  withFakeServer, withKiteEnterpriseInstalled, withBothKiteInstalled,
  withKiteEnterpriseRunning, withKiteEnterpriseNotRunning,
} = require('../spec-helpers.js');

describe('StateController - OSX Support', () => {
  beforeEach(() => {
    spyOn(os, 'platform').andReturn('darwin');
    spyOn(os, 'release').andReturn('14.0.0');
  });

  fakeKiteInstallPaths();

  describe('.isKiteSupported()', () => {
    it('returns a resolved promise', () => {
      waitsForPromise(() => StateController.isKiteSupported());
    });

    describe('when the os release is below 10.10', () => {
      beforeEach(() => {
        os.release.andReturn('13.0.0');
      });

      it('returns a rejected promise', () => {
        waitsForPromise({shouldReject: true}, () => StateController.isKiteSupported());
      });
    });
  });

  describe('.isKiteInstalled()', () => {
    withKiteInstalled(() => {
      it('returns a resolved promise', () => {
        waitsForPromise(() => StateController.isKiteInstalled());
      });
    });

    describe('when kite is not installed', () => {
      it('returns a rejected promise', () => {
        waitsForPromise({
          shouldReject: true,
        }, () => StateController.isKiteInstalled());
      });
    });

    withKiteEnterpriseInstalled(() => {
      it('returns a rejected promise', () => {
        waitsForPromise({shouldReject: true}, () =>
          StateController.isKiteInstalled());
      });
    });
  });

  describe('.isKiteEnterpriseInstalled()', () => {
    describe('when kite enterprise is not installed', () => {
      it('returns a rejected promise', () => {
        waitsForPromise({shouldReject: true}, () =>
          StateController.isKiteEnterpriseInstalled());
      });
    });

    withKiteInstalled(() => {
      it('returns a rejected promise', () => {
        waitsForPromise({shouldReject: true}, () =>
          StateController.isKiteEnterpriseInstalled());
      });
    });

    withKiteEnterpriseInstalled(() => {
      it('returns a resolved promise', () => {
        waitsForPromise(() => StateController.isKiteEnterpriseInstalled());
      });
    });
  });

  describe('.hasBothKiteInstalled()', () => {
    describe('when no kite is installed', () => {
      it('returns a rejected promise', () => {
        waitsForPromise({shouldReject: true}, () =>
        StateController.hasBothKiteInstalled());
      });
    });

    describe('when kite enterprise is not installed', () => {
      withKiteInstalled(() => {
        it('returns a rejected promise', () => {
          waitsForPromise({shouldReject: true}, () =>
          StateController.hasBothKiteInstalled());
        });
      });
    });

    describe('when kite is not installed', () => {
      withKiteEnterpriseInstalled(() => {
        it('returns a rejected promise', () => {
          waitsForPromise({shouldReject: true}, () =>
          StateController.hasBothKiteInstalled());
        });
      });
    });

    withBothKiteInstalled(() => {
      it('returns a resolved promise', () => {
        waitsForPromise(() => StateController.hasBothKiteInstalled());
      });
    });
  });

  describe('.installKite()', () => {
    describe('when every command succeeds', () => {
      beforeEach(() => {
        fakeProcesses({
          hdiutil: () => 0,
          cp: () => 0,
          rm: () => 0,
          mdfind: (ps, args) => {
            const [, key] = args[0].split(/\s=\s/);
            key === '"com.kite.Kite"'
              ? ps.stdout('/Applications/Kite.app')
              : ps.stdout('');
            return 0;
          },
        });
      });

      it('returns a resolved promise', () => {
        const options = {
          onInstallStart: jasmine.createSpy(),
          onMount: jasmine.createSpy(),
          onCopy: jasmine.createSpy(),
          onUnmount: jasmine.createSpy(),
          onRemove: jasmine.createSpy(),
        };

        waitsForPromise(() => StateController.installKite(options));
        runs(() => {
          expect(proc.spawn).toHaveBeenCalledWith('hdiutil', [
            'attach', '-nobrowse',
            OSXSupport.KITE_DMG_PATH,
          ]);
          expect(proc.spawn).toHaveBeenCalledWith('cp', [
            '-r',
            OSXSupport.KITE_APP_PATH.mounted,
            OSXSupport.APPS_PATH,
          ]);
          expect(proc.spawn).toHaveBeenCalledWith('hdiutil', [
            'detach',
            OSXSupport.KITE_VOLUME_PATH,
          ]);
          expect(proc.spawn).toHaveBeenCalledWith('rm', [
            OSXSupport.KITE_DMG_PATH,
          ]);
          expect(proc.spawn).toHaveBeenCalledWith('mdfind', [
            'kMDItemCFBundleIdentifier = "com.kite.Kite"',
          ]);

          expect(options.onInstallStart).toHaveBeenCalled();
          expect(options.onMount).toHaveBeenCalled();
          expect(options.onCopy).toHaveBeenCalled();
          expect(options.onUnmount).toHaveBeenCalled();
          expect(options.onRemove).toHaveBeenCalled();
        });
      });
    });

    describe('when mounting the archive fails', () => {
      beforeEach(() => {
        fakeProcesses({
          hdiutil: () => 1,
          cp: () => 0,
          rm: () => 0,
        });
      });

      it('returns a rejected promise', () => {
        waitsForPromise({shouldReject: true}, () => StateController.installKite());
      });
    });

    describe('when copying the archive content fails', () => {
      beforeEach(() => {
        fakeProcesses({
          hdiutil: () => 0,
          cp: () => 1,
          rm: () => 0,
        });
      });

      it('returns a rejected promise', () => {
        waitsForPromise({shouldReject: true}, () => StateController.installKite());
      });
    });

    describe('when unmounting the archive fails', () => {
      beforeEach(() => {
        fakeProcesses({
          hdiutil: (ps, [command]) => command === 'attach' ? 0 : 1,
          cp: () => 0,
          rm: () => 0,
        });
      });

      it('returns a rejected promise', () => {
        waitsForPromise({shouldReject: true}, () => StateController.installKite());
      });
    });

    describe('when removing the downloaded archive fails', () => {
      beforeEach(() => {
        fakeProcesses({
          hdiutil: () => 0,
          cp: () => 0,
          rm: () => 1,
        });
      });

      it('returns a rejected promise', () => {
        waitsForPromise({shouldReject: true}, () => StateController.installKite());
      });
    });
  });

  describe('.downloadKite()', () => {
    withFakeServer([
      [
        o => /^http:\/\/kite\.com/.test(o),
        o => fakeResponse(303, '', {headers: {location: 'https://download.kite.com'}}),
      ], [
        o => /^https:\/\/download\.kite\.com/.test(o),
        o => fakeResponse(200, 'foo'),
      ],
    ], () => {
      describe('when the download succeeds', () => {
        beforeEach(() => {
          fakeProcesses({
            hdiutil: () => 0,
            cp: () => 0,
            rm: () => 0,
            mdfind: (ps) => {
              ps.stdout('');
              return 0;
            },
          });
        });

        describe('with the install option', () => {
          it('returns a promise resolved after the install', () => {
            const options = {
              install: true,
              onDownload: jasmine.createSpy(),
              onInstallStart: jasmine.createSpy(),
              onMount: jasmine.createSpy(),
              onCopy: jasmine.createSpy(),
              onUnmount: jasmine.createSpy(),
              onRemove: () => {
                fakeProcesses({
                  mdfind: (ps, args) => {
                    const [, key] = args[0].split(/\s=\s/);
                    key === '"com.kite.Kite"'
                      ? ps.stdout('/Applications/Kite.app')
                      : ps.stdout('');
                    return 0;
                  },
                });
              },
            };
           const url = 'http://kite.com/download';

            waitsForPromise(() => StateController.downloadKite(url, options));
            runs(() => {
              expect(https.request).toHaveBeenCalledWith('http://kite.com/download');
              expect(proc.spawn).toHaveBeenCalledWith('hdiutil', [
                'attach', '-nobrowse',
                OSXSupport.KITE_DMG_PATH,
              ]);
              expect(proc.spawn).toHaveBeenCalledWith('cp', [
                '-r',
                OSXSupport.KITE_APP_PATH.mounted,
                OSXSupport.APPS_PATH,
              ]);
              expect(proc.spawn).toHaveBeenCalledWith('hdiutil', [
                'detach',
                OSXSupport.KITE_VOLUME_PATH,
              ]);
              expect(proc.spawn).toHaveBeenCalledWith('rm', [
                OSXSupport.KITE_DMG_PATH,
              ]);

              expect(options.onDownload).toHaveBeenCalled();
              expect(options.onInstallStart).toHaveBeenCalled();
              expect(options.onMount).toHaveBeenCalled();
              expect(options.onCopy).toHaveBeenCalled();
              expect(options.onUnmount).toHaveBeenCalled();
            });
          });
        });
      });
    });
  });

  describe('.isKiteRunning()', () => {
    describe('when kite is not installed', () => {
      it('returns a rejected promise', () => {
        waitsForPromise({shouldReject: true}, () => StateController.isKiteRunning());
      });
    });

    withKiteInstalled(() => {
      describe('but not running', () => {
        beforeEach(() => {
          fakeProcesses({
            '/bin/ps': (ps) => {
              ps.stdout('');
              return 0;
            },
          });
        });

        it('returns a rejected promise', () => {
          waitsForPromise({shouldReject: true}, () => StateController.isKiteRunning());
        });
      });

      withKiteRunning(() => {
        it('returns a resolved promise', () => {
          waitsForPromise(() => StateController.isKiteRunning());
        });
      });
    });
  });

  describe('.canRunKite()', () => {
    describe('when kite is not installed', () => {
      it('returns a rejected function', () => {
        waitsForPromise({shouldReject: true}, () => StateController.canRunKite());
      });
    });

    withKiteNotRunning(() => {
      it('returns a resolved promise', () => {
        waitsForPromise(() => StateController.canRunKite());
      });
    });

    withKiteRunning(() => {
      it('returns a rejected function', () => {
        waitsForPromise({shouldReject: true}, () => StateController.canRunKite());
      });
    });
  });

  describe('.runKite()', () => {
    describe('when kite is not installed', () => {
      it('returns a rejected function', () => {
        waitsForPromise({shouldReject: true}, () => StateController.runKite());
      });
    });

    withKiteRunning(() => {
      it('returns a resolved function', () => {
        waitsForPromise(() => StateController.runKite());
      });
    });

    withKiteNotRunning(() => {
      it('returns a resolved promise', () => {
        waitsForPromise(() => StateController.runKite());
        runs(() => {
          expect(proc.spawn).toHaveBeenCalledWith('defaults', [
            'write', 'com.kite.Kite', 'shouldReopenSidebar', '0',
          ]);

          expect(proc.spawn).toHaveBeenCalledWith('open', [
            '-a', OSXSupport.installPath,
          ]);
        });
      });
    });
  });

  describe('.isKiteEnterpriseRunning()', () => {
    describe('when kite is not installed', () => {
      it('returns a rejected promise', () => {
        waitsForPromise({shouldReject: true}, () => StateController.isKiteEnterpriseRunning());
      });
    });

    withKiteEnterpriseInstalled(() => {
      describe('but not running', () => {
        beforeEach(() => {
          fakeProcesses({
            '/bin/ps': (ps) => {
              ps.stdout('');
              return 0;
            },
          });
        });

        it('returns a rejected promise', () => {
          waitsForPromise({shouldReject: true}, () => StateController.isKiteEnterpriseRunning());
        });
      });

      withKiteEnterpriseRunning(() => {
        it('returns a resolved promise', () => {
          waitsForPromise(() => StateController.isKiteEnterpriseRunning());
        });
      });
    });
  });

  describe('.canRunKiteEnterprise()', () => {
    describe('when kite is not installed', () => {
      it('returns a rejected function', () => {
        waitsForPromise({shouldReject: true}, () => StateController.canRunKiteEnterprise());
      });
    });

    withKiteEnterpriseNotRunning(() => {
      it('returns a resolved promise', () => {
        waitsForPromise(() => StateController.canRunKiteEnterprise());
      });
    });

    withKiteEnterpriseRunning(() => {
      it('returns a rejected function', () => {
        waitsForPromise({shouldReject: true}, () => StateController.canRunKiteEnterprise());
      });
    });
  });

  describe('.runKiteEnterprise()', () => {
    describe('when kite is not installed', () => {
      it('returns a rejected function', () => {
        waitsForPromise({shouldReject: true}, () => StateController.runKiteEnterprise());
      });
    });

    withKiteEnterpriseRunning(() => {
      it('returns a resolved function', () => {
        waitsForPromise(() => StateController.runKiteEnterprise());
      });
    });

    withKiteEnterpriseNotRunning(() => {
      it('returns a resolved promise', () => {
        waitsForPromise(() => StateController.runKiteEnterprise());
        runs(() => {
          expect(proc.spawn).toHaveBeenCalledWith('defaults', [
            'write', 'enterprise.kite.Kite', 'shouldReopenSidebar', '0',
          ]);

          expect(proc.spawn).toHaveBeenCalledWith('open', [
            '-a', OSXSupport.enterpriseInstallPath,
          ]);
        });
      });
    });
  });
});
<|endoftext|>


<commit_before>define('spec/surfnperfRT_spec', [
  'surfnperf/resource-timing'
], function(
  SurfNPerfRT
) {
  describe('SurfNPerfRT', function() {
    var NOW_TS = 1388595600000, // Wed Jan 01 2014 12:00:00 GMT-0500 (EST)
      NOW_HIGH_RES = 3.1415926;

    beforeEach(function() {
      var name = "a";
      if(!window.performance) {
        window.performance = {
          now: function() {
            return NOW_HIGH_RES;
          },
          getEntriesByName: function(name) {},
          timing: {}
        };
      }
    });

    describe('Singleton Behavior', function() {
      it('is only instantiated once, even if the library is attempted to be instantiated more than once (as good singletons do)', function() {
        var a = SurfNPerfRT,
          b = SurfNPerfRT;
        expect(a).toBe(b);
      });
    });

    describe('#initialize', function() {

      beforeEach(function() {
        SurfNPerfRT.initialize();
      });

      it('sets the Resource Timing API properties appropriately', function() {
        expect(SurfNPerfRT._resourceTiming).not.toBeNull();
      });

    });

    describe('#_inList', function() {
      // Minsu
      describe('whitelist as a key', function() {
        var options = {
          "whitelist": ["A", "B", "C"]
        }
        it('returns true if the given origin is listed in whitelist', function() {
          expect(SurfNPerfRT._inList("A", options)).toEqual(true);
        });
        it('returns false if the given origin is not listed in whitelist', function() {
          expect(SurfNPerfRT._inList("D", options)).toEqual(false);
        });
      });
      describe('blackList as a key', function() {
        var options = {
          "blacklist": ["A", "B", "C"]
        }
        it('returns true if the given origin is not listed in blacklist', function() {
          expect(SurfNPerfRT._inList("D", options)).toEqual(true);
        });
        it('returns false if the given origin is listed in blacklist', function() {
          expect(SurfNPerfRT._inList("A", options)).toEqual(false);
        });
      });
      describe('none specific key', function() {
        options = {}
        it('returns true no matter what if options does not have any key', function() {
          expect(SurfNPerfRT._inList("A", options)).toBe(true);
        });
      });

    });

    describe('#_getURLOrigin', function() {
      describe('when the provided URL has no port', function() {
        it('returns the origin', function() {
          expect(SurfNPerfRT._getURLOrigin("http://johnriv.github.io/Surf-N-Perf/")).toEqual("http://johnriv.github.io");
        });
      });
      describe('when the provided URL has a port', function() {
        it('returns the origin', function() {
          expect(SurfNPerfRT._getURLOrigin("http://johnriv.github.io:3000/Surf-N-Perf/")).toEqual("http://johnriv.github.io:3000");
        });
      });
    });

    describe('#getOrigins', function() {
      // Minsu

    });

    describe('#getResourcesFromOrigin', function() {
      describe('when the browser does not support resource timings', function() {
        it('returns null', function() {
          SurfNPerfRT._resourceTiming = false;
          expect(SurfNPerfRT.getResourcesFromOrigin("http://johnriv.github.io:3000")).toEqual(null);
        });
      });
      describe('when the browser supports resource timings', function() {

      });
    });

    describe('#_name', function() {
      // Minsu
    });

    describe('#getResource', function() {
      // Ros
      describe('when the browser does not support resource timings', function() {
        it('returns null', function() {
          SurfNPerfRT._resourceTiming = false;
          expect(SurfNPerfRT.getResource(name)).toEqual(null);
        });
      });
      describe('when the browser supports resource timings', function() {

      });
    });

    describe('#duration', function() {
      // Minsu
      describe('when the browser does not support resource timings', function() {
        it('returns null', function() {
          SurfNPerfRT._resourceTiming = false;
          expect(SurfNPerfRT.duration(name, "A", "B", {})).toEqual(null);
        });
      });
      describe('when the browser supports resource timings', function() {
        // it('returns the diff between 2 resource timing marks, not rounded if optional 4th param not included', function() {
        //   SurfNPerfRT._resourceTiming = true;
        //   spyOn(window.performance, 'getEntriesByName').andReturn([{
        //     eventA: 480.04,
        //     eventB: 490.05
        //   }]);
        //   expect(SurfNPerfRT.duration(name, "eventA", "eventB")).toEqual(10.01);
        // });
        it('returns false if either eventA or eventB is 0', function() {
          SurfNPerfRT._resourceTiming = true;
          spyOn(window.performance, 'getEntriesByName').andReturn([{
            eventA: 0,
            eventB: 0,
            eventC: 10
          }]);
          expect(SurfNPerfRT.duration(name, "eventA", "eventC")).toEqual(false);
          expect(SurfNPerfRT.duration(name, "eventC", "eventB")).toEqual(false);
        });
        // it('returns the diff between 2 resource timing marks, rounded when optional 4th param decimalPlaces included', function() {
        //   SurfNPerfRT._resourceTiming = true;
        //   spyOn(window.performance, 'getEntriesByName').andReturn([{
        //     eventA: 480.04,
        //     eventB: 490.05
        //   }]);
        //   expect(SurfNPerfRT.duration(name, "eventA", "eventB", {
        //     "decimalPlaces": 1
        //   })).toEqual(10.0);
        //   expect(SurfNPerfRT.duration(name, "eventA", "eventB", {
        //     "decimalPlaces": 2
        //   })).toEqual(10.01);
        // });
      });
    });

    describe('#start', function() {
      // Ros
      describe('when the browser does not support resource timings', function() {
        it('returns null', function() {
          SurfNPerfRT._resourceTiming = false;
          expect(SurfNPerfRT.start(name)).toEqual(null);
        });
      });
      describe('when the browser supports resource timings', function() {
        it("returns the start time of the resource", function() {
          SurfNPerfRT._resourceTiming = true;
          spyOn(window.performance, 'getEntriesByName').andReturn([{
            startTime: 487.05
          }]);
          expect(SurfNPerfRT.start(name, {
            decimalPlaces: 2
          })).toEqual(487.05);
        });
      });
    });

    describe('#end', function() {
      // Minsu
      describe('when the browser does not support resource timings', function() {
        it('returns null', function() {
          SurfNPerfRT._resourceTiming = false;
          expect(SurfNPerfRT.end("http://johnriv.github.io:3000")).toEqual(null);
        });
      });
      describe('when the browser supports resource timings', function() {
        it("returns the end time of the resource response", function() {
          SurfNPerfRT._resourceTiming = true;
          spyOn(window.performance, 'getEntriesByName').andReturn([{
            responseEnd: 487.05
          }]);
          expect(SurfNPerfRT.end(name, {
            decimalPlaces: 2
          })).toEqual(487.05);
        });
      });
    });

    describe('#getFullRequestLoadTime', function() {
      // Ros
      describe('when the browser does not support resource timings', function() {
        it('returns null', function() {
          SurfNPerfRT._resourceTiming = false;
          expect(SurfNPerfRT.getFullRequestLoadTime(name)).toEqual(null);
        });
      });
      describe('when the browser supports resource timings', function() {
        it("returns the duration of the resource load time", function() {
          SurfNPerfRT._resourceTiming = true;
          spyOn(window.performance, 'getEntriesByName').andReturn([{
            duration: 487.05
          }]);
          expect(SurfNPerfRT.getFullRequestLoadTime(name, {
            decimalPlaces: 2
          })).toEqual(487.05);
        });

      });
    });

    describe('#getNetworkTime', function() {
      // Minsu
      describe('when the browser does not support resource timings', function() {
        it('returns null', function() {
          SurfNPerfRT._resourceTiming = false;
          expect(SurfNPerfRT.getNetworkTime("http://johnriv.github.io:3000", {})).toEqual(null);
        });
      });
      describe('when the browser supports resource timings', function() {
        it("returns the network time while loading the resource", function() {
          SurfNPerfRT._resourceTiming = true;
          spyOn(window.performance, 'getEntriesByName').andReturn([{
            fetchStart: 480.05,
            connectEnd: 490.05
          }]);
          expect(SurfNPerfRT.getNetworkTime(name)).toEqual(10.0);
        });
      });
    });

    describe('#getServerTime', function() {
      // Ros
      describe('when the browser does not support resource timings', function() {
        it('returns null', function() {
          SurfNPerfRT._resourceTiming = false;
          expect(SurfNPerfRT.getServerTime(name)).toEqual(null);
        });
      });
      describe('when the browser supports resource timings', function() {
        it("returns the server time while loading the resource", function() {
          SurfNPerfRT._resourceTiming = true;
          spyOn(window.performance, 'getEntriesByName').andReturn([{
            requestStart: 480.05,
            responseEnd: 490.05
          }]);
          expect(SurfNPerfRT.getServerTime(name)).toEqual(10.0);
        });
      });
    });

    describe('#getBlockingTime', function() {
      // Minsu
      describe('when the browser does not support resource timings', function() {
        it('returns null', function() {
          SurfNPerfRT._resourceTiming = false;
          expect(SurfNPerfRT.getBlockingTime("http://johnriv.github.io:3000", {})).toEqual(null);
        });
      });
      describe('when the browser supports resource timings', function() {
        SurfNPerfRT._resourceTiming = true;
      });
    });

  });
});
<commit_msg>duration tests updated<commit_after>define('spec/surfnperfRT_spec', [
  'surfnperf/resource-timing'
], function(
  SurfNPerfRT
) {
  describe('SurfNPerfRT', function() {
    var NOW_TS = 1388595600000, // Wed Jan 01 2014 12:00:00 GMT-0500 (EST)
      NOW_HIGH_RES = 3.1415926;

    beforeEach(function() {
      var name = "a";
      if(!window.performance) {
        window.performance = {
          now: function() {
            return NOW_HIGH_RES;
          },
          getEntriesByName: function(name) {},
          timing: {}
        };
      }
    });

    describe('Singleton Behavior', function() {
      it('is only instantiated once, even if the library is attempted to be instantiated more than once (as good singletons do)', function() {
        var a = SurfNPerfRT,
          b = SurfNPerfRT;
        expect(a).toBe(b);
      });
    });

    describe('#initialize', function() {

      beforeEach(function() {
        SurfNPerfRT.initialize();
      });

      it('sets the Resource Timing API properties appropriately', function() {
        expect(SurfNPerfRT._resourceTiming).not.toBeNull();
      });

    });

    describe('#_inList', function() {
      // Minsu
      describe('whitelist as a key', function() {
        var options = {
          "whitelist": ["A", "B", "C"]
        }
        it('returns true if the given origin is listed in whitelist', function() {
          expect(SurfNPerfRT._inList("A", options)).toEqual(true);
        });
        it('returns false if the given origin is not listed in whitelist', function() {
          expect(SurfNPerfRT._inList("D", options)).toEqual(false);
        });
      });
      describe('blackList as a key', function() {
        var options = {
          "blacklist": ["A", "B", "C"]
        }
        it('returns true if the given origin is not listed in blacklist', function() {
          expect(SurfNPerfRT._inList("D", options)).toEqual(true);
        });
        it('returns false if the given origin is listed in blacklist', function() {
          expect(SurfNPerfRT._inList("A", options)).toEqual(false);
        });
      });
      describe('none specific key', function() {
        options = {}
        it('returns true no matter what if options does not have any key', function() {
          expect(SurfNPerfRT._inList("A", options)).toBe(true);
        });
      });

    });

    describe('#_getURLOrigin', function() {
      describe('when the provided URL has no port', function() {
        it('returns the origin', function() {
          expect(SurfNPerfRT._getURLOrigin("http://johnriv.github.io/Surf-N-Perf/")).toEqual("http://johnriv.github.io");
        });
      });
      describe('when the provided URL has a port', function() {
        it('returns the origin', function() {
          expect(SurfNPerfRT._getURLOrigin("http://johnriv.github.io:3000/Surf-N-Perf/")).toEqual("http://johnriv.github.io:3000");
        });
      });
    });

    describe('#getOrigins', function() {
      // Minsu

    });

    describe('#getResourcesFromOrigin', function() {
      describe('when the browser does not support resource timings', function() {
        it('returns null', function() {
          SurfNPerfRT._resourceTiming = false;
          expect(SurfNPerfRT.getResourcesFromOrigin("http://johnriv.github.io:3000")).toEqual(null);
        });
      });
      describe('when the browser supports resource timings', function() {

      });
    });

    describe('#_name', function() {
      // Minsu
    });

    describe('#getResource', function() {
      // Ros
      describe('when the browser does not support resource timings', function() {
        it('returns null', function() {
          SurfNPerfRT._resourceTiming = false;
          expect(SurfNPerfRT.getResource(name)).toEqual(null);
        });
      });
      describe('when the browser supports resource timings', function() {

      });
    });

    describe('#duration', function() {
      // Minsu
      describe('when the browser does not support resource timings', function() {
        it('returns null', function() {
          SurfNPerfRT._resourceTiming = false;
          expect(SurfNPerfRT.duration(name, "A", "B", {})).toEqual(null);
        });
      });
      describe('when the browser supports resource timings', function() {
        it('returns the diff between 2 resource timing marks', function() {
          SurfNPerfRT._resourceTiming = true;
          spyOn(window.performance, 'getEntriesByName').andReturn([{
            eventA: 480.04,
            eventB: 490.05
          }]);
          expect(SurfNPerfRT.duration(name, "eventA", "eventB", {
            "decimalPlaces": 2
          })).toEqual(10.01);
        });
        it('returns false if either eventA or eventB is 0', function() {
          SurfNPerfRT._resourceTiming = true;
          spyOn(window.performance, 'getEntriesByName').andReturn([{
            eventA: 0,
            eventB: 0,
            eventC: 10
          }]);
          expect(SurfNPerfRT.duration(name, "eventA", "eventC")).toEqual(false);
          expect(SurfNPerfRT.duration(name, "eventC", "eventB")).toEqual(false);
        });
        it('returns the diff between 2 resource timing marks, rounded when optional 4th param decimalPlaces included', function() {
          SurfNPerfRT._resourceTiming = true;
          spyOn(window.performance, 'getEntriesByName').andReturn([{
            eventA: 480.04,
            eventB: 490.05
          }]);
          expect(SurfNPerfRT.duration(name, "eventA", "eventB", {
            "decimalPlaces": 1
          })).toEqual(10.0);
          expect(SurfNPerfRT.duration(name, "eventA", "eventB", {
            "decimalPlaces": 2
          })).toEqual(10.01);
        });
      });
    });

    describe('#start', function() {
      // Ros
      describe('when the browser does not support resource timings', function() {
        it('returns null', function() {
          SurfNPerfRT._resourceTiming = false;
          expect(SurfNPerfRT.start(name)).toEqual(null);
        });
      });
      describe('when the browser supports resource timings', function() {
        it("returns the start time of the resource", function() {
          SurfNPerfRT._resourceTiming = true;
          spyOn(window.performance, 'getEntriesByName').andReturn([{
            startTime: 487.05
          }]);
          expect(SurfNPerfRT.start(name, {
            decimalPlaces: 2
          })).toEqual(487.05);
        });
      });
    });

    describe('#end', function() {
      // Minsu
      describe('when the browser does not support resource timings', function() {
        it('returns null', function() {
          SurfNPerfRT._resourceTiming = false;
          expect(SurfNPerfRT.end("http://johnriv.github.io:3000")).toEqual(null);
        });
      });
      describe('when the browser supports resource timings', function() {
        it("returns the end time of the resource response", function() {
          SurfNPerfRT._resourceTiming = true;
          spyOn(window.performance, 'getEntriesByName').andReturn([{
            responseEnd: 487.05
          }]);
          expect(SurfNPerfRT.end(name, {
            decimalPlaces: 2
          })).toEqual(487.05);
        });
      });
    });

    describe('#getFullRequestLoadTime', function() {
      // Ros
      describe('when the browser does not support resource timings', function() {
        it('returns null', function() {
          SurfNPerfRT._resourceTiming = false;
          expect(SurfNPerfRT.getFullRequestLoadTime(name)).toEqual(null);
        });
      });
      describe('when the browser supports resource timings', function() {
        it("returns the duration of the resource load time", function() {
          SurfNPerfRT._resourceTiming = true;
          spyOn(window.performance, 'getEntriesByName').andReturn([{
            duration: 487.05
          }]);
          expect(SurfNPerfRT.getFullRequestLoadTime(name, {
            decimalPlaces: 2
          })).toEqual(487.05);
        });

      });
    });

    describe('#getNetworkTime', function() {
      // Minsu
      describe('when the browser does not support resource timings', function() {
        it('returns null', function() {
          SurfNPerfRT._resourceTiming = false;
          expect(SurfNPerfRT.getNetworkTime("http://johnriv.github.io:3000", {})).toEqual(null);
        });
      });
      describe('when the browser supports resource timings', function() {
        it("returns the network time while loading the resource", function() {
          SurfNPerfRT._resourceTiming = true;
          spyOn(window.performance, 'getEntriesByName').andReturn([{
            fetchStart: 480.05,
            connectEnd: 490.05
          }]);
          expect(SurfNPerfRT.getNetworkTime(name)).toEqual(10.0);
        });
      });
    });

    describe('#getServerTime', function() {
      // Ros
      describe('when the browser does not support resource timings', function() {
        it('returns null', function() {
          SurfNPerfRT._resourceTiming = false;
          expect(SurfNPerfRT.getServerTime(name)).toEqual(null);
        });
      });
      describe('when the browser supports resource timings', function() {
        it("returns the server time while loading the resource", function() {
          SurfNPerfRT._resourceTiming = true;
          spyOn(window.performance, 'getEntriesByName').andReturn([{
            requestStart: 480.05,
            responseEnd: 490.05
          }]);
          expect(SurfNPerfRT.getServerTime(name)).toEqual(10.0);
        });
      });
    });

    describe('#getBlockingTime', function() {
      // Minsu
      describe('when the browser does not support resource timings', function() {
        it('returns null', function() {
          SurfNPerfRT._resourceTiming = false;
          expect(SurfNPerfRT.getBlockingTime("http://johnriv.github.io:3000", {})).toEqual(null);
        });
      });
      describe('when the browser supports resource timings', function() {
        SurfNPerfRT._resourceTiming = true;
      });
    });

  });
});
<|endoftext|>


<commit_before>/* http://github.com/mindmup/bootstrap-wysiwyg */
/*global jQuery, $, FileReader*/
/*jslint browser:true*/
jQuery(function ($) {
	'use strict';
	var readFileIntoDataUrl = function (fileInfo) {
		var loader = $.Deferred(),
			fReader = new FileReader();
		fReader.onload = function (e) {
			loader.resolve(e.target.result);
		};
		fReader.onerror = loader.reject;
		fReader.onprogress = loader.notify;
		fReader.readAsDataURL(fileInfo);
		return loader.promise();
	};
	$.fn.cleanHtml = function () {
		var html = $(this).html();
		return html && html.replace(/(
|\s|

<\/div>| )*$/, '');
	};
	$.fn.wysiwyg = function (options) {
		var editor = this,
			selectedRange,
			defaultOptions = {
				hotKeys: {
					'ctrl+b meta+b': 'bold',
					'ctrl+i meta+i': 'italic',
					'ctrl+u meta+u': 'underline',
					'ctrl+z meta+z': 'undo',
					'ctrl+y meta+y meta+shift+z': 'redo',
					'ctrl+l meta+l': 'justifyleft',
					'ctrl+r meta+r': 'justifyright',
					'ctrl+e meta+e': 'justifycenter',
					'ctrl+j meta+j': 'justifyfull',
					'shift+tab': 'outdent',
					'tab': 'indent'
	            },
				toolbarSelector: '[data-role=editor-toolbar]',
				commandRole: 'edit'
			},
			execCommand = function (commandWithArgs, valueArg) {
				var commandArr = commandWithArgs.split(' '),
					command = commandArr.shift(),
					args = commandArr.join(' ') + (valueArg || '');
				document.execCommand(command, 0, args);
			},
			bindHotkeys = function (hotKeys) {
				$.each(hotKeys, function (hotkey, command) {
					editor.keydown(hotkey, function (e) {
						if (editor.attr('contenteditable') && editor.is(':visible')) {
							e.preventDefault();
							e.stopPropagation();
							execCommand(command);
						}
					}).keyup(hotkey, function (e) {
						if (editor.attr('contenteditable') && editor.is(':visible')) {
							e.preventDefault();
							e.stopPropagation();
						}
					});
				});
			},
			getCurrentRange = function () {
				var sel = window.getSelection();
				if (sel.getRangeAt && sel.rangeCount) {
					return sel.getRangeAt(0);
				}
			},
			saveSelectionRange = function () {
				selectedRange = getCurrentRange();
			},
			restoreSelectionRange = function () {
				var selection = window.getSelection();
				if (selectedRange) {
					selection.removeAllRanges();
					selection.addRange(selectedRange);
				}
			},
			insertFiles = function (files) {
				editor.focus();
				$.each(files, function (idx, fileInfo) {
					if (/^image\//.test(fileInfo.type)) {
						$.when(readFileIntoDataUrl(fileInfo)).done(function (dataUrl) {
							execCommand('insertimage', dataUrl);
						});
					}
				});
			},
			bindToolbar = function (toolbar, options) {
				toolbar.find('a[data-' + options.commandRole + ']').click(function () {
					restoreSelectionRange();
					execCommand($(this).data(options.commandRole));
					saveSelectionRange();
				});
				toolbar.find('[data-toggle=dropdown]').click(restoreSelectionRange);
				toolbar.find('input[type=text][data-' + options.commandRole + ']').on('webkitspeechchange change', function () {
					var newValue = this.value; /* ugly but prevents fake double-calls due to selection restoration */
					this.value = '';
					restoreSelectionRange();
					if (newValue) {
						editor.focus();
						execCommand($(this).data(options.commandRole), newValue);
					}
					saveSelectionRange();
				});
				toolbar.find('input[type=file][data-' + options.commandRole + ']').change(function () {
					restoreSelectionRange();
					if (this.type === 'file' && this.files && this.files.length > 0) {
						insertFiles(this.files);
					}
					saveSelectionRange();
				});
			},
			initFileDrops = function () {
				editor.on('dragenter dragover', false)
					.on('drop', function (e) {
						var dataTransfer = e.originalEvent.dataTransfer;
						e.stopPropagation();
						e.preventDefault();
						if (dataTransfer && dataTransfer.files && dataTransfer.files.length > 0) {
							insertFiles(dataTransfer.files);
						}
					});
			};
		options = $.extend({}, defaultOptions, options);
		bindHotkeys(options.hotKeys);
		initFileDrops();
		bindToolbar($(options.toolbarSelector), options);
		$.each(this, function () {
			var before,
				element = $(this);
			element.attr('contenteditable', true)
				.on('focus', function () {
					before = element.html();
				})
				.on('mouseup keyup mouseout', saveSelectionRange)
				.on('input blur keyup paste', function () {
					if (before !== element.html()) {
						before = element.html();
						element.trigger('change');
					}
				});
			$(window).bind('touchend', function (e) {
				var isInside = (e.target === element[0] || $(element).children().index($(e.target)) !== -1 || $(element).has(e.target).length > 0),
					currentRange = getCurrentRange(),
					clear = currentRange && (currentRange.startContainer === currentRange.endContainer && currentRange.startOffset === currentRange.endOffset);
				if (!clear || isInside) {
					saveSelectionRange();
				}
			});
		});
		return this;
	};
});
<commit_msg>optional style for active toolbar buttons<commit_after>/* http://github.com/mindmup/bootstrap-wysiwyg */
/*global jQuery, $, FileReader*/
/*jslint browser:true*/
jQuery(function ($) {
	'use strict';
	var readFileIntoDataUrl = function (fileInfo) {
		var loader = $.Deferred(),
			fReader = new FileReader();
		fReader.onload = function (e) {
			loader.resolve(e.target.result);
		};
		fReader.onerror = loader.reject;
		fReader.onprogress = loader.notify;
		fReader.readAsDataURL(fileInfo);
		return loader.promise();
	};
	$.fn.cleanHtml = function () {
		var html = $(this).html();
		return html && html.replace(/(
|\s|

<\/div>| )*$/, '');
	};
	$.fn.wysiwyg = function (userOptions) {
		var editor = this,
			selectedRange,
			defaultOptions = {
				hotKeys: {
					'ctrl+b meta+b': 'bold',
					'ctrl+i meta+i': 'italic',
					'ctrl+u meta+u': 'underline',
					'ctrl+z meta+z': 'undo',
					'ctrl+y meta+y meta+shift+z': 'redo',
					'ctrl+l meta+l': 'justifyleft',
					'ctrl+r meta+r': 'justifyright',
					'ctrl+e meta+e': 'justifycenter',
					'ctrl+j meta+j': 'justifyfull',
					'shift+tab': 'outdent',
					'tab': 'indent'
	            },
				toolbarSelector: '[data-role=editor-toolbar]',
				commandRole: 'edit',
				activeToolbarClass: 'btn-info'
			},
			options,
			updateToolbar = function () {
				if (options.activeToolbarClass) {
					$(options.toolbarSelector).find('.btn[data-' + options.commandRole + ']').each(function () {
						var command = $(this).data(options.commandRole);
						if (document.queryCommandState(command)) {
							$(this).addClass(options.activeToolbarClass);
						} else {
							$(this).removeClass(options.activeToolbarClass);
						}
					});
				}
			},
			execCommand = function (commandWithArgs, valueArg) {
				var commandArr = commandWithArgs.split(' '),
					command = commandArr.shift(),
					args = commandArr.join(' ') + (valueArg || '');
				document.execCommand(command, 0, args);
				updateToolbar();
			},
			bindHotkeys = function (hotKeys) {
				$.each(hotKeys, function (hotkey, command) {
					editor.keydown(hotkey, function (e) {
						if (editor.attr('contenteditable') && editor.is(':visible')) {
							e.preventDefault();
							e.stopPropagation();
							execCommand(command);
						}
					}).keyup(hotkey, function (e) {
						if (editor.attr('contenteditable') && editor.is(':visible')) {
							e.preventDefault();
							e.stopPropagation();
						}
					});
				});
			},
			getCurrentRange = function () {
				var sel = window.getSelection();
				if (sel.getRangeAt && sel.rangeCount) {
					return sel.getRangeAt(0);
				}
			},
			saveSelectionRange = function () {
				selectedRange = getCurrentRange();
			},
			restoreSelectionRange = function () {
				var selection = window.getSelection();
				if (selectedRange) {
					selection.removeAllRanges();
					selection.addRange(selectedRange);
				}
			},
			insertFiles = function (files) {
				editor.focus();
				$.each(files, function (idx, fileInfo) {
					if (/^image\//.test(fileInfo.type)) {
						$.when(readFileIntoDataUrl(fileInfo)).done(function (dataUrl) {
							execCommand('insertimage', dataUrl);
						});
					}
				});
			},
			bindToolbar = function (toolbar, options) {
				toolbar.find('a[data-' + options.commandRole + ']').click(function () {
					restoreSelectionRange();
					editor.focus();
					execCommand($(this).data(options.commandRole));
					saveSelectionRange();
				});
				toolbar.find('[data-toggle=dropdown]').click(restoreSelectionRange);
				toolbar.find('input[type=text][data-' + options.commandRole + ']').on('webkitspeechchange change', function () {
					var newValue = this.value; /* ugly but prevents fake double-calls due to selection restoration */
					this.value = '';
					restoreSelectionRange();
					if (newValue) {
						editor.focus();
						execCommand($(this).data(options.commandRole), newValue);
					}
					saveSelectionRange();
				});
				toolbar.find('input[type=file][data-' + options.commandRole + ']').change(function () {
					restoreSelectionRange();
					if (this.type === 'file' && this.files && this.files.length > 0) {
						insertFiles(this.files);
					}
					saveSelectionRange();
				});
			},
			initFileDrops = function () {
				editor.on('dragenter dragover', false)
					.on('drop', function (e) {
						var dataTransfer = e.originalEvent.dataTransfer;
						e.stopPropagation();
						e.preventDefault();
						if (dataTransfer && dataTransfer.files && dataTransfer.files.length > 0) {
							insertFiles(dataTransfer.files);
						}
					});
			};
		options = $.extend({}, defaultOptions, userOptions);
		bindHotkeys(options.hotKeys);
		initFileDrops();
		bindToolbar($(options.toolbarSelector), options);
		$.each(this, function () {
			var before,
				element = $(this);
			element.attr('contenteditable', true)
				.on('focus', function () {
					before = element.html();
				})
				.on('mouseup keyup mouseout', saveSelectionRange)
				.on('mouseup keyup mouseout', updateToolbar)
				.on('input blur keyup paste', function () {
					if (before !== element.html()) {
						before = element.html();
						element.trigger('change');
					}
				});
			$(window).bind('touchend', function (e) {
				var isInside = (e.target === element[0] || $(element).children().index($(e.target)) !== -1 || $(element).has(e.target).length > 0),
					currentRange = getCurrentRange(),
					clear = currentRange && (currentRange.startContainer === currentRange.endContainer && currentRange.startOffset === currentRange.endOffset);
				if (!clear || isInside) {
					saveSelectionRange();
					updateToolbar();
				}
			});
		});
		return this;
	};
});
<|endoftext|>


<commit_before>var miio = require('./lib');

// var vacuum = python.import('mirobot/protocol');

class MiHome {

  constructor(name, ip, port, token, model) {

    this.ip = ip;
    this.port = port
    this.token = token;
    this.name = name
    this.model = model
    this.device = null;

  // initialize the vacuum independently, and general device will create ether with token or without token
    if (model == 'vacuum') {
      this.device = miio.createDevice({
        address: this.ip,
        token: this.token,
        model: 'rockrobo.vacuum.v1'
      });

      this.device.init()
      .then(() => {
          console.log(this.model + " init success");
          return this;
      })
      .catch(err => console.error(this.model + " init error: " + err));
    }
    else {

      if (token == null) {
        var para = { address: ip };
      }
      else {
        var para = { address: ip, token: token };
      };

      return new Promise(function(resolve, reject){
         miio.device(para)
          .then(device => {
              this.device = device;
              var returnObj = this;
              debugger;
              console.log(returnObj.name + " " + returnObj.device.type + " init success");
              resolve(returnObj);
            })
          .catch(err => {
            console.error(this.name + " init error: " + err);
            reject(err);
          });
        });

      // miio.device(para)
      //   .then(device => {
      //       this.device = device;
      //       debugger;
      //       console.log(this.name + " " + this.device.type + " init success");
      //       return this;
      //     })
      //   .catch(err => console.error(this.name + " init error: " + err));
    };
  }

  exec (cmd) {

    var that = this;

    if (cmd == 'Stop') {
      cmd = 'Charge';
    }

    switch (cmd) {
      case 'Start':

        if (this.device.type == 'vacuum') {
          this.device.start()
            .then(res => console.log(this.name + " start result : " + res))
            .catch(err => console.error(this.name + " start error: " + err));
        }

        break;

      case 'Charge':

        if (this.device.type == 'vacuum') {
          this.device.charge()
            .then(res => console.log(this.name + " charge result : " + res))
            .catch(err => console.error(this.name + " charge error: " + err));
        }

        break;

      case 'Pause':

        if (this.device.type == 'vacuum') {
          this.device.pause()
            .then(res => console.log(this.name + " pause result : " + res))
            .catch(err => console.error(this.name + " pause error: " + err));
        }

        break;

      case 'List':
        if (this.device.type == 'gateway') {
          console.log(this.device.devices);
        }

        break;

      default:
        console.log('Invalid type:' + cmd);
    }

    return;

  }
};

// MiHome.prototype.exec = function(cmd) {

//   var that = this;

//   if (cmd == 'Stop') {
//     cmd = 'Charge';
//   }

//   switch (cmd) {
//     case 'Start':

//       if (this.device.type == 'vacuum') {
//         this.device.start()
//           .then(res => console.log(this.name + " start result : " + res))
//           .catch(err => console.error(this.name + " start error: " + err));
//       }

//       break;

//     case 'Charge':

//       if (this.device.type == 'vacuum') {
//         this.device.charge()
//           .then(res => console.log(this.name + " charge result : " + res))
//           .catch(err => console.error(this.name + " charge error: " + err));
//       }

//       break;

//     case 'Pause':

//       if (this.device.type == 'vacuum') {
//         this.device.pause()
//           .then(res => console.log(this.name + " pause result : " + res))
//           .catch(err => console.error(this.name + " pause error: " + err));
//       }

//       break;

//     case 'List':
//       if (this.device.type == 'gateway') {
//         console.log(this.device.devices);
//       }

//       break;

//     default:
//       console.log('Invalid type:' + cmd);
//   }

//   return;

// };

// MiHome.prototype.powerOn = function() {

//   var that = this;

//   if(this.device.hasCapability('power')) {
//     this.device.setPower(true)
//       .then(console.log(this.name + ":Power On"))
//       .catch(console.error(this.name + "Failed to Power On"));
//   }

// };

module.exports = MiHome;

<commit_msg>update mihome index<commit_after>var miio = require('./lib');

// var vacuum = python.import('mirobot/protocol');

class MiHome {

  constructor(name, ip, port, token, model) {

    this.ip = ip;
    this.port = port
    this.token = token;
    this.name = name
    this.model = model
    this.device = null;

  // initialize the vacuum independently, and general device will create ether with token or without token
    if (model == 'vacuum') {
      this.device = miio.createDevice({
        address: this.ip,
        token: this.token,
        model: 'rockrobo.vacuum.v1'
      });

      this.device.init()
      .then(() => {
          console.log(this.model + " init success");
          return this;
      })
      .catch(err => console.error(this.model + " init error: " + err));
    }
    else {

      if (token == null) {
        var para = { address: ip };
      }
      else {
        var para = { address: ip, token: token };
      };

      return new Promise(function(resolve, reject){
         this.ip = ip;
      this.port = port
      this.token = token;
      this.name = name
      this.model = model
      this.device = null;

         miio.device(para)
          .then(device => {
              this.device = device;
              console.log(this.name + " " + this.device.type + " init success");
              resolve(this);
            })
          .catch(err => {
            console.error(this.name + " init error: " + err);
            reject(err);
          });
        });

      // miio.device(para)
      //   .then(device => {
      //       this.device = device;
      //       debugger;
      //       console.log(this.name + " " + this.device.type + " init success");
      //       return this;
      //     })
      //   .catch(err => console.error(this.name + " init error: " + err));
    };
  }

  exec (cmd) {

    var that = this;

    if (cmd == 'Stop') {
      cmd = 'Charge';
    }

    switch (cmd) {
      case 'Start':

        if (this.device.type == 'vacuum') {
          this.device.start()
            .then(res => console.log(this.name + " start result : " + res))
            .catch(err => console.error(this.name + " start error: " + err));
        }

        break;

      case 'Charge':

        if (this.device.type == 'vacuum') {
          this.device.charge()
            .then(res => console.log(this.name + " charge result : " + res))
            .catch(err => console.error(this.name + " charge error: " + err));
        }

        break;

      case 'Pause':

        if (this.device.type == 'vacuum') {
          this.device.pause()
            .then(res => console.log(this.name + " pause result : " + res))
            .catch(err => console.error(this.name + " pause error: " + err));
        }

        break;

      case 'List':
        if (this.device.type == 'gateway') {
          console.log(this.device.devices);
        }

        break;

      default:
        console.log('Invalid type:' + cmd);
    }

    return;

  }
};

// MiHome.prototype.exec = function(cmd) {

//   var that = this;

//   if (cmd == 'Stop') {
//     cmd = 'Charge';
//   }

//   switch (cmd) {
//     case 'Start':

//       if (this.device.type == 'vacuum') {
//         this.device.start()
//           .then(res => console.log(this.name + " start result : " + res))
//           .catch(err => console.error(this.name + " start error: " + err));
//       }

//       break;

//     case 'Charge':

//       if (this.device.type == 'vacuum') {
//         this.device.charge()
//           .then(res => console.log(this.name + " charge result : " + res))
//           .catch(err => console.error(this.name + " charge error: " + err));
//       }

//       break;

//     case 'Pause':

//       if (this.device.type == 'vacuum') {
//         this.device.pause()
//           .then(res => console.log(this.name + " pause result : " + res))
//           .catch(err => console.error(this.name + " pause error: " + err));
//       }

//       break;

//     case 'List':
//       if (this.device.type == 'gateway') {
//         console.log(this.device.devices);
//       }

//       break;

//     default:
//       console.log('Invalid type:' + cmd);
//   }

//   return;

// };

// MiHome.prototype.powerOn = function() {

//   var that = this;

//   if(this.device.hasCapability('power')) {
//     this.device.setPower(true)
//       .then(console.log(this.name + ":Power On"))
//       .catch(console.error(this.name + "Failed to Power On"));
//   }

// };

module.exports = MiHome;

<|endoftext|>


<commit_before>Package.describe({
  name: 'packaging:autopublish-test',
  summary: 'Dummy package to be used to test auto-publish with TravisCI. DO NOT USE!',
  version: '1.0.0',
  git: 'https://github.com/MeteorPackaging/autopublish-test.git'
});

Package.onUse(function(api) {
  api.versionsFrom('1.0.1');
  api.addFiles('lib/main.js');
});

Package.onTest(function(api) {
  api.use('tinytest');
  api.use('packaging:autopublish-test');
  api.addFiles('tests/main.js');
});
<commit_msg>Bump to version 0.0.0<commit_after>Package.describe({
  name: 'packaging:autopublish-test',
  summary: 'Dummy package to be used to test auto-publish with TravisCI. DO NOT USE!',
  version: '0.0.0',
  git: 'https://github.com/MeteorPackaging/autopublish-test.git'
});

Package.onUse(function(api) {
  api.versionsFrom('1.0.1');
  api.addFiles('lib/main.js');
});

Package.onTest(function(api) {
  api.use('tinytest');
  api.use('packaging:autopublish-test');
  api.addFiles('tests/main.js');
});
<|endoftext|>


<commit_before>/*
 * grunt-partial-extract
 * https://github.com/tilmanjusten/grunt-partial-extract
 *
 * Copyright (c) 2014 Tilman Justen
 * Licensed under the MIT license.
 */

'use strict';

module.exports = function(grunt) {

  // Please see the Grunt documentation for more information regarding task
  // creation: http://gruntjs.com/creating-tasks

  var options = {};

  grunt.registerMultiTask('partial-extract', 'Extract partials from any text based file and write to distinct file.', function() {
    // Merge task-specific and/or target-specific options with these defaults.
    options = this.options({
      pattern: [
        /<\!--\s*extract:\s*(([\w\/-_]+\/)([\w_\.-]+))\s*-->/,
        /<\!--\s*endextract\s*-->/
      ],
      wrap: [
        '<template id="partial">',
        '</template>'
      ]
    });

    grunt.log.writeln('Destination: ' + options.dest);
    grunt.verbose.writeln('Files: ' + this.files.length);
    grunt.log.writeln();

    var existingFiles = [];

    // Iterate over all specified file groups.
    this.files.forEach(function(file) {
      var content = grunt.util.normalizelf(grunt.file.read(file.src));

      if (!options.pattern[0].test(content)) {
        grunt.log.errorlns('No partials in file ' + file.src);
        grunt.verbose.writeln();

        return;
      }

      var lines = content.split(grunt.util.linefeed);
      var blocks = getPartials(lines);

      grunt.log.oklns('Found ' + blocks.length + ' partials in file ' + file.src);

      // Write blocks to separate files
      blocks.filter(function (block) {
        if (existingFiles.indexOf(block.dest) !== -1) {
          grunt.verbose.warn("Skip file " + block.dest + " which already exists.");
          return false;
        } else {
          return true;
        }
      }).map(function (block) {
        var lines = block.lines.map(properIndentation);
        var leadingWhitespace = lines.map(countWhitespace);
        var crop = leadingWhitespace.reduce(getLeadingWhitespace);

        lines = trimLines(lines, crop);

        if (options.wrap.length) {
          lines.unshift(options.wrap[0]);
          lines.push(options.wrap[1]);
        }

        grunt.file.write(options.dest + block.dest, lines.join(grunt.util.linefeed));
        existingFiles.push(block.dest);
      });

      grunt.verbose.writeln();
    });

    grunt.log.oklns('Extracted ' + existingFiles.length + ' unique partials.');
  });

  /**
   * extract partials
   *
   * @param lines
   * @returns {Array}
   */
  function getPartials(lines) {
    var block;
    var add = false;
    var match;
    var blocks = [];

    // Import blocks from file
    lines.forEach(function (line) {
      if (line.match(options.pattern[1])) {
        add = false;
        blocks.push(block);
      }

      if (add) {
        block.lines.push(line);
      }

      if (match = line.match(options.pattern[0])) {
        add = true;
        block = {dest: match[1], lines: []};
      }
    });

    return blocks;
  }

  /**
   * replace tabs by four spaces
   *
   * @param line
   * @return string
   */
  function properIndentation(line) {
    return line.replace(/\t/, '    ');
  }

  /**
   * count leading whitespace chars
   *
   * @param line
   * @return integer
   */
  function countWhitespace(line) {
    // return a somewhat high value for empty lines
    return line.length ? line.match(/^\s*/)[0].length : 9999;
  }

  /**
   * get lowest value of leading whitespace in a given block
   *
   * @param previous
   * @param current
   * @returns integer
   */
  function getLeadingWhitespace(previous, current) {
    return previous <= current ? previous : current;
  }

  /**
   * trim given number of leading characters
   *
   * @param lines
   * @param num Number of chars to be removed
   * @returns Array
   */
  function trimLines(lines, num) {
    return lines.map(function (line) {
      return line.substr(num);
    });
  }
};
<commit_msg>Update option name: wrap get's partialWrap<commit_after>/*
 * grunt-partial-extract
 * https://github.com/tilmanjusten/grunt-partial-extract
 *
 * Copyright (c) 2014 Tilman Justen
 * Licensed under the MIT license.
 */

'use strict';

module.exports = function(grunt) {

  // Please see the Grunt documentation for more information regarding task
  // creation: http://gruntjs.com/creating-tasks

  var options = {};

  grunt.registerMultiTask('partial-extract', 'Extract partials from any text based file and write to distinct file.', function() {
    // Merge task-specific and/or target-specific options with these defaults.
    options = this.options({
      pattern: [
        /<\!--\s*extract:\s*(([\w\/-_]+\/)([\w_\.-]+))\s*-->/,
        /<\!--\s*endextract\s*-->/
      ],
      partialWrap: [
        '<template id="partial">',
        '</template>'
      ]
    });

    grunt.log.writeln('Destination: ' + options.dest);
    grunt.verbose.writeln('Files: ' + this.files.length);
    grunt.log.writeln();

    var existingFiles = [];

    // Iterate over all specified file groups.
    this.files.forEach(function(file) {
      var content = grunt.util.normalizelf(grunt.file.read(file.src));

      if (!options.pattern[0].test(content)) {
        grunt.log.errorlns('No partials in file ' + file.src);
        grunt.verbose.writeln();

        return;
      }

      var lines = content.split(grunt.util.linefeed);
      var blocks = getPartials(lines);

      grunt.log.oklns('Found ' + blocks.length + ' partials in file ' + file.src);

      // Write blocks to separate files
      blocks.filter(function (block) {
        if (existingFiles.indexOf(block.dest) !== -1) {
          grunt.verbose.warn("Skip file " + block.dest + " which already exists.");
          return false;
        } else {
          return true;
        }
      }).map(function (block) {
        var lines = block.lines.map(properIndentation);
        var leadingWhitespace = lines.map(countWhitespace);
        var crop = leadingWhitespace.reduce(getLeadingWhitespace);

        lines = trimLines(lines, crop);

        if (options.partialWrap.length) {
          lines.unshift(options.partialWrap[0]);
          lines.push(options.partialWrap[1]);
        }

        grunt.file.write(options.dest + block.dest, lines.join(grunt.util.linefeed));
        existingFiles.push(block.dest);
      });

      grunt.verbose.writeln();
    });

    grunt.log.oklns('Extracted ' + existingFiles.length + ' unique partials.');
  });

  /**
   * extract partials
   *
   * @param lines
   * @returns {Array}
   */
  function getPartials(lines) {
    var block;
    var add = false;
    var match;
    var blocks = [];

    // Import blocks from file
    lines.forEach(function (line) {
      if (line.match(options.pattern[1])) {
        add = false;
        blocks.push(block);
      }

      if (add) {
        block.lines.push(line);
      }

      if (match = line.match(options.pattern[0])) {
        add = true;
        block = {dest: match[1], lines: []};
      }
    });

    return blocks;
  }

  /**
   * replace tabs by four spaces
   *
   * @param line
   * @return string
   */
  function properIndentation(line) {
    return line.replace(/\t/, '    ');
  }

  /**
   * count leading whitespace chars
   *
   * @param line
   * @return integer
   */
  function countWhitespace(line) {
    // return a somewhat high value for empty lines
    return line.length ? line.match(/^\s*/)[0].length : 9999;
  }

  /**
   * get lowest value of leading whitespace in a given block
   *
   * @param previous
   * @param current
   * @returns integer
   */
  function getLeadingWhitespace(previous, current) {
    return previous <= current ? previous : current;
  }

  /**
   * trim given number of leading characters
   *
   * @param lines
   * @param num Number of chars to be removed
   * @returns Array
   */
  function trimLines(lines, num) {
    return lines.map(function (line) {
      return line.substr(num);
    });
  }
};
<|endoftext|>


<commit_before>/**
 * srvoa - soa infrastructure for node js
 *
 * @copyright   Copyright (c) 2015, Alrik Zachert
 * @license     https://gitlab.com/a-z/node-srvoa/blob/master/LICENSE BSD-2-Clause
 */

var assert = require('assert'),
    Service = require('../Service'),
    ConfigService = require('../ConfigService');

describe('srvoa::config-service', function() {
    it('is derivative of abstract service.', function() {
        var srv = new ConfigService;

        assert(srv instanceof Service);
    });

    it('should configure config files to load.', function() {
        var srv = new ConfigService,
            files = [
                './config/config-1.js',
                './config/config-2.js'
            ];

        srv.configure({
            files: files
        });

        assert(files === srv.getFiles());
    });

    it('should ignore non existent files.', function() {
       assert.doesNotThrow(function() {
           var srv = new ConfigService,
               files = [
                   './config/config-1.js',
                   './config/config-does-not-exists.js'
               ];

           srv.configure({
               files: files
           }).bootstrap().launch();
       });
    });

    it('should return undefined if key was not found.', function() {
        var srv = new ConfigService;

        assert(typeof srv.get('foo') === 'undefined');
    });

    it('should be aware of returning default value if key was not found.', function() {
        var srv = new ConfigService;

        [true, false, 1, 0, '', 'test', [], {}, new Date].forEach(function(value) {
            assert(srv.get('not.existent.key', value) === value);
            assert(srv.get('not-existent-key', value) === value);
        });
    });

    it('should merge multiple config hashes.', function() {
        var srv = new ConfigService;

        srv.setConfig({
            foo: 1,
            bar: 1,
            nested: {
                foo: 1,
                bar: 1
            }
        }, {
            bar: 'ok',
            nested: {
                foo: 'ok'
            }
        });

        assert(srv.get('foo') === 1);
        assert(srv.get('bar') === 'ok');

        assert(srv.get('nested.bar') === 1);
        assert(srv.get('nested.foo') === 'ok');
    });

    it('should not try to merge arrays but override them.', function() {
        var srv = new ConfigService;

        srv.setConfig({
            a: [1, 2]
        }, {
            a: [2]
        });

        assert(srv.get('a').length === 1 && srv.get('a')[0] === 2);
    });

    it('should merge multiple config files.', function() {
        var srv = new ConfigService,
            files = [
                __dirname + '/config/config-1.js',
                __dirname + '/config/config-2.js'
            ];

        srv.configure({
            files: files
        }).bootstrap().launch();

        assert(srv.get('foo') === 1);
        assert(srv.get('bar') === 'ok');

        assert(srv.get('nested.bar') === 1);
        assert(srv.get('nested.foo') === 'ok');
    });
});
<commit_msg>add config tests - check if configs can be deleted by overriding them with null.<commit_after>/**
 * srvoa - soa infrastructure for node js
 *
 * @copyright   Copyright (c) 2015, Alrik Zachert
 * @license     https://gitlab.com/a-z/node-srvoa/blob/master/LICENSE BSD-2-Clause
 */

var assert = require('assert'),
    Service = require('../Service'),
    ConfigService = require('../ConfigService');

describe('srvoa::config-service', function() {
    it('is derivative of abstract service.', function() {
        var srv = new ConfigService;

        assert(srv instanceof Service);
    });

    it('should configure config files to load.', function() {
        var srv = new ConfigService,
            files = [
                './config/config-1.js',
                './config/config-2.js'
            ];

        srv.configure({
            files: files
        });

        assert(files === srv.getFiles());
    });

    it('should ignore non existent files.', function() {
       assert.doesNotThrow(function() {
           var srv = new ConfigService,
               files = [
                   './config/config-1.js',
                   './config/config-does-not-exists.js'
               ];

           srv.configure({
               files: files
           }).bootstrap().launch();
       });
    });

    it('should return undefined if key was not found.', function() {
        var srv = new ConfigService;

        assert(typeof srv.get('foo') === 'undefined');
    });

    it('should be aware of returning default value if key was not found.', function() {
        var srv = new ConfigService;

        [true, false, 1, 0, '', 'test', [], {}, new Date].forEach(function(value) {
            assert(srv.get('not.existent.key', value) === value);
            assert(srv.get('not-existent-key', value) === value);
        });
    });

    it('should merge multiple config hashes.', function() {
        var srv = new ConfigService;

        srv.setConfig({
            foo: 1,
            bar: 1,
            nested: {
                foo: 1,
                bar: 1
            }
        }, {
            bar: 'ok',
            nested: {
                foo: 'ok'
            }
        });

        assert(srv.get('foo') === 1);
        assert(srv.get('bar') === 'ok');

        assert(srv.get('nested.bar') === 1);
        assert(srv.get('nested.foo') === 'ok');
    });

    it('should not try to merge arrays but override them.', function() {
        var srv = new ConfigService;

        srv.setConfig({
            a: [1, 2]
        }, {
            a: [2]
        });

        assert(srv.get('a').length === 1 && srv.get('a')[0] === 2);
    });

    it('should delete a config key when overriden with null.', function() {
        var srv = new ConfigService;

        srv.setConfig({
            a: 'test',
            b: {}
        }, {
            a: null,
            b: null
        });

        assert(srv.get('a') === undefined);
        assert(srv.get('b') === undefined);
    });

    it('should merge multiple config files.', function() {
        var srv = new ConfigService,
            files = [
                __dirname + '/config/config-1.js',
                __dirname + '/config/config-2.js'
            ];

        srv.configure({
            files: files
        }).bootstrap().launch();

        assert(srv.get('foo') === 1);
        assert(srv.get('bar') === 'ok');

        assert(srv.get('nested.bar') === 1);
        assert(srv.get('nested.foo') === 'ok');
    });
});
<|endoftext|>