<commit_before>asyncTest('Value test', function() {
    setTimeout(function() {
        $.address.value('/test');
        equals($.address.value(), '/test');
        setTimeout(function() {
            window.history.back();
        }, 500);
        start();
    }, 1000);
});

asyncTest('History test', function() {
    setTimeout(function() {
        equals($.address.value(), '/');
        setTimeout(function() {
            window.history.forward();
        }, 500);
        start();
    }, 1000);
});

asyncTest('Path names test', function() {
    setTimeout(function() {
        equals($.address.value(), '/test');
        same($.address.pathNames(), ['test']);
        start();
    }, 1000);
});

asyncTest('Path names test', function() {
    setTimeout(function() {
        $.address.value('/test/1/2/');
        same($.address.pathNames(), ['test', '1', '2']);
        start();
    }, 1000);
});

asyncTest('Path names test', function() {
    setTimeout(function() {
        $.address.value('/');
        same($.address.pathNames(), []);
        start();
    }, 1000);
});

asyncTest('Path names test', function() {
    setTimeout(function() {
        $.address.value('/test');
        same($.address.pathNames(), ['test']);
        start();
    }, 1000);
});

asyncTest('Query test', function() {
    setTimeout(function() {
        $.address.queryString('p=0');
        equals($.address.value(), '/test?p=0');
        equals($.address.path(), '/test');
        equals($.address.queryString(), 'p=0');
        start();
    }, 1000);
});

asyncTest('Parameter test', function() {
    setTimeout(function() {
        $.address.parameter('a', null);
        $.address.parameter('p', 1);
        equals($.address.value(), '/test?p=1');
        equals($.address.queryString(), 'p=1');
        equals($.address.parameter('p'), '1');
        start();
    }, 1000);
});

asyncTest('Parameter test', function() {
    setTimeout(function() {
        $.address.path('/test');
        $.address.parameter('p', 2, true);
        equals($.address.value(), '/test?p=1&p=2');
        equals($.address.queryString(), 'p=1&p=2');
        same($.address.parameter('p'), ['1','2']);
        same($.address.parameterNames(), ['p']);
        start();
    }, 1000);
});

asyncTest('Parameter test', function() {
    setTimeout(function() {
        $.address.autoUpdate(false)
            .queryString('')
            .parameter('p', 1, true)
            .parameter('p', 2)
            .parameter('p', 3, true)
            .parameter('s', 1)
            .parameter('s', 2, true)
            .parameter('s', 3)
            .parameter('t', 0)
            .parameter('t', null)
            .autoUpdate(true)
            .update();
        equals($.address.value(), '/test?p=2&p=3&s=3');
        same($.address.parameter('p'), ['2','3']);
        equals($.address.parameter('s'), 3);
        same($.address.parameterNames(), ['p','s']);
        start();
    }, 1000);
});

asyncTest('Parameter test', function() {
    setTimeout(function() {
        $.address.autoUpdate(false)
            .value('/')
            .parameter('p1', 'a#b')
            .parameter('p2', 'a&b')
            .autoUpdate(true)
            .update();
        equals($.address.value(), '/?p1=a#b&p2=a&b');
        equals($.address.parameter('p1'), 'a#b');
        equals($.address.parameter('p2'), 'a&b');
        start();
    }, 1000);
});

asyncTest('Parameter test', function() {
    setTimeout(function() {
        $.address.autoUpdate(false)
            .value('/')
            .queryString($.param({start: 0, order: 'index0'}))
            .autoUpdate(true)
            .update();
        equals($.address.parameter('start'), 0);
        equals($.address.parameter('order'), 'index0');
        start();
    }, 1000);
});

asyncTest('Parameter test', function() {
    setTimeout(function() {
        $.address.autoUpdate(false)
            .value('/')
            .parameter('data', $.param({start: 1, order: 'index1'}))
            .autoUpdate(true)
            .update();
        equals($.address.parameter('data'), $.param({start: 1, order:'index1'}));
        same($.address.parameterNames(), ['data']);
        start();
    }, 1000);
});

asyncTest('Hash test with parameters', function() {
    setTimeout(function() {
        $.address.path('/test');
        $.address.queryString('p=2&p=3&s=3');
        $.address.hash('comment-2');
        equals($.address.value(), '/test?p=2&p=3&s=3#comment-2');
        equals($.address.path(), '/test');
        equals($.address.parameter('p').toString(), '2,3');
        equals($.address.parameter('s').toString(), 3);
        equals($.address.hash(), 'comment-2');
        same($.address.parameterNames(), ['p','s']);
        start();
    }, 1000);
});

asyncTest('Hash test', function() {
    setTimeout(function() {
        $.address.value('/test');
        $.address.hash('comment-1');
        equals($.address.value(), '/test#comment-1');
        equals($.address.path(), '/test');
        equals($.address.hash(), 'comment-1');
        start();
    }, 1000);
});

asyncTest('Character test', function() {
    setTimeout(function() {
        $.address.value('/børn?тест=символ');
        equals($.address.path(), '/børn');
        equals($.address.parameter('тест'), 'символ');
        start();
    }, 1000);
});

asyncTest('Character test', function() {
    setTimeout(function() {
        $.address.value('/Test%20Encoding');
        equals($.address.value(), '/Test Encoding');
        start();
    }, 1000);
});

asyncTest('Character test', function() {
    setTimeout(function() {
        var str = 'Test mit Sonderzeichen + - / = ÖÄÜ und Leerzeichen';
        $.address.value(str);
        $.address.queryString('str=' + str);
        equals($.address.value(), '/' + str + '?str=' + str);
        equals($.address.path(), '/' + str);
        equals($.address.queryString(), 'str=' + str);
        equals($.address.parameter('str'), str);
        start();
    }, 1000);
});

asyncTest('Value test', function() {
    setTimeout(function() {
        $.address.value(1);
        equals($.address.value(), '/1');
        start();
    }, 1000);
});

asyncTest('Strict test', function() {
    setTimeout(function() {
        $.address.value('test');
        equals($.address.value(), '/test');
        start();
    }, 1000);
});

asyncTest('Strict test', function() {
    setTimeout(function() {
        $.address.value('?p=1&p=2');
        equals($.address.value(), '/?p=1&p=2');
        equals($.address.path(), '/');
        equals($.address.queryString(), 'p=1&p=2');
        equals($.address.parameter('p').toString(), '1,2');
        start();
    }, 1000);
});

asyncTest('Strict test', function() {
    setTimeout(function() {
        $.address.strict(false);
        $.address.value('test');
        equals($.address.value(), 'test');
        start();
    }, 1000);
});

asyncTest('Strict test', function() {
    setTimeout(function() {
        $.address.strict(false);
        $.address.value('?p=1&p=2');
        equals($.address.value(), '?p=1&p=2');
        equals($.address.path(), '');
        equals($.address.queryString(), 'p=1&p=2');
        equals($.address.parameter('p').toString(), '1,2');
        start();
    }, 1000);
});

setTimeout(function() {
    $.address.value('/');
}, 30000);<commit_msg>Adds more tests.<commit_after>asyncTest('Value test', function() {
    setTimeout(function() {
        $.address.value('/test');
        equals($.address.value(), '/test');
        setTimeout(function() {
            window.history.back();
        }, 500);
        start();
    }, 1000);
});

asyncTest('History test', function() {
    setTimeout(function() {
        equals($.address.value(), '/');
        setTimeout(function() {
            window.history.forward();
        }, 500);
        start();
    }, 1000);
});

asyncTest('Path names test', function() {
    setTimeout(function() {
        equals($.address.value(), '/test');
        same($.address.pathNames(), ['test']);
        start();
    }, 1000);
});

asyncTest('Path names test', function() {
    setTimeout(function() {
        $.address.value('/test/1/2/');
        same($.address.pathNames(), ['test', '1', '2']);
        start();
    }, 1000);
});

asyncTest('Path names test', function() {
    setTimeout(function() {
        $.address.value('/');
        same($.address.pathNames(), []);
        start();
    }, 1000);
});

asyncTest('Path names test', function() {
    setTimeout(function() {
        $.address.value('/test');
        same($.address.pathNames(), ['test']);
        start();
    }, 1000);
});

asyncTest('Query test', function() {
    setTimeout(function() {
        $.address.queryString('p=0');
        equals($.address.value(), '/test?p=0');
        equals($.address.path(), '/test');
        equals($.address.queryString(), 'p=0');
        start();
    }, 1000);
});

asyncTest('Parameter test', function() {
    setTimeout(function() {
        $.address.parameter('a', null);
        $.address.parameter('p', 1);
        equals($.address.value(), '/test?p=1');
        equals($.address.queryString(), 'p=1');
        equals($.address.parameter('p'), '1');
        start();
    }, 1000);
});

asyncTest('Parameter test', function() {
    setTimeout(function() {
        $.address.path('/test');
        $.address.parameter('p', 2, true);
        equals($.address.value(), '/test?p=1&p=2');
        equals($.address.queryString(), 'p=1&p=2');
        same($.address.parameter('p'), ['1','2']);
        same($.address.parameterNames(), ['p']);
        start();
    }, 1000);
});

asyncTest('Parameter test', function() {
    setTimeout(function() {
        $.address.autoUpdate(false)
            .queryString('')
            .parameter('p', 1, true)
            .parameter('p', 2)
            .parameter('p', 3, true)
            .parameter('s', 1)
            .parameter('s', 2, true)
            .parameter('s', 3)
            .parameter('t', 0)
            .parameter('t', null)
            .autoUpdate(true)
            .update();
        equals($.address.value(), '/test?p=2&p=3&s=3');
        same($.address.parameter('p'), ['2','3']);
        equals($.address.parameter('s'), 3);
        same($.address.parameterNames(), ['p','s']);
        start();
    }, 1000);
});

asyncTest('Parameter test', function() {
    setTimeout(function() {
        $.address.autoUpdate(false)
            .value('/')
            .parameter('p1', 'a#b')
            .parameter('p2', 'a&b')
            .autoUpdate(true)
            .update();
        equals($.address.value(), '/?p1=a#b&p2=a&b');
        equals($.address.parameter('p1'), 'a#b');
        equals($.address.parameter('p2'), 'a&b');
        start();
    }, 1000);
});

