<commit_before>import test from 'ava';
import path from 'path';
import assign from "object-assign";
import MemoryFS from 'memory-fs';
import webpack from 'webpack';
import pify from 'pify';
import elmAssetsLoader from './index.js';

const outputPath = path.join(__dirname, 'build');
const fixturesPath = path.join(__dirname, "fixtures");
const elmMakePath = path.join(__dirname, 'node_modules/.bin/elm-make');

const globalConfig = {
  context: fixturesPath,
  output: {
    path: outputPath,
    filename: 'main.js'
  },
  resolve: {
    root: fixturesPath,
    extensions: ['', '.js', '.elm']
  },
  module: {
    loaders: [
      {
        test: /\.elm$/,
        loaders: [
          path.join(__dirname, 'index.js'),
          'elm-webpack?cwd=' + fixturesPath + '&pathToMake=' + elmMakePath
        ]
      },
      {
        test: /\.svg$/,
        loader: 'file-loader'
      }
    ]
  },
  plugins: [
    new webpack.NoErrorsPlugin()
  ]
};

const compile = (config) => {
  return compileWithStats(config)
    .then(outputAndStats => outputAndStats.output);
};

const compileWithStats = (config) => {
  const fs = new MemoryFS();
  const compiler = webpack(config);
  compiler.outputFileSystem = fs;
  return pify(compiler.run.bind(compiler))()
    .then(stats => {
      if (stats.compilation.errors.length > 0) {
        throw stats.compilation.errors.map(error => error.message);
      }
      const exitPath = path.join(outputPath, 'main.js');
      const output = fs.readFileSync(exitPath).toString('utf-8');
      return {output: output, stats: stats.toJson()};
    });
}

/* finding the tagger in compiled JS code */

test('transform tagger in a package with hyphen', async t => {
  const config = assign({}, globalConfig, {
    entry: './Just',
    elmAssetsLoader: {
      package: 'elm-lang/core',
      module: 'Maybe',
      tagger: 'Just'
    }
  });
  const result = await compile(config);
  t.regex(result, /Just\(__webpack_require__\(\d+\)\)/);
});

test('transform tagger not in package', async t => {
  const config = assign({}, globalConfig, {
    entry: './UserProject',
    elmAssetsLoader: {
      module: 'UserProject',
      tagger: 'Asset'
    }
  });
  const result = await compile(config);
  t.regex(result, /Asset\(__webpack_require__\(\d+\)\)/);
});

