Skip to content
This repository was archived by the owner on Aug 19, 2019. It is now read-only.

Commit

Permalink
Merge pull request #56 from iffy/better-testing
Browse files Browse the repository at this point in the history
Better testing
  • Loading branch information
iffy authored Feb 23, 2017
2 parents c964046 + 1fd99db commit 9c83519
Show file tree
Hide file tree
Showing 11 changed files with 452 additions and 623 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ language: node_js
node_js:
- '7'

script: ./test/travis-build.sh
script: ./test/runtests.sh

cache:
yarn: true
Expand Down
30 changes: 30 additions & 0 deletions functest/e2e.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
const assert = require('assert');
const {setDialogAnswer, setMessageBoxAnswer} = require('./mocks.js');
const fs = require('fs-extra');
const Path = require('path');
const {waitUntilEqual} = require('./util.js');
const Mocha = require('mocha');
const {app} = require('../src/main.js');

const Tmp = require('tmp');
Tmp.setGracefulCleanup();

app.on('ready', function() {
let mocha = new Mocha();
let testDir = 'functest';
fs.readdirSync(testDir).filter(function(file){
// Only keep the .js files
return file.substr(-3) === '.js' && Path.basename(file).startsWith('test_');
}).forEach(function(file){
mocha.addFile(
Path.join(testDir, file)
);
});

mocha.run(function(failures){
process.on('exit', function () {
process.exit(failures && 1); // exit with non-zero status if there were failures
});
process.exit(0);
});
})
23 changes: 23 additions & 0 deletions functest/mocks.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
var {dialog} = require('electron');

let dialog_path = [];
let message_choice = 0;

dialog.showOpenDialog = (options, cb) => {
cb(dialog_path);
}
dialog.showSaveDialog = (options, cb) => {
cb(dialog_path);
}
dialog.showMessageBox = (options) => {
return message_choice;
}

function setDialogAnswer(answer) {
dialog_path = answer;
}
function setMessageBoxAnswer(answer) {
message_choice = answer;
}

module.exports = {setDialogAnswer, setMessageBoxAnswer};
284 changes: 284 additions & 0 deletions functest/test_e2e.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,284 @@
var assert = require('assert');
// var chai = require('chai');
// var chaiAsPromised = require('chai-as-promised');
const {mock, setDialogAnswer, setMessageBoxAnswer} = require('./mocks.js');
var fs = require('fs-extra');
var Path = require('path');
const {app, openPath, saveFocusedDoc, saveAsFocusedDoc, closeFocusedDoc, reloadFocusedDoc} = require('../src/main.js');
const {waitUntil, waitUntilEqual} = require('./util.js');
const {webContents, BrowserWindow} = require('electron');
const AdmZip = require('adm-zip');

const Tmp = require('tmp');
Tmp.setGracefulCleanup();

const _ = require('lodash');

function _wrapFunction(func) {
if (_.isFunction(func)) {
return `(function() {
try {
return (${func.toString()})();
} catch(err) {
return {executeJavaScriptError:err.toString()};
}
})()`;
}
return func;
}

function executeJavaScript(web, func) {
let code = _wrapFunction(func)
return web.executeJavaScript(code, /* because of issue 8743 */()=>{})
.then(result => {
if (result && result.executeJavaScriptError) {
throw new Error(result.executeJavaScriptError);
}
return result;
})
.catch(err => {
console.log('error', err);
})
}

function readFromZip(zipfile, path) {
let zip = new AdmZip(zipfile);
return zip.readFile(path);
}

function openDocument(path) {
openPath(path);
return waitUntil(function() {
return BrowserWindow.getAllWindows().length == 1;
})
.then(() => {
return waitUntil(function() {
return webContents.getAllWebContents().length == 2;
})
})
.then(() => {
return waitUntil(function() {
return _.filter(webContents.getAllWebContents(), wc => {
return wc.isLoading();
}).length === 0;
})
})
.then(() => {
let webview;
let container;
_.each(webContents.getAllWebContents(), wc => {
if (wc.getURL().startsWith('lhtml://')) {
webview = wc;
} else {
container = wc;
}
})
return {
webview: webview,
container: container,
}
})
}

function reloadDocument() {
reloadFocusedDoc()
return waitUntil(function() {
return _.filter(webContents.getAllWebContents(), wc => {
return wc.isLoading();
}).length === 0;
})
}

assert.contains = function(haystack, needle) {
let assertion;
if (haystack === null || needle === null) {
assertion = false;
} else {
assertion = haystack.indexOf(needle) !== -1
}
return assert.ok(assertion, `Expected to find\n-->${needle}<--\ninside\n-->${haystack}<--`)
}
assert.doesNotContain = function(haystack, needle) {
let assertion;
if (haystack === null || needle === null) {
assertion = false;
} else {
assertion = haystack.indexOf(needle) === -1
}
return assert.ok(assertion, `Expected not to find\n-->${needle}<--\ninside\n-->${haystack}<--`);
}