asyncTest('Parameter test', function() {
    setTimeout(function() {
        $.address.autoUpdate(false)
            .value('/')
            .parameter('p', 'a b +ċ')
            .autoUpdate(true)
            .update();
        equals($.address.value(), '/?p=a b +ċ');
        equals($.address.parameter('p'), 'a b +ċ');
        start();
    }, 1000);
});

asyncTest('Parameter test', function() {
    setTimeout(function() {
        $.address.autoUpdate(false)
            .value('/')
            .parameter('p', 'a+b ç=2')
            .autoUpdate(true)
            .update();
        equals($.address.value(), '/?p=a+b ç=2');
        equals($.address.parameter('p'), 'a+b ç=2');
        start();
    }, 1000);
});

asyncTest('Parameter test', function() {
    setTimeout(function() {
        $.address.autoUpdate(false)
            .value('/')
            .queryString($.param({start: 0, order: 'index0'}))
            .autoUpdate(true)
            .update();
        equals($.address.parameter('start'), 0);
        equals($.address.parameter('order'), 'index0');
        start();
    }, 1000);
});

asyncTest('Parameter test', function() {
    setTimeout(function() {
        $.address.autoUpdate(false)
            .value('/')
            .parameter('data', $.param({start: 1, order: 'index1'}))
            .autoUpdate(true)
            .update();
        equals($.address.parameter('data'), $.param({start: 1, order:'index1'}));
        same($.address.parameterNames(), ['data']);
        start();
    }, 1000);
});

asyncTest('Hash test with parameters', function() {
    setTimeout(function() {
        $.address.path('/test');
        $.address.queryString('p=2&p=3&s=3');
        $.address.hash('comment-2');
        equals($.address.value(), '/test?p=2&p=3&s=3#comment-2');
        equals($.address.path(), '/test');
        equals($.address.parameter('p').toString(), '2,3');
        equals($.address.parameter('s').toString(), 3);
        equals($.address.hash(), 'comment-2');
        same($.address.parameterNames(), ['p','s']);
        start();
    }, 1000);
});

asyncTest('Hash test', function() {
    setTimeout(function() {
        $.address.value('/test');
        $.address.hash('comment-1');
        equals($.address.value(), '/test#comment-1');
        equals($.address.path(), '/test');
        equals($.address.hash(), 'comment-1');
        start();
    }, 1000);
});

asyncTest('Character test', function() {
    setTimeout(function() {
        $.address.value('/børn?тест=символ');
        equals($.address.path(), '/børn');
        equals($.address.parameter('тест'), 'символ');
        start();
    }, 1000);
});

asyncTest('Character test', function() {
    setTimeout(function() {
        $.address.value('/Test%20Encoding');
        equals($.address.value(), '/Test Encoding');
        start();
    }, 1000);
});

asyncTest('Character test', function() {
    setTimeout(function() {
        var str = 'Test mit Sonderzeichen + - / = ÖÄÜ und Leerzeichen';
        $.address.value(str);
        $.address.queryString('str=' + str);
        equals($.address.value(), '/' + str + '?str=' + str);
        equals($.address.path(), '/' + str);
        equals($.address.queryString(), 'str=' + str);
        equals($.address.parameter('str'), str);
        start();
    }, 1000);
});

asyncTest('Value test', function() {
    setTimeout(function() {
        $.address.value(1);
        equals($.address.value(), '/1');
        start();
    }, 1000);
});

asyncTest('Strict test', function() {
    setTimeout(function() {
        $.address.value('test');
        equals($.address.value(), '/test');
        start();
    }, 1000);
});

asyncTest('Strict test', function() {
    setTimeout(function() {
        $.address.value('?p=1&p=2');
        equals($.address.value(), '/?p=1&p=2');
        equals($.address.path(), '/');
        equals($.address.queryString(), 'p=1&p=2');
        equals($.address.parameter('p').toString(), '1,2');
        start();
    }, 1000);
});

asyncTest('Strict test', function() {
    setTimeout(function() {
        $.address.strict(false);
        $.address.value('test');
        equals($.address.value(), 'test');
        start();
    }, 1000);
});

asyncTest('Strict test', function() {
    setTimeout(function() {
        $.address.strict(false);
        $.address.value('?p=1&p=2');
        equals($.address.value(), '?p=1&p=2');
        equals($.address.path(), '');
        equals($.address.queryString(), 'p=1&p=2');
        equals($.address.parameter('p').toString(), '1,2');
        start();
    }, 1000);
});

setTimeout(function() {
    $.address.value('/');
}, 30000);<|endoftext|>


<commit_before>'use strict';

var request = require('request');
var fs = require('fs');

module.exports = function(grunt){

  grunt.registerTask('rackspace','Commands for working with Rackspace Cloud.',function(){
    grunt.config.requires('rackspace.config.authUser','rackspace.config.authKey');
    grunt.config('rackspaceInit',grunt.config('rackspace.config'));
    grunt.task.run('rackspaceInit');
    if(grunt.config('rackspace.upload')){
      grunt.config('rackspaceUpload',grunt.config('rackspace.upload'));
      grunt.task.run('rackspaceUpload');
    }
    // TODO: Implement other rackspace api commands
  });

  grunt.registerTask('rackspaceInit','Authenticates with Rackspace; needed for other rackspace tasks.', function(){
    grunt.config.requires('rackspaceInit.authKey','rackspaceInit.authUser');
    var url = grunt.config('rackspaceInit.apiUrl') || 'https://auth.api.rackspacecloud.com/v1.0';
    var done = this.async();
    grunt.log.debug('requesting token from ' + url);
    request({
      url : url,
      headers : {
        "X-Auth-Key" : grunt.config('rackspaceInit.authKey'),
        "X-Auth-User" : grunt.config('rackspaceInit.authUser')
      },
      method : "HEAD"
    },function(error, response){
      if(error){
        grunt.log.error(error);
        done(false);
      }
      if(response.headers["x-auth-token"])
        grunt.config.set('rackspaceInit.authToken', response.headers["x-auth-token"]);
      else{
        error = 'No authentication token was returned in the headers. ' +
          'Request url: ' + url + '. Try setting "apiUrl" to something else.';
        grunt.fatal(error);
      }
      if(response.headers["x-storage-url"])
        grunt.config.set('rackspaceInit.storageUrl', grunt.utils._.rtrim(response.headers["x-storage-url"]), '/');
      else{
        error = 'No storage url was returned in the headers. ' +
          'Request url: ' + url + '. Try setting "apiUrl" to something else.';
        grunt.fatal(error);
      }
      grunt.log.debug('got token: ' + grunt.config('rackspaceInit.authToken'));
      grunt.log.debug('storage url: ' + grunt.config('rackspaceInit.storageUrl'));
      done();
    });
  });

  grunt.registerMultiTask('rackspaceUpload','Uploads files to Rackspace Cloud Files.',function(){
    this.requires('rackspaceInit');
    grunt.file.expandFiles(this.data.filename).forEach(uploadFile);
  });

  // Helper function for uploading a single file to rackspace cloud files
  function uploadFile() {
    var task = grunt.task.current;
    var data = task.data;
    var remote = grunt.utils._.trim(data.remoteDir, '/') + '/' + data.filename;
    var url = grunt.config('rackspaceInit.storageUrl') + '/' + remote;
    var done = task.async();
    grunt.log.debug('uploading ' + data.filename + ', remote: ' + remote);
    var uploadRequest = request({
      method : "PUT",
      url : url,
      headers : {
        "X-Auth-Token" : grunt.config('rackspaceInit.authToken')
      }
    });
    fs.createReadStream(data.filename).pipe(request(uploadRequest,function(error){
      if(error){
        grunt.log.error(error);
        done(false);
      }
      done();
    }));
  }
};
<commit_msg>change 'apiUrl' to 'authUrl'<commit_after>'use strict';

var request = require('request');
var fs = require('fs');

module.exports = function(grunt){

  grunt.registerTask('rackspace','Commands for working with Rackspace Cloud.',function(){
    grunt.config.requires('rackspace.config.authUser','rackspace.config.authKey');
    grunt.config('rackspaceInit',grunt.config('rackspace.config'));
    grunt.task.run('rackspaceInit');
    if(grunt.config('rackspace.upload')){
      grunt.config('rackspaceUpload',grunt.config('rackspace.upload'));
      grunt.task.run('rackspaceUpload');
    }
    // TODO: Implement other rackspace api commands
  });

  grunt.registerTask('rackspaceInit','Authenticates with Rackspace; needed for other rackspace tasks.', function(){
    grunt.config.requires('rackspaceInit.authKey','rackspaceInit.authUser');
    var url = grunt.config('rackspaceInit.authUrl') || 'https://auth.api.rackspacecloud.com/v1.0';
    var done = this.async();
    grunt.log.debug('requesting token from ' + url);
    request({
      url : url,
      headers : {
        "X-Auth-Key" : grunt.config('rackspaceInit.authKey'),
        "X-Auth-User" : grunt.config('rackspaceInit.authUser')
      },
      method : "HEAD"
    },function(error, response){
      if(error){
        grunt.log.error(error);
        done(false);
      }
      if(response.headers["x-auth-token"])
        grunt.config.set('rackspaceInit.authToken', response.headers["x-auth-token"]);
      else{
        error = 'No authentication token was returned in the headers. ' +
          'Request url: ' + url + '. Try setting "authUrl" to something else.';
        grunt.fatal(error);
      }
      if(response.headers["x-storage-url"])
        grunt.config.set('rackspaceInit.storageUrl', grunt.utils._.rtrim(response.headers["x-storage-url"]), '/');
      else{
        error = 'No storage url was returned in the headers. ' +
          'Request url: ' + url + '. Try setting "authUrl" to something else.';
        grunt.fatal(error);
      }
      grunt.log.debug('got token: ' + grunt.config('rackspaceInit.authToken'));
      grunt.log.debug('storage url: ' + grunt.config('rackspaceInit.storageUrl'));
      done();
    });
  });

  grunt.registerMultiTask('rackspaceUpload','Uploads files to Rackspace Cloud Files.',function(){
    this.requires('rackspaceInit');
    grunt.file.expandFiles(this.data.filename).forEach(uploadFile);
  });

  // Helper function for uploading a single file to rackspace cloud files
  function uploadFile() {
    var task = grunt.task.current;
    var data = task.data;
    var remote = grunt.utils._.trim(data.remoteDir, '/') + '/' + data.filename;
    var url = grunt.config('rackspaceInit.storageUrl') + '/' + remote;
    var done = task.async();
    grunt.log.debug('uploading ' + data.filename + ', remote: ' + remote);
    var uploadRequest = request({
      method : "PUT",
      url : url,
      headers : {
        "X-Auth-Token" : grunt.config('rackspaceInit.authToken')
      }
    });
    fs.createReadStream(data.filename).pipe(request(uploadRequest,function(error){
      if(error){
        grunt.log.error(error);
        done(false);
      }
      done();
    }));
  }
};
<|endoftext|>


