blob: 6b0129a5f8093d74194e820062147d500981bddd [file] [log] [blame]
/**
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
var hooker = require('../../src/hooker'),
shell = require('shelljs'),
path = require('path'),
fs = require('fs'),
os = require('os'),
tempDir= path.join(__dirname, '..', '..', 'temp'),
hooks = path.join(__dirname, '..', 'fixtures', 'hooks'),
cordova= require('../../cordova');
var platform = os.platform();
var cwd = process.cwd();
describe('hooker', function() {
it('should throw if provided directory is not a cordova project', function() {
shell.rm('-rf', tempDir);
shell.mkdir('-p', tempDir);
this.after(function() {
shell.rm('-rf', tempDir);
});
expect(function() {
var h = new hooker(tempDir);
}).toThrow();
});
it('should not throw if provided directory is a cordova project', function() {
cordova.create(tempDir);
this.after(function() {
shell.rm('-rf', tempDir);
});
expect(function() {
var h = new hooker(tempDir);
}).not.toThrow();
});
describe('fire method', function() {
var h;
beforeEach(function() {
cordova.create(tempDir);
h = new hooker(tempDir);
});
afterEach(function() {
shell.rm('-rf', tempDir);
});
describe('failure', function() {
it('should not error if the hook is unrecognized', function(done) {
h.fire('CLEAN YOUR SHORTS GODDAMNIT LIKE A BIG BOY!', function(err){
expect(err).not.toBeDefined();
done();
});
});
it('should error if any script exits with non-zero code', function(done) {
var script;
if (platform.match(/(win32|win64)/)) {
script = path.join(tempDir, '.cordova', 'hooks', 'before_build', 'fail.bat');
shell.cp(path.join(hooks, 'fail', 'fail.bat'), script);
} else {
script = path.join(tempDir, '.cordova', 'hooks', 'before_build', 'fail.sh');
shell.cp(path.join(hooks, 'fail', 'fail.sh'), script);
}
fs.chmodSync(script, '754');
h.fire('before_build', function(err){
expect(err).toBeDefined();
done();
});
});
});
describe('success', function() {
it('should execute all scripts in order and fire callback', function(done) {
var hook = path.join(tempDir, '.cordova', 'hooks', 'before_build');
if (platform.match(/(win32|win64)/)) {
shell.cp(path.join(hooks, 'test', '0.bat'), hook);
shell.cp(path.join(hooks, 'test', '1.bat'), hook);
} else {
shell.cp(path.join(hooks, 'test', '0.sh'), hook);
shell.cp(path.join(hooks, 'test', '1.sh'), hook);
}
fs.readdirSync(hook).forEach(function(script) {
fs.chmodSync(path.join(hook, script), '754');
});
var returnValue;
var s = spyOn(shell, 'exec').andCallFake(function(cmd, opts, cb) {
cb(0, '');
});
h.fire('before_build', function(err) {
expect(err).not.toBeDefined();
if (platform.match(/(win32|win64)/)) {
expect(s.calls[0].args[0]).toMatch(/0.bat/);
expect(s.calls[1].args[0]).toMatch(/1.bat/);
} else {
expect(s.calls[0].args[0]).toMatch(/0.sh/);
expect(s.calls[1].args[0]).toMatch(/1.sh/);
}
done();
});
});
it('should pass the project root folder as parameter into the project-level hooks', function(done) {
var hook = path.join(tempDir, '.cordova', 'hooks', 'before_build');
if (platform.match(/(win32|win64)/)) {
shell.cp(path.join(hooks, 'test', '0.bat'), hook);
} else {
shell.cp(path.join(hooks, 'test', '0.sh'), hook);
}
fs.readdirSync(hook).forEach(function(script) {
fs.chmodSync(path.join(hook, script), '754');
});
var s = spyOn(shell, 'exec').andCallFake(function(cmd, opts, cb) {
cb(0, '');
});
h.fire('before_build', function(err) {
expect(err).not.toBeDefined();
var param_str;
if (platform.match(/(win32|win64)/)) {
param_str = '0.bat "'+tempDir+'"';
} else {
param_str = '0.sh "'+tempDir+'"';
}
expect(s.calls[0].args[0].indexOf(param_str)).not.toEqual(-1);
done();
});
});
describe('module-level hooks', function() {
var handler = jasmine.createSpy();
var test_event = 'before_build';
afterEach(function() {
cordova.off(test_event, handler);
handler.reset();
});
it('should fire handlers using cordova.on', function(done) {
cordova.on(test_event, handler);
h.fire(test_event, function(err) {
expect(handler).toHaveBeenCalled();
expect(err).not.toBeDefined();
done();
});
});
it('should pass the project root folder as parameter into the module-level handlers', function(done) {
cordova.on(test_event, handler);
h.fire(test_event, function(err) {
expect(handler).toHaveBeenCalledWith({root:tempDir});
expect(err).not.toBeDefined();
done();
});
});
it('should be able to stop listening to events using cordova.off', function(done) {
cordova.on(test_event, handler);
cordova.off(test_event, handler);
h.fire(test_event, function(err) {
expect(handler).not.toHaveBeenCalled();
done();
});
});
it('should allow for hook to opt into asynchronous execution and block further hooks from firing using the done callback', function(done) {
var h1_fired = false;
var h1 = function(root, cb) {
h1_fired = true;
setTimeout(cb, 100);
};
var h2_fired = false;
var h2 = function() {
h2_fired = true;
};
runs(function() {
cordova.on(test_event, h1);
cordova.on(test_event, h2);
h.fire(test_event, function(err) {
done();
});
expect(h1_fired).toBe(true);
expect(h2_fired).toBe(false);
});
waits(100);
runs(function() {
expect(h2_fired).toBe(true);
});
});
});
});
});
});