describe('app launch', function() {
this.timeout(10000);

beforeEach(() => {
});
afterEach(() => {
return closeFocusedDoc();
});

//----------------------------------------------------------------------
// saving/loading
//----------------------------------------------------------------------
describe('saving', function() {
let workdir;
beforeEach(() => {
workdir = Tmp.dirSync({unsafeCleanup: true}).name;
console.log('working in', workdir);
});

describe('from LHTML dir,', function() {
let src_dir;
let webview;
let container;

beforeEach(() => {
src_dir = Path.join(workdir, 'src');
fs.ensureDirSync(src_dir);
fs.writeFileSync(Path.join(src_dir, 'index.html'),
'<html><body><input id="theinput"></body></html>');
return openDocument(src_dir)
.then(result => {
webview = result.webview;
container = result.container;
})
})

it('"Save" should overwrite dir', () => {
return executeJavaScript(webview, function() {
return document.getElementById('theinput').setAttribute('value', 'jimbo');
})
.then(() => {
return saveFocusedDoc()
})
.then(() => {
assert.contains(fs.readFileSync(Path.join(src_dir, 'index.html')),
'jimbo');
})
.then(() => {
return reloadDocument()
})
.then(() => {
return executeJavaScript(webview, function() {
return document.getElementById('theinput').getAttribute('value')
})
})
.then(value => {
assert.equal(value, 'jimbo');
})
});

it('"Save As" should create a new file', () => {
let dst_file = Path.join(workdir, 'dst.lhtml');
return executeJavaScript(webview, function() {
return document.getElementById('theinput').setAttribute('value', 'garbage');
})
.then(() => {
setDialogAnswer(dst_file)
return saveAsFocusedDoc()
})
.then(() => {
// Should not have overwritten original
assert.doesNotContain(fs.readFileSync(Path.join(src_dir, 'index.html')),
'garbage');
})
.then(() => {
// Should have written new file
assert.contains(readFromZip(dst_file, './index.html'), 'garbage');
})
.then(() => {
return reloadDocument()
})
.then(() => {
// Should be using the new file
return executeJavaScript(webview, function() {
return document.getElementById('theinput').getAttribute('value')
})
})
.then(value => {
assert.equal(value, 'garbage');
})
});
});

describe('from LHTML file', function() {
let src_file;
let src_dir;
let webview;
let container;

beforeEach(() => {
src_file = Path.join(workdir, 'src.lhtml');
src_dir = Path.join(workdir, 'src');
let zip = new AdmZip();
zip.addFile('./index.html', '<html><body><input id="theinput"></body></html>');
zip.writeZip(src_file);

return openDocument(src_file)
.then(result => {
webview = result.webview;
container = result.container;
})
})

it('"Save" should overwrite file', () => {
return executeJavaScript(webview, function() {
return document.getElementById('theinput').setAttribute('value', 'jimbo');
})
.then(() => {
return saveFocusedDoc()
})
.then(() => {
assert.contains(readFromZip(src_file, './index.html'), 'jimbo');
})
.then(() => {
return reloadDocument()
})
.then(() => {
return executeJavaScript(webview, function() {
return document.getElementById('theinput').getAttribute('value')
})
})
.then(value => {
assert.equal(value, 'jimbo');
})
});

it('"Save As" should create a new file', () => {
let dst_file = Path.join(workdir, 'dst.lhtml');
return executeJavaScript(webview, function() {
return document.getElementById('theinput').setAttribute('value', 'garbage');
})
.then(() => {
setDialogAnswer(dst_file)
return saveAsFocusedDoc()
})
.then(() => {
// Should not have overwritten original
assert.doesNotContain(readFromZip(src_file, './index.html'), 'garbage')
})
.then(() => {
// Should have written new file with data in it
assert.contains(readFromZip(dst_file, './index.html'), 'garbage')
})
.then(() => {
return reloadDocument()
})
.then(() => {
// Should be using the new file
return executeJavaScript(webview, function() {
return document.getElementById('theinput').getAttribute('value')
})
})
.then(value => {
assert.equal(value, 'garbage');
})
});
});
})
})





File renamed without changes.
9 changes: 4 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"description": "LHTML Viewer",
"author": "Matt Haggard <[email protected]>",
"scripts": {
"test": "mocha",
"test": "test/runtests.sh",
"pack": "build --dir",
"dist": "build",
"postinstall": "install-app-deps"
Expand All @@ -16,9 +16,7 @@
"electron-builder": "^13.6.0",
"electron-packager": "^8.5.0",
"esdoc": "^0.5.2",
"http-server": "^0.9.0",
"mocha": "^3.2.0",
"spectron": "^3.4.1"
"mocha": "^3.2.0"
},
"dependencies": {
"adm-zip": "^0.4.7",
Expand Down Expand Up @@ -46,7 +44,8 @@
"!samples${/*}",
"!demos${/*}",
"!doc${/*}",
"!test${/*}"
"!test${/*}",
"!functest${/*}"
],
"fileAssociations": [
{
Expand Down
Loading

0 comments on commit 9c83519

Please sign in to comment.