Publish Vulpes Preview 15 sources for desktop, Android and Tundra
Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
This commit is contained in:
parent
93e3a48004
commit
b38dea0597
25901 changed files with 9982925 additions and 369 deletions
437
gaia/apps/keyboard/test/build/integration/keyboard_test.js
Executable file
437
gaia/apps/keyboard/test/build/integration/keyboard_test.js
Executable file
|
|
@ -0,0 +1,437 @@
|
|||
'use strict';
|
||||
|
||||
/* jshint node: true, mocha: true */
|
||||
/* global suiteSetup */
|
||||
|
||||
var assert = require('chai').assert;
|
||||
var path = require('path');
|
||||
var fs = require('fs');
|
||||
var helper = require('helper');
|
||||
var AdmZip = require('adm-zip');
|
||||
var jsdom = require('jsdom').jsdom;
|
||||
|
||||
function checkLayoutsJSON(zipPath, expectedArr) {
|
||||
var zip = new AdmZip(zipPath);
|
||||
var entry = zip.getEntry('js/settings/layouts.json');
|
||||
var actualArr = JSON.parse(zip.readAsText(entry));
|
||||
|
||||
actualArr.forEach(function(layout) {
|
||||
assert.isTrue(
|
||||
!!layout.dictFileSize,
|
||||
'Expect layout contain to non-zero dictFileSize, id=' + layout.id);
|
||||
delete layout.dictFileSize;
|
||||
});
|
||||
|
||||
expectedArr.forEach(function(layout) {
|
||||
delete layout.dictFileSize;
|
||||
});
|
||||
|
||||
assert.deepEqual(actualArr, expectedArr);
|
||||
}
|
||||
|
||||
suite('Keyboard layouts building tests', function() {
|
||||
suiteSetup(helper.cleanupWorkspace);
|
||||
teardown(helper.cleanupWorkspace);
|
||||
|
||||
// default make -- build with selected layouts and dictionaries
|
||||
test('APP=keyboard make', function(done) {
|
||||
var cmd = 'APP=keyboard make';
|
||||
helper.exec(cmd, function(error, stdout, stderr) {
|
||||
helper.checkError(error, stdout, stderr);
|
||||
|
||||
var config = JSON.parse(process.env.BUILD_CONFIG);
|
||||
var layoutIds = ['ar',
|
||||
'bn-Avro',
|
||||
'bn-Probhat',
|
||||
'de',
|
||||
'de-Neo',
|
||||
'dz-BT',
|
||||
'en',
|
||||
'en-Colemak',
|
||||
'en-Dvorak',
|
||||
'en-Neo',
|
||||
'eo',
|
||||
'es',
|
||||
'es-Americas',
|
||||
'fa',
|
||||
'fr',
|
||||
'fr-CA',
|
||||
'fr-CH',
|
||||
'fr-Dvorak-bepo',
|
||||
'he',
|
||||
'hi',
|
||||
'ig',
|
||||
'ko',
|
||||
'mk',
|
||||
'my',
|
||||
'pl',
|
||||
'pt-BR',
|
||||
'ta',
|
||||
'te',
|
||||
'th',
|
||||
'uk',
|
||||
'vi-Qwerty',
|
||||
'vi-Telex',
|
||||
'vi-Typewriter',
|
||||
'wo',
|
||||
'zh-Hans-Pinyin'];
|
||||
var zipPath = path.join(process.cwd(), 'profile',
|
||||
'webapps', 'keyboard.gaiamobile.org', 'application.zip');
|
||||
var appDirPath = config.GAIA_DIR + '/apps/keyboard';
|
||||
|
||||
var layouts = layoutIds.map(function(layout) {
|
||||
return 'js/layouts/' + layout + '.js';
|
||||
});
|
||||
|
||||
// Unfortunately we can only whilelist files here because we shouldn't
|
||||
// throw error if excluded files are missing (e.g. README).
|
||||
var imes = [
|
||||
'js/imes/jshangul/jshangul.js',
|
||||
'js/imes/jspinyin/empinyin_files.data',
|
||||
'js/imes/jspinyin/empinyin_files.js',
|
||||
'js/imes/jspinyin/jspinyin.js',
|
||||
'js/imes/jspinyin/libpinyin.js',
|
||||
'js/imes/jspinyin/worker.js',
|
||||
'js/imes/latin/latin.js',
|
||||
'js/imes/latin/predictions.js',
|
||||
'js/imes/latin/worker.js'
|
||||
];
|
||||
|
||||
var dicts = [
|
||||
'js/imes/latin/dictionaries/de.dict',
|
||||
'js/imes/latin/dictionaries/en_us.dict',
|
||||
'js/imes/latin/dictionaries/es.dict',
|
||||
'js/imes/latin/dictionaries/fr.dict',
|
||||
'js/imes/latin/dictionaries/pl.dict',
|
||||
'js/imes/latin/dictionaries/pt_br.dict'
|
||||
];
|
||||
|
||||
var checkList = [].concat(layouts, imes, dicts);
|
||||
checkList.forEach(function(path) {
|
||||
helper.checkFileInZip(zipPath, path, appDirPath + '/' + path);
|
||||
});
|
||||
|
||||
// Verify inputs entry in manifest
|
||||
var zip = new AdmZip(zipPath);
|
||||
var entry = zip.getEntry('manifest.webapp');
|
||||
var manifest = JSON.parse(zip.readAsText(entry));
|
||||
var inputKeysInManifest = Object.keys(manifest.inputs);
|
||||
|
||||
assert.deepEqual(inputKeysInManifest.sort(),
|
||||
[].concat(layoutIds, 'number', 'emoji').sort());
|
||||
|
||||
// Verify dictionary config
|
||||
var dictJSON = JSON.parse(fs.readFileSync(
|
||||
appDirPath +
|
||||
'/test/build/integration/resources/' +
|
||||
'default-make-layouts.json'));
|
||||
|
||||
checkLayoutsJSON(zipPath, dictJSON);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
// Build with all layouts and dictionaries
|
||||
test('APP=keyboard GAIA_KEYBOARD_LAYOUTS=* make', function(done) {
|
||||
var cmd = 'APP=keyboard GAIA_KEYBOARD_LAYOUTS=* make';
|
||||
helper.exec(cmd, function(error, stdout, stderr) {
|
||||
helper.checkError(error, stdout, stderr);
|
||||
|
||||
var config = JSON.parse(process.env.BUILD_CONFIG);
|
||||
var zipPath = path.join(process.cwd(), 'profile',
|
||||
'webapps', 'keyboard.gaiamobile.org', 'application.zip');
|
||||
var appDirPath = config.GAIA_DIR + '/apps/keyboard';
|
||||
var layoutIds =
|
||||
fs.readdirSync(appDirPath + '/js/layouts').filter(function(filename) {
|
||||
return (path.extname(filename) === '.js');
|
||||
}).map(function(filename) {
|
||||
return path.basename(filename, '.js');
|
||||
}).filter(function(layoutId) {
|
||||
// Exclude noIncludeInExpandLayoutIdSet layouts
|
||||
return (['emoji'].indexOf(layoutId) === -1);
|
||||
});
|
||||
|
||||
var layouts = layoutIds.map(function(layout) {
|
||||
return 'js/layouts/' + layout + '.js';
|
||||
});
|
||||
|
||||
// Unfortunately we can only whilelist files here because we shouldn't
|
||||
// throw error if excluded files are missing (e.g. README).
|
||||
|
||||
// For the sake of simplicity let's only check the main scripts.
|
||||
var imes = [
|
||||
'js/imes/handwriting/handwriting.js',
|
||||
'js/imes/india/india.js',
|
||||
'js/imes/jshangul/jshangul.js',
|
||||
'js/imes/jskanji/jskanji.js',
|
||||
'js/imes/jspinyin/jspinyin.js',
|
||||
'js/imes/latin/latin.js',
|
||||
'js/imes/vietnamese/vietnamese.js',
|
||||
'js/imes/myanmar/myanmar.js'
|
||||
];
|
||||
|
||||
var dicts = [
|
||||
'js/imes/latin/dictionaries/bg.dict',
|
||||
'js/imes/latin/dictionaries/bs.dict',
|
||||
'js/imes/latin/dictionaries/ca.dict',
|
||||
'js/imes/latin/dictionaries/cs.dict',
|
||||
'js/imes/latin/dictionaries/da.dict',
|
||||
'js/imes/latin/dictionaries/de.dict',
|
||||
'js/imes/latin/dictionaries/el.dict',
|
||||
'js/imes/latin/dictionaries/en_gb.dict',
|
||||
'js/imes/latin/dictionaries/en_us.dict',
|
||||
'js/imes/latin/dictionaries/es.dict',
|
||||
'js/imes/latin/dictionaries/eu.dict',
|
||||
'js/imes/latin/dictionaries/fr.dict',
|
||||
'js/imes/latin/dictionaries/ga.dict',
|
||||
'js/imes/latin/dictionaries/gd.dict',
|
||||
'js/imes/latin/dictionaries/gl.dict',
|
||||
'js/imes/latin/dictionaries/gv.dict',
|
||||
'js/imes/latin/dictionaries/hr.dict',
|
||||
'js/imes/latin/dictionaries/hu.dict',
|
||||
'js/imes/latin/dictionaries/it.dict',
|
||||
'js/imes/latin/dictionaries/lt.dict',
|
||||
'js/imes/latin/dictionaries/lv.dict',
|
||||
'js/imes/latin/dictionaries/nb.dict',
|
||||
'js/imes/latin/dictionaries/nl.dict',
|
||||
'js/imes/latin/dictionaries/pl.dict',
|
||||
'js/imes/latin/dictionaries/pt_br.dict',
|
||||
'js/imes/latin/dictionaries/pt_pt.dict',
|
||||
'js/imes/latin/dictionaries/ro.dict',
|
||||
'js/imes/latin/dictionaries/ru.dict',
|
||||
'js/imes/latin/dictionaries/sk.dict',
|
||||
'js/imes/latin/dictionaries/sq.dict',
|
||||
'js/imes/latin/dictionaries/sr-Cyrl.dict',
|
||||
'js/imes/latin/dictionaries/sr-Latn.dict',
|
||||
'js/imes/latin/dictionaries/sv.dict',
|
||||
'js/imes/latin/dictionaries/tr.dict',
|
||||
'js/imes/latin/dictionaries/af.dict'
|
||||
];
|
||||
|
||||
var checkList = [].concat(layouts, imes, dicts);
|
||||
checkList.forEach(function(path) {
|
||||
helper.checkFileInZip(zipPath, path, appDirPath + '/' + path);
|
||||
});
|
||||
|
||||
// Verify inputs entry in manifest
|
||||
var zip = new AdmZip(zipPath);
|
||||
var entry = zip.getEntry('manifest.webapp');
|
||||
var manifest = JSON.parse(zip.readAsText(entry));
|
||||
var inputKeysInManifest = Object.keys(manifest.inputs);
|
||||
|
||||
assert.deepEqual(inputKeysInManifest.sort(),
|
||||
[].concat(layoutIds, 'number', 'emoji').sort());
|
||||
|
||||
// Verify dictionary config
|
||||
var dictJSON = JSON.parse(fs.readFileSync(
|
||||
appDirPath +
|
||||
'/test/build/integration/resources/' +
|
||||
'all-layout-make-layouts.json'));
|
||||
|
||||
checkLayoutsJSON(zipPath, dictJSON);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
// Build with all layouts with no dictionaries
|
||||
// (preload ko layout here to avoid empty check.)
|
||||
test('APP=keyboard GAIA_KEYBOARD_LAYOUTS=ko ' +
|
||||
'GAIA_KEYBOARD_DOWNLOADABLE_LAYOUTS=noPreloadDictRequired make',
|
||||
function(done) {
|
||||
var cmd = 'APP=keyboard GAIA_KEYBOARD_LAYOUTS=ko ' +
|
||||
'GAIA_KEYBOARD_DOWNLOADABLE_LAYOUTS=noPreloadDictRequired make';
|
||||
helper.exec(cmd, function(error, stdout, stderr) {
|
||||
helper.checkError(error, stdout, stderr);
|
||||
|
||||
var config = JSON.parse(process.env.BUILD_CONFIG);
|
||||
var zipPath = path.join(process.cwd(), 'profile',
|
||||
'webapps', 'keyboard.gaiamobile.org', 'application.zip');
|
||||
var appDirPath = config.GAIA_DIR + '/apps/keyboard';
|
||||
|
||||
// For this test, we verify there isn't any dictionary
|
||||
// in the zip.
|
||||
var zip = new AdmZip(zipPath);
|
||||
var entries = zip.getEntries();
|
||||
var imePath = 'js/imes';
|
||||
var sizeLimit = (1 << 10) * 100; // 100K
|
||||
entries.forEach(function(entry) {
|
||||
if (entry.entryName.substr(0, imePath.length) !== imePath) {
|
||||
return;
|
||||
}
|
||||
|
||||
var fileSize = entry.getData().length;
|
||||
assert.isTrue(fileSize < sizeLimit,
|
||||
'IME file is larger than non-dictionary limit: ' + entry.entryName +
|
||||
', size: ' + fileSize + ' bytes.');
|
||||
});
|
||||
|
||||
// Verify dictionary config
|
||||
var dictJSON = JSON.parse(fs.readFileSync(
|
||||
appDirPath +
|
||||
'/test/build/integration/resources/' +
|
||||
'no-preload-dict-required-make-layouts.json'));
|
||||
|
||||
checkLayoutsJSON(zipPath, dictJSON);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
// Build default layouts with only en dictionary, and extra IMEs
|
||||
test('APP=keyboard GAIA_KEYBOARD_LAYOUTS=en ' +
|
||||
'GAIA_KEYBOARD_DOWNLOADABLE_LAYOUTS=' +
|
||||
'en,pt-BR,es,de,fr,fr-CA,pl,ko,zh-Hans-Pinyin,en-Dvorak make',
|
||||
function(done) {
|
||||
var cmd = 'APP=keyboard GAIA_KEYBOARD_LAYOUTS=en ' +
|
||||
'GAIA_KEYBOARD_DOWNLOADABLE_LAYOUTS=' +
|
||||
'en,pt-BR,es,de,fr,fr-CA,pl,ko,zh-Hans-Pinyin,en-Dvorak make';
|
||||
helper.exec(cmd, function(error, stdout, stderr) {
|
||||
helper.checkError(error, stdout, stderr);
|
||||
|
||||
var config = JSON.parse(process.env.BUILD_CONFIG);
|
||||
var zipPath = path.join(process.cwd(), 'profile',
|
||||
'webapps', 'keyboard.gaiamobile.org', 'application.zip');
|
||||
var appDirPath = config.GAIA_DIR + '/apps/keyboard';
|
||||
var layoutIds = config.GAIA_KEYBOARD_LAYOUTS.split(',').sort()
|
||||
.filter(function(layoutId) {
|
||||
// Exclude noIncludeInExpandLayoutIdSet layouts
|
||||
return (['emoji'].indexOf(layoutId) === -1);
|
||||
});
|
||||
|
||||
var layouts = layoutIds.map(function(layout) {
|
||||
return 'js/layouts/' + layout + '.js';
|
||||
});
|
||||
|
||||
// Unfortunately we can only whilelist files here because we shouldn't
|
||||
// throw error if excluded files are missing (e.g. README).
|
||||
var imes = [
|
||||
'js/imes/jshangul/jshangul.js',
|
||||
'js/imes/jspinyin/empinyin_files.data',
|
||||
'js/imes/jspinyin/empinyin_files.js',
|
||||
'js/imes/jspinyin/jspinyin.js',
|
||||
'js/imes/jspinyin/libpinyin.js',
|
||||
'js/imes/jspinyin/worker.js',
|
||||
'js/imes/latin/latin.js',
|
||||
'js/imes/latin/predictions.js',
|
||||
'js/imes/latin/worker.js'
|
||||
];
|
||||
|
||||
var dicts = [
|
||||
'js/imes/latin/dictionaries/es.dict',
|
||||
'js/imes/latin/dictionaries/fr.dict',
|
||||
'js/imes/latin/dictionaries/pl.dict',
|
||||
'js/imes/latin/dictionaries/pt_br.dict'
|
||||
];
|
||||
|
||||
var checkList = [].concat(layouts, imes);
|
||||
checkList.forEach(function(path) {
|
||||
helper.checkFileInZip(zipPath, path, appDirPath + '/' + path);
|
||||
});
|
||||
|
||||
// Verify inputs entry in manifest
|
||||
var zip = new AdmZip(zipPath);
|
||||
var entry = zip.getEntry('manifest.webapp');
|
||||
var manifest = JSON.parse(zip.readAsText(entry));
|
||||
var inputKeysInManifest = Object.keys(manifest.inputs);
|
||||
|
||||
// Only layouts with dictionaries should be declaried.
|
||||
// Noted that en-Dvorak use the same dictionary as en so it should also
|
||||
// be declaried.
|
||||
assert.deepEqual(inputKeysInManifest.sort(),
|
||||
['en', 'en-Dvorak', 'ko', 'number', 'zh-Hans-Pinyin']);
|
||||
|
||||
// Verify dictionaries are not built (except en_us.dict)
|
||||
dicts.forEach(function(dict) {
|
||||
var entry = zip.getEntry(dict);
|
||||
assert.equal(entry, null, 'Dictionary should not be built: ' + dict);
|
||||
});
|
||||
|
||||
// Verify dictionary config
|
||||
var dictJSON = JSON.parse(fs.readFileSync(
|
||||
appDirPath +
|
||||
'/test/build/integration/resources/' +
|
||||
'default-make-en-dict-layouts.json'));
|
||||
|
||||
checkLayoutsJSON(zipPath, dictJSON);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
suite('Keyboard settings building tests', function() {
|
||||
suiteSetup(helper.cleanupWorkspace);
|
||||
teardown(helper.cleanupWorkspace);
|
||||
|
||||
// parse settings.html and return domDoc.
|
||||
var getSettingsDomDoc = function() {
|
||||
var zipPath = path.join(process.cwd(), 'profile',
|
||||
'webapps', 'keyboard.gaiamobile.org', 'application.zip');
|
||||
|
||||
// Verify settings.html content in manifest
|
||||
var zip = new AdmZip(zipPath);
|
||||
var entry = zip.getEntry('settings.html');
|
||||
return jsdom(zip.readAsText(entry));
|
||||
};
|
||||
|
||||
// return an array of <scripts> tag in <head>
|
||||
var getScriptsFromDomDoc = function(domDoc) {
|
||||
// We don't have Array.from in our node version, so use an old way to
|
||||
// convert HTMLCollections to array
|
||||
return Array.prototype.slice.call(
|
||||
domDoc.head.getElementsByTagName('script'));
|
||||
};
|
||||
|
||||
suite('For handwriting', function() {
|
||||
// return an array of <sections> in the general panel
|
||||
var getSectionsFromGeneralPanel = function(domDoc) {
|
||||
return Array.prototype.slice.call(
|
||||
domDoc.querySelectorAll('#general-container > section'));
|
||||
};
|
||||
|
||||
// default: there shouldn't be handwriting elements in resulting file
|
||||
test('APP=keyboard make', function(done) {
|
||||
var cmd = 'APP=keyboard make';
|
||||
helper.exec(cmd, function(error, stdout, stderr) {
|
||||
helper.checkError(error, stdout, stderr);
|
||||
|
||||
var settingsDOMDoc = getSettingsDomDoc();
|
||||
|
||||
assert.isTrue(getScriptsFromDomDoc(settingsDOMDoc).every(function(elem){
|
||||
return elem.src !== 'js/settings/handwriting_settings_view.js';
|
||||
}), 'No script should include handwriting_settings_view.js');
|
||||
|
||||
assert.isTrue(
|
||||
getSectionsFromGeneralPanel(settingsDOMDoc).every(function(elem){
|
||||
return elem.id !== 'handwriting-settings';
|
||||
}), 'No section in general panel should include handwriting settings');
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('GAIA_KEYBOARD_LAYOUTS=zh-Hans-Handwriting APP=keyboard make',
|
||||
function(done) {
|
||||
var cmd = 'GAIA_KEYBOARD_LAYOUTS=zh-Hans-Handwriting APP=keyboard make';
|
||||
helper.exec(cmd, function(error, stdout, stderr) {
|
||||
helper.checkError(error, stdout, stderr);
|
||||
|
||||
var settingsDOMDoc = getSettingsDomDoc();
|
||||
|
||||
assert.isTrue(getScriptsFromDomDoc(settingsDOMDoc).some(function(elem){
|
||||
return elem.src === 'js/settings/handwriting_settings_view.js';
|
||||
}), 'Some script should include handwriting_settings_view.js');
|
||||
|
||||
assert.isTrue(
|
||||
getSectionsFromGeneralPanel(settingsDOMDoc).some(function(elem){
|
||||
return elem.id === 'handwriting-settings';
|
||||
}),
|
||||
'Some section in general panel should include handwriting settings');
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
Loading…
Reference in a new issue