<commit_before>/* eslint-env mocha */
'use strict';
var path = require('path');
var assert = require('assert');
var assign = require('object-assign');
var pathExists = require('path-exists');
var rimraf = require('rimraf');
var vinylFile = require('vinyl-file');
var sass = require('../');

var defaultOptions = {
	quiet: true,
	// normalize compilation results on Windows systems
	unixNewlines: true
};

// load the expected result file from the compiled results directory
var loadExpectedFile = function (relativePath, base) {
	base = base || 'result';
	var file = path.join(base, relativePath);
	return vinylFile.readSync(file, {base: base});
};

var sortByRelative = function (a, b) {
	return a.relative.localeCompare(b.relative);
};

describe('single file', function () {
	this.timeout(20000);
	var files = [];
	var expected = [loadExpectedFile('file.css')];

	before(function (done) {
		sass('source/file.scss', defaultOptions)
		.on('data', function (data) {
			files.push(data);
		})
		.on('end', done);
	});

	it('creates correct number of files', function () {
		assert.equal(files.length, expected.length);
	});

	it('creates file at correct path', function () {
		assert(files.length);
		files.forEach(function (file, i) {
			assert.equal(file.relative, expected[i].relative);
		});
	});

	it('creates correct file contents', function () {
		assert(files.length);
		files.forEach(function (file, i) {
			assert.deepEqual(
				file.contents.toString(),
				expected[i].contents.toString()
			);
		});
	});
});

describe('multiple files', function () {
	this.timeout(20000);
	var files = [];
	var expected = [
		loadExpectedFile('directory with spaces/file with spaces.css'),
		loadExpectedFile('directory/file.css'),
		loadExpectedFile('file.css'),
		loadExpectedFile('warnings.css')
	];

	before(function (done) {
		sass('source/**/*.scss', defaultOptions)
		.on('data', function (data) {
			files.push(data);
		})
		.on('end', function () {
			files.sort(sortByRelative);
			done();
		});
	});

	it('creates correct number of files', function () {
		assert.equal(files.length, expected.length);
	});

	it('creates file at correct path', function () {
		assert(files.length);
		files.forEach(function (file, i) {
			assert.equal(file.relative, expected[i].relative);
		});
	});

	it('creates correct file contents', function () {
		assert(files.length);
		files.forEach(function (file, i) {
			assert.deepEqual(
				file.contents.toString(),
				expected[i].contents.toString()
			);
		});
	});
});

describe('array sources', function () {
	this.timeout(20000);

	var files = [];
	var expected = [
		loadExpectedFile('file with spaces.css', 'result/directory with spaces'),
		loadExpectedFile('file.css')
	];

	before(function (done) {
		sass([
			'source/file.scss',
			'source/directory with spaces/file with spaces.scss'
		], defaultOptions)
		.on('data', function (data) {
			files.push(data);
		})
		.on('end', function () {
			files.sort(sortByRelative);
			done();
		});
	});

	it('creates correct number of files', function () {
		assert.equal(files.length, expected.length);
	});

	it('creates file at correct path', function () {
		assert(files.length);
		files.forEach(function (file, i) {
			assert.equal(file.relative, expected[i].relative);
		});
	});

	it('creates correct file contents', function () {
		assert(files.length);
		files.forEach(function (file, i) {
			assert.deepEqual(
				file.contents.toString(),
				expected[i].contents.toString()
			);
		});
	});
});

describe('concurrently run tasks', function () {
	this.timeout(20000);
	var aFiles = [];
	var bFiles = [];
	var cFiles = [];
	var counter = 0;

	var isDone = function (done) {
		counter++;

		if (counter === 3) {
			done();
		}
	};

	before(function (done) {
		sass('source/file.scss', defaultOptions)
		.on('data', function (data) {
			aFiles.push(data);
		})
		.on('end', function () {
			isDone(done);
		});

		sass('source/directory/file.scss', defaultOptions)
		.on('data', function (data) {
			bFiles.push(data);
		})
		.on('end', function () {
			isDone(done);
		});

		sass('source/directory with spaces/file with spaces.scss', defaultOptions)
		.on('data', function (data) {
			cFiles.push(data);
		})
		.on('end', function () {
			isDone(done);
		});
	});

	it('don\'t intermix result files', function () {
		assert.equal(aFiles.length, 1);
		assert.equal(bFiles.length, 1);
		assert.equal(cFiles.length, 1);
	});
});

describe('sourcemap', function () {
	this.timeout(20000);

	var files = [];
	var options = assign({}, defaultOptions, {sourcemap: true});

	before(function (done) {
		sass('source/file.scss', options)
		.on('data', function (data) {
			files.push(data);
		})
		.on('end', done);
	});

	it('doesn\'t stream Sass sourcemap files', function () {
		assert.equal(files.length, 1);
	});

	it('removes Sass sourcemap comment', function () {
		assert(
			files[0].contents.toString().indexOf('sourceMap') === -1,
			'File contains sourcemap comment'
		);
	});

	it('adds a vinyl sourcemap', function () {
		assert.equal(typeof files[0].sourceMap, 'object');
		assert.equal(files[0].sourceMap.version, 3);
	});

	it('includes the correct sources', function () {
		assert.deepEqual(
			files[0].sourceMap.sources,
			['_partial.scss', 'file.scss', 'directory/_nested-partial.scss']
		);
	});

	describe('compiling files from glob source', function () {
		var expected = [
			['_partial.scss'],
			['_partial.scss', 'file.scss', 'directory/_nested-partial.scss']
		];

		before(function (done) {
			files = [];

			sass('source/**/file.scss', options)
			.on('data', function (data) {
				files.push(data);
			})
			.on('end', function () {
				files.sort(sortByRelative);
				done();
			});
		});

		it('includes the correct sources', function () {
			files.forEach(function (file, i) {
				assert.deepEqual(file.sourceMap.sources, expected[i]);
			});
		});
	});

	describe('compiling files and directories with spaces', function () {
		var expected = ['file with spaces.scss'];

		before(function (done) {
			files = [];

			sass('source/directory with spaces/file with spaces.scss', options)
			.on('data', function (data) {
				files.push(data);
			})
			.on('end', done);
		});

		it('includes the correct sources', function () {
			assert.deepEqual(files[0].sourceMap.sources, expected);
		});
	});
});

describe('options', function () {
	this.timeout(20000);

	describe('emitCompileError', function () {
		var error;

		before(function (done) {
			var options = assign({}, defaultOptions, {emitCompileError: true});

			sass('special/error.scss', options)
			.on('data', function () {})
			.on('error', function (err) {
				error = err;
			})
			.on('end', done);
		});

		it('emits a gulp error when Sass compilation fails', function () {
			assert(error instanceof Error);
			assert.equal(
				error.message,
				'Sass compilation failed. See console output for more information.'
			);
		});
	});

	describe('base (for colliding sources)', function () {
		this.timeout(20000);
		var files = [];
		var expected = [
			loadExpectedFile('directory/file.css'),
			loadExpectedFile('file.css')
		];
		var options = assign({}, defaultOptions, {base: 'source'});

		before(function (done) {
			sass(['source/file.scss', 'source/directory/file.scss'], options)
			.on('data', function (data) {
				files.push(data);
			})
			.on('end', function () {
				files.sort(sortByRelative);
				done();
			});
		});

		it('creates correct number of files', function () {
			assert.equal(files.length, expected.length);
		});

		it('creates file at correct path', function () {
			assert(files.length);
			files.forEach(function (file, i) {
				assert.equal(file.relative, expected[i].relative);
			});
		});

		it('creates correct file contents', function () {
			assert(files.length);
			files.forEach(function (file, i) {
				assert.deepEqual(
					file.contents.toString(),
					expected[i].contents.toString()
				);
			});
		});
	});

	describe('tempDir', function () {
		it('compiles files to the specified directory', function (done) {
			var source = 'source/file.scss';
			var tempDir = './custom-temp-dir';
			var options = assign({}, defaultOptions, {tempDir: tempDir});

			assert.equal(
				pathExists.sync(tempDir),
				false,
				'The temporary directory already exists, and would create false positives.'
			);

			sass(source, options)

			.on('data', function () {
				assert(pathExists.sync(tempDir));
			})

			// clean up if tests are run locally
			.on('end', function () {
				rimraf(tempDir, done);
			});
		});
	});
});

describe('caching', function () {
	it('compiles an unchanged file faster the second time', function (done) {
		sass.clearCache();

		var startOne = new Date();

		sass('special/computational.scss', defaultOptions)
		.on('data', function () {})
		.on('end', function () {
			var endOne = new Date();
			var runtimeOne = endOne - startOne;

			sass('special/computational.scss', defaultOptions)
			.on('data', function () {})
			.on('end', function () {
				var runtimeTwo = new Date() - endOne;

				assert(
					// pad time to avoid potential intermittents
					runtimeOne > runtimeTwo + 50,
					'Compilation times were not decreased significantly. Caching may be broken.'
				);

				done();
			});
		});
	});
});
<commit_msg>DRY compilation tests with a function<commit_after>/* eslint-env mocha */
'use strict';
var path = require('path');
var assert = require('assert');
var assign = require('object-assign');
var pathExists = require('path-exists');
var rimraf = require('rimraf');
var vinylFile = require('vinyl-file');
var sass = require('../');

var defaultOptions = {
	quiet: true,
	// normalize compilation results on Windows systems
	unixNewlines: true
};