test('do not transform tagger in different package', async t => {
  const config = assign({}, globalConfig, {
    entry: './MyMaybe',
    elmAssetsLoader: {
      module: 'MyMaybe',
      tagger: 'Just'
    }
  });
  const result = await compile(config);
  t.regex(result, /Just\((["'])dont_touch_me.png\1\)/);
});

test('do not transform tagger in different module', async t => {
  const config = assign({}, globalConfig, {
    entry: './MyTag',
    elmAssetsLoader: {
      module: 'MyTag',
      tagger: 'Asset'
    }
  });
  const result = await compile(config);
  t.regex(result, /Asset\((["'])dont_touch_me.png\1\)/);
});

/* argument handling */

test('cannot detect when tagger has multiple args', async t => {
  const config = assign({}, globalConfig, {
    entry: './MultiArg',
    elmAssetsLoader: {
      module: 'MultiArg',
      tagger: 'Asset'
    }
  });
  const result = await compile(config);
  // inside an A2 call
  t.regex(result, /Asset,\s*(["'])elm_logo.svg\1,\s*\1elm_logo.svg\1\)/);
});

test('do not fail when something else is called with multiple args ', async t => {
  const config = assign({}, globalConfig, {
    entry: './IrrelevantMultiArg',
    elmAssetsLoader: {
      module: 'IrrelevantMultiArg',
      tagger: 'AssetPath'
    }
  });
  const result = await compile(config);
  // inside an A2 call
  t.regex(result, /AssetPair,\s*(["'])elm_logo.svg\1,\s*\1elm_logo.svg\1\)/);
});

test('cannot detect if tagger with multiple values is called with a single arg', async t => {
  const config = assign({}, globalConfig, {
    entry: './PartialMultiArg',
    elmAssetsLoader: {
      module: 'PartialMultiArg',
      tagger: 'AssetPair'
    }
  });
  const result = await compile(config);
  t.regex(result, /AssetPair\(__webpack_require__\(\d+\)\)/);
});

test('do not transform tagger that is actually a constant func', async t => {
  const config = assign({}, globalConfig, {
    entry: './NoArg',
    elmAssetsLoader: {
      module: 'NoArg',
      tagger: 'assetPath'
    }
  });
  const result = await compile(config);
  t.regex(result, /assetPath\s*=\s*(["'])star.png\1/);
});

/* dynamicRequires */

test('dynamicRequires: default - warn', async t => {
  const config = assign({}, globalConfig, {
    entry: './ComplexCall',
    elmAssetsLoader: {
      module: 'ComplexCall',
      tagger: 'ComplexCallAsset'
    }
  });
  const result = await compileWithStats(config);
  t.regex(result.output, /ComplexCallAsset\(A2/);
  t.regex(result.output, /ComplexCallAsset\(A2/);
  t.regex(result.stats.warnings[0], /will not be run through webpack.*ComplexCallAsset/);
});

test('dynamicRequires: ok - be silent', async t => {
  const config = assign({}, globalConfig, {
    entry: './ComplexCall',
    elmAssetsLoader: {
      module: 'ComplexCall',
      tagger: 'ComplexCallAsset',
      dynamicRequires: 'ok'
    }
  });
  const result = await compileWithStats(config);
  t.regex(result.output, /ComplexCallAsset\(A2/);
  t.is(result.stats.warnings.length, 0);
});

test('dynamicRequires: warn - just warn', async t => {
  const config = assign({}, globalConfig, {
    entry: './ComplexCall',
    elmAssetsLoader: {
      module: 'ComplexCall',
      tagger: 'ComplexCallAsset',
      dynamicRequires: 'warn'
    }
  });
  const result = await compileWithStats(config);
  t.regex(result.output, /ComplexCallAsset\(A2/);
  t.regex(result.stats.warnings[0], /will not be run through webpack.*ComplexCallAsset/);
});

test('dynamicRequires: error - raise when a string concatenation is tagge', async t => {
  const config = assign({}, globalConfig, {
    entry: './ComplexCall',
    elmAssetsLoader: {
      module: 'ComplexCall',
      tagger: 'ComplexCallAsset',
      dynamicRequires: 'error'
    }
  });
  t.throws(compile(config), /Failing hard to make sure all assets.*ComplexCallAsset/);
});

test('dynamicRequires: error - raise when a variable is tagged', async t => {
  const config = assign({}, globalConfig, {
    entry: './VariableCall',
    elmAssetsLoader: {
      module: 'VariableCall',
      tagger: 'VariableCallAsset',
      dynamicRequires: 'error'
    }
  });
  t.throws(compile(config), /Failing hard to make sure all assets.*VariableCallAsset/);
});

/* localPath */

test('find module after applying localPath transformation', async t => {
  const config = assign({}, globalConfig, {
    entry: './LocalPathOverride',
    elmAssetsLoader: {
      module: 'LocalPathOverride',
      tagger: 'Asset',
      localPath: s => 'elm_logo.svg'
    }
  });
  const result = await compile(config);
  t.regex(result, /Asset\(__webpack_require__\(\d+\)\)/);
});

test('fail to find module when localPath is not correctly configured', async t => {
  const config = assign({}, globalConfig, {
    entry: './LocalPathOverride',
    elmAssetsLoader: {
      module: 'LocalPathOverride',
      tagger: 'Asset'
    }
  });
  t.throws(compile(config), /Cannot resolve module \'non_sensical.png\'/);
});

test('raise when localPath does not return a string', async t => {
  const config = assign({}, globalConfig, {
    entry: './LocalPathOverride',
    elmAssetsLoader: {
      module: 'LocalPathOverride',
      tagger: 'Asset',
      localPath: s => 42
    }
  });
  t.throws(compile(config), /not a string/);
});

/* query params */

test('require module to be configured', async t => {
  const config = assign({}, globalConfig, {
    entry: './UserProject',
    elmAssetsLoader: {
      tagger: 'Asset'
    }
  });
  t.throws(compile(config), /configure module and tagger/);
});

test('require tagger to be configured', async t => {
  const config = assign({}, globalConfig, {
    entry: './UserProject',
    elmAssetsLoader: {
      module: 'UserProject'
    }
  });
  t.throws(compile(config), /configure module and tagger/);
});

test('raise when dynamicRequires is set to an unknown value', async t => {
  const config = assign({}, globalConfig, {
    entry: './UserProject',
    elmAssetsLoader: {
      module: 'UserProject',
      tagger: 'Asset',
      dynamicRequires: 'ignore'
    }
  });
  t.throws(compile(config), /Expecting dynamicRequires to be one of: error | warn | ok. You gave me: ignore/);
});
<commit_msg>Update test config to conform to webpack 2 config schema<commit_after>import test from 'ava';
import path from 'path';
import assign from "object-assign";
import MemoryFS from 'memory-fs';
import webpack from 'webpack';
import pify from 'pify';
import elmAssetsLoader from './index.js';

const outputPath = path.join(__dirname, 'build');
const fixturesPath = path.join(__dirname, "fixtures");
const elmMakePath = path.join(__dirname, 'node_modules/.bin/elm-make');

const globalConfig = {
  context: fixturesPath,
  output: {
    path: outputPath,
    filename: 'main.js'
  },
  resolve: {
    modules: [
      fixturesPath
    ],
    extensions: ['.js', '.elm']
  },
  module: {
    rules: [
      {
        test: /\.elm$/,
        use: [
          path.join(__dirname, 'index.js'),
          'elm-webpack?cwd=' + fixturesPath + '&pathToMake=' + elmMakePath
        ]
      },
      {
        test: /\.svg$/,
        use: 'file-loader'
      }
    ]
  },
  plugins: [
    new webpack.NoErrorsPlugin()
  ]
};

const compile = (config) => {
  return compileWithStats(config)
    .then(outputAndStats => outputAndStats.output);
};

const compileWithStats = (config) => {
  const fs = new MemoryFS();
  const compiler = webpack(config);
  compiler.outputFileSystem = fs;
  return pify(compiler.run.bind(compiler))()
    .then(stats => {
      if (stats.compilation.errors.length > 0) {
        throw stats.compilation.errors.map(error => error.message);
      }
      const exitPath = path.join(outputPath, 'main.js');
      const output = fs.readFileSync(exitPath).toString('utf-8');
      return {output: output, stats: stats.toJson()};
    });
}

/* finding the tagger in compiled JS code */

test('transform tagger in a package with hyphen', async t => {
  const config = assign({}, globalConfig, {
    entry: './Just',
    elmAssetsLoader: {
      package: 'elm-lang/core',
      module: 'Maybe',
      tagger: 'Just'
    }
  });
  const result = await compile(config);
  t.regex(result, /Just\(__webpack_require__\(\d+\)\)/);
});

test('transform tagger not in package', async t => {
  const config = assign({}, globalConfig, {
    entry: './UserProject',
    elmAssetsLoader: {
      module: 'UserProject',
      tagger: 'Asset'
    }
  });
  const result = await compile(config);
  t.regex(result, /Asset\(__webpack_require__\(\d+\)\)/);
});

test('do not transform tagger in different package', async t => {
  const config = assign({}, globalConfig, {
    entry: './MyMaybe',
    elmAssetsLoader: {
      module: 'MyMaybe',
      tagger: 'Just'
    }
  });
  const result = await compile(config);
  t.regex(result, /Just\((["'])dont_touch_me.png\1\)/);
});

test('do not transform tagger in different module', async t => {
  const config = assign({}, globalConfig, {
    entry: './MyTag',
    elmAssetsLoader: {
      module: 'MyTag',
      tagger: 'Asset'
    }
  });
  const result = await compile(config);
  t.regex(result, /Asset\((["'])dont_touch_me.png\1\)/);
});

/* argument handling */

test('cannot detect when tagger has multiple args', async t => {
  const config = assign({}, globalConfig, {
    entry: './MultiArg',
    elmAssetsLoader: {
      module: 'MultiArg',
      tagger: 'Asset'
    }
  });
  const result = await compile(config);
  // inside an A2 call
  t.regex(result, /Asset,\s*(["'])elm_logo.svg\1,\s*\1elm_logo.svg\1\)/);
});

test('do not fail when something else is called with multiple args ', async t => {
  const config = assign({}, globalConfig, {
    entry: './IrrelevantMultiArg',
    elmAssetsLoader: {
      module: 'IrrelevantMultiArg',
      tagger: 'AssetPath'
    }
  });
  const result = await compile(config);
  // inside an A2 call
  t.regex(result, /AssetPair,\s*(["'])elm_logo.svg\1,\s*\1elm_logo.svg\1\)/);
});

test('cannot detect if tagger with multiple values is called with a single arg', async t => {
  const config = assign({}, globalConfig, {
    entry: './PartialMultiArg',
    elmAssetsLoader: {
      module: 'PartialMultiArg',
      tagger: 'AssetPair'
    }
  });
  const result = await compile(config);
  t.regex(result, /AssetPair\(__webpack_require__\(\d+\)\)/);
});

test('do not transform tagger that is actually a constant func', async t => {
  const config = assign({}, globalConfig, {
    entry: './NoArg',
    elmAssetsLoader: {
      module: 'NoArg',
      tagger: 'assetPath'
    }
  });
  const result = await compile(config);
  t.regex(result, /assetPath\s*=\s*(["'])star.png\1/);
});

/* dynamicRequires */

test('dynamicRequires: default - warn', async t => {
  const config = assign({}, globalConfig, {
    entry: './ComplexCall',
    elmAssetsLoader: {
      module: 'ComplexCall',
      tagger: 'ComplexCallAsset'
    }
  });
  const result = await compileWithStats(config);
  t.regex(result.output, /ComplexCallAsset\(A2/);
  t.regex(result.output, /ComplexCallAsset\(A2/);
  t.regex(result.stats.warnings[0], /will not be run through webpack.*ComplexCallAsset/);
});

test('dynamicRequires: ok - be silent', async t => {
  const config = assign({}, globalConfig, {
    entry: './ComplexCall',
    elmAssetsLoader: {
      module: 'ComplexCall',
      tagger: 'ComplexCallAsset',
      dynamicRequires: 'ok'
    }
  });
  const result = await compileWithStats(config);
  t.regex(result.output, /ComplexCallAsset\(A2/);
  t.is(result.stats.warnings.length, 0);
});

test('dynamicRequires: warn - just warn', async t => {
  const config = assign({}, globalConfig, {
    entry: './ComplexCall',
    elmAssetsLoader: {
      module: 'ComplexCall',
      tagger: 'ComplexCallAsset',
      dynamicRequires: 'warn'
    }
  });
  const result = await compileWithStats(config);
  t.regex(result.output, /ComplexCallAsset\(A2/);
  t.regex(result.stats.warnings[0], /will not be run through webpack.*ComplexCallAsset/);
});

test('dynamicRequires: error - raise when a string concatenation is tagge', async t => {
  const config = assign({}, globalConfig, {
    entry: './ComplexCall',
    elmAssetsLoader: {
      module: 'ComplexCall',
      tagger: 'ComplexCallAsset',
      dynamicRequires: 'error'
    }
  });
  t.throws(compile(config), /Failing hard to make sure all assets.*ComplexCallAsset/);
});

test('dynamicRequires: error - raise when a variable is tagged', async t => {
  const config = assign({}, globalConfig, {
    entry: './VariableCall',
    elmAssetsLoader: {
      module: 'VariableCall',
      tagger: 'VariableCallAsset',
      dynamicRequires: 'error'
    }
  });
  t.throws(compile(config), /Failing hard to make sure all assets.*VariableCallAsset/);
});

/* localPath */

test('find module after applying localPath transformation', async t => {
  const config = assign({}, globalConfig, {
    entry: './LocalPathOverride',
    elmAssetsLoader: {
      module: 'LocalPathOverride',
      tagger: 'Asset',
      localPath: s => 'elm_logo.svg'
    }
  });
  const result = await compile(config);
  t.regex(result, /Asset\(__webpack_require__\(\d+\)\)/);
});

test('fail to find module when localPath is not correctly configured', async t => {
  const config = assign({}, globalConfig, {
    entry: './LocalPathOverride',
    elmAssetsLoader: {
      module: 'LocalPathOverride',
      tagger: 'Asset'
    }
  });
  t.throws(compile(config), /Cannot resolve module \'non_sensical.png\'/);
});

test('raise when localPath does not return a string', async t => {
  const config = assign({}, globalConfig, {
    entry: './LocalPathOverride',
    elmAssetsLoader: {
      module: 'LocalPathOverride',
      tagger: 'Asset',
      localPath: s => 42
    }
  });
  t.throws(compile(config), /not a string/);
});

/* query params */

test('require module to be configured', async t => {
  const config = assign({}, globalConfig, {
    entry: './UserProject',
    elmAssetsLoader: {
      tagger: 'Asset'
    }
  });
  t.throws(compile(config), /configure module and tagger/);
});

test('require tagger to be configured', async t => {
  const config = assign({}, globalConfig, {
    entry: './UserProject',
    elmAssetsLoader: {
      module: 'UserProject'
    }
  });
  t.throws(compile(config), /configure module and tagger/);
});

test('raise when dynamicRequires is set to an unknown value', async t => {
  const config = assign({}, globalConfig, {
    entry: './UserProject',
    elmAssetsLoader: {
      module: 'UserProject',
      tagger: 'Asset',
      dynamicRequires: 'ignore'
    }
  });
  t.throws(compile(config), /Expecting dynamicRequires to be one of: error | warn | ok. You gave me: ignore/);
});
<|endoftext|>


<commit_before>'use strict';

var S = require('string')
var quoteEscape = "`~`"

// "users": { "briansturgill": true, jonamorua: true },

// but:
// users: { "some": "this, that: other" } is ok

function isAlpha(char) {
  return ((char >= 'a' && char <= 'z') || (char >= 'A' && char <= 'Z'))
}

function fixSubLine(subline) {
  var firstQuote = subline.indexOf('"')
  var firstColon = subline.indexOf(':')
  var first = subline.substr(0,1)
  if (firstColon >= 0 && isAlpha(first)) {
    if (firstQuote < 0 || firstQuote > firstColon) {
      subline = '"' + subline
      subline = subline.replace(':', '":')
    }
  }
  return subline
}

function fixUpLine(line) {
  line = S(line).trim().s
  var first = line.substr(0,1)
  if (line.length > 0 && isAlpha(first)) {
    line = '"' + line
    line = line.replace(':', '":')
    var sub = line.split(', ')
    for (var i=1; i < sub.length; i++) {
      sub[i] = fixSubLine(sub[i])
    }
    line = sub.join(', ')
  }
  return line
}

function parse(jsObjString) {
  var result = S(jsObjString).replaceAll('"', quoteEscape).s
  result = S(result).replaceAll("'", '"').s
  result = S(result).replaceAll("{", "{\n").s
  result = S(result).replaceAll("},", "\n},\n").s
  result = S(result).replaceAll("[", "[\n").s
  result = S(result).replaceAll("],", "\n],\n").s
  var lines = result.split("\n")
  result = []
  for (var i=0; i < lines.length; i++) {
    var line = fixUpLine(lines[i])
    if (line.length > 0) {
      result.push(line)
    }
  }

  result = result.join("\n")
  result = S(result).replaceAll("{\n", "{ ").s
  result = S(result).replaceAll("[\n", "[ ").s
  result = S(result).replaceAll("\n}", " }").s
  result = S(result).replaceAll("\n]", " ]").s

  try {
    return JSON.parse(result)
  } catch (e) { }

  return result
}

module.exports = parse
<commit_msg>restore quoteEscape<commit_after>'use strict';

var S = require('string')
var quoteEscape = "`~`"

// "users": { "briansturgill": true, jonamorua: true },

// but:
// users: { "some": "this, that: other" } is ok

function isAlpha(char) {
  return ((char >= 'a' && char <= 'z') || (char >= 'A' && char <= 'Z'))
}

function fixSubLine(subline) {
  var firstQuote = subline.indexOf('"')
  var firstColon = subline.indexOf(':')
  var first = subline.substr(0,1)
  if (firstColon >= 0 && isAlpha(first)) {
    if (firstQuote < 0 || firstQuote > firstColon) {
      subline = '"' + subline
      subline = subline.replace(':', '":')
    }
  }
  return subline
}

function fixUpLine(line) {
  line = S(line).trim().s
  var first = line.substr(0,1)
  if (line.length > 0 && isAlpha(first)) {
    line = '"' + line
    line = line.replace(':', '":')
    var sub = line.split(', ')
    for (var i=1; i < sub.length; i++) {
      sub[i] = fixSubLine(sub[i])
    }
    line = sub.join(', ')
  }
  return line
}

function parse(jsObjString) {
  var result = S(jsObjString).replaceAll('"', quoteEscape).s
  result = S(result).replaceAll("'", '"').s
  result = S(result).replaceAll("{", "{\n").s
  result = S(result).replaceAll("},", "\n},\n").s
  result = S(result).replaceAll("[", "[\n").s
  result = S(result).replaceAll("],", "\n],\n").s
  var lines = result.split("\n")
  result = []
  for (var i=0; i < lines.length; i++) {
    var line = fixUpLine(lines[i])
    if (line.length > 0) {
      result.push(line)
    }
  }

  result = result.join("\n")
  result = S(result).replaceAll("{\n", "{ ").s
  result = S(result).replaceAll("[\n", "[ ").s
  result = S(result).replaceAll("\n}", " }").s
  result = S(result).replaceAll("\n]", " ]").s

  result = S(result).replaceAll(quoteEscape, '"').s

  try {
    return JSON.parse(result)
  } catch (e) { }

  return result
}

module.exports = parse
<|endoftext|>


<commit_before>var test = require('tape');
var polygon = require('./');

test('polygon', function(t){
  t.plan(6);

  var poly = polygon([[[5, 10], [20, 40], [40, 0]]], {name: 'test polygon'});

  t.ok(poly);
  t.equal(poly.geometry.coordinates[0][0][0], 5);
  t.equal(poly.geometry.coordinates[0][1][0], 20);
  t.equal(poly.geometry.coordinates[0][2][0], 40);
  t.equal(poly.properties.name, 'test polygon');
  t.equal(poly.geometry.type, 'Polygon');
});<commit_msg>Add test for complete LinearRings in coordinate input<commit_after>var test = require('tape');
var polygon = require('./');

test('polygon', function(t){
  t.plan(7);

  var poly = polygon([[[5, 10], [20, 40], [40, 0]]], {name: 'test polygon'});

  t.ok(poly);
  t.equal(poly.geometry.coordinates[0][0][0], 5);
  t.equal(poly.geometry.coordinates[0][1][0], 20);
  t.equal(poly.geometry.coordinates[0][2][0], 40);
  t.equal(poly.properties.name, 'test polygon');
  t.equal(poly.geometry.type, 'Polygon');
  t.equal(polygon([[[20.0,0.0],[101.0,0.0],[101.0,1.0],[100.0,1.0],[100.0,0.0]]]).message, 'First and last coordinate pair are not equivalent', 'returns an error message');
});
<|endoftext|>


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

var watch = require('fs-watch').Watcher,
    nopt = require('nopt'),
    path = require('path'),
    spawn = require('child_process').spawn,
    debounce = require('lodash.debounce'),
    blocked = false,
    process,
    command,
    watcher

var noptions = {
  root: Array,
  files: Array,
  dirs: Array,
  notfiles: Array,
  notdirs: Array,
  verbose: Boolean,
  help: Boolean,
  version: Boolean
},
    shorts = {
  r: ['--root'],
  d: ['--dirs'],
  f: ['--files'],
  D: ['--notdirs'],
  F: ['--notfiles'],
  v: ['--verbose'],
  h: ['--help'],
  V: ['--version']
},
options = nopt(noptions, shorts, process.argv)
command = options.argv.remain

if (!command.length || options.help) return help()

watcher = new Watcher()

watcher.on('any', debounce(trigger_command))

function trigger_command() {
  if (blocked) return console.log('previous process still running')
  blocked = true
  var child = spawn(command[0], command.slice(1))
  child.on('close', finish_child)

  if (options.verbose) {
    child.process.stdout.pipe(process.stdout)
    child.process.stderr.pipe(process.stderr)
  }

  function finish_child(code) {
    if (code !== 0) process.stderr.write('command exited with code ' + code)
    blocked = false
  }

}

watcher.start()
<commit_msg>uglay<commit_after>#!/usr/bin/env node

var Watcher = require('fs-watch').Watcher,
    nopt = require('nopt'),
    path = require('path'),
    spawn = require('child_process').spawn,
    debounce = require('lodash.debounce'),
    blocked = false,
    command,
    watcher

var noptions = {
  root: Array,
  files: Array,
  dirs: Array,
  notfiles: Array,
  notdirs: Array,
  wait: Number,
  verbose: Boolean,
  help: Boolean,
  version: Boolean
},
    shorts = {
  r: ['--root'],
  d: ['--dirs'],
  f: ['--files'],
  w: ['--wait'],
  D: ['--notdirs'],
  F: ['--notfiles'],
  v: ['--verbose'],
  h: ['--help'],
  V: ['--version']
},
options = nopt(noptions, shorts, process.argv)
command = options.argv.remain

if (!command.length || options.help) return help()
if (!options.root || !options.root.length) options.root = [process.cwd()]
if (!options.wait) options.wait = 1000

function make_filter(type) {
  var not_array = type === 'file' ? options.notfiles : options.notdirs,
      good_array = type === 'file' ? options.files : options.dirs,
  not_array = (not_array || []).map(regex)
  good_array = (good_array || []).map(regex)

  return function (path) {
    for (var i = 0, l = good_array.length; i < l; ++i) {
      if (compiled[i].test(path)) return true
    }
    for (var i = 0, l = not_array.length; i < l; ++i) {
      if (compiled[i].test(path)) return false
    }
    return true
  }

  function regex(str) {
    return new RegExp(str)
  }
}

function dir_filter() {
}

var watcher_options = { paths: options.root, filters: {} }

watcher = new Watcher(watcher_options)

watcher.on('any', debounce(trigger_command, options.wait))

function trigger_command() {
  if (blocked) return console.log('previous process still running')
  blocked = true
  var child = spawn(command[0], command.slice(1))
  child.on('close', finish_child)

  if (options.verbose) {
    child.process.stdout.pipe(process.stdout)
    child.process.stderr.pipe(process.stderr)
  }

  function finish_child(code) {
    if (code !== 0) process.stderr.write('command exited with code ' + code)
    blocked = false
  }

}

watcher.start()
<|endoftext|>


<commit_before>'use strict';

var path = require('path');
var fs = require('fs');
var resolve = require('resolve');
var minimatch = require('minimatch');
var browserBuiltins = require('browser-builtins');

var startClientFile = path.normalize(__dirname + '/start-client.js');

function framework(files) {
  files.push({
    pattern: startClientFile,
    included: true,
    served: true,
    watched: false
  });
}

function createPreprocessor(config, basePath, logger) {
  var log = logger.create('preprocessor.common_js');
  var seenNpmFiles = [];
  var npmFilesPerModule = {};
  var transforms = config.transforms || {};
  var autostartPatterns = config.autoRequire || ['**/*.js'];

  function shouldAutoStart(filepath) {
    for (var i = 0; i < autostartPatterns.length; i++) {
      if (minimatch(filepath, autostartPatterns[i])) {
        return true;
      }
    }
    return false;
  }

  function process(content, file, done) {
    log.debug('Processing "%s"', file.originalPath);
    // operations contains the number of files to process that
    // this scope is currently waiting for. If it's 0 at the end
    // of the scope it means we don't have to wait, and we can call
    // `done()`
    var operations = 0;

    var filePath = path.dirname(file.originalPath);
    var wrappedContent = '';

    var aliases = '';

    var wrapperHead =
      'window.__cjsModules = window.__cjsModules || {};' +
      'window.__cjsModules["' + file.originalPath + '"] = ' +
        'function (require, module, exports, global, __filename, __dirname, process) {';
    var wrapperFoot = '\n};window.__cjsModules["' + file.originalPath + '"].autostart = ' + shouldAutoStart(file.originalPath);

    // If the file is something other than a .js file, we have
    // to add .js to make Karma serve it as a js file.
    // This is for things like transforming an .html file
    // to a CommonJS module.
    if (file.path.indexOf('.js') !== file.path.length - 3) {
      file.path = file.path + '.js';
    }

    // If a file was reloaded that contained one or more
    // modules from node_modules, we have to make sure
    // that we reload them as well by removing them from
    // seenNpmFiles
    if (npmFilesPerModule[file.originalPath]) {
      npmFilesPerModule[file.originalPath].forEach(function (npmModulePath) {
        seenNpmFiles.splice(seenNpmFiles.indexOf(npmModulePath), 1);
      });
    }

    function replaceModuleName(match, moduleName) {
      var modulePath;
      try {
        if (moduleName.charAt(0) === '.') {
          modulePath = require.resolve(path.resolve(filePath, moduleName));
        } else {
          if (moduleName in browserBuiltins) {
            modulePath = browserBuiltins[moduleName];
          } else {
            var opts = {
              basedir: filePath,
              packageFilter: function (info) {
                if (typeof info.browserify === 'string' && !info.browser) {
                  info.browser = info.browserify;
                }

                if (!info.browser) {
                  return info;
                }
                // replace main
                if (typeof info.browser === 'string') {
                  info.main = info.browser;
                  return info;
                }
                var replace_main = info.browser[info.main || './index.js'] || info.browser['./' + info.main || './index.js'];
                info.main = replace_main || info.main;
                return info;
              }
            };
            modulePath = resolve.sync(moduleName, opts);

            // In the client we need to be able to map the npm name to
            // the absolute path, since we allow stubbing out modules.
            // So when you say you want to stub out 'jquery' in the client
            // we need to know the physical path to the jquery file.
            aliases +=
              'window.__cjsModuleAliases = window.__cjsModuleAliases || {};' +
              'window.__cjsModuleAliases["' + moduleName + '"] = "' + modulePath + '";';
          }
        }
        log.debug('Replacing require "%s" with "%s"', moduleName, modulePath);
      } catch (e) {
        log.error('Failed to resolve "%s" in %s', moduleName, file.originalPath);
        throw e;
      }

      // Since you don't want to specify your npm modules in karma.conf.js, we check
      // for a node_modules folder in it's path. If we see it, it means that
      // we have to call `process()` on in because Karma won't call `process()` for
      // us with that file.
      // This means that if `my-module.js` requires `jquery` from node_modules,
      // we'll append the contents of `jquery` in `my-module.js` when karma serves it.
      // This has the unfortunate behaviour that any error in jquery.js will be seen
      // as the error occured in `my-module.js`, but there's not a lot to be about that.
      // At least you get the correct line numbers for errors in `my-module.js`.
      if (modulePath.indexOf('/node_modules/') !== -1 && seenNpmFiles.indexOf(modulePath) === -1) {
        operations++;

        seenNpmFiles.push(modulePath);
        if (!npmFilesPerModule[file.originalPath]) {
          npmFilesPerModule[file.originalPath] = [];
        }
        npmFilesPerModule[file.originalPath].push(modulePath);

        fs.readFile(modulePath, function (err, npmFileContent) {
          if (err) {
            log.error('Cannot read "%s"', modulePath);
            return;
          }

          process(npmFileContent.toString(), {originalPath: modulePath, path: modulePath}, function (npmContent) {
            operations--;
            wrappedContent += '\n' + npmContent;
            if (!operations) {
              log.debug('Done processing "%s"', file.originalPath);
              done(wrappedContent);
            }
          });
        });
      }
      return match.replace(/require\(.*?\)/, 'require("' + modulePath + '")');
    }

    var processedContent = content;

    // Allow Browserify streams to process the file first
    Object.keys(transforms).forEach(function (transformName) {
      if (transforms[transformName].exclude) {
        var excludePatterns = [];
        if (!Array.isArray(transforms[transformName].exclude)) {
          excludePatterns.push(transforms[transformName].exclude);
        } else {
          excludePatterns = transforms[transformName].exclude;
        }

        for (var i = 0; i < excludePatterns.length; i++) {
          var pattern = excludePatterns[i];
          if (minimatch(file.originalPath, pattern)) {
            log.debug('Excluding "' + file.originalPath + '" for the "' + transformName + '" transform');
            return;
          }
        }
      }
      log.debug('Running transform "' + transformName + '" on "' + file.originalPath + '"');
      var transformer = require(transformName);
      var stream = transformer(file.originalPath);

      stream.on('data', function (d) {
        processedContent = d;
      });
      stream.write(processedContent);
      stream.end();
    });

    var usesGlobalBuffer = (processedContent.indexOf('new Buffer') !== -1);
    var isBufferModule = (file.originalPath.indexOf('browser-builtins/node_modules/buffer/index.js') !== -1);

    // If any module uses the global Buffer constructor, we want to replace that with a call to require it first
    if (usesGlobalBuffer && !isBufferModule) {
      processedContent = processedContent.replace(/new Buffer/g, "new require('buffer').Buffer");
    }

    processedContent = processedContent.replace(/^(?!\s*[\/\/|\*]).*require\(["']([^\)]+)["'][,\)]/mg, replaceModuleName);

    wrappedContent = aliases + wrapperHead + processedContent + wrapperFoot;

    if (!operations) {
      log.debug('Done processing "%s"', file.originalPath);
      done(wrappedContent);
    }
  }

  return process;
}

framework.$inject = ['config.files'];
createPreprocessor.$inject = ['config.common_js', 'config.basePath', 'logger'];

module.exports = {
  'framework:common_js': ['factory', framework],
  'preprocessor:common_js': ['factory', createPreprocessor]
};
<commit_msg>Don't throw preprocess error for unknown modules<commit_after>'use strict';

var path = require('path');
var fs = require('fs');
var resolve = require('resolve');
var minimatch = require('minimatch');
var browserBuiltins = require('browser-builtins');

var startClientFile = path.normalize(__dirname + '/start-client.js');

function framework(files) {
  files.push({
    pattern: startClientFile,
    included: true,
    served: true,
    watched: false
  });
}

function createPreprocessor(config, basePath, logger) {
  var log = logger.create('preprocessor.common_js');
  var seenNpmFiles = [];
  var npmFilesPerModule = {};
  var transforms = config.transforms || {};
  var autostartPatterns = config.autoRequire || ['**/*.js'];

  function shouldAutoStart(filepath) {
    for (var i = 0; i < autostartPatterns.length; i++) {
      if (minimatch(filepath, autostartPatterns[i])) {
        return true;
      }
    }
    return false;
  }

  function process(content, file, done) {
    log.debug('Processing "%s"', file.originalPath);
    // operations contains the number of files to process that
    // this scope is currently waiting for. If it's 0 at the end
    // of the scope it means we don't have to wait, and we can call
    // `done()`
    var operations = 0;

    var filePath = path.dirname(file.originalPath);
    var wrappedContent = '';

    var aliases = '';

    var wrapperHead =
      'window.__cjsModules = window.__cjsModules || {};' +
      'window.__cjsModules["' + file.originalPath + '"] = ' +
        'function (require, module, exports, global, __filename, __dirname, process) {';
    var wrapperFoot = '\n};window.__cjsModules["' + file.originalPath + '"].autostart = ' + shouldAutoStart(file.originalPath);

    // If the file is something other than a .js file, we have
    // to add .js to make Karma serve it as a js file.
    // This is for things like transforming an .html file
    // to a CommonJS module.
    if (file.path.indexOf('.js') !== file.path.length - 3) {
      file.path = file.path + '.js';
    }

    // If a file was reloaded that contained one or more
    // modules from node_modules, we have to make sure
    // that we reload them as well by removing them from
    // seenNpmFiles
    if (npmFilesPerModule[file.originalPath]) {
      npmFilesPerModule[file.originalPath].forEach(function (npmModulePath) {
        seenNpmFiles.splice(seenNpmFiles.indexOf(npmModulePath), 1);
      });
    }

    function replaceModuleName(match, moduleName) {
      var modulePath;
      try {
        if (moduleName.charAt(0) === '.') {
          modulePath = require.resolve(path.resolve(filePath, moduleName));
        } else {
          if (moduleName in browserBuiltins) {
            modulePath = browserBuiltins[moduleName];
          } else {
            var opts = {
              basedir: filePath,
              packageFilter: function (info) {
                if (typeof info.browserify === 'string' && !info.browser) {
                  info.browser = info.browserify;
                }

                if (!info.browser) {
                  return info;
                }
                // replace main
                if (typeof info.browser === 'string') {
                  info.main = info.browser;
                  return info;
                }
                var replaceMain = info.browser[info.main || './index.js'] || info.browser['./' + info.main || './index.js'];
                info.main = replaceMain || info.main;
                return info;
              }
            };
            modulePath = resolve.sync(moduleName, opts);

            // In the client we need to be able to map the npm name to
            // the absolute path, since we allow stubbing out modules.
            // So when you say you want to stub out 'jquery' in the client
            // we need to know the physical path to the jquery file.
            aliases +=
              'window.__cjsModuleAliases = window.__cjsModuleAliases || {};' +
              'window.__cjsModuleAliases["' + moduleName + '"] = "' + modulePath + '";';
          }
        }
        log.debug('Replacing require "%s" with "%s"', moduleName, modulePath);
      } catch (e) {
        modulePath = moduleName;
        log.debug('Replacing require "%s" with "%s"', moduleName, modulePath);
      }

      // Since you don't want to specify your npm modules in karma.conf.js, we check
      // for a node_modules folder in it's path. If we see it, it means that
      // we have to call `process()` on in because Karma won't call `process()` for
      // us with that file.
      // This means that if `my-module.js` requires `jquery` from node_modules,
      // we'll append the contents of `jquery` in `my-module.js` when karma serves it.
      // This has the unfortunate behaviour that any error in jquery.js will be seen
      // as the error occured in `my-module.js`, but there's not a lot to be about that.
      // At least you get the correct line numbers for errors in `my-module.js`.
      if (modulePath.indexOf('/node_modules/') !== -1 && seenNpmFiles.indexOf(modulePath) === -1) {
        operations++;

        seenNpmFiles.push(modulePath);
        if (!npmFilesPerModule[file.originalPath]) {
          npmFilesPerModule[file.originalPath] = [];
        }
        npmFilesPerModule[file.originalPath].push(modulePath);

        fs.readFile(modulePath, function (err, npmFileContent) {
          if (err) {
            log.error('Cannot read "%s"', modulePath);
            return;
          }

          process(npmFileContent.toString(), {originalPath: modulePath, path: modulePath}, function (npmContent) {
            operations--;
            wrappedContent += '\n' + npmContent;
            if (!operations) {
              log.debug('Done processing "%s"', file.originalPath);
              done(wrappedContent);
            }
          });
        });
      }
      return match.replace(/require\(.*?\)/, 'require("' + modulePath + '")');
    }

    var processedContent = content;

    // Allow Browserify streams to process the file first
    Object.keys(transforms).forEach(function (transformName) {
      if (transforms[transformName].exclude) {
        var excludePatterns = [];
        if (!Array.isArray(transforms[transformName].exclude)) {
          excludePatterns.push(transforms[transformName].exclude);
        } else {
          excludePatterns = transforms[transformName].exclude;
        }

        for (var i = 0; i < excludePatterns.length; i++) {
          var pattern = excludePatterns[i];
          if (minimatch(file.originalPath, pattern)) {
            log.debug('Excluding "' + file.originalPath + '" for the "' + transformName + '" transform');
            return;
          }
        }
      }
      log.debug('Running transform "' + transformName + '" on "' + file.originalPath + '"');
      var transformer = require(transformName);
      var stream = transformer(file.originalPath);

      stream.on('data', function (d) {
        processedContent = d;
      });
      stream.write(processedContent);
      stream.end();
    });

    var usesGlobalBuffer = (processedContent.indexOf('new Buffer') !== -1);
    var isBufferModule = (file.originalPath.indexOf('browser-builtins/node_modules/buffer/index.js') !== -1);

    // If any module uses the global Buffer constructor, we want to replace that with a call to require it first
    if (usesGlobalBuffer && !isBufferModule) {
      processedContent = processedContent.replace(/new Buffer/g, "new require('buffer').Buffer");
    }

    if (/\.json$/.test(file.originalPath)) {
      processedContent = 'module.exports = ' + processedContent;
    } else {
      processedContent = processedContent.replace(/^(?!\s*[\/\/|\*]).*require\(["']([^\)]+)["'][,\)]/mg, replaceModuleName);
    }

    wrappedContent = aliases + wrapperHead + processedContent + wrapperFoot;

    if (!operations) {
      log.debug('Done processing "%s"', file.originalPath);
      done(wrappedContent);
    }
  }

  return process;
}

framework.$inject = ['config.files'];
createPreprocessor.$inject = ['config.common_js', 'config.basePath', 'logger'];

module.exports = {
  'framework:common_js': ['factory', framework],
  'preprocessor:common_js': ['factory', createPreprocessor]
};
<|endoftext|>


<commit_before>var set = require('./index.js');
var assert = require('assert');

describe('mocha-let', function() {
  var object = {};
  set('object', () => object);

  context("in a sub-context", function() {
    var aDifferentObject = {};
    set('object', () => aDifferentObject);

    it("allows overriding the value of an existing property", function() {
      assert.equal(this.object, aDifferentObject);
    });

    var otherDependedValue = {};
    set('dependedValue', () => otherDependedValue);
    it("overriding the value of properties depended on by existing properties changes the value of the dependent property", function() {
      assert.equal(this.dependentObject.prop, otherDependedValue);
    });
  });

  it("allows accessing the return value of the given function as the specified property on `this`", function() {
    assert.equal(this.object, object);
  });

  // Can't use arrow functions for dependant objects because of lexical `this`.
  set('dependentObject', function() { return {prop: this.dependedValue}; });
  var dependedValue = {};
  set('dependedValue', () => dependedValue);
  it("allows dependencies between properties", function() {
    assert.equal(this.dependentObject.prop, dependedValue);
  });

  set('memoizedObject', () => ({}));
  it('memoizes the values of each property', function() {
    assert.equal(this.memoizedObject, this.memoizedObject);
  });
});
<commit_msg>Reorder tests to improve readability<commit_after>var set = require('./index.js');
var assert = require('assert');

describe('mocha-let', function() {
  var object = {};
  set('object', () => object);

  it("allows accessing the return value of the given function as the specified property on `this`", function() {
    assert.equal(this.object, object);
  });

  // Can't use arrow functions for dependant objects because of lexical `this`.
  set('dependentObject', function() { return {prop: this.dependedValue}; });
  var dependedValue = {};
  set('dependedValue', () => dependedValue);
  it("allows dependencies between properties", function() {
    assert.equal(this.dependentObject.prop, dependedValue);
  });

  set('memoizedObject', () => ({}));
  it('memoizes the values of each property', function() {
    assert.equal(this.memoizedObject, this.memoizedObject);
  });

  context("in a sub-context", function() {
    var aDifferentObject = {};
    set('object', () => aDifferentObject);

    it("allows overriding the value of an existing property", function() {
      assert.equal(this.object, aDifferentObject);
    });

    var otherDependedValue = {};
    set('dependedValue', () => otherDependedValue);
    it("overriding the value of properties depended on by existing properties changes the value of the dependent property", function() {
      assert.equal(this.dependentObject.prop, otherDependedValue);
    });
  });
});
<|endoftext|>


<commit_before>import test from 'ava';

const objc = require('./src/index.js');

test('string creation', t => {
  const NSString = objc.NSString;
  let string = NSString.stringWithString_('Hello World');
  t.is(String(string), 'Hello World');
});

test('primitive return values', t => {
  const NSString = objc.NSString;
  let string = NSString.stringWithString_('I am the doctor');
  let length = string.length();
  t.is(length, 15);
  t.is(typeof length, 'number');
});

test('load constant w/out bundle', t => {
  objc.import('AppKit');
  let NSFontAttributeName = objc.constant('NSFontAttributeName');

  t.is(NSFontAttributeName, 'NSFont');
});

test('load constant w/ bundle', t => {
  objc.import('AppKit');
  let NSFontAttributeName = objc.constant('NSFontAttributeName', 'AppKit');

  t.is(NSFontAttributeName, 'NSFont');
});

test('load constant w/ full bundle name', t => {
  objc.import('AppKit');
  let NSFontAttributeName = objc.constant('NSFontAttributeName', 'com.apple.AppKit');

  t.is(NSFontAttributeName, 'NSFont');
});

test.skip('get username using NSProcessInfo, convert to javascript string and compare the value to the username given by `os.userInfo()`', t => { // eslint-disable-line ava/no-skip-test
  const NSProcessInfo = objc.NSProcessInfo;
  const os = require('os');

  let processInfo = NSProcessInfo.processInfo();
  let username = processInfo.userName();

  t.is(String(username), os.userInfo().username);
});

// This one fails 100% reprodicible w/ "Misaligned pointer"
test.skip('primitive argument types', t => { // eslint-disable-line ava/no-skip-test
  const NSNumber = objc.NSNumber;

  let number = NSNumber.numberWithInt_(5);

  t.is(Number(number), 5);
});

test('inout parameters 1 (^@)', t => {
  const NSFileManager = objc.NSFileManager;
  let fm = NSFileManager.defaultManager();

  const filepath = '/Library/Caches/randomfilenamethatsurelydoesntexust.hey';
  fm.createFileAtPath_contents_attributes_(filepath, null, null);

  let error1 = objc.ref(null);
  let success1 = fm.removeItemAtPath_error_(filepath, error1);

  t.is(success1, true);
  t.is(typeof objc.deref(error1), 'undefined');

  let error2 = objc.ref(null);
  let success2 = fm.removeItemAtPath_error_(filepath, error2);

  t.is(success2, false);
  t.is(typeof objc.deref(error2), 'object');
});

test('inout parameters 2 (^@)', t => {
  const NSDictionary = objc.NSDictionary;
  const NSAppleScript = objc.NSAppleScript;
  let source = 'telll application "Safari" to get URL of current tab of window 1';

  let script = NSAppleScript.alloc().initWithSource_(source);

  let error = objc.ref(null);
  let success = script.compileAndReturnError_(error);

  t.is(success, false);
  t.is(objc.deref(error).isKindOfClass_(NSDictionary), true);
});
<commit_msg>New test: Automatic array conversion (JS array -> NSArray)<commit_after>import test from 'ava';

const objc = require('./src/index.js');

test('string creation', t => {
  const NSString = objc.NSString;
  let string = NSString.stringWithString_('Hello World');
  t.is(String(string), 'Hello World');
});

test('primitive return values', t => {
  const NSString = objc.NSString;
  let string = NSString.stringWithString_('I am the doctor');
  let length = string.length();
  t.is(length, 15);
  t.is(typeof length, 'number');
});

test('load constant w/out bundle', t => {
  objc.import('AppKit');
  let NSFontAttributeName = objc.constant('NSFontAttributeName');

  t.is(NSFontAttributeName, 'NSFont');
});

test('load constant w/ bundle', t => {
  objc.import('AppKit');
  let NSFontAttributeName = objc.constant('NSFontAttributeName', 'AppKit');

  t.is(NSFontAttributeName, 'NSFont');
});

test('load constant w/ full bundle name', t => {
  objc.import('AppKit');
  let NSFontAttributeName = objc.constant('NSFontAttributeName', 'com.apple.AppKit');

  t.is(NSFontAttributeName, 'NSFont');
});

test.skip('get username using NSProcessInfo, convert to javascript string and compare the value to the username given by `os.userInfo()`', t => { // eslint-disable-line ava/no-skip-test
  const NSProcessInfo = objc.NSProcessInfo;
  const os = require('os');

  let processInfo = NSProcessInfo.processInfo();
  let username = processInfo.userName();

  t.is(String(username), os.userInfo().username);
});

// This one fails 100% reprodicible w/ "Misaligned pointer"
test.skip('primitive argument types', t => { // eslint-disable-line ava/no-skip-test
  const NSNumber = objc.NSNumber;

  let number = NSNumber.numberWithInt_(5);

  t.is(Number(number), 5);
});

test('inout parameters 1 (^@)', t => {
  const NSFileManager = objc.NSFileManager;
  let fm = NSFileManager.defaultManager();

  const filepath = '/Library/Caches/randomfilenamethatsurelydoesntexust.hey';
  fm.createFileAtPath_contents_attributes_(filepath, null, null);

  let error1 = objc.ref(null);
  let success1 = fm.removeItemAtPath_error_(filepath, error1);

  t.is(success1, true);
  t.is(typeof objc.deref(error1), 'undefined');

  let error2 = objc.ref(null);
  let success2 = fm.removeItemAtPath_error_(filepath, error2);

  t.is(success2, false);
  t.is(typeof objc.deref(error2), 'object');
});

test('inout parameters 2 (^@)', t => {
  const NSDictionary = objc.NSDictionary;
  const NSAppleScript = objc.NSAppleScript;
  let source = 'telll application "Safari" to get URL of current tab of window 1';

  let script = NSAppleScript.alloc().initWithSource_(source);

  let error = objc.ref(null);
  let success = script.compileAndReturnError_(error);

  t.is(success, false);
  t.is(objc.deref(error).isKindOfClass_(NSDictionary), true);
});

test('Automatic array conversion (JS array -> NSArray)', t => {
  let NSArray = objc.NSArray;

  let inputArray = ['I', 'am', 'the', 'doctor'];
  let array = NSArray.arrayWithArray_(inputArray);

  inputArray.forEach((object, index) => {
    let str1 = String(object);
    let str2 = String(array.objectAtIndex_(index));
    t.is(str1, str2);
  });
});
<|endoftext|>


<commit_before>/* jshint node: true */
'use strict';
var path = require('path');
var mergeTrees = require('broccoli-merge-trees');
var Funnel = require('broccoli-funnel');
var unwatchedTree = require('broccoli-unwatched-tree');

module.exports = {
  name: 'ember-cli-mirage',

  options: {
    nodeAssets: {
      'route-recognizer': npmAsset({
        path: 'dist/route-recognizer.js',
        sourceMap: 'dist/route-recognizer.js.map'
      }),
      'fake-xml-http-request': npmAsset('fake_xml_http_request.js'),
      'pretender': npmAsset('pretender.js'),
      'faker': npmAsset('build/build/faker.js')
    }
  },

  included: function included(app) {
    // see: https://github.com/ember-cli/ember-cli/issues/3718
    if (typeof app.import !== 'function' && app.app) {
      app = app.app;
    }

    this.app = app;
    this.addonConfig = this.app.project.config(app.env)['ember-cli-mirage'] || {};
    this.addonBuildConfig = this.app.options['ember-cli-mirage'] || {};

    // Call super after initializing config so we can use _shouldIncludeFiles for the node assets
    this._super.included.apply(this, arguments);

    if (this.addonBuildConfig['directory']) {
      this.mirageDirectory = this.addonBuildConfig['directory'];
    } else if (this.addonConfig['directory']) {
      this.mirageDirectory = this.addonConfig['directory'];
    } else if (app.project.pkg['ember-addon'] && !app.project.pkg['ember-addon'].paths) {
      this.mirageDirectory = path.resolve(app.project.root, path.join('tests', 'dummy', 'mirage'));
    } else {
      this.mirageDirectory = path.join(this.app.project.root, '/mirage');
    }

    if (this._shouldIncludeFiles()) {
      app.import('vendor/ember-cli-mirage/pretender-shim.js', {
        type: 'vendor',
        exports: { 'pretender': ['default'] }
      });
    }
  },

  blueprintsPath: function() {
    return path.join(__dirname, 'blueprints');
  },

  treeFor: function(name) {
    if (!this._shouldIncludeFiles()) {
      return;
    }

    return this._super.treeFor.apply(this, arguments);
  },

  _lintMirageTree: function(mirageTree) {
    var lintedMirageTrees;
    // _eachProjectAddonInvoke was added in ember-cli@2.5.0
    // this conditional can be removed when we no longer support
    // versions older than 2.5.0
    if (this._eachProjectAddonInvoke) {
      lintedMirageTrees = this._eachProjectAddonInvoke('lintTree', ['mirage', mirageTree]);
    } else {
      lintedMirageTrees = this.project.addons.map(function(addon) {
        if (addon.lintTree) {
          return addon.lintTree('mirage', mirageTree);
        }
      }).filter(Boolean);
    }

    var lintedMirage = mergeTrees(lintedMirageTrees, {
      overwrite: true,
      annotation: 'TreeMerger (mirage-lint)'
    });

    return new Funnel(lintedMirage, {
      destDir: 'tests/mirage/'
    });
  },

  treeForApp: function(appTree) {
    var trees = [ appTree ];
    var mirageFilesTree = new Funnel(this.mirageDirectory, {
      destDir: 'mirage'
    });
    trees.push(mirageFilesTree);

    if (this.hintingEnabled()) {
      trees.push(this._lintMirageTree(mirageFilesTree));
    }

    return mergeTrees(trees);
  },

  _shouldIncludeFiles: function() {
    if (process.env.EMBER_CLI_FASTBOOT) { return false; }
    var enabledInProd = this.app.env === 'production' && this.addonConfig.enabled;
    var explicitExcludeFiles = this.addonConfig.excludeFilesFromBuild;
    if (enabledInProd && explicitExcludeFiles) {
      throw new Error('Mirage was explicitly enabled in production, but its files were excluded ' +
                      'from the build. Please, use only ENV[\'ember-cli-mirage\'].enabled in ' +
                      'production environment.');
    }
    return enabledInProd || (this.app.env !== 'production' && explicitExcludeFiles !== true);
  }
};

function npmAsset(filePath) {
  return function() {
    return {
      enabled: this._shouldIncludeFiles(),
      import: [filePath]
    };
  };
}
<commit_msg>updated<commit_after>/* jshint node: true */
'use strict';
var path = require('path');
var mergeTrees = require('broccoli-merge-trees');
var Funnel = require('broccoli-funnel');
var unwatchedTree = require('broccoli-unwatched-tree');

module.exports = {
  name: 'ember-cli-mirage',

  options: {
    nodeAssets: {
      'route-recognizer': npmAsset({
        path: 'dist/route-recognizer.js',
        sourceMap: 'dist/route-recognizer.js.map'
      }),
      'fake-xml-http-request': npmAsset('fake_xml_http_request.js'),
      'pretender': npmAsset('pretender.js'),
      'faker': npmAsset('build/build/faker.js')
    }
  },

  included: function included(app) {
    // see: https://github.com/ember-cli/ember-cli/issues/3718
    if (typeof app.import !== 'function' && app.app) {
      app = app.app;
    }

    this.app = app;
    this.addonConfig = this.app.project.config(app.env)['ember-cli-mirage'] || {};
    this.addonBuildConfig = this.app.options['ember-cli-mirage'] || {};

    // Call super after initializing config so we can use _shouldIncludeFiles for the node assets
    this._super.included.apply(this, arguments);

    if (this.addonBuildConfig['directory']) {
      this.mirageDirectory = this.addonBuildConfig['directory'];
    } else if (this.addonConfig['directory']) {
      this.mirageDirectory = this.addonConfig['directory'];
    } else if (app.project.pkg['ember-addon'] && !app.project.pkg['ember-addon'].paths) {
      this.mirageDirectory = path.resolve(app.project.root, path.join('tests', 'dummy', 'mirage'));
    } else {
      this.mirageDirectory = path.join(this.app.project.root, '/mirage');
    }

    if (this._shouldIncludeFiles()) {
      app.import('vendor/ember-cli-mirage/pretender-shim.js', {
        type: 'vendor',
        exports: { 'pretender': ['default'] }
      });
    }
  },

  blueprintsPath: function() {
    return path.join(__dirname, 'blueprints');
  },

  treeFor: function(name) {
    if (!this._shouldIncludeFiles()) {
      return;
    }

    return this._super.treeFor.apply(this, arguments);
  },

  _lintMirageTree: function(mirageTree) {
    var lintedMirageTrees;
    // _eachProjectAddonInvoke was added in ember-cli@2.5.0
    // this conditional can be removed when we no longer support
    // versions older than 2.5.0
    if (this._eachProjectAddonInvoke) {
      lintedMirageTrees = this._eachProjectAddonInvoke('lintTree', ['mirage', mirageTree]);
    } else {
      lintedMirageTrees = this.project.addons.map(function(addon) {
        if (addon.lintTree) {
          return addon.lintTree('mirage', mirageTree);
        }
      }).filter(Boolean);
    }

    var lintedMirage = mergeTrees(lintedMirageTrees, {
      overwrite: true,
      annotation: 'TreeMerger (mirage-lint)'
    });

    return new Funnel(lintedMirage, {
      destDir: 'tests/mirage/'
    });
  },

  treeForApp: function(appTree) {
    var trees = [ appTree ];
    var mirageFilesTree = new Funnel(this.mirageDirectory, {
      destDir: 'mirage'
    });
    trees.push(mirageFilesTree);

    if (this.hintingEnabled()) {
      trees.push(this._lintMirageTree(mirageFilesTree));
    }

    return mergeTrees(trees);
  },

  _shouldIncludeFiles: function() {
    if (process.env.EMBER_CLI_FASTBOOT) { return false; }
    var environment = this.app.env;
    var enabledInProd = environment === 'production' && this.addonConfig.enabled;
    var explicitExcludeFiles = this.addonConfig.excludeFilesFromBuild;
    if (enabledInProd && explicitExcludeFiles) {
      throw new Error('Mirage was explicitly enabled in production, but its files were excluded ' +
                      'from the build. Please, use only ENV[\'ember-cli-mirage\'].enabled in ' +
                      'production environment.');
    }
    return enabledInProd || (environment && environment !== 'production' && explicitExcludeFiles !== true);
  }
};

function npmAsset(filePath) {
  return function() {
    return {
      enabled: this._shouldIncludeFiles(),
      import: [filePath]
    };
  };
}
<|endoftext|>


<commit_before>module.exports = {
    plugins: [
        // foo.default -> foo["default"]
        require('babel-plugin-transform-es3-member-expression-literals'),
        // default: "bar" -> "default": "bar"
        require('babel-plugin-transform-es3-property-literals'),
        // "use strict"
        require('babel-plugin-transform-strict-mode')
    ],
    sourceMaps: "inline"
};

// __VERSION__
const fs = require('fs');
if (fs.statSync('package.json').isFile()) {
    module.exports.plugins.push(require('babel-plugin-version-inline').default);
}
<commit_msg>don't fail if package.json is missing<commit_after>module.exports = {
    plugins: [
        // foo.default -> foo["default"]
        require('babel-plugin-transform-es3-member-expression-literals'),
        // default: "bar" -> "default": "bar"
        require('babel-plugin-transform-es3-property-literals'),
        // "use strict"
        require('babel-plugin-transform-strict-mode')
    ],
    sourceMaps: "inline"
};

// __VERSION__
const fs = require('fs');
try {
    if (fs.statSync('package.json').isFile()) {
        module.exports.plugins.push(require('babel-plugin-version-inline').default);
    }
} catch (err) {
    // ignore: ENOENT: no such file or directory, stat 'package.json'
}
<|endoftext|>


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

require('should');

const cp = require('child_process');
const path = require('path');
const streamSplitter = require('stream-splitter');
const Mqtt = require('mqtt');

mqtt = Mqtt.connect('mqtt://127.0.0.1');

const config = require('./example-homekit2mqtt.json');

const homekitCmd = path.join(__dirname, '/index.js');
const homekitArgs = ['-v', 'debug'];
let homekit;
let homekitPipeOut;
let homekitPipeErr;
const homekitSubscriptions = {};
const homekitBuffer = [];

let subIndex = 0;

const clientCmd = path.join(__dirname, '/node_modules/.bin/hap-client-tool -d 127.0.0.1 -p 51826');
let clientAccs;

const mqttSubscriptions = {};
function mqttSubscribe(topic, callback) {
    if (mqttSubscriptions[topic]) {
        mqttSubscriptions[topic].push(callback);
    } else {
        mqttSubscriptions[topic] = [callback];
        mqtt.subscribe(topic);
    }
}
mqtt.on('message', (topic, payload) => {
    if (mqttSubscriptions[topic]) {
        mqttSubscriptions[topic].forEach(callback => {
            callback(payload.toString());
        });
    }
});

function subscribe(type, rx, cb) {
    subIndex += 1;
    if (type === 'sim') {
        simSubscriptions[subIndex] = {rx, cb};
    } else if (type === 'homekit') {
        homekitSubscriptions[subIndex] = {rx, cb};
    }
    matchSubscriptions(type);
    return subIndex;
}

function unsubscribe(type, subIndex) {
    if (type === 'sim') {
        delete simSubscriptions[subIndex];
    } else if (type === 'homekit') {
        delete homekitSubscriptions[subIndex];
    }
}

function matchSubscriptions(type, data) {
    let subs;
    let buf;
    if (type === 'sim') {
        subs = simSubscriptions;
        buf = simBuffer;
    } else if (type === 'homekit') {
        subs = homekitSubscriptions;
        buf = homekitBuffer;
    }
    if (data) {
        buf.push(data);
    }
    buf.forEach((line, index) => {
        Object.keys(subs).forEach(key => {
            const sub = subs[key];
            if (line.match(sub.rx)) {
                sub.cb(line);
                delete subs[key];
                buf.splice(index, 1);
            }
        });
    });
}

function startHomekit() {
    homekit = cp.spawn(homekitCmd, homekitArgs);
    homekitPipeOut = homekit.stdout.pipe(streamSplitter('\n'));
    homekitPipeErr = homekit.stderr.pipe(streamSplitter('\n'));
    homekitPipeOut.on('token', data => {
        console.log('homekit', data.toString());
        matchSubscriptions('homekit', data.toString());
    });
    homekitPipeErr.on('token', data => {
        console.log('homekit', data.toString());
        matchSubscriptions('homekit', data.toString());
    });
}

function end(code) {
    if (homekit.kill) {
        homekit.kill();
    }
    if (typeof code !== 'undefined') {
        process.exit(code);
    }
}

process.on('SIGINT', () => {
    end(1);
});

process.on('exit', () => {
    end();
});

describe('start homekit2mqtt', () => {
    it('should start without error', function (done) {
        this.timeout(20000);
        subscribe('homekit', /homekit2mqtt [0-9.]+ starting/, () => {
            done();
        });
        startHomekit();
    });
    it('should create accessories', function (done) {
        subscribe('homekit', /hap created [0-9]+ Accessories/, () => {
            done();
        });
    });
    it('should announce the bridge', function (done) {
        subscribe('homekit', /hap publishing bridge/, () => {
            done();
        });
    });
    it('should listen on port 51826', function (done) {
        subscribe('homekit', /hap Bridge listening on port 51826/, () => {
            done();
        });
    });
});

describe('homekit2mqtt - mqtt connection', () => {
    it('homekit2mqtt should connect to the mqtt broker', function (done) {
        this.timeout(12000);
        subscribe('homekit', /mqtt connected/, () => {
            done();
        });
    });
    it('should publish connected=2 on mqtt', function (done) {
        mqttSubscribe('homekit/connected', function (payload) {
            if (payload === '2') {
                done();
            }
        });
    });
});

let aidSwitch;
let iidSwitch;

describe('start dbus', function () {
    this.timeout(60000);
    it('should start dbus', done => {
        cp.exec('dbus-launch', (err, stdout, stderr) => {
            console.log('dbus err', err);
            console.log('dbus stdout', stdout);
            console.log('dbus stderr', stderr);
            setTimeout(done, 3000);
        });
    });
});

describe('hap-client - homekit2mqtt connection', function () {
    it('should pair without error', function (done)  {
        console.log('--- setting timeout to 60000');
        this.timeout(60000);
        console.log('--- subscribing...');
        subscribe('homekit', /hap paired/, () => {
            setTimeout(function () {
                done();
            }, 5000);
        });

        console.log('--- trying to pair...');
        var pair = cp.spawn(path.join(__dirname, '/node_modules/.bin/hap-client-tool'), ['-d', '127.0.0.1', '-p', '51826', 'pair'], {shell: true});

        setTimeout(function () {
            console.log('--- writing pin to stdin');
            pair.stdin.write('031-45-154\n');
            pair.stdin.write('\n');
        }, 5000);

        var pairPipeOut = pair.stdout.pipe(streamSplitter('\n'));
        var pairPipeErr = pair.stderr.pipe(streamSplitter('\n'));
        pairPipeOut.on('token', data => {
            console.log('pair', data.toString());
        });

        pairPipeErr.on('token', data => {
            console.log('pair', data.toString());
        });
        /*
        cp.exec('echo "031-45-154" | ' + clientCmd + ' pair', (err, stdout, stderr) => {
            console.log('client err', err);
            console.log('client stdout', stdout);
            console.log('client stderr', stderr);

        });
        */
    });
    it('should be able to dump accessories', (done) => {
        cp.exec(clientCmd + ' dump', (err, stdout, stderr) => {
            console.log('dump err', err);
            console.log('dump stdout', stdout);
            console.log('dump stderr', stderr);
            var clientAccs = JSON.parse(stdout).accessories;

            clientAccs.forEach(acc => {
                acc.services.forEach(service => {
                    if (service.Name === 'Switch') {
                        aidSwitch = acc.aid;
                        service.characteristics.forEach(ch => {
                            if (ch.Name === 'On') {
                                iidSwitch = ch.iid;

                            }
                        });

                    }
                });
            });
            // add one because the bridge itself is also an accessory
            if (clientAccs.length === (Object.keys(config).length + 1)) {
                done();
            }
        });
    });
    it('should get the status of the switch', (done) => {
        cp.exec(clientCmd + ' get --aid ' + aidSwitch + ' --iid ' + iidSwitch, (err, stdout, stderr) => {
            if (stdout === 'false\n') {
                done();
            }
        });
    });
});

describe('mqtt - homekit2mqtt - client', () => {
    it('homekit2mqtt should receive a status via mqtt and update it on hap', function (done) {
        this.timeout(12000);
        subscribe('homekit', /hap update Steckdose Fernseher On true/, () => {
            done();

        });
        mqtt.publish('Switch/status', '1');
    });
    it('client should get the status of the switch', (done) => {
        cp.exec(clientCmd + ' get --aid ' + aidSwitch + ' --iid ' + iidSwitch, (err, stdout, stderr) => {
            if (stdout === 'true\n') {
                done();
            }
        });
    });
    it('homekit2mqtt should receive a status via mqtt and update it on hap', function (done) {
        this.timeout(12000);
        subscribe('homekit', /hap update Steckdose Fernseher On false/, () => {
            done();

        });
        mqtt.publish('Switch/status', '0');
    });
    it('client should get the status of the switch', (done) => {
        cp.exec(clientCmd + ' get --aid ' + aidSwitch + ' --iid ' + iidSwitch, (err, stdout, stderr) => {
            if (stdout === 'false\n') {
                done();
            }
        });
    });
});

describe('client - homekit2mqtt - mqtt', () => {
    it('homekit2mqtt should publish on mqtt after client did a set', (done) => {
        mqttSubscribe('Switch/set', payload => {
            if (payload === '1') {
                done();
            }
        });
        cp.exec(clientCmd + ' set --aid ' + aidSwitch + ' --iid ' + iidSwitch + ' true');

    });
});

setTimeout(() => {
    homekit.kill();
    process.exit(1);
}, 30000);
<commit_msg>trial&error with hap client pairing. another really last try for today. seriously.<commit_after>#!/usr/bin/env node

require('should');

const cp = require('child_process');
const path = require('path');
const streamSplitter = require('stream-splitter');
const Mqtt = require('mqtt');

mqtt = Mqtt.connect('mqtt://127.0.0.1');

const config = require('./example-homekit2mqtt.json');

const homekitCmd = path.join(__dirname, '/index.js');
const homekitArgs = ['-v', 'debug'];
let homekit;
let homekitPipeOut;
let homekitPipeErr;
const homekitSubscriptions = {};
const homekitBuffer = [];

let subIndex = 0;

const clientCmd = path.join(__dirname, '/node_modules/.bin/hap-client-tool -d 127.0.0.1 -p 51826');
let clientAccs;

const mqttSubscriptions = {};
function mqttSubscribe(topic, callback) {
    if (mqttSubscriptions[topic]) {
        mqttSubscriptions[topic].push(callback);
    } else {
        mqttSubscriptions[topic] = [callback];
        mqtt.subscribe(topic);
    }
}
mqtt.on('message', (topic, payload) => {
    if (mqttSubscriptions[topic]) {
        mqttSubscriptions[topic].forEach(callback => {
            callback(payload.toString());
        });
    }
});

function subscribe(type, rx, cb) {
    subIndex += 1;
    if (type === 'sim') {
        simSubscriptions[subIndex] = {rx, cb};
    } else if (type === 'homekit') {
        homekitSubscriptions[subIndex] = {rx, cb};
    }
    matchSubscriptions(type);
    return subIndex;
}

function unsubscribe(type, subIndex) {
    if (type === 'sim') {
        delete simSubscriptions[subIndex];
    } else if (type === 'homekit') {
        delete homekitSubscriptions[subIndex];
    }
}

function matchSubscriptions(type, data) {
    let subs;
    let buf;
    if (type === 'sim') {
        subs = simSubscriptions;
        buf = simBuffer;
    } else if (type === 'homekit') {
        subs = homekitSubscriptions;
        buf = homekitBuffer;
    }
    if (data) {
        buf.push(data);
    }
    buf.forEach((line, index) => {
        Object.keys(subs).forEach(key => {
            const sub = subs[key];
            if (line.match(sub.rx)) {
                sub.cb(line);
                delete subs[key];
                buf.splice(index, 1);
            }
        });
    });
}

function startHomekit() {
    homekit = cp.spawn(homekitCmd, homekitArgs);
    homekitPipeOut = homekit.stdout.pipe(streamSplitter('\n'));
    homekitPipeErr = homekit.stderr.pipe(streamSplitter('\n'));
    homekitPipeOut.on('token', data => {
        console.log('homekit', data.toString());
        matchSubscriptions('homekit', data.toString());
    });
    homekitPipeErr.on('token', data => {
        console.log('homekit', data.toString());
        matchSubscriptions('homekit', data.toString());
    });
}

function end(code) {
    if (homekit.kill) {
        homekit.kill();
    }
    if (typeof code !== 'undefined') {
        process.exit(code);
    }
}

process.on('SIGINT', () => {
    end(1);
});

process.on('exit', () => {
    end();
});

describe('start homekit2mqtt', () => {
    it('should start without error', function (done) {
        this.timeout(20000);
        subscribe('homekit', /homekit2mqtt [0-9.]+ starting/, () => {
            done();
        });
        startHomekit();
    });
    it('should create accessories', function (done) {
        subscribe('homekit', /hap created [0-9]+ Accessories/, () => {
            done();
        });
    });
    it('should announce the bridge', function (done) {
        subscribe('homekit', /hap publishing bridge/, () => {
            done();
        });
    });
    it('should listen on port 51826', function (done) {
        subscribe('homekit', /hap Bridge listening on port 51826/, () => {
            done();
        });
    });
});

describe('homekit2mqtt - mqtt connection', () => {
    it('homekit2mqtt should connect to the mqtt broker', function (done) {
        this.timeout(12000);
        subscribe('homekit', /mqtt connected/, () => {
            done();
        });
    });
    it('should publish connected=2 on mqtt', function (done) {
        mqttSubscribe('homekit/connected', function (payload) {
            if (payload === '2') {
                done();
            }
        });
    });
});

let aidSwitch;
let iidSwitch;

describe('start dbus', function () {
    this.timeout(60000);
    it('should start dbus', done => {
        cp.exec('dbus-launch', (err, stdout, stderr) => {
            console.log('dbus err', err);
            console.log('dbus stdout', stdout);
            console.log('dbus stderr', stderr);
            setTimeout(done, 3000);
        });
    });
});

describe('hap-client - homekit2mqtt connection', function () {
    it('should pair without error', function (done)  {
        console.log('--- setting timeout to 60000');
        this.timeout(60000);
        console.log('--- subscribing...');
        subscribe('homekit', /hap paired/, () => {
            setTimeout(function () {
                done();
            }, 5000);
        });

        console.log('--- trying to pair...');
        var pair = cp.spawn(path.join(__dirname, '/node_modules/.bin/hap-client-tool'), ['-d', '127.0.0.1', '-p', '51826', 'pair'], {shell: true});

        pair.on('close', (code) => {
            console.log(`--- pair - child process exited with code ${code}`);
        });
        pair.on('error', (err) => {
            console.log('--- pair - Failed to start child process.', err);
        });
        setTimeout(function () {
            console.log('--- writing pin to stdin');
            pair.stdin.write('031-45-154\n');
            pair.stdin.write('\n');
        }, 5000);

        var pairPipeOut = pair.stdout.pipe(streamSplitter('\n'));
        var pairPipeErr = pair.stderr.pipe(streamSplitter('\n'));
        pairPipeOut.on('token', data => {
            console.log('pair', data.toString());
        });

        pairPipeErr.on('token', data => {
            console.log('pair', data.toString());
        });
        /*
        cp.exec('echo "031-45-154" | ' + clientCmd + ' pair', (err, stdout, stderr) => {
            console.log('client err', err);
            console.log('client stdout', stdout);
            console.log('client stderr', stderr);

        });
        */
    });
    it('should be able to dump accessories', (done) => {
        cp.exec(clientCmd + ' dump', (err, stdout, stderr) => {
            console.log('dump err', err);
            console.log('dump stdout', stdout);
            console.log('dump stderr', stderr);
            var clientAccs = JSON.parse(stdout).accessories;

            clientAccs.forEach(acc => {
                acc.services.forEach(service => {
                    if (service.Name === 'Switch') {
                        aidSwitch = acc.aid;
                        service.characteristics.forEach(ch => {
                            if (ch.Name === 'On') {
                                iidSwitch = ch.iid;

                            }
                        });

                    }
                });
            });
            // add one because the bridge itself is also an accessory
            if (clientAccs.length === (Object.keys(config).length + 1)) {
                done();
            }
        });
    });
    it('should get the status of the switch', (done) => {
        cp.exec(clientCmd + ' get --aid ' + aidSwitch + ' --iid ' + iidSwitch, (err, stdout, stderr) => {
            if (stdout === 'false\n') {
                done();
            }
        });
    });
});

describe('mqtt - homekit2mqtt - client', () => {
    it('homekit2mqtt should receive a status via mqtt and update it on hap', function (done) {
        this.timeout(12000);
        subscribe('homekit', /hap update Steckdose Fernseher On true/, () => {
            done();

        });
        mqtt.publish('Switch/status', '1');
    });
    it('client should get the status of the switch', (done) => {
        cp.exec(clientCmd + ' get --aid ' + aidSwitch + ' --iid ' + iidSwitch, (err, stdout, stderr) => {
            if (stdout === 'true\n') {
                done();
            }
        });
    });
    it('homekit2mqtt should receive a status via mqtt and update it on hap', function (done) {
        this.timeout(12000);
        subscribe('homekit', /hap update Steckdose Fernseher On false/, () => {
            done();

        });
        mqtt.publish('Switch/status', '0');
    });
    it('client should get the status of the switch', (done) => {
        cp.exec(clientCmd + ' get --aid ' + aidSwitch + ' --iid ' + iidSwitch, (err, stdout, stderr) => {
            if (stdout === 'false\n') {
                done();
            }
        });
    });
});

describe('client - homekit2mqtt - mqtt', () => {
    it('homekit2mqtt should publish on mqtt after client did a set', (done) => {
        mqttSubscribe('Switch/set', payload => {
            if (payload === '1') {
                done();
            }
        });
        cp.exec(clientCmd + ' set --aid ' + aidSwitch + ' --iid ' + iidSwitch + ' true');

    });
});

setTimeout(() => {
    homekit.kill();
    process.exit(1);
}, 30000);
<|endoftext|>


<commit_before>import EntityManager from './EntityManager';
import { TreeTypeService } from '../../services';
import DataManager from './DataManager';

/**
 * Tree structures
 *
 * @author Ondřej Kopr
 * @author Radek Tomiška
 */
export default class TreeTypeManager extends EntityManager {

  constructor() {
    super();
    this.service = new TreeTypeService();
    this.dataManager = new DataManager();
  }

  getService() {
    return this.service;
  }

  getEntityType() {
    return 'TreeType';
  }

  getCollectionType() {
    return 'treeTypes';
  }

  /**
   * Returns default tree type => organization structure
   *
   * @return {action}
   */
  fetchDefaultTreeType() {
    const uiKey = TreeTypeManager.UI_KEY_DEFAULT_TREE_TYPE;
    //
    return (dispatch) => {
      dispatch(this.dataManager.requestData(uiKey));
      this.getService().getDefaultTreeType()
        .then(json => {
          dispatch(this.receiveEntity(json.id, json, uiKey));
          dispatch(this.dataManager.receiveData(uiKey, json));
        })
        .catch(error => {
          if (error.statusCode === 404) {
              dispatch(this.dataManager.receiveData(uiKey, null));
          } else {
            // TODO: data uiKey
            dispatch(this.dataManager.receiveError(null, uiKey, error));
          }
        });
    };
  }
}

TreeTypeManager.UI_KEY_DEFAULT_TREE_TYPE = 'default-tree-type';
<commit_msg>fix: tree type manager - lint cleanup<commit_after>import EntityManager from './EntityManager';
import { TreeTypeService } from '../../services';
import DataManager from './DataManager';

/**
 * Tree structures
 *
 * @author Ondřej Kopr
 * @author Radek Tomiška
 */
export default class TreeTypeManager extends EntityManager {

  constructor() {
    super();
    this.service = new TreeTypeService();
    this.dataManager = new DataManager();
  }

  getService() {
    return this.service;
  }

  getEntityType() {
    return 'TreeType';
  }

  getCollectionType() {
    return 'treeTypes';
  }

  /**
   * Returns default tree type => organization structure
   *
   * @return {action}
   */
  fetchDefaultTreeType() {
    const uiKey = TreeTypeManager.UI_KEY_DEFAULT_TREE_TYPE;
    //
    return (dispatch) => {
      dispatch(this.dataManager.requestData(uiKey));
      this.getService().getDefaultTreeType()
        .then(json => {
          dispatch(this.receiveEntity(json.id, json, uiKey));
          dispatch(this.dataManager.receiveData(uiKey, json));
        })
        .catch(error => {
          if (error.statusCode === 404) {
            dispatch(this.dataManager.receiveData(uiKey, null));
          } else {
            // TODO: data uiKey
            dispatch(this.dataManager.receiveError(null, uiKey, error));
          }
        });
    };
  }
}

TreeTypeManager.UI_KEY_DEFAULT_TREE_TYPE = 'default-tree-type';
<|endoftext|>


<commit_before>'use strict';

var postcss = require('postcss');
var filterDeclarations = require('./');
var test = require('tape');

var fixture = [
  'a {',
  '  display: none;',
  '  border: 1px solid #000;',
  '}',
  '@media screen {',
  '  b:after {',
  '    content: "b";',
  '  }',
  '  @media (min-width: 300px) {',
  '    p q {',
  '      display: block;',
  '    }',
  '  }',
  '}'
].join('\n');

var includeDisplay = [
  'a {',
  '  display: none;',
  '}',
  '@media screen {',
  '  b:after {',
  '  }',
  '  @media (min-width: 300px) {',
  '    p q {',
  '      display: block;',
  '    }',
  '  }',
  '}'
].join('\n');

var includeBorderAndContent = [
  'a {',
  '  border: 1px solid #000;',
  '}',
  '@media screen {',
  '  b:after {',
  '    content: "b";',
  '  }',
  '  @media (min-width: 300px) {',
  '    p q {',
  '    }',
  '  }',
  '}'
].join('\n');

var includeNothing = [
  'a {',
  '}',
  '@media screen {',
  '  b:after {',
  '  }',
  '  @media (min-width: 300px) {',
  '    p q {',
  '    }',
  '  }',
  '}'
].join('\n');

test('filterDeclarations()', function(t) {
  t.plan(6);

  t.equal(
    postcss().use(filterDeclarations({props: 'display'})).process(fixture).css, includeDisplay,
    'should select the rules based on the property name.'
  );

  t.equal(
    postcss().use(filterDeclarations({properties: 'display'})).process(fixture).css,
    includeDisplay,
    'should use `properties` option as an alias of `props` option.'
  );

  t.equal(
    postcss().use(filterDeclarations({props: ['border', 'content']})).process(fixture).css,
    includeBorderAndContent,
    'should select the rules based on an array of the property names.'
  );

  t.equal(
    postcss().use(filterDeclarations({
      props: 'display',
      exclude: true
    })).process(fixture).css,
    includeBorderAndContent,
    'should exclude the rules based on the property name, using `exclude` option.'
  );

  t.equal(
    postcss().use(filterDeclarations({
      props: ['border', 'content'],
      exclude: true
    })).process(fixture).css,
    includeDisplay,
    'should exclude the rules based on an array of the property names, using `exclude` option.'
  );

  t.equal(
    postcss().use(filterDeclarations()).process(fixture).css, includeNothing,
    'should exclude all properties when it takes no arguments.'
  );
});
<commit_msg>add more tests to cover various cases<commit_after>'use strict';

var postcss = require('postcss');
var filterDeclarations = require('./');
var test = require('tape');

var fixture = [
  'a {',
  '  display: none;',
  '  border: 1px solid #000;',
  '}',
  '@media screen {',
  '  b:after {',
  '    content: "b";',
  '  }',
  '  @media (min-width: 300px) {',
  '    p q {',
  '      display: block;',
  '    }',
  '  }',
  '}'
].join('\n');

var includeDisplay = [
  'a {',
  '  display: none;',
  '}',
  '@media screen {',
  '  b:after {',
  '  }',
  '  @media (min-width: 300px) {',
  '    p q {',
  '      display: block;',
  '    }',
  '  }',
  '}'
].join('\n');

var includeBorderAndContent = [
  'a {',
  '  border: 1px solid #000;',
  '}',
  '@media screen {',
  '  b:after {',
  '    content: "b";',
  '  }',
  '  @media (min-width: 300px) {',
  '    p q {',
  '    }',
  '  }',
  '}'
].join('\n');

var includeNothing = [
  'a {',
  '}',
  '@media screen {',
  '  b:after {',
  '  }',
  '  @media (min-width: 300px) {',
  '    p q {',
  '    }',
  '  }',
  '}'
].join('\n');

test('postcssFilterDeclarations()', function(t) {
  t.plan(8);

  t.equal(filterDeclarations.name, 'postcssFilterDeclarations', 'should have a function name.');

  t.equal(
    postcss().use(filterDeclarations({properties: 'display'})).process(fixture).css,
    includeDisplay,
    'should select the rules based on the property name.'
  );

  t.equal(
    postcss().use(filterDeclarations({props: 'display'})).process(fixture).css,
    includeDisplay,
    'should use `props` option as an alias of `properties` option.'
  );

  t.equal(
    postcss().use(filterDeclarations({props: ['border', 'content']})).process(fixture).css,
    includeBorderAndContent,
    'should select the rules in response to the array of property names.'
  );

  var options = {
    props: ['border', 'content'],
    exclude: true
  };

  t.equal(
    postcss().use(filterDeclarations(options)).process(fixture).css,
    includeDisplay,
    'should exclude the rules in response to the property names, using `exclude` option.'
  );

  t.deepEqual(
    options,
    {
      props: ['border', 'content'],
      exclude: true
    },
    'should not modify the original option object.'
  );

  t.equal(
    postcss().use(filterDeclarations({properties: [{foo: 'bar'}, 123]})).process(fixture).css,
    includeNothing,
    'should ignore non-string values in the `properties` option.'
  );

  t.equal(
    postcss().use(filterDeclarations()).process(fixture).css,
    includeNothing,
    'should exclude all properties when it takes no arguments.'
  );
});
<|endoftext|>