// load the expected result file from the compiled results directory
var loadExpectedFile = function (relativePath, base) {
	base = base || 'result';
	var file = path.join(base, relativePath);
	return vinylFile.readSync(file, {base: base});
};

var sortByRelative = function (a, b) {
	return a.relative.localeCompare(b.relative);
};

var compilesSource = function (source, expected) {
	var files = [];

	before(function (done) {
		sass(source, defaultOptions)
		.on('data', function (data) {
			files.push(data);
		})
		.on('end', function () {
			files.sort(sortByRelative);
			done();
		});
	});

	it('creates the correct number of files', function () {
		assert.equal(files.length, expected.length);
	});

	it('creates files at the correct path', function () {
		assert(files.length);
		files.forEach(function (file, i) {
			assert.equal(file.relative, expected[i].relative);
		});
	});

	it('creates correct file contents', function () {
		assert(files.length);
		files.forEach(function (file, i) {
			assert.deepEqual(
				file.contents.toString(),
				expected[i].contents.toString()
			);
		});
	});
};

describe('single file', function () {
	this.timeout(20000);
	var source = 'source/file.scss';
	var expected = [loadExpectedFile('file.css')];

	compilesSource(source, expected);
});

describe('multiple files', function () {
	this.timeout(20000);
	var source = 'source/**/*.scss';
	var expected = [
		loadExpectedFile('directory with spaces/file with spaces.css'),
		loadExpectedFile('directory/file.css'),
		loadExpectedFile('file.css'),
		loadExpectedFile('warnings.css')
	];

	compilesSource(source, expected);
});

describe('array sources', function () {
	this.timeout(20000);
	var source = [
		'source/file.scss',
		'source/directory with spaces/file with spaces.scss'
	];
	var expected = [
		loadExpectedFile('file with spaces.css', 'result/directory with spaces'),
		loadExpectedFile('file.css')
	];

	compilesSource(source, expected);
});

describe('concurrently run tasks', function () {
	this.timeout(20000);
	var aFiles = [];
	var bFiles = [];
	var cFiles = [];
	var counter = 0;

	var isDone = function (done) {
		counter++;

		if (counter === 3) {
			done();
		}
	};

	before(function (done) {
		sass('source/file.scss', defaultOptions)
		.on('data', function (data) {
			aFiles.push(data);
		})
		.on('end', function () {
			isDone(done);
		});

		sass('source/directory/file.scss', defaultOptions)
		.on('data', function (data) {
			bFiles.push(data);
		})
		.on('end', function () {
			isDone(done);
		});

		sass('source/directory with spaces/file with spaces.scss', defaultOptions)
		.on('data', function (data) {
			cFiles.push(data);
		})
		.on('end', function () {
			isDone(done);
		});
	});

	it('don\'t intermix result files', function () {
		assert.equal(aFiles.length, 1);
		assert.equal(bFiles.length, 1);
		assert.equal(cFiles.length, 1);
	});
});

describe('sourcemap', function () {
	this.timeout(20000);

	var files = [];
	var options = assign({}, defaultOptions, {sourcemap: true});

	before(function (done) {
		sass('source/file.scss', options)
		.on('data', function (data) {
			files.push(data);
		})
		.on('end', done);
	});

	it('doesn\'t stream Sass sourcemap files', function () {
		assert.equal(files.length, 1);
	});

	it('removes Sass sourcemap comment', function () {
		assert(
			files[0].contents.toString().indexOf('sourceMap') === -1,
			'File contains sourcemap comment'
		);
	});

	it('adds a vinyl sourcemap', function () {
		assert.equal(typeof files[0].sourceMap, 'object');
		assert.equal(files[0].sourceMap.version, 3);
	});

	it('includes the correct sources', function () {
		assert.deepEqual(
			files[0].sourceMap.sources,
			['_partial.scss', 'file.scss', 'directory/_nested-partial.scss']
		);
	});

	describe('compiling files from glob source', function () {
		var expected = [
			['_partial.scss'],
			['_partial.scss', 'file.scss', 'directory/_nested-partial.scss']
		];

		before(function (done) {
			files = [];

			sass('source/**/file.scss', options)
			.on('data', function (data) {
				files.push(data);
			})
			.on('end', function () {
				files.sort(sortByRelative);
				done();
			});
		});

		it('includes the correct sources', function () {
			files.forEach(function (file, i) {
				assert.deepEqual(file.sourceMap.sources, expected[i]);
			});
		});
	});

	describe('compiling files and directories with spaces', function () {
		var expected = ['file with spaces.scss'];

		before(function (done) {
			files = [];

			sass('source/directory with spaces/file with spaces.scss', options)
			.on('data', function (data) {
				files.push(data);
			})
			.on('end', done);
		});

		it('includes the correct sources', function () {
			assert.deepEqual(files[0].sourceMap.sources, expected);
		});
	});
});

describe('options', function () {
	this.timeout(20000);

	describe('emitCompileError', function () {
		var error;

		before(function (done) {
			var options = assign({}, defaultOptions, {emitCompileError: true});

			sass('special/error.scss', options)
			.on('data', function () {})
			.on('error', function (err) {
				error = err;
			})
			.on('end', done);
		});

		it('emits a gulp error when Sass compilation fails', function () {
			assert(error instanceof Error);
			assert.equal(
				error.message,
				'Sass compilation failed. See console output for more information.'
			);
		});
	});

	describe('base (for colliding sources)', function () {
		this.timeout(20000);
		var files = [];
		var expected = [
			loadExpectedFile('directory/file.css'),
			loadExpectedFile('file.css')
		];
		var options = assign({}, defaultOptions, {base: 'source'});

		before(function (done) {
			sass(['source/file.scss', 'source/directory/file.scss'], options)
			.on('data', function (data) {
				files.push(data);
			})
			.on('end', function () {
				files.sort(sortByRelative);
				done();
			});
		});

		it('creates correct number of files', function () {
			assert.equal(files.length, expected.length);
		});

		it('creates file at correct path', function () {
			assert(files.length);
			files.forEach(function (file, i) {
				assert.equal(file.relative, expected[i].relative);
			});
		});

		it('creates correct file contents', function () {
			assert(files.length);
			files.forEach(function (file, i) {
				assert.deepEqual(
					file.contents.toString(),
					expected[i].contents.toString()
				);
			});
		});
	});

	describe('tempDir', function () {
		it('compiles files to the specified directory', function (done) {
			var source = 'source/file.scss';
			var tempDir = './custom-temp-dir';
			var options = assign({}, defaultOptions, {tempDir: tempDir});

			assert.equal(
				pathExists.sync(tempDir),
				false,
				'The temporary directory already exists, and would create false positives.'
			);

			sass(source, options)

			.on('data', function () {
				assert(pathExists.sync(tempDir));
			})

			// clean up if tests are run locally
			.on('end', function () {
				rimraf(tempDir, done);
			});
		});
	});
});

describe('caching', function () {
	it('compiles an unchanged file faster the second time', function (done) {
		sass.clearCache();

		var startOne = new Date();

		sass('special/computational.scss', defaultOptions)
		.on('data', function () {})
		.on('end', function () {
			var endOne = new Date();
			var runtimeOne = endOne - startOne;

			sass('special/computational.scss', defaultOptions)
			.on('data', function () {})
			.on('end', function () {
				var runtimeTwo = new Date() - endOne;

				assert(
					// pad time to avoid potential intermittents
					runtimeOne > runtimeTwo + 50,
					'Compilation times were not decreased significantly. Caching may be broken.'
				);

				done();
			});
		});
	});
});
<|endoftext|>


<commit_before>var botgram = require("botgram");
var bot = botgram(process.argv[2]);

var rant = "When you say Linux, you probably mean the GNU operating " +
"system, running Linux as the kernel. You should therefore say " +
"GNU/Linux or GNU+Linux.";
var fag = "When you say Raphy, you probably mean the faggot " +
", running Raphy as the kernel. You should therefore say " +
"faggot/Raphy or faggot+Raphy.";
var fag1 = "HAHA yeah what a FAG";

bot.text(function (msg, reply, next) {
	var text = msg.text.toLowerCase();
	if (text.indexOf("linux") != -1 && text.indexOf("gnu") == -1)
		reply.reply(msg).text(rant);
	if (text.indexOf("raphy") != -1 && text.indexOf("faggot") == -1)
		reply.reply(msg).text(fag);
});

bot.command("start", function (msg, reply, next) {
	reply.text("fuck off");
});

<commit_msg>replace ``text.IndexOf() with ``text.includes()<commit_after>var botgram = require("botgram");
var bot = botgram(process.argv[2]);

var rant = "When you say Linux, you probably mean the GNU operating " +
"system, running Linux as the kernel. You should therefore say " +
"GNU/Linux or GNU+Linux.";
var fag = "When you say Raphy, you probably mean the faggot " +
", running Raphy as the kernel. You should therefore say " +
"faggot/Raphy or faggot+Raphy.";
var fag1 = "HAHA yeah what a FAG";

bot.text(function (msg, reply, next) {
	var text = msg.text.toLowerCase();
	if (text.includes("linux") && !text.includes("gnu"))
		reply.reply(msg).text(rant);
	if (text.includes("raphy") && !text.includes("faggot"))
		reply.reply(msg).text(fag);
});

bot.command("start", function (msg, reply, next) {
	reply.text("fuck off");
});

<|endoftext|>


<commit_before>/*
 * grunt-slack-api
 * https://github.com/nerrad/grunt-slack-api
 *
 * Copyright (c) 2015 Darren Ethier
 * Licensed under the MIT license.
 */

'use strict';

var request = require( 'superagent' );
var querystring = require('querystring');

module.exports = function(grunt) {

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

  grunt.registerMultiTask('slack_api', 'A more comprehensive slack api integration using grunt.', function() {
        // Merge task-specific and/or target-specific options with these defaults.
        var options = this.options();
        var done = this.async();
        var data = {
            type : ! options.type ? 'message' : options.type,
            text : options.text
        }

        /** verify there is a token **/
        if ( ! options.token ) {
            grunt.log.error( 'Token is required for Slack API requests' );
            return;
        } else {
            data.token = options.token;
        }

        /** channel? **/
        if ( options.channel) {
            data.channel = options.channel;
        } else {
            data.channel = '#general';
        }

        /** set up options and defaults **/
        if ( ! options.endpoint ) {
            options.endpoint = 'https://slack.com/api/';
        }

        /** setup various data depending on type of api request **/
        switch ( data.type ) {
            case 'topic' :
                options.endpoint += 'channels.setTopic';
                data.topic = data.text;
                break;
            case 'message' :
                options.endpoint += 'chat.postMessage';
                /**
                 * attachment?
                 * todo: need to do some validation of the attachment(s) coming in
                 **/
                if ( options.attachments ) {
                    data.attachments = JSON.stringify(options.attachments);
                }
                if ( typeof options.as_user !== 'undefined' ) {
                    data.as_user = options.as_user;
                }
                if ( options.username ) {
                    data.username = options.username;
                } else {
                    data.as_user = true;
                }
                if ( options.parse ) {
                    data.parse = options.parse;
                }
                if ( typeof options.link_names !== 'undefined' ) {
                    data.link_names = options.link_names;
                }
                if ( typeof options.unfurl_links !== 'undefined' ) {
                    data.unfurl_links = options.unfurl_links;
                }
                if ( typeof options.unfurl_media !== 'undefined' ) {
                    data.unfurl_media = options.unfurl_media;
                }
                if ( options.icon_url ) {
                    data.icon_url = options.icon_url;
                }
                if ( options.icon_emoji ) {
                    data.icon_emoji = options.icon_emoji
                }

                if ( options.fields ) {
                    data.fields = JSON.stringify( options.fields );
                }
                break;
        }

        var stringified = querystring.stringify(data);
        console.log(stringified);

        request.post( options.endpoint )
            .type('form')
            .send( stringified )
            .end( function(res ) {
                if ( ! res.ok ) {
                    grunt.log.error( 'Error with slack api: ', res.text );
                    return done(false);
                }
                console.log( res.text );
                grunt.log.writeln( "Finished communicating with slack." );
                done();
            })
            .on( 'error', function(err) {
                //handling network error
                grunt.log.error( 'Error communicating with slack: ', err.message );
                done(false);
            });
    });
};
<commit_msg>fix undefined messages<commit_after>/*
 * grunt-slack-api
 * https://github.com/nerrad/grunt-slack-api
 *
 * Copyright (c) 2015 Darren Ethier
 * Licensed under the MIT license.
 */

'use strict';

var request = require( 'superagent' );
var querystring = require('querystring');

module.exports = function(grunt) {

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

  grunt.registerMultiTask('slack_api', 'A more comprehensive slack api integration using grunt.', function() {
        // Merge task-specific and/or target-specific options with these defaults.
        var options = this.options();
        var done = this.async();
        var data = {
            type : ! options.type ? 'message' : options.type,
            text : options.text
        }

        /** verify there is a token **/
        if ( ! options.token ) {
            grunt.log.error( 'Token is required for Slack API requests' );
            return;
        } else {
            data.token = options.token;
        }

        /** channel? **/
        if ( options.channel) {
            data.channel = options.channel;
        } else {
            data.channel = '#general';
        }

        /** set up options and defaults **/
        if ( ! options.endpoint ) {
            options.endpoint = 'https://slack.com/api/';
        }

        /** setup various data depending on type of api request **/
        switch ( data.type ) {
            case 'topic' :
                options.endpoint += 'channels.setTopic';
                data.topic = data.text;
                break;
            case 'message' :
                options.endpoint += 'chat.postMessage';
                /**
                 * attachment?
                 * todo: need to do some validation of the attachment(s) coming in
                 **/
                if ( options.attachments ) {
                    data.attachments = JSON.stringify(options.attachments);
                }
                if ( typeof options.as_user !== 'undefined' ) {
                    data.as_user = options.as_user;
                }
                if ( options.username ) {
                    data.username = options.username;
                } else {
                    data.as_user = true;
                }
                if ( options.parse ) {
                    data.parse = options.parse;
                }
                if ( typeof options.link_names !== 'undefined' ) {
                    data.link_names = options.link_names;
                }
                if ( typeof options.unfurl_links !== 'undefined' ) {
                    data.unfurl_links = options.unfurl_links;
                }
                if ( typeof options.unfurl_media !== 'undefined' ) {
                    data.unfurl_media = options.unfurl_media;
                }
                if ( options.icon_url ) {
                    data.icon_url = options.icon_url;
                }
                if ( options.icon_emoji ) {
                    data.icon_emoji = options.icon_emoji
                }

                if ( options.fields ) {
                    data.fields = JSON.stringify( options.fields );
                }
                break;
        }

        var stringified = querystring.stringify(data);

        request.post( options.endpoint )
            .type('form')
            .send( stringified )
            .end( function(res ) {
                if ( ! res.ok ) {
                    grunt.log.error( 'Error with slack api: ', res.text );
                    return done(false);
                }
                grunt.log.writeln( "Finished communicating with slack." );
                done();
            })
            .on( 'error', function(err) {
                //handling network error
                grunt.log.error( 'Error communicating with slack: ', err.message );
                done(false);
            });
    });
};
<|endoftext|>


<commit_before>
const fs = require('fs')

const moo = require('../moo')
const compile = moo.compile
const python = require('./python')

describe('moo compiler', () => {

  test("warns for /g, /y, /i, /m", () => {
    expect(() => compile({ word: /foo/ })).not.toThrow()
    expect(() => compile({ word: /foo/g })).toThrow()
    expect(() => compile({ word: /foo/i })).toThrow()
    expect(() => compile({ word: /foo/y })).toThrow()
    expect(() => compile({ word: /foo/m })).toThrow()
  })

  // TODO warns for multiple capture groups

  // TODO wraps zero capture groups

  // TODO warns if no lineBreaks: true

  test('sorts regexps and strings', () => {
    let lexer = moo.compile({
      tok: [/t[ok]+/, /\w/, 'tok', 'token']
    })
    expect(lexer.re.source.replace(/[(?:)]/g, '')).toBe('token|tok|t[ok]+|\\w')
  })

  test('warns about missing states', () => {
    const rules = [
      {match: '=', next: 'missing'},
      {match: '=', push: 'missing'},
    ]
    for (const rule of rules) {
      expect(() => moo.states({start: {thing: rule}}))
      .toThrow("Missing state 'missing' (in token 'thing' of state 'start')")
    }
  })

  test('warns about inappropriate state-switching options', () => {
    const rules = [
      {match: '=', next: 'state'},
      {match: '=', push: 'state'},
      {match: '=', pop: true},
    ]
    for (const rule of rules) {
      expect(() => moo.compile({thing: rule}))
      .toThrow("State-switching options are not allowed in stateless lexers (for token 'thing')")
    }
  })

})

describe('moo lexer', () => {

  var simpleLexer = compile({
    word: /[a-z]+/,
    number: /[0-9]+/,
    ws: / +/,
  })

  test('vaguely works', () => {
    simpleLexer.reset('ducks are 123 bad')
    expect(simpleLexer.lex()).toMatchObject({ type: 'word', value: 'ducks' })
    expect(simpleLexer.lex()).toMatchObject({ type: 'ws', value: ' ' })
    expect(simpleLexer.lex()).toMatchObject({ type: 'word', value: 'are' })
  })

  test('accepts rules in an object', () => {
    const lexer = compile({
      word: /[a-z]+/,
      number: /[0-9]+/,
      space: / +/,
    })
    lexer.reset('ducks are 123 bad')
    expect(lexer.lex()).toMatchObject({type: 'word', value: 'ducks'})
    expect(lexer.lex()).toMatchObject({type: 'space', value: ' '})
  })

  test('accepts a list of regexps', () => {
    const lexer = compile({
      number: [
        /[0-9]+\.[0-9]+/,
        /[0-9]+/,
      ],
      space: / +/,
    })
    lexer.reset('12.04 123 3.14')
    var tokens = lexer.lexAll().filter(t => t.type !== 'space')
    expect(tokens.shift()).toMatchObject({type: 'number', value: '12.04'})
    expect(tokens.shift()).toMatchObject({type: 'number', value: '123'})
    expect(tokens.shift()).toMatchObject({type: 'number', value: '3.14'})
  })

  test('no capture groups', () => {
    let lexer = compile({
      a: /a+/,
      b: /b|c/,
    })
    lexer.reset('aaaaabcbcbcbc')
    expect(lexer.lex().value).toEqual('aaaaa')
    expect(lexer.lex().value).toEqual('b')
    expect(lexer.lex().value).toEqual('c')
    expect(lexer.lex().value).toEqual('b')
  })

  test('multiline', () => {
    var lexer = compile({
      file: { match: /([^]+)/, lineBreaks: true },
    }).reset('I like to moo\na lot')
    expect(lexer.lex().value).toBe('I like to moo\na lot')
  })

  test('match EOL $', () => {
    var lexer = compile({
      x_eol: /x$/,
      x: /x/,
      WS: / +/,
      NL: { match: /\n/, lineBreaks: true },
      other: /[^ \n]+/,
    }).reset('x \n x\n yz x')
    let tokens = lexer.lexAll().filter(t => t.type !== 'WS')
    expect(tokens.map(t => [t.type, t.value])).toEqual([
      ['x', 'x'],
      ['NL', '\n'],
      ['x_eol', 'x'],
      ['NL', '\n'],
      ['other', 'yz'],
      ['x_eol', 'x'],
    ])
  })

  test('match BOL ^', () => {
    var lexer = compile({
      x_bol: /^x/,
      x: /x/,
      WS: / +/,
      NL: { match: /\n/, lineBreaks: true },
      other: /[^ \n]+/,
    }).reset('x \n x\nx yz')
    let tokens = lexer.lexAll().filter(t => t.type !== 'WS')
    expect(tokens.map(t => [t.type, t.value])).toEqual([
      ['x_bol', 'x'],
      ['NL', '\n'],
      ['x', 'x'],
      ['NL', '\n'],
      ['x_bol', 'x'],
      ['other', 'yz'],
    ])
  })

  test('token to string conversion', () => {
    const lexer = compile({
      apples: /()a/,
      pears: /p/,
    }).reset('ap')
    expect(String(lexer.lex())).toBe('apples')
    expect(String(lexer.lex())).toBe('p')
  })

  // TODO test / design API for errors
  // - check the reported error location

  test('kurt tokens', () => {
    let pythonLexer = compile(python.rules)
    let tokens = pythonLexer.reset(fs.readFileSync('test/kurt.py', 'utf-8')).lexAll()
    expect(tokens.length).toBe(14513)
  })

  // TODO test clone()
})

describe('moo stateful lexer', () => {

  test('switches states', () => {
    const lexer = moo.states({
      start: {
        word: /\w+/,
        eq: {match: '=', next: 'ab'},
      },
      ab: {
        a: 'a',
        b: 'b',
        semi: {match: ';', next: 'start'},
      },
    })

    lexer.reset('one=ab;two=')
    expect(lexer.lexAll().map(({type, value}) => [type, value])).toEqual([
      ['word', 'one'],
      ['eq', '='],
      ['a', 'a'],
      ['b', 'b'],
      ['semi', ';'],
      ['word', 'two'],
      ['eq', '='],
    ])
  })

  const parens = moo.states({
    start: {
      word: /\w+/,
      lpar: {match: '(', push: 'inner'},
      rpar: ')',
    },
    inner: {
      thing: /\w+/,
      lpar: {match: '(', push: 'inner'},
      rpar: {match: ')', pop: true},
    },
  })

  test('maintains a stack', () => {
    parens.reset('a(b(c)d)e')
    expect(parens.lexAll().map(({type, value}) => [type, value])).toEqual([
      ['word', 'a'],
      ['lpar', '('],
      ['thing', 'b'],
      ['lpar', '('],
      ['thing', 'c'],
      ['rpar', ')'],
      ['thing', 'd'],
      ['rpar', ')'],
      ['word', 'e'],
    ])
  })

  test('allows popping too many times', () => {
    parens.reset(')e')
    expect(parens.lexAll().map(({type, value}) => [type, value])).toEqual([
      ['rpar', ')'],
      ['word', 'e'],
    ])
  })
})

describe('line numbers', () => {

  var testLexer = compile({
    WS: / +/,
    word: /[a-z]+/,
    NL: { match: /\n/, lineBreaks: true },
  })

  test('counts line numbers', () => {
    var tokens = testLexer.reset('cow\nfarm\ngrass').lexAll()
    expect(tokens.map(t => t.value)).toEqual(['cow', '\n', 'farm', '\n', 'grass'])
    expect(tokens.map(t => t.lineBreaks)).toEqual([0, 1, 0, 1, 0])
    expect(tokens.map(t => t.size)).toEqual([3, 1, 4, 1, 5])
    expect(tokens.map(t => t.line)).toEqual([1, 1, 2, 2, 3])
    expect(tokens.map(t => t.col)).toEqual([1, 4, 1, 5, 1])
  })

  test('tracks columns', () => {
    var lexer = compile({
      WS: / +/,
      thing: { match: /[a-z\n]+/, lineBreaks: true },
    })
    lexer.reset('pie cheese\nsalad what\n ')
    expect(lexer.lex()).toMatchObject({ value: 'pie', col: 1 })
    expect(lexer.lex()).toMatchObject({ value: ' ', col: 4 })
    expect(lexer.lex()).toMatchObject({ value: 'cheese\nsalad', col: 5, line: 1 })
    expect(lexer.lex()).toMatchObject({ value: ' ', col: 6, line: 2 })
    expect(lexer.lex()).toMatchObject({ value: 'what\n', col: 7, line: 2 })
    expect(lexer.lex()).toMatchObject({ value: ' ', col: 1, line: 3 })
  })

  test('tries to warn if rule matches \\n', () => {
    expect(() => compile([['whitespace', /\s+/]])).toThrow()
    expect(() => compile([['multiline', /q[^]*/]])).not.toThrow()
  })

  test('resets state', () => {
    var lexer = compile({
      WS: / +/,
      word: /[a-z]+/,
    })
    lexer.reset('potatoes\nsalad')
    expect(lexer).toMatchObject({buffer: 'potatoes\nsalad', line: 1, col: 1})
    lexer.lexAll()
    expect(lexer).toMatchObject({line: 2, col: 6})
    lexer.reset('cheesecake')
    expect(lexer).toMatchObject({buffer: 'cheesecake', line: 1, col: 1})
  })

  // TODO test clone()
})

describe('save/restore', () => {

  const testLexer = compile({
    word: /[a-z]+/,
    NL: { match: '\n', lineBreaks: true },
  })

  test('can be saved', () => {
    testLexer.reset('one\ntwo')
    testLexer.lexAll()
    expect(testLexer.save()).toEqual({line: 2, col: 4})
  })

  test('can be restored', () => {
    testLexer.reset('\nthree', {line: 2, col: 4})
    expect(testLexer).toMatchObject({line: 2, col: 4, buffer: '\nthree'})
  })

})

describe('python tokenizer', () => {

  test("1 + 2", () => {
    expect(python.outputTokens("1 + 2")).toEqual([
      'NUMBER "1"',
      'OP "+"',
      'NUMBER "2"',
      'ENDMARKER ""',
    ])
  })

  // use non-greedy matching
  test('triple-quoted strings', () => {
    let example = '"""abc""" 1+1 """def"""'
    let pythonLexer = compile(python.rules)
    expect(pythonLexer.reset(example).lexAll().map(t => t.value)).toEqual(
      ['"""abc"""', " ", "1", "+", "1", " ", '"""def"""']
    )
  })

  test('example python file', () => {
    expect(python.outputTokens(python.pythonFile)).toEqual([
      // 'ENCODING "utf-8"',
      'COMMENT "#!/usr/local/bin/python3"',
      'NL "\\n"',
      'NAME "import"',
      'NAME "sys"',
      'NEWLINE "\\n"',
      'NAME "from"',
      'NAME "tokenize"',
      'NAME "import"',
      'NAME "tokenize"',
      'OP ","',
      'NAME "tok_name"',
      'NEWLINE "\\n"',
      'NAME "import"',
      'NAME "json"',
      'NEWLINE "\\n"',
      'NAME "from"',
      'NAME "io"',
      'NAME "import"',
      'NAME "BytesIO"',
      'NEWLINE "\\n"',
      'NL "\\n"',
      'NAME "path"',
      'OP "="',
      'NAME "sys"',
      'OP "."',
      'NAME "argv"',
      'OP "["',
      'NUMBER "1"',
      'OP "]"',
      'NEWLINE "\\n"',
      'NAME "for"',
      'NAME "info"',
      'NAME "in"',
      'NAME "tokenize"',
      'OP "("',
      'NAME "open"',
      'OP "("',
      'NAME "path"',
      'OP ","',
      'STRING "rb"',
      'OP ")"',
      'OP "."',
      'NAME "readline"',
      'OP ")"',
      'OP ":"',
      'NEWLINE "\\n"',
      'INDENT "    "',
      'NAME "print"',
      'OP "("',
      'NAME "tok_name"',
      'OP "["',
      'NAME "info"',
      'OP "."',
      'NAME "type"',
      'OP "]"',
      'OP ","',
      'NAME "json"',
      'OP "."',
      'NAME "dumps"',
      'OP "("',
      'NAME "info"',
      'OP "."',
      'NAME "string"',
      'OP ")"',
      'OP ")"',
      'NEWLINE "\\n"',
      // 'NL "\\n"',
      'DEDENT ""',
      'ENDMARKER ""',
    ])
  })

  test("kurt python", () => {
    let tokens = python.outputTokens(fs.readFileSync('test/kurt.py', 'utf-8'))
    expect(tokens[100]).toBe('NAME "def"')
    expect(tokens.pop()).toBe('ENDMARKER ""')
    tokens.pop()
    expect(tokens.pop()).not.toBe('ERRORTOKEN ""')
    expect(tokens.length).toBe(11616)

    // let expected = fs.readFileSync('test/kurt-tokens.txt', 'utf-8').split('\n')
    // expect(tokens).toEqual(expected)
  })

})

describe('tosh tokenizer', () => {

  const tosh = require('./tosh')

  test('tosh', () => {
    let oldTokens = tosh.oldTokenizer(tosh.exampleFile)
    expect(tosh.tokenize(tosh.exampleFile)).toEqual(oldTokens)
  })

})
<commit_msg>Add test based on string interpolation example (#22)<commit_after>
const fs = require('fs')

const moo = require('../moo')
const compile = moo.compile
const python = require('./python')

describe('moo compiler', () => {

  test("warns for /g, /y, /i, /m", () => {
    expect(() => compile({ word: /foo/ })).not.toThrow()
    expect(() => compile({ word: /foo/g })).toThrow()
    expect(() => compile({ word: /foo/i })).toThrow()
    expect(() => compile({ word: /foo/y })).toThrow()
    expect(() => compile({ word: /foo/m })).toThrow()
  })

  // TODO warns for multiple capture groups

  // TODO wraps zero capture groups

  // TODO warns if no lineBreaks: true

  test('sorts regexps and strings', () => {
    let lexer = moo.compile({
      tok: [/t[ok]+/, /\w/, 'tok', 'token']
    })
    expect(lexer.re.source.replace(/[(?:)]/g, '')).toBe('token|tok|t[ok]+|\\w')
  })

  test('warns about missing states', () => {
    const rules = [
      {match: '=', next: 'missing'},
      {match: '=', push: 'missing'},
    ]
    for (const rule of rules) {
      expect(() => moo.states({start: {thing: rule}}))
      .toThrow("Missing state 'missing' (in token 'thing' of state 'start')")
    }
  })

  test('warns about inappropriate state-switching options', () => {
    const rules = [
      {match: '=', next: 'state'},
      {match: '=', push: 'state'},
      {match: '=', pop: true},
    ]
    for (const rule of rules) {
      expect(() => moo.compile({thing: rule}))
      .toThrow("State-switching options are not allowed in stateless lexers (for token 'thing')")
    }
  })

})

describe('moo lexer', () => {

  var simpleLexer = compile({
    word: /[a-z]+/,
    number: /[0-9]+/,
    ws: / +/,
  })

  test('vaguely works', () => {
    simpleLexer.reset('ducks are 123 bad')
    expect(simpleLexer.lex()).toMatchObject({ type: 'word', value: 'ducks' })
    expect(simpleLexer.lex()).toMatchObject({ type: 'ws', value: ' ' })
    expect(simpleLexer.lex()).toMatchObject({ type: 'word', value: 'are' })
  })

  test('accepts rules in an object', () => {
    const lexer = compile({
      word: /[a-z]+/,
      number: /[0-9]+/,
      space: / +/,
    })
    lexer.reset('ducks are 123 bad')
    expect(lexer.lex()).toMatchObject({type: 'word', value: 'ducks'})
    expect(lexer.lex()).toMatchObject({type: 'space', value: ' '})
  })

  test('accepts a list of regexps', () => {
    const lexer = compile({
      number: [
        /[0-9]+\.[0-9]+/,
        /[0-9]+/,
      ],
      space: / +/,
    })
    lexer.reset('12.04 123 3.14')
    var tokens = lexer.lexAll().filter(t => t.type !== 'space')
    expect(tokens.shift()).toMatchObject({type: 'number', value: '12.04'})
    expect(tokens.shift()).toMatchObject({type: 'number', value: '123'})
    expect(tokens.shift()).toMatchObject({type: 'number', value: '3.14'})
  })

  test('no capture groups', () => {
    let lexer = compile({
      a: /a+/,
      b: /b|c/,
    })
    lexer.reset('aaaaabcbcbcbc')
    expect(lexer.lex().value).toEqual('aaaaa')
    expect(lexer.lex().value).toEqual('b')
    expect(lexer.lex().value).toEqual('c')
    expect(lexer.lex().value).toEqual('b')
  })

  test('multiline', () => {
    var lexer = compile({
      file: { match: /([^]+)/, lineBreaks: true },
    }).reset('I like to moo\na lot')
    expect(lexer.lex().value).toBe('I like to moo\na lot')
  })

  test('match EOL $', () => {
    var lexer = compile({
      x_eol: /x$/,
      x: /x/,
      WS: / +/,
      NL: { match: /\n/, lineBreaks: true },
      other: /[^ \n]+/,
    }).reset('x \n x\n yz x')
    let tokens = lexer.lexAll().filter(t => t.type !== 'WS')
    expect(tokens.map(t => [t.type, t.value])).toEqual([
      ['x', 'x'],
      ['NL', '\n'],
      ['x_eol', 'x'],
      ['NL', '\n'],
      ['other', 'yz'],
      ['x_eol', 'x'],
    ])
  })

  test('match BOL ^', () => {
    var lexer = compile({
      x_bol: /^x/,
      x: /x/,
      WS: / +/,
      NL: { match: /\n/, lineBreaks: true },
      other: /[^ \n]+/,
    }).reset('x \n x\nx yz')
    let tokens = lexer.lexAll().filter(t => t.type !== 'WS')
    expect(tokens.map(t => [t.type, t.value])).toEqual([
      ['x_bol', 'x'],
      ['NL', '\n'],
      ['x', 'x'],
      ['NL', '\n'],
      ['x_bol', 'x'],
      ['other', 'yz'],
    ])
  })

  test('token to string conversion', () => {
    const lexer = compile({
      apples: /()a/,
      pears: /p/,
    }).reset('ap')
    expect(String(lexer.lex())).toBe('apples')
    expect(String(lexer.lex())).toBe('p')
  })

  // TODO test / design API for errors
  // - check the reported error location

  test('kurt tokens', () => {
    let pythonLexer = compile(python.rules)
    let tokens = pythonLexer.reset(fs.readFileSync('test/kurt.py', 'utf-8')).lexAll()
    expect(tokens.length).toBe(14513)
  })

  // TODO test clone()
})

describe('moo stateful lexer', () => {

  test('switches states', () => {
    const lexer = moo.states({
      start: {
        word: /\w+/,
        eq: {match: '=', next: 'ab'},
      },
      ab: {
        a: 'a',
        b: 'b',
        semi: {match: ';', next: 'start'},
      },
    })

    lexer.reset('one=ab;two=')
    expect(lexer.lexAll().map(({type, value}) => [type, value])).toEqual([
      ['word', 'one'],
      ['eq', '='],
      ['a', 'a'],
      ['b', 'b'],
      ['semi', ';'],
      ['word', 'two'],
      ['eq', '='],
    ])
  })

  const parens = moo.states({
    start: {
      word: /\w+/,
      lpar: {match: '(', push: 'inner'},
      rpar: ')',
    },
    inner: {
      thing: /\w+/,
      lpar: {match: '(', push: 'inner'},
      rpar: {match: ')', pop: true},
    },
  })

  test('maintains a stack', () => {
    parens.reset('a(b(c)d)e')
    expect(parens.lexAll().map(({type, value}) => [type, value])).toEqual([
      ['word', 'a'],
      ['lpar', '('],
      ['thing', 'b'],
      ['lpar', '('],
      ['thing', 'c'],
      ['rpar', ')'],
      ['thing', 'd'],
      ['rpar', ')'],
      ['word', 'e'],
    ])
  })

  test('allows popping too many times', () => {
    parens.reset(')e')
    expect(parens.lexAll().map(({type, value}) => [type, value])).toEqual([
      ['rpar', ')'],
      ['word', 'e'],
    ])
  })

  test('lexes interpolation example', () => {
    let lexer = moo.states({
      main: {
        strstart: {match: '`', push: 'lit'},
        ident:    /\w+/,
        lbrace:   {match: '{', push: 'main'},
        rbrace:   {match: '}', pop: 1},
        colon:    ':',
        space:    {match: /\s+/, lineBreaks: true},
      },
      lit: {
        interp:   {match: '${', push: 'main'},
        escape:   /\\./,
        strend:   {match: '`', pop: 1},
        const:    {match: /(?:[^$`]|\$(?!\{))+/, lineBreaks: true},
      },
    }).feed('`a${{c: d}}e`')
    expect(lexer.lexAll().map(t => t.type).join(' ')).toBe('strstart const interp lbrace ident colon space ident rbrace rbrace const strend')
  })

})

describe('line numbers', () => {

  var testLexer = compile({
    WS: / +/,
    word: /[a-z]+/,
    NL: { match: /\n/, lineBreaks: true },
  })

  test('counts line numbers', () => {
    var tokens = testLexer.reset('cow\nfarm\ngrass').lexAll()
    expect(tokens.map(t => t.value)).toEqual(['cow', '\n', 'farm', '\n', 'grass'])
    expect(tokens.map(t => t.lineBreaks)).toEqual([0, 1, 0, 1, 0])
    expect(tokens.map(t => t.size)).toEqual([3, 1, 4, 1, 5])
    expect(tokens.map(t => t.line)).toEqual([1, 1, 2, 2, 3])
    expect(tokens.map(t => t.col)).toEqual([1, 4, 1, 5, 1])
  })

  test('tracks columns', () => {
    var lexer = compile({
      WS: / +/,
      thing: { match: /[a-z\n]+/, lineBreaks: true },
    })
    lexer.reset('pie cheese\nsalad what\n ')
    expect(lexer.lex()).toMatchObject({ value: 'pie', col: 1 })
    expect(lexer.lex()).toMatchObject({ value: ' ', col: 4 })
    expect(lexer.lex()).toMatchObject({ value: 'cheese\nsalad', col: 5, line: 1 })
    expect(lexer.lex()).toMatchObject({ value: ' ', col: 6, line: 2 })
    expect(lexer.lex()).toMatchObject({ value: 'what\n', col: 7, line: 2 })
    expect(lexer.lex()).toMatchObject({ value: ' ', col: 1, line: 3 })
  })

  test('tries to warn if rule matches \\n', () => {
    expect(() => compile([['whitespace', /\s+/]])).toThrow()
    expect(() => compile([['multiline', /q[^]*/]])).not.toThrow()
  })

  test('resets state', () => {
    var lexer = compile({
      WS: / +/,
      word: /[a-z]+/,
    })
    lexer.reset('potatoes\nsalad')
    expect(lexer).toMatchObject({buffer: 'potatoes\nsalad', line: 1, col: 1})
    lexer.lexAll()
    expect(lexer).toMatchObject({line: 2, col: 6})
    lexer.reset('cheesecake')
    expect(lexer).toMatchObject({buffer: 'cheesecake', line: 1, col: 1})
  })

  // TODO test clone()
})

describe('save/restore', () => {

  const testLexer = compile({
    word: /[a-z]+/,
    NL: { match: '\n', lineBreaks: true },
  })

  test('can be saved', () => {
    testLexer.reset('one\ntwo')
    testLexer.lexAll()
    expect(testLexer.save()).toEqual({line: 2, col: 4})
  })

  test('can be restored', () => {
    testLexer.reset('\nthree', {line: 2, col: 4})
    expect(testLexer).toMatchObject({line: 2, col: 4, buffer: '\nthree'})
  })

})

describe('python tokenizer', () => {

  test("1 + 2", () => {
    expect(python.outputTokens("1 + 2")).toEqual([
      'NUMBER "1"',
      'OP "+"',
      'NUMBER "2"',
      'ENDMARKER ""',
    ])
  })

  // use non-greedy matching
  test('triple-quoted strings', () => {
    let example = '"""abc""" 1+1 """def"""'
    let pythonLexer = compile(python.rules)
    expect(pythonLexer.reset(example).lexAll().map(t => t.value)).toEqual(
      ['"""abc"""', " ", "1", "+", "1", " ", '"""def"""']
    )
  })

  test('example python file', () => {
    expect(python.outputTokens(python.pythonFile)).toEqual([
      // 'ENCODING "utf-8"',
      'COMMENT "#!/usr/local/bin/python3"',
      'NL "\\n"',
      'NAME "import"',
      'NAME "sys"',
      'NEWLINE "\\n"',
      'NAME "from"',
      'NAME "tokenize"',
      'NAME "import"',
      'NAME "tokenize"',
      'OP ","',
      'NAME "tok_name"',
      'NEWLINE "\\n"',
      'NAME "import"',
      'NAME "json"',
      'NEWLINE "\\n"',
      'NAME "from"',
      'NAME "io"',
      'NAME "import"',
      'NAME "BytesIO"',
      'NEWLINE "\\n"',
      'NL "\\n"',
      'NAME "path"',
      'OP "="',
      'NAME "sys"',
      'OP "."',
      'NAME "argv"',
      'OP "["',
      'NUMBER "1"',
      'OP "]"',
      'NEWLINE "\\n"',
      'NAME "for"',
      'NAME "info"',
      'NAME "in"',
      'NAME "tokenize"',
      'OP "("',
      'NAME "open"',
      'OP "("',
      'NAME "path"',
      'OP ","',
      'STRING "rb"',
      'OP ")"',
      'OP "."',
      'NAME "readline"',
      'OP ")"',
      'OP ":"',
      'NEWLINE "\\n"',
      'INDENT "    "',
      'NAME "print"',
      'OP "("',
      'NAME "tok_name"',
      'OP "["',
      'NAME "info"',
      'OP "."',
      'NAME "type"',
      'OP "]"',
      'OP ","',
      'NAME "json"',
      'OP "."',
      'NAME "dumps"',
      'OP "("',
      'NAME "info"',
      'OP "."',
      'NAME "string"',
      'OP ")"',
      'OP ")"',
      'NEWLINE "\\n"',
      // 'NL "\\n"',
      'DEDENT ""',
      'ENDMARKER ""',
    ])
  })

  test("kurt python", () => {
    let tokens = python.outputTokens(fs.readFileSync('test/kurt.py', 'utf-8'))
    expect(tokens[100]).toBe('NAME "def"')
    expect(tokens.pop()).toBe('ENDMARKER ""')
    tokens.pop()
    expect(tokens.pop()).not.toBe('ERRORTOKEN ""')
    expect(tokens.length).toBe(11616)

    // let expected = fs.readFileSync('test/kurt-tokens.txt', 'utf-8').split('\n')
    // expect(tokens).toEqual(expected)
  })

})

describe('tosh tokenizer', () => {

  const tosh = require('./tosh')

  test('tosh', () => {
    let oldTokens = tosh.oldTokenizer(tosh.exampleFile)
    expect(tosh.tokenize(tosh.exampleFile)).toEqual(oldTokens)
  })

})
<|endoftext|>


<commit_before>/*
 * grunt-snakeskin
 * https://github.com/kobezzza/grunt-snakeskin
 *
 * Copyright (c) 2014 Kobezzza
 * Licensed under the MIT license.
 */

var path = require('path');
var snakeskin = require('snakeskin'),
	beautify = require('js-beautify');

module.exports = function (grunt) {
	grunt.registerMultiTask('snakeskin', 'Compile Snakeskin templates', function () {
		var options = this.options(),
			prettyPrint;

		if (options.exec && options.prettyPrint) {
			options.prettyPrint = false;
			prettyPrint = true;
		}

		this.files.forEach(function (f) {
			var src = f.src.filter(function (filepath) {
				if (!grunt.file.exists(filepath)) {
					grunt.log.warn('Source file "' + filepath + '" not found.');
					return false;

				} else {
					return true;
				}

			}).map(function (filepath) {
				var tpls = {};

				if (options.exec) {
					options.context = tpls;
				}

				var res = snakeskin.compile(grunt.file.read(filepath), options, {file: filepath});

				if (options.exec) {
					res = snakeskin.returnMainTpl(tpls, filepath, options.tpl);
					res = res ? res(options.data) : '';
				}

				return res;

			}).join('');

			if (prettyPrint) {
				src = (beautify[path.extname(f.dest).replace(/^\./, '')] || beautify['html'])(src);
			}

			grunt.file.write(f.dest, src);
			grunt.log.writeln('File "' + f.dest + '" created.');
		});
	});
};
<commit_msg>Доработка<commit_after>/*
 * grunt-snakeskin
 * https://github.com/kobezzza/grunt-snakeskin
 *
 * Copyright (c) 2014 Kobezzza
 * Licensed under the MIT license.
 */

var path = require('path');
var snakeskin = require('snakeskin'),
	beautify = require('js-beautify');

module.exports = function (grunt) {
	grunt.registerMultiTask('snakeskin', 'Compile Snakeskin templates', function () {
		var options = this.options(),
			prettyPrint;

		if (options.exec && options.prettyPrint) {
			options.prettyPrint = false;
			prettyPrint = true;
		}

		this.files.forEach(function (f) {
			var isDir = !path.extname(f.dest);
			var src = f.src.filter(function (filepath) {
				if (grunt.file.exists(filepath)) {
					return true;
				}

				grunt.log.warn('Source file "' + filepath + '" not found.');
				return false;

			}).map(function (filepath) {
				var tpls = {};

				if (options.exec) {
					options.context = tpls;
				}

				var res = snakeskin.compile(grunt.file.read(filepath), options, {file: filepath});

				if (options.exec) {
					res = snakeskin.returnMainTpl(tpls, filepath, options.tpl) || '';

					if (res) {
						res = res(options.data);

						if (isDir && prettyPrint) {
							res = beautify['html'](res);
						}
					}
				}

				if (isDir) {
					grunt.file.write(
						path.join(f.dest, path.basename(filepath) + (options.exec ? '.html' : '.js')),
						res
					);

					grunt.log.writeln('File "' + f.dest + '" created.');
				}

				return res;

			}).join('');

			if (!isDir) {
				if (prettyPrint) {
					src = (beautify[path.extname(f.dest).replace(/^\./, '')] || beautify['html'])(src);
				}

				grunt.file.write(f.dest, src);
				grunt.log.writeln('File "' + f.dest + '" created.');
			}
		});
	});
};
<|endoftext|>


<commit_before>const assert = require('assert')
const fl     = require('../lib/main')
const data   = require('./data')
const fp     = require('lodash/fp')

describe('flatulence', () => {

  describe('#flatten()', () => {
    it('should flatten object', () => {
      const flattened = fl.flatten(data)

      console.log(flattened)

      assert.equal(flattened['array[0][1]'], 1)
    })

    it('should use prefix arg if provided', () => {
      const prefix = 'this.is.my.custom.prefix'
      const flattened = fl.flatten(
        {
          id: 'anid',
          map: { a:1, b:2, c:3}
        },
        prefix
      )

      console.log(flattened)

      assert.equal(flattened[prefix + '.id'], 'anid')
      assert.equal(flattened[prefix + '.map.a'], 1)
    })
  })

  describe('#unflatten()', () => {
    it('should reverse flattened object to an unflattened one', () => {
      const flattened = fl.flatten(data)
      const unflattened = fl.unflatten(flattened)

      assert.deepEqual(data, unflattened)

    })

    it('should reverse flattened object to an unflattened one at a prefix', () => {
      const flattened = fl.flatten(data)
      const unflattened = fl.unflatten(flattened, 'cc')

      assert.deepEqual(data.cc, unflattened)

    })

    it('should produce an unflat array when prefix points at array', () => {
      const flattened = fl.flatten(data)
      const unflattened = fl.unflatten(flattened, 'cc.contract.multiContractSetup')

      console.log('unflattened', unflattened)

      assert.ok(Array.isArray(unflattened))

    })
  })
})<commit_msg>prepare test<commit_after>const assert = require('assert')
const fl     = require('../lib/main')
const data   = require('./data')
const fp     = require('lodash/fp')

describe('flatulence', () => {

  describe('#flatten()', () => {
    it('should flatten object', () => {
      const flattened = fl.flatten(data)

      console.log(flattened)

      assert.equal(flattened['array[0][1]'], 1)
    })

    it('should keep empty arrays', () => {
      const flattened = fl.flatten({
        "name": "Mega Group 2",
        "loginId": "admin_mega_merchant_2",
        "description": "again, some description here",
        "merchantUsers": []
      })

      // assert(flattened.merchantUsers)
    })

    it('should use prefix arg if provided', () => {
      const prefix = 'this.is.my.custom.prefix'
      const flattened = fl.flatten(
        {
          id: 'anid',
          map: { a:1, b:2, c:3}
        },
        prefix
      )

      console.log(flattened)

      assert.equal(flattened[prefix + '.id'], 'anid')
      assert.equal(flattened[prefix + '.map.a'], 1)
    })
  })

  describe('#unflatten()', () => {
    it('should reverse flattened object to an unflattened one', () => {
      const flattened = fl.flatten(data)
      const unflattened = fl.unflatten(flattened)

      assert.deepEqual(data, unflattened)

    })

    it('should reverse flattened object to an unflattened one at a prefix', () => {
      const flattened = fl.flatten(data)
      const unflattened = fl.unflatten(flattened, 'cc')

      assert.deepEqual(data.cc, unflattened)

    })

    it('should produce an unflat array when prefix points at array', () => {
      const flattened = fl.flatten(data)
      const unflattened = fl.unflatten(flattened, 'cc.contract.multiContractSetup')

      console.log('unflattened', unflattened)

      assert.ok(Array.isArray(unflattened))

    })
  })
})<|endoftext|>


<commit_before><commit_msg>tests for mongoose<commit_after>var mongoose = require('mongoose')
  , Schema = mongoose.Schema

var schema = new Schema({
  name:    String,
  binary:  Buffer,
  living:  Boolean,
  updated: { type: Date, default: Date.now },
  age:     { type: Number, min: 18, max: 65 },
  mixed:   Schema.Types.Mixed,
  _someId: Schema.Types.ObjectId,
  array:      [],
  ofString:   [String],
  ofNumber:   [Number],
  ofDates:    [Date],
  ofBuffer:   [Buffer],
  ofBoolean:  [Boolean],
  ofMixed:    [Schema.Types.Mixed],
  ofObjectId: [Schema.Types.ObjectId],
  nested: {
    stuff: { type: String, lowercase: true, trim: true }
  }
})

// example use

var Thing = mongoose.model('Thing', schema);

var m = new Thing;
m.name = 'Statue of Liberty'
m.age = 125;
m.updated = new Date;
m.binary = new Buffer(0);
m.living = false;
m.markModified('mixed');
m._someId = new mongoose.Types.ObjectId;
m.array.push(1);
m.ofString.push("strings!");
m.ofNumber.unshift(1,2,3,4);
m.ofBuffer.pop();
m.ofMixed = [1, [], 'three', { four: 5 }];
m.nested.stuff = 'good';

console.log(m);
<|endoftext|>