mirror of
https://github.com/S2-/gitlit
synced 2025-08-03 12:50:04 +02:00
add node modules to repo
This commit is contained in:
105
node_modules/electron-packager/test/_setup.js
generated
vendored
Normal file
105
node_modules/electron-packager/test/_setup.js
generated
vendored
Normal file
@@ -0,0 +1,105 @@
|
||||
'use strict'
|
||||
|
||||
const common = require('../common')
|
||||
const download = require('../download')
|
||||
const config = require('./config.json')
|
||||
const exec = require('mz/child_process').exec
|
||||
const fs = require('fs-extra')
|
||||
const os = require('os')
|
||||
const path = require('path')
|
||||
const targets = require('../targets')
|
||||
|
||||
function fixtureSubdir (subdir) {
|
||||
return path.join(__dirname, 'fixtures', subdir)
|
||||
}
|
||||
|
||||
/**
|
||||
* Skip testing darwin/mas target on Windows since Electron Packager itself skips it
|
||||
* (see https://github.com/electron-userland/electron-packager/issues/71)
|
||||
*/
|
||||
function skipDownloadingMacZips (platform, arch) {
|
||||
return common.isPlatformMac(platform) && process.platform === 'win32'
|
||||
}
|
||||
|
||||
function downloadAll (version) {
|
||||
console.log(`Calling electron-download for ${version} before running tests...`)
|
||||
const combinations = download.createDownloadCombos({electronVersion: config.version, all: true}, targets.officialPlatforms, targets.officialArchs, skipDownloadingMacZips)
|
||||
|
||||
return Promise.all(combinations.map(combination => downloadElectronZip(version, combination)))
|
||||
}
|
||||
|
||||
function downloadElectronZip (version, options) {
|
||||
return download.downloadElectronZip(Object.assign({}, options, {
|
||||
cache: path.join(os.homedir(), '.electron'),
|
||||
quiet: !!process.env.CI,
|
||||
version: version
|
||||
}))
|
||||
}
|
||||
|
||||
function downloadMASLoginHelperElectronZip () {
|
||||
if (process.platform !== 'win32') {
|
||||
const version = '2.0.0-beta.1'
|
||||
console.log(`Calling electron-download for ${version} (MAS only) before running tests...`)
|
||||
return downloadElectronZip(version, { platform: 'mas', arch: 'x64' })
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Download all Electron distributions before running tests to avoid timing out due to network
|
||||
* speed. Most tests run with the config.json version, but we have some tests using 0.37.4, an
|
||||
* `electron` module specific test using 1.3.1., and an MAS-specific test using 2.0.0-beta.1.
|
||||
*/
|
||||
function preDownloadElectron () {
|
||||
const versions = [
|
||||
config.version,
|
||||
'0.37.4',
|
||||
'1.3.1'
|
||||
]
|
||||
return Promise.all(versions.map(downloadAll))
|
||||
.then(downloadMASLoginHelperElectronZip)
|
||||
}
|
||||
|
||||
function npmInstallForFixture (fixture) {
|
||||
const fixtureDir = fixtureSubdir(fixture)
|
||||
return fs.exists(path.join(fixtureDir, 'node_modules'))
|
||||
.then(exists => {
|
||||
if (exists) {
|
||||
return true
|
||||
} else {
|
||||
console.log(`Running npm install in fixtures/${fixture}...`)
|
||||
return exec('npm install --no-bin-links', {cwd: fixtureDir})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function npmInstallForFixtures () {
|
||||
const fixtures = [
|
||||
'basic',
|
||||
'basic-renamed-to-electron',
|
||||
'electron-in-dependencies',
|
||||
'infer-missing-version-only',
|
||||
'el-0374'
|
||||
]
|
||||
return Promise.all(fixtures.map(npmInstallForFixture))
|
||||
}
|
||||
|
||||
const WORK_CWD = path.join(__dirname, 'work')
|
||||
|
||||
function ensureEmptyWorkDirExists () {
|
||||
return fs.remove(WORK_CWD)
|
||||
.then(() => fs.mkdirs(WORK_CWD))
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
fixtureSubdir: fixtureSubdir,
|
||||
setupTestsuite: function setupTestsuite () {
|
||||
return preDownloadElectron()
|
||||
.then(npmInstallForFixtures)
|
||||
.catch(error => {
|
||||
console.error(error.stack || error)
|
||||
return process.exit(1)
|
||||
})
|
||||
.then(ensureEmptyWorkDirExists)
|
||||
},
|
||||
WORK_CWD: WORK_CWD
|
||||
}
|
117
node_modules/electron-packager/test/_util.js
generated
vendored
Normal file
117
node_modules/electron-packager/test/_util.js
generated
vendored
Normal file
@@ -0,0 +1,117 @@
|
||||
'use strict'
|
||||
|
||||
// Keeping this module because it handles non-buffers gracefully
|
||||
const bufferEqual = require('buffer-equal')
|
||||
const common = require('../common')
|
||||
const config = require('./config.json')
|
||||
const fs = require('fs-extra')
|
||||
const packager = require('../index')
|
||||
const path = require('path')
|
||||
const setup = require('./_setup')
|
||||
const tempy = require('tempy')
|
||||
const test = require('ava')
|
||||
|
||||
const ORIGINAL_CWD = process.cwd()
|
||||
|
||||
test.before(t => {
|
||||
if (!process.env.CI) {
|
||||
return setup.setupTestsuite()
|
||||
.then(() => process.chdir(setup.WORK_CWD))
|
||||
}
|
||||
return Promise.resolve(process.chdir(setup.WORK_CWD))
|
||||
})
|
||||
|
||||
test.after.always(t => {
|
||||
process.chdir(ORIGINAL_CWD)
|
||||
return fs.remove(setup.WORK_CWD)
|
||||
})
|
||||
|
||||
test.beforeEach(t => {
|
||||
t.context.workDir = tempy.directory()
|
||||
t.context.tempDir = tempy.directory()
|
||||
})
|
||||
|
||||
test.afterEach.always(t => {
|
||||
return fs.remove(t.context.workDir)
|
||||
.then(() => fs.remove(t.context.tempDir))
|
||||
})
|
||||
|
||||
function testSinglePlatform (name, testFunction, testFunctionArgs, parallel) {
|
||||
module.exports.packagerTest(name, (t, opts) => {
|
||||
Object.assign(opts, module.exports.singlePlatformOptions())
|
||||
return testFunction.apply(null, [t, opts].concat(testFunctionArgs))
|
||||
}, parallel)
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
allPlatformArchCombosCount: 9,
|
||||
areFilesEqual: function areFilesEqual (file1, file2) {
|
||||
let buffer1, buffer2
|
||||
|
||||
return fs.readFile(file1)
|
||||
.then((data) => {
|
||||
buffer1 = data
|
||||
return fs.readFile(file2)
|
||||
}).then((data) => {
|
||||
buffer2 = data
|
||||
return bufferEqual(buffer1, buffer2)
|
||||
})
|
||||
},
|
||||
fixtureSubdir: setup.fixtureSubdir,
|
||||
generateResourcesPath: function generateResourcesPath (opts) {
|
||||
return common.isPlatformMac(opts.platform)
|
||||
? path.join(opts.name + '.app', 'Contents', 'Resources')
|
||||
: 'resources'
|
||||
},
|
||||
invalidOptionTest: function invalidOptionTest (opts) {
|
||||
return t => t.throws(packager(opts))
|
||||
},
|
||||
packageAndEnsureResourcesPath: function packageAndEnsureResourcesPath (t, opts) {
|
||||
let resourcesPath
|
||||
|
||||
return packager(opts)
|
||||
.then(paths => {
|
||||
resourcesPath = path.join(paths[0], module.exports.generateResourcesPath(opts))
|
||||
return fs.stat(resourcesPath)
|
||||
}).then(stats => {
|
||||
t.true(stats.isDirectory(), 'The output directory should contain the expected resources subdirectory')
|
||||
return resourcesPath
|
||||
})
|
||||
},
|
||||
packagerTest: function packagerTest (name, testFunction, parallel) {
|
||||
const testDefinition = parallel ? test : test.serial
|
||||
testDefinition(name, t => {
|
||||
return testFunction(t, {
|
||||
name: 'packagerTest',
|
||||
out: t.context.workDir,
|
||||
tmpdir: t.context.tempDir
|
||||
})
|
||||
})
|
||||
},
|
||||
singlePlatformOptions: function singlePlatformOptions () {
|
||||
return {
|
||||
platform: 'linux',
|
||||
arch: 'x64',
|
||||
electronVersion: config.version
|
||||
}
|
||||
},
|
||||
// Rest parameters are added (not behind a feature flag) in Node 6
|
||||
testSinglePlatform: function (name, testFunction /*, ...testFunctionArgs */) {
|
||||
const testFunctionArgs = Array.prototype.slice.call(arguments, 2)
|
||||
return testSinglePlatform(name, testFunction, testFunctionArgs, false)
|
||||
},
|
||||
// Rest parameters are added (not behind a feature flag) in Node 6
|
||||
testSinglePlatformParallel: function (name, testFunction /*, ...testFunctionArgs */) {
|
||||
const testFunctionArgs = Array.prototype.slice.call(arguments, 2)
|
||||
return testSinglePlatform(name, testFunction, testFunctionArgs, true)
|
||||
},
|
||||
verifyPackageExistence: function verifyPackageExistence (finalPaths) {
|
||||
return Promise.all(finalPaths.map((finalPath) => {
|
||||
return fs.stat(finalPath)
|
||||
.then(
|
||||
stats => stats.isDirectory(),
|
||||
() => false
|
||||
)
|
||||
}))
|
||||
}
|
||||
}
|
55
node_modules/electron-packager/test/asar.js
generated
vendored
Normal file
55
node_modules/electron-packager/test/asar.js
generated
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
'use strict'
|
||||
|
||||
const common = require('../common')
|
||||
const fs = require('fs-extra')
|
||||
const path = require('path')
|
||||
const test = require('ava')
|
||||
const util = require('./_util')
|
||||
|
||||
test('asar argument test: asar is not set', t => {
|
||||
const asarOpts = common.createAsarOpts({})
|
||||
t.false(asarOpts, 'createAsarOpts returns false')
|
||||
})
|
||||
|
||||
test('asar argument test: asar is true', t => {
|
||||
t.deepEqual(common.createAsarOpts({asar: true}), {})
|
||||
})
|
||||
|
||||
test('asar argument test: asar is not an Object or a bool', t => {
|
||||
t.false(common.createAsarOpts({asar: 'string'}), 'createAsarOpts returns false')
|
||||
})
|
||||
|
||||
util.testSinglePlatform('default_app.asar removal test', (t, opts) => {
|
||||
opts.name = 'default_appASARTest'
|
||||
opts.dir = util.fixtureSubdir('el-0374')
|
||||
opts.electronVersion = '0.37.4'
|
||||
|
||||
return util.packageAndEnsureResourcesPath(t, opts)
|
||||
.then(resourcesPath => fs.pathExists(path.join(resourcesPath, 'default_app.asar')))
|
||||
.then(exists => t.false(exists, 'The output directory should not contain the Electron default_app.asar file'))
|
||||
})
|
||||
|
||||
util.testSinglePlatform('asar test', (t, opts) => {
|
||||
opts.name = 'asarTest'
|
||||
opts.dir = util.fixtureSubdir('basic')
|
||||
opts.asar = {
|
||||
'unpack': '*.pac',
|
||||
'unpackDir': 'dir_to_unpack'
|
||||
}
|
||||
let resourcesPath
|
||||
|
||||
return util.packageAndEnsureResourcesPath(t, opts)
|
||||
.then(generatedResourcesPath => {
|
||||
resourcesPath = generatedResourcesPath
|
||||
return fs.stat(path.join(resourcesPath, 'app.asar'))
|
||||
}).then(stats => {
|
||||
t.true(stats.isFile(), 'app.asar should exist under the resources subdirectory when opts.asar is true')
|
||||
return fs.pathExists(path.join(resourcesPath, 'app'))
|
||||
}).then(exists => {
|
||||
t.false(exists, 'app subdirectory should NOT exist when app.asar is built')
|
||||
return fs.stat(path.join(resourcesPath, 'app.asar.unpacked'))
|
||||
}).then(stats => {
|
||||
t.true(stats.isDirectory(), 'app.asar.unpacked should exist under the resources subdirectory when opts.asar_unpack is set some expression')
|
||||
return fs.stat(path.join(resourcesPath, 'app.asar.unpacked', 'dir_to_unpack'))
|
||||
}).then(stats => t.true(stats.isDirectory(), 'dir_to_unpack should exist under app.asar.unpacked subdirectory when opts.asar-unpack-dir is set dir_to_unpack'))
|
||||
})
|
347
node_modules/electron-packager/test/basic.js
generated
vendored
Normal file
347
node_modules/electron-packager/test/basic.js
generated
vendored
Normal file
@@ -0,0 +1,347 @@
|
||||
'use strict'
|
||||
|
||||
const common = require('../common')
|
||||
const download = require('../download')
|
||||
const fs = require('fs-extra')
|
||||
const hostArch = require('../targets').hostArch
|
||||
const packager = require('..')
|
||||
const path = require('path')
|
||||
const test = require('ava')
|
||||
const util = require('./_util')
|
||||
|
||||
// Generates a path to the generated app that reflects the name given in the options.
|
||||
// Returns the Helper.app location on darwin since the top-level .app is already tested for the
|
||||
// resources path; on other OSes, returns the executable.
|
||||
function generateNamePath (opts) {
|
||||
if (common.isPlatformMac(opts.platform)) {
|
||||
return path.join(`${opts.name}.app`, 'Contents', 'Frameworks', `${opts.name} Helper.app`)
|
||||
}
|
||||
|
||||
return opts.name + (opts.platform === 'win32' ? '.exe' : '')
|
||||
}
|
||||
|
||||
test('setting the quiet option does not print messages', (t) => {
|
||||
const errorLog = console.error
|
||||
const warningLog = console.warn
|
||||
let output = ''
|
||||
console.error = (message) => { output += message }
|
||||
console.warn = (message) => { output += message }
|
||||
|
||||
common.warning('warning', true)
|
||||
t.is('', output, 'quieted common.warning should not call console.warn')
|
||||
common.info('info', true)
|
||||
t.is('', output, 'quieted common.info should not call console.error')
|
||||
|
||||
console.error = errorLog
|
||||
console.warn = warningLog
|
||||
})
|
||||
|
||||
test('download argument test: download.{arch,platform,version} does not overwrite {arch,platform,version}', t => {
|
||||
const opts = {
|
||||
download: {
|
||||
arch: 'ia32',
|
||||
platform: 'win32',
|
||||
version: '0.30.0'
|
||||
},
|
||||
electronVersion: '0.36.0'
|
||||
}
|
||||
|
||||
const downloadOpts = download.createDownloadOpts(opts, 'linux', 'x64')
|
||||
t.deepEqual(downloadOpts, {arch: 'x64', platform: 'linux', version: '0.36.0'})
|
||||
})
|
||||
|
||||
test('sanitize app name for use in file/directory names', t => {
|
||||
t.is('@username-package', common.sanitizeAppName('@username/package'), 'slash should be replaced')
|
||||
})
|
||||
|
||||
test('sanitize app name for use in the out directory name', t => {
|
||||
let opts = {
|
||||
arch: 'x64',
|
||||
name: '@username/package-name',
|
||||
platform: 'linux'
|
||||
}
|
||||
t.is('@username-package-name-linux-x64', common.generateFinalBasename(opts), 'generateFinalBasename output should be sanitized')
|
||||
})
|
||||
|
||||
test('cannot build apps where the name ends in " Helper"', (t) => {
|
||||
const opts = {
|
||||
arch: 'x64',
|
||||
dir: path.join(__dirname, 'fixtures', 'el-0374'),
|
||||
name: 'Bad Helper',
|
||||
platform: 'linux'
|
||||
}
|
||||
|
||||
return packager(opts)
|
||||
.then(
|
||||
() => { throw new Error('should not finish') },
|
||||
(err) => t.is(err.message, 'Application names cannot end in " Helper" due to limitations on macOS')
|
||||
)
|
||||
})
|
||||
|
||||
test('deprecatedParameter moves value in deprecated param to new param if new param is not set', (t) => {
|
||||
let opts = {
|
||||
old: 'value'
|
||||
}
|
||||
common.deprecatedParameter(opts, 'old', 'new', 'new-value')
|
||||
|
||||
t.false(opts.hasOwnProperty('old'), 'old property is not set')
|
||||
t.true(opts.hasOwnProperty('new'), 'new property is set')
|
||||
|
||||
opts.not_overwritten_old = 'another'
|
||||
common.deprecatedParameter(opts, 'not_overwritten_old', 'new', 'new-value')
|
||||
|
||||
t.false(opts.hasOwnProperty('not_overwritten_old'), 'not_overwritten_old property is not set')
|
||||
t.true(opts.hasOwnProperty('new'), 'new property is set')
|
||||
t.is('value', opts.new, 'new property is not overwritten')
|
||||
})
|
||||
|
||||
util.testSinglePlatform('defaults test', (t, opts) => {
|
||||
opts.name = 'defaultsTest'
|
||||
opts.dir = util.fixtureSubdir('basic')
|
||||
delete opts.platform
|
||||
delete opts.arch
|
||||
|
||||
let defaultOpts = {
|
||||
arch: hostArch(),
|
||||
name: opts.name,
|
||||
platform: process.platform
|
||||
}
|
||||
|
||||
let finalPath
|
||||
let resourcesPath
|
||||
|
||||
return packager(opts)
|
||||
.then(paths => {
|
||||
t.true(Array.isArray(paths), 'packager call should resolve to an array')
|
||||
t.is(paths.length, 1, 'Single-target run should resolve to a 1-item array')
|
||||
|
||||
finalPath = paths[0]
|
||||
t.is(finalPath, path.join(t.context.workDir, common.generateFinalBasename(defaultOpts)),
|
||||
'Path should follow the expected format and be in the cwd')
|
||||
return fs.stat(finalPath)
|
||||
}).then(stats => {
|
||||
t.true(stats.isDirectory(), 'The expected output directory should exist')
|
||||
resourcesPath = path.join(finalPath, util.generateResourcesPath(defaultOpts))
|
||||
return fs.stat(path.join(finalPath, generateNamePath(defaultOpts)))
|
||||
}).then(stats => {
|
||||
if (common.isPlatformMac(defaultOpts.platform)) {
|
||||
t.true(stats.isDirectory(), 'The Helper.app should reflect opts.name')
|
||||
} else {
|
||||
t.true(stats.isFile(), 'The executable should reflect opts.name')
|
||||
}
|
||||
return fs.stat(resourcesPath)
|
||||
}).then(stats => {
|
||||
t.true(stats.isDirectory(), 'The output directory should contain the expected resources subdirectory')
|
||||
return fs.pathExists(path.join(resourcesPath, 'app', 'node_modules', 'run-waterfall'))
|
||||
}).then(exists => {
|
||||
t.false(exists, 'The output directory should NOT contain devDependencies by default (prune=true)')
|
||||
return util.areFilesEqual(path.join(opts.dir, 'main.js'), path.join(resourcesPath, 'app', 'main.js'))
|
||||
}).then(equal => {
|
||||
t.true(equal, 'File under packaged app directory should match source file')
|
||||
return util.areFilesEqual(path.join(opts.dir, 'ignore', 'this.txt'),
|
||||
path.join(resourcesPath, 'app', 'ignore', 'this.txt'))
|
||||
}).then(equal => {
|
||||
t.true(equal, 'File under subdirectory of packaged app directory should match source file and not be ignored by default')
|
||||
return fs.pathExists(path.join(resourcesPath, 'default_app'))
|
||||
}).then(exists => {
|
||||
t.false(exists, 'The output directory should not contain the Electron default_app directory')
|
||||
return fs.pathExists(path.join(resourcesPath, 'default_app.asar'))
|
||||
}).then(exists => t.false(exists, 'The output directory should not contain the Electron default_app.asar file'))
|
||||
})
|
||||
|
||||
util.testSinglePlatform('out test', (t, opts) => {
|
||||
opts.name = 'outTest'
|
||||
opts.dir = util.fixtureSubdir('basic')
|
||||
opts.out = 'dist'
|
||||
|
||||
let finalPath
|
||||
|
||||
return packager(opts)
|
||||
.then(paths => {
|
||||
finalPath = paths[0]
|
||||
t.is(finalPath, path.join('dist', common.generateFinalBasename(opts)),
|
||||
'Path should follow the expected format and be under the folder specified in `out`')
|
||||
return fs.stat(finalPath)
|
||||
}).then(stats => {
|
||||
t.true(stats.isDirectory(), 'The expected output directory should exist')
|
||||
return fs.stat(path.join(finalPath, util.generateResourcesPath(opts)))
|
||||
}).then(stats => t.true(stats.isDirectory(), 'The output directory should contain the expected resources subdirectory'))
|
||||
})
|
||||
|
||||
util.testSinglePlatform('overwrite test', (t, opts) => {
|
||||
opts.name = 'overwriteTest'
|
||||
opts.dir = util.fixtureSubdir('basic')
|
||||
|
||||
let finalPath
|
||||
let testPath
|
||||
|
||||
return packager(opts)
|
||||
.then(paths => {
|
||||
finalPath = paths[0]
|
||||
return fs.stat(finalPath)
|
||||
}).then(stats => {
|
||||
t.true(stats.isDirectory(), 'The expected output directory should exist')
|
||||
// Create a dummy file to detect whether the output directory is replaced in subsequent runs
|
||||
testPath = path.join(finalPath, 'test.txt')
|
||||
return fs.writeFile(testPath, 'test')
|
||||
}).then(() => packager(opts)) // Run again, defaulting to overwrite false
|
||||
.then(paths => fs.stat(testPath))
|
||||
.then(stats => {
|
||||
t.true(stats.isFile(), 'The existing output directory should exist as before (skipped by default)')
|
||||
// Run a third time, explicitly setting overwrite to true
|
||||
opts.overwrite = true
|
||||
return packager(opts)
|
||||
}).then(paths => fs.pathExists(testPath))
|
||||
.then(exists => t.false(exists, 'The output directory should be regenerated when overwrite is true'))
|
||||
})
|
||||
|
||||
util.testSinglePlatform('overwrite test sans platform/arch set', (t, opts) => {
|
||||
delete opts.platfrom
|
||||
delete opts.arch
|
||||
opts.dir = util.fixtureSubdir('basic')
|
||||
opts.overwrite = true
|
||||
|
||||
return packager(opts)
|
||||
.then(paths => fs.pathExists(paths[0]))
|
||||
.then(exists => {
|
||||
t.true(exists, 'The output directory exists')
|
||||
return packager(opts)
|
||||
}).then(paths => fs.pathExists(paths[0]))
|
||||
.then(exists => t.true(exists, 'The output directory exists'))
|
||||
})
|
||||
|
||||
util.testSinglePlatform('tmpdir test', (t, opts) => {
|
||||
opts.name = 'tmpdirTest'
|
||||
opts.dir = path.join(__dirname, 'fixtures', 'basic')
|
||||
opts.out = 'dist'
|
||||
opts.tmpdir = path.join(t.context.workDir, 'tmp')
|
||||
|
||||
return packager(opts)
|
||||
.then(paths => fs.stat(path.join(opts.tmpdir, 'electron-packager')))
|
||||
.then(stats => t.true(stats.isDirectory(), 'The expected temp directory should exist'))
|
||||
})
|
||||
|
||||
util.testSinglePlatform('disable tmpdir test', (t, opts) => {
|
||||
opts.name = 'disableTmpdirTest'
|
||||
opts.dir = util.fixtureSubdir('basic')
|
||||
opts.out = 'dist'
|
||||
opts.tmpdir = false
|
||||
|
||||
return packager(opts)
|
||||
.then(paths => fs.stat(paths[0]))
|
||||
.then(stats => t.true(stats.isDirectory(), 'The expected out directory should exist'))
|
||||
})
|
||||
|
||||
util.testSinglePlatform('deref symlink test', (t, opts) => {
|
||||
opts.name = 'disableSymlinkDerefTest'
|
||||
opts.dir = util.fixtureSubdir('basic')
|
||||
opts.derefSymlinks = false
|
||||
|
||||
const src = path.join(opts.dir, 'main.js')
|
||||
const dest = path.join(opts.dir, 'main-link.js')
|
||||
|
||||
return fs.ensureSymlink(src, dest)
|
||||
.then(() => packager(opts))
|
||||
.then(paths => {
|
||||
const destLink = path.join(paths[0], 'resources', 'app', 'main-link.js')
|
||||
return fs.lstat(destLink)
|
||||
}).then(stats => {
|
||||
t.true(stats.isSymbolicLink(), 'The expected file should still be a symlink')
|
||||
return fs.remove(dest)
|
||||
})
|
||||
})
|
||||
|
||||
function createExtraResourceStringTest (t, opts, platform) {
|
||||
const extra1Base = 'data1.txt'
|
||||
const extra1Path = path.join(__dirname, 'fixtures', extra1Base)
|
||||
|
||||
opts.name = 'extraResourceStringTest'
|
||||
opts.dir = util.fixtureSubdir('basic')
|
||||
opts.out = 'dist'
|
||||
opts.platform = platform
|
||||
opts.extraResource = extra1Path
|
||||
|
||||
return util.packageAndEnsureResourcesPath(t, opts)
|
||||
.then(resourcesPath => util.areFilesEqual(extra1Path, path.join(resourcesPath, extra1Base)))
|
||||
.then(equal => t.true(equal, 'resource file data1.txt should match'))
|
||||
}
|
||||
|
||||
function createExtraResourceArrayTest (t, opts, platform) {
|
||||
const extra1Base = 'data1.txt'
|
||||
const extra1Path = path.join(__dirname, 'fixtures', extra1Base)
|
||||
const extra2Base = 'extrainfo.plist'
|
||||
const extra2Path = path.join(__dirname, 'fixtures', extra2Base)
|
||||
|
||||
opts.name = 'extraResourceArrayTest'
|
||||
opts.dir = util.fixtureSubdir('basic')
|
||||
opts.out = 'dist'
|
||||
opts.platform = platform
|
||||
opts.extraResource = [extra1Path, extra2Path]
|
||||
|
||||
let extra1DistPath
|
||||
let extra2DistPath
|
||||
|
||||
return util.packageAndEnsureResourcesPath(t, opts)
|
||||
.then(resourcesPath => {
|
||||
extra1DistPath = path.join(resourcesPath, extra1Base)
|
||||
extra2DistPath = path.join(resourcesPath, extra2Base)
|
||||
return fs.pathExists(extra1DistPath)
|
||||
}).then(exists => {
|
||||
t.true(exists, 'resource file data1.txt exists')
|
||||
return util.areFilesEqual(extra1Path, extra1DistPath)
|
||||
}).then(equal => {
|
||||
t.true(equal, 'resource file data1.txt should match')
|
||||
return fs.pathExists(extra2DistPath)
|
||||
}).then(exists => {
|
||||
t.true(exists, 'resource file extrainfo.plist exists')
|
||||
return util.areFilesEqual(extra2Path, extra2DistPath)
|
||||
}).then(equal => t.true(equal, 'resource file extrainfo.plist should match'))
|
||||
}
|
||||
|
||||
for (const platform of ['darwin', 'linux']) {
|
||||
util.testSinglePlatform(`extraResource test: string (${platform})`, createExtraResourceStringTest, platform)
|
||||
util.testSinglePlatform(`extraResource test: array (${platform})`, createExtraResourceArrayTest, platform)
|
||||
}
|
||||
|
||||
util.testSinglePlatform('building for Linux target sanitizes binary name', (t, opts) => {
|
||||
opts.name = '@username/package-name'
|
||||
opts.dir = util.fixtureSubdir('basic')
|
||||
|
||||
return packager(opts)
|
||||
.then(paths => {
|
||||
t.is(1, paths.length, '1 bundle created')
|
||||
return fs.stat(path.join(paths[0], '@username-package-name'))
|
||||
}).then(stats => t.true(stats.isFile(), 'The sanitized binary filename should exist'))
|
||||
})
|
||||
|
||||
util.testSinglePlatform('executableName honored when building for Linux target', (t, opts) => {
|
||||
opts.name = 'PackageName'
|
||||
opts.executableName = 'my-package'
|
||||
opts.dir = util.fixtureSubdir('basic')
|
||||
|
||||
return packager(opts)
|
||||
.then(paths => {
|
||||
t.is(1, paths.length, '1 bundle created')
|
||||
return fs.stat(path.join(paths[0], 'my-package'))
|
||||
}).then(stats => t.true(stats.isFile(), 'The executableName-based filename should exist'))
|
||||
})
|
||||
|
||||
util.packagerTest('fails with invalid version', util.invalidOptionTest({
|
||||
name: 'invalidElectronTest',
|
||||
dir: util.fixtureSubdir('el-0374'),
|
||||
electronVersion: '0.0.1',
|
||||
arch: 'x64',
|
||||
platform: 'linux',
|
||||
download: {
|
||||
quiet: !!process.env.CI
|
||||
}
|
||||
}))
|
||||
|
||||
util.testSinglePlatform('dir argument test: should work with relative path', (t, opts) => {
|
||||
opts.name = 'ElectronTest'
|
||||
opts.dir = path.join('..', 'fixtures', 'el-0374')
|
||||
opts.electronVersion = '0.37.4'
|
||||
|
||||
return packager(opts)
|
||||
.then(paths => t.is(path.join(t.context.workDir, 'ElectronTest-linux-x64'), paths[0], 'paths returned'))
|
||||
})
|
5
node_modules/electron-packager/test/ci/_before_script.js
generated
vendored
Executable file
5
node_modules/electron-packager/test/ci/_before_script.js
generated
vendored
Executable file
@@ -0,0 +1,5 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
'use strict'
|
||||
|
||||
require('../_setup').setupTestsuite()
|
34
node_modules/electron-packager/test/ci/appveyor.yml
generated
vendored
Normal file
34
node_modules/electron-packager/test/ci/appveyor.yml
generated
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
platform:
|
||||
- x86
|
||||
- x64
|
||||
environment:
|
||||
matrix:
|
||||
- nodejs_version: "4"
|
||||
- nodejs_version: "6"
|
||||
- nodejs_version: "8"
|
||||
- nodejs_version: "9"
|
||||
matrix:
|
||||
allow_failures:
|
||||
- nodejs_version: "9"
|
||||
cache:
|
||||
- 'node_modules'
|
||||
- '%USERPROFILE%\.electron'
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
|
||||
install:
|
||||
- ps: Install-Product node $env:nodejs_version $env:platform
|
||||
- npm install -g npm@4
|
||||
- set PATH=%APPDATA%\npm;%PATH%
|
||||
- npm install
|
||||
- npm update
|
||||
|
||||
test_script:
|
||||
- node --version
|
||||
- npm --version
|
||||
- node test/ci/_before_script.js
|
||||
- npm test
|
||||
- npm run codecov
|
||||
|
||||
build: off
|
33
node_modules/electron-packager/test/ci/before_install.sh
generated
vendored
Executable file
33
node_modules/electron-packager/test/ci/before_install.sh
generated
vendored
Executable file
@@ -0,0 +1,33 @@
|
||||
#!/bin/bash -xe
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
case "$TRAVIS_OS_NAME" in
|
||||
"linux")
|
||||
# Not using Trusty containers because it can't install wine1.6(-i386),
|
||||
# see: https://github.com/travis-ci/travis-ci/issues/6460
|
||||
sudo rm /etc/apt/sources.list.d/google-chrome.list
|
||||
sudo dpkg --add-architecture i386
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y wine1.6
|
||||
;;
|
||||
"osx")
|
||||
# Create CA
|
||||
openssl req -newkey rsa:4096 -days 1 -x509 -nodes -subj \
|
||||
"/C=CI/ST=Travis/L=Developer/O=Developer/CN=Developer CA" \
|
||||
-out /tmp/root.cer -keyout /tmp/root.key
|
||||
touch /tmp/certindex
|
||||
sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain \
|
||||
/tmp/root.cer
|
||||
# Create dev certificate
|
||||
openssl req -newkey rsa:1024 -nodes -subj \
|
||||
"/C=CI/ST=Travis/L=Developer/O=Developer/CN=Developer CodeCert" \
|
||||
-out codesign.csr -keyout codesign.key
|
||||
openssl ca -batch -config $(pwd)/test/ci/dev_ca.cnf -notext -create_serial \
|
||||
-in codesign.csr -out codesign.cer
|
||||
openssl pkcs12 -export -in codesign.cer -inkey codesign.key -out codesign.p12 -password pass:12345
|
||||
security import codesign.p12 -k ~/Library/Keychains/login.keychain -P 12345 -T /usr/bin/codesign
|
||||
npm install wine-darwin@1.9.17-1
|
||||
# Setup ~/.wine by running a command
|
||||
./node_modules/.bin/wine hostname
|
||||
;;
|
||||
esac
|
33
node_modules/electron-packager/test/ci/dev_ca.cnf
generated
vendored
Normal file
33
node_modules/electron-packager/test/ci/dev_ca.cnf
generated
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
[ ca ]
|
||||
default_ca = devca
|
||||
|
||||
[ crl_ext ]
|
||||
authorityKeyIdentifier=keyid:always
|
||||
|
||||
[ devca ]
|
||||
new_certs_dir = /tmp
|
||||
unique_subject = no
|
||||
certificate = /tmp/root.cer
|
||||
database = /tmp/certindex
|
||||
private_key = /tmp/root.key
|
||||
serial = /tmp/serialfile
|
||||
default_days = 1
|
||||
default_md = sha1
|
||||
policy = devca_policy
|
||||
x509_extensions = devca_extensions
|
||||
|
||||
[ devca_policy ]
|
||||
commonName = supplied
|
||||
stateOrProvinceName = supplied
|
||||
countryName = supplied
|
||||
emailAddress = optional
|
||||
organizationName = supplied
|
||||
organizationalUnitName = optional
|
||||
|
||||
[ devca_extensions ]
|
||||
basicConstraints = CA:false
|
||||
subjectKeyIdentifier = hash
|
||||
authorityKeyIdentifier = keyid:always
|
||||
keyUsage = digitalSignature,keyEncipherment
|
||||
extendedKeyUsage = codeSigning
|
||||
crlDistributionPoints = URI:http://path.to.crl/devca.crl
|
68
node_modules/electron-packager/test/cli.js
generated
vendored
Normal file
68
node_modules/electron-packager/test/cli.js
generated
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
'use strict'
|
||||
|
||||
const common = require('../common')
|
||||
const test = require('ava')
|
||||
|
||||
test('CLI argument test: --electron-version populates opts.electronVersion', t => {
|
||||
let args = common.parseCLIArgs([])
|
||||
t.is(args.electronVersion, undefined)
|
||||
args = common.parseCLIArgs(['--electron-version=1.2.3'])
|
||||
t.is(args.electronVersion, '1.2.3')
|
||||
})
|
||||
|
||||
test('CLI argument test: --download.strictSSL default', t => {
|
||||
const args = common.parseCLIArgs([])
|
||||
t.true(args.download.strictSSL, 'default for --download.strictSSL is true')
|
||||
})
|
||||
|
||||
test('CLI argument test: --asar=true', t => {
|
||||
const args = common.parseCLIArgs(['--asar=true'])
|
||||
t.true(args.asar)
|
||||
})
|
||||
|
||||
test('CLI argument test: using --asar overrides other --asar.options', t => {
|
||||
let args = common.parseCLIArgs(['--asar', '--asar.unpack=*.node'])
|
||||
t.true(args.asar)
|
||||
args = common.parseCLIArgs(['--asar.unpack=*.node', '--asar'])
|
||||
t.true(args.asar)
|
||||
})
|
||||
|
||||
test('CLI argument test: --osx-sign=true', t => {
|
||||
const args = common.parseCLIArgs(['--osx-sign=true'])
|
||||
t.true(args.osxSign)
|
||||
})
|
||||
|
||||
test('CLI argument test: --tmpdir=false', t => {
|
||||
const args = common.parseCLIArgs(['--tmpdir=false'])
|
||||
t.false(args.tmpdir)
|
||||
})
|
||||
|
||||
test('CLI argument test: --deref-symlinks default', t => {
|
||||
const args = common.parseCLIArgs([])
|
||||
t.true(args.derefSymlinks)
|
||||
})
|
||||
|
||||
test('CLI argument test: --out always resolves to a string', t => {
|
||||
const args = common.parseCLIArgs(['--out=1'])
|
||||
t.is(args.out, '1')
|
||||
})
|
||||
|
||||
test('CLI argument test: --out without a value is the same as not passing --out', t => {
|
||||
const args = common.parseCLIArgs(['--out'])
|
||||
t.is(args.out, null)
|
||||
})
|
||||
|
||||
test('CLI argument test: --protocol with a corresponding --protocol-name', t => {
|
||||
const args = common.parseCLIArgs(['--protocol=foo', '--protocol-name=Foo'])
|
||||
t.deepEqual(args.protocols, [{schemes: ['foo'], name: 'Foo'}])
|
||||
})
|
||||
|
||||
test('CLI argument test: --protocol without a corresponding --protocol-name', t => {
|
||||
const args = common.parseCLIArgs(['--protocol=foo'])
|
||||
t.deepEqual(args.protocols, undefined, 'no protocols have been fully defined')
|
||||
})
|
||||
|
||||
test('CLI argument test: multiple --protocol/--protocol-name argument pairs', t => {
|
||||
const args = common.parseCLIArgs(['--protocol=foo', '--protocol-name=Foo', '--protocol=bar', '--protocol-name=Bar'])
|
||||
t.deepEqual(args.protocols, [{schemes: ['foo'], name: 'Foo'}, {schemes: ['bar'], name: 'Bar'}])
|
||||
})
|
3
node_modules/electron-packager/test/config.json
generated
vendored
Normal file
3
node_modules/electron-packager/test/config.json
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"version": "0.35.6"
|
||||
}
|
445
node_modules/electron-packager/test/darwin.js
generated
vendored
Normal file
445
node_modules/electron-packager/test/darwin.js
generated
vendored
Normal file
@@ -0,0 +1,445 @@
|
||||
'use strict'
|
||||
|
||||
const config = require('./config.json')
|
||||
const exec = require('mz/child_process').exec
|
||||
const fs = require('fs-extra')
|
||||
const mac = require('../mac')
|
||||
const packager = require('..')
|
||||
const path = require('path')
|
||||
const plist = require('plist')
|
||||
const test = require('ava')
|
||||
const util = require('./_util')
|
||||
|
||||
const darwinOpts = {
|
||||
name: 'darwinTest',
|
||||
dir: util.fixtureSubdir('basic'),
|
||||
electronVersion: config.version,
|
||||
arch: 'x64',
|
||||
platform: 'darwin'
|
||||
}
|
||||
|
||||
const el0374Opts = Object.assign({}, darwinOpts, {
|
||||
name: 'el0374Test',
|
||||
dir: util.fixtureSubdir('el-0374'),
|
||||
electronVersion: '0.37.4'
|
||||
})
|
||||
|
||||
function testWrapper (testName, extraOpts, testFunction/*, ...extraArgs */) {
|
||||
const extraArgs = Array.prototype.slice.call(arguments, 3)
|
||||
|
||||
util.packagerTest(testName, (t, baseOpts) => {
|
||||
const opts = Object.assign({}, baseOpts, extraOpts)
|
||||
|
||||
return testFunction.apply(null, [t, opts].concat(extraArgs))
|
||||
})
|
||||
}
|
||||
|
||||
function darwinTest (testName, testFunction/*, ...extraArgs */) {
|
||||
const extraArgs = Array.prototype.slice.call(arguments, 2)
|
||||
return testWrapper.apply(null, [testName, darwinOpts, testFunction].concat(extraArgs))
|
||||
}
|
||||
|
||||
function electron0374Test (testName, testFunction) {
|
||||
const extraArgs = Array.prototype.slice.call(arguments, 2)
|
||||
return testWrapper.apply(null, [testName, el0374Opts, testFunction].concat(extraArgs))
|
||||
}
|
||||
|
||||
function getHelperExecutablePath (helperName) {
|
||||
return path.join(`${helperName}.app`, 'Contents', 'MacOS', helperName)
|
||||
}
|
||||
|
||||
function parseInfoPlist (t, opts, basePath) {
|
||||
const plistPath = path.join(basePath, `${opts.name}.app`, 'Contents', 'Info.plist')
|
||||
|
||||
return fs.stat(plistPath)
|
||||
.then(stats => {
|
||||
t.true(stats.isFile(), 'The expected Info.plist file should exist')
|
||||
return fs.readFile(plistPath, 'utf8')
|
||||
}).then(file => plist.parse(file))
|
||||
}
|
||||
|
||||
function packageAndParseInfoPlist (t, opts) {
|
||||
return packager(opts)
|
||||
.then(paths => parseInfoPlist(t, opts, paths[0]))
|
||||
}
|
||||
|
||||
function helperAppPathsTest (t, baseOpts, extraOpts, expectedName) {
|
||||
const opts = Object.assign(baseOpts, extraOpts)
|
||||
let frameworksPath
|
||||
|
||||
if (!expectedName) {
|
||||
expectedName = opts.name
|
||||
}
|
||||
|
||||
return packager(opts)
|
||||
.then(paths => {
|
||||
frameworksPath = path.join(paths[0], `${expectedName}.app`, 'Contents', 'Frameworks')
|
||||
// main Helper.app is already tested in basic test suite; test its executable and the other helpers
|
||||
return fs.stat(path.join(frameworksPath, getHelperExecutablePath(`${expectedName} Helper`)))
|
||||
}).then(stats => {
|
||||
t.true(stats.isFile(), 'The Helper.app executable should reflect sanitized opts.name')
|
||||
return fs.stat(path.join(frameworksPath, `${expectedName} Helper EH.app`))
|
||||
}).then(stats => {
|
||||
t.true(stats.isDirectory(), 'The Helper EH.app should reflect sanitized opts.name')
|
||||
return fs.stat(path.join(frameworksPath, getHelperExecutablePath(`${expectedName} Helper EH`)))
|
||||
}).then(stats => {
|
||||
t.true(stats.isFile(), 'The Helper EH.app executable should reflect sanitized opts.name')
|
||||
return fs.stat(path.join(frameworksPath, `${expectedName} Helper NP.app`))
|
||||
}).then(stats => {
|
||||
t.true(stats.isDirectory(), 'The Helper NP.app should reflect sanitized opts.name')
|
||||
return fs.stat(path.join(frameworksPath, getHelperExecutablePath(`${expectedName} Helper NP`)))
|
||||
}).then(stats => t.true(stats.isFile(), 'The Helper NP.app executable should reflect sanitized opts.name'))
|
||||
}
|
||||
|
||||
function iconTest (t, opts, icon, iconPath) {
|
||||
opts.icon = icon
|
||||
|
||||
let resourcesPath
|
||||
|
||||
return util.packageAndEnsureResourcesPath(t, opts)
|
||||
.then(generatedResourcesPath => {
|
||||
resourcesPath = generatedResourcesPath
|
||||
const outputPath = resourcesPath.replace(`${path.sep}${util.generateResourcesPath(opts)}`, '')
|
||||
return parseInfoPlist(t, opts, outputPath)
|
||||
}).then(obj => {
|
||||
return util.areFilesEqual(iconPath, path.join(resourcesPath, obj.CFBundleIconFile))
|
||||
}).then(equal => t.true(equal, 'installed icon file should be identical to the specified icon file'))
|
||||
}
|
||||
|
||||
function extendInfoTest (t, baseOpts, extraPathOrParams) {
|
||||
const opts = Object.assign({}, baseOpts, {
|
||||
appBundleId: 'com.electron.extratest',
|
||||
appCategoryType: 'public.app-category.music',
|
||||
buildVersion: '3.2.1',
|
||||
extendInfo: extraPathOrParams
|
||||
})
|
||||
|
||||
return packageAndParseInfoPlist(t, opts)
|
||||
.then(obj => {
|
||||
t.is(obj.TestKeyString, 'String data', 'TestKeyString should come from extendInfo')
|
||||
t.is(obj.TestKeyInt, 12345, 'TestKeyInt should come from extendInfo')
|
||||
t.is(obj.TestKeyBool, true, 'TestKeyBool should come from extendInfo')
|
||||
t.deepEqual(obj.TestKeyArray, ['public.content', 'public.data'], 'TestKeyArray should come from extendInfo')
|
||||
t.deepEqual(obj.TestKeyDict, { Number: 98765, CFBundleVersion: '0.0.0' }, 'TestKeyDict should come from extendInfo')
|
||||
t.is(obj.CFBundleVersion, opts.buildVersion, 'CFBundleVersion should reflect buildVersion argument')
|
||||
t.is(obj.CFBundleIdentifier, 'com.electron.extratest', 'CFBundleIdentifier should reflect appBundleId argument')
|
||||
t.is(obj.LSApplicationCategoryType, 'public.app-category.music', 'LSApplicationCategoryType should reflect appCategoryType argument')
|
||||
return t.is(obj.CFBundlePackageType, 'APPL', 'CFBundlePackageType should be Electron default')
|
||||
})
|
||||
}
|
||||
|
||||
function binaryNameTest (t, baseOpts, extraOpts, expectedExecutableName, expectedAppName) {
|
||||
const opts = Object.assign({}, baseOpts, extraOpts)
|
||||
const appName = expectedAppName || expectedExecutableName || opts.name
|
||||
const executableName = expectedExecutableName || opts.name
|
||||
|
||||
let binaryPath
|
||||
|
||||
return packager(opts)
|
||||
.then(paths => {
|
||||
binaryPath = path.join(paths[0], `${appName}.app`, 'Contents', 'MacOS')
|
||||
return fs.stat(path.join(binaryPath, executableName))
|
||||
}).then(stats => t.true(stats.isFile(), 'The binary should reflect a sanitized opts.name'))
|
||||
}
|
||||
|
||||
function appVersionTest (t, opts, appVersion, buildVersion) {
|
||||
opts.appVersion = appVersion
|
||||
opts.buildVersion = buildVersion || appVersion
|
||||
|
||||
return packageAndParseInfoPlist(t, opts)
|
||||
.then(obj => {
|
||||
t.is(obj.CFBundleVersion, '' + opts.buildVersion, 'CFBundleVersion should reflect buildVersion')
|
||||
t.is(obj.CFBundleShortVersionString, '' + opts.appVersion, 'CFBundleShortVersionString should reflect appVersion')
|
||||
t.is(typeof obj.CFBundleVersion, 'string', 'CFBundleVersion should be a string')
|
||||
return t.is(typeof obj.CFBundleShortVersionString, 'string', 'CFBundleShortVersionString should be a string')
|
||||
})
|
||||
}
|
||||
|
||||
function appBundleTest (t, opts, appBundleId) {
|
||||
if (appBundleId) {
|
||||
opts.appBundleId = appBundleId
|
||||
}
|
||||
|
||||
const defaultBundleName = `com.electron.${opts.name.toLowerCase()}`
|
||||
const appBundleIdentifier = mac.filterCFBundleIdentifier(opts.appBundleId || defaultBundleName)
|
||||
|
||||
return packageAndParseInfoPlist(t, opts)
|
||||
.then(obj => {
|
||||
t.is(obj.CFBundleDisplayName, opts.name, 'CFBundleDisplayName should reflect opts.name')
|
||||
t.is(obj.CFBundleName, opts.name, 'CFBundleName should reflect opts.name')
|
||||
t.is(obj.CFBundleIdentifier, appBundleIdentifier, 'CFBundleName should reflect opts.appBundleId or fallback to default')
|
||||
t.is(typeof obj.CFBundleDisplayName, 'string', 'CFBundleDisplayName should be a string')
|
||||
t.is(typeof obj.CFBundleName, 'string', 'CFBundleName should be a string')
|
||||
t.is(typeof obj.CFBundleIdentifier, 'string', 'CFBundleIdentifier should be a string')
|
||||
return t.is(/^[a-zA-Z0-9-.]*$/.test(obj.CFBundleIdentifier), true, 'CFBundleIdentifier should allow only alphanumeric (A-Z,a-z,0-9), hyphen (-), and period (.)')
|
||||
})
|
||||
}
|
||||
|
||||
function appHelpersBundleTest (t, opts, helperBundleId, appBundleId) {
|
||||
let tempPath, plistPath
|
||||
|
||||
if (helperBundleId) {
|
||||
opts.helperBundleId = helperBundleId
|
||||
}
|
||||
if (appBundleId) {
|
||||
opts.appBundleId = appBundleId
|
||||
}
|
||||
const defaultBundleName = `com.electron.${opts.name.toLowerCase()}`
|
||||
const appBundleIdentifier = mac.filterCFBundleIdentifier(opts.appBundleId || defaultBundleName)
|
||||
const helperBundleIdentifier = mac.filterCFBundleIdentifier(opts.helperBundleId || appBundleIdentifier + '.helper')
|
||||
|
||||
return packager(opts)
|
||||
.then(paths => {
|
||||
tempPath = paths[0]
|
||||
plistPath = path.join(tempPath, opts.name + '.app', 'Contents', 'Frameworks', opts.name + ' Helper.app', 'Contents', 'Info.plist')
|
||||
return fs.stat(plistPath)
|
||||
}).then(stats => {
|
||||
t.true(stats.isFile(), 'The expected Info.plist file should exist in helper app')
|
||||
return fs.readFile(plistPath, 'utf8')
|
||||
}).then(file => {
|
||||
const obj = plist.parse(file)
|
||||
t.is(obj.CFBundleName, opts.name, 'CFBundleName should reflect opts.name in helper app')
|
||||
t.is(obj.CFBundleIdentifier, helperBundleIdentifier, 'CFBundleIdentifier should reflect opts.helperBundleId, opts.appBundleId or fallback to default in helper app')
|
||||
t.is(typeof obj.CFBundleName, 'string', 'CFBundleName should be a string in helper app')
|
||||
t.is(typeof obj.CFBundleIdentifier, 'string', 'CFBundleIdentifier should be a string in helper app')
|
||||
t.is(/^[a-zA-Z0-9-.]*$/.test(obj.CFBundleIdentifier), true, 'CFBundleIdentifier should allow only alphanumeric (A-Z,a-z,0-9), hyphen (-), and period (.)')
|
||||
// check helper EH
|
||||
plistPath = path.join(tempPath, opts.name + '.app', 'Contents', 'Frameworks', opts.name + ' Helper EH.app', 'Contents', 'Info.plist')
|
||||
return fs.stat(plistPath)
|
||||
}).then(stats => {
|
||||
t.true(stats.isFile(), 'The expected Info.plist file should exist in helper EH app')
|
||||
return fs.readFile(plistPath, 'utf8')
|
||||
}).then(file => {
|
||||
const obj = plist.parse(file)
|
||||
t.is(obj.CFBundleName, opts.name + ' Helper EH', 'CFBundleName should reflect opts.name in helper EH app')
|
||||
t.is(obj.CFBundleDisplayName, opts.name + ' Helper EH', 'CFBundleDisplayName should reflect opts.name in helper EH app')
|
||||
t.is(obj.CFBundleExecutable, opts.name + ' Helper EH', 'CFBundleExecutable should reflect opts.name in helper EH app')
|
||||
t.is(obj.CFBundleIdentifier, helperBundleIdentifier + '.EH', 'CFBundleName should reflect opts.helperBundleId, opts.appBundleId or fallback to default in helper EH app')
|
||||
t.is(typeof obj.CFBundleName, 'string', 'CFBundleName should be a string in helper EH app')
|
||||
t.is(typeof obj.CFBundleDisplayName, 'string', 'CFBundleDisplayName should be a string in helper EH app')
|
||||
t.is(typeof obj.CFBundleExecutable, 'string', 'CFBundleExecutable should be a string in helper EH app')
|
||||
t.is(typeof obj.CFBundleIdentifier, 'string', 'CFBundleIdentifier should be a string in helper EH app')
|
||||
t.is(/^[a-zA-Z0-9-.]*$/.test(obj.CFBundleIdentifier), true, 'CFBundleIdentifier should allow only alphanumeric (A-Z,a-z,0-9), hyphen (-), and period (.)')
|
||||
// check helper NP
|
||||
plistPath = path.join(tempPath, opts.name + '.app', 'Contents', 'Frameworks', opts.name + ' Helper NP.app', 'Contents', 'Info.plist')
|
||||
return fs.stat(plistPath)
|
||||
}).then(stats => {
|
||||
t.true(stats.isFile(), 'The expected Info.plist file should exist in helper NP app')
|
||||
return fs.readFile(plistPath, 'utf8')
|
||||
}).then(file => {
|
||||
const obj = plist.parse(file)
|
||||
t.is(obj.CFBundleName, opts.name + ' Helper NP', 'CFBundleName should reflect opts.name in helper NP app')
|
||||
t.is(obj.CFBundleDisplayName, opts.name + ' Helper NP', 'CFBundleDisplayName should reflect opts.name in helper NP app')
|
||||
t.is(obj.CFBundleExecutable, opts.name + ' Helper NP', 'CFBundleExecutable should reflect opts.name in helper NP app')
|
||||
t.is(obj.CFBundleIdentifier, helperBundleIdentifier + '.NP', 'CFBundleName should reflect opts.helperBundleId, opts.appBundleId or fallback to default in helper NP app')
|
||||
t.is(typeof obj.CFBundleName, 'string', 'CFBundleName should be a string in helper NP app')
|
||||
t.is(typeof obj.CFBundleDisplayName, 'string', 'CFBundleDisplayName should be a string in helper NP app')
|
||||
t.is(typeof obj.CFBundleExecutable, 'string', 'CFBundleExecutable should be a string in helper NP app')
|
||||
t.is(typeof obj.CFBundleIdentifier, 'string', 'CFBundleIdentifier should be a string in helper NP app')
|
||||
return t.is(/^[a-zA-Z0-9-.]*$/.test(obj.CFBundleIdentifier), true, 'CFBundleIdentifier should allow only alphanumeric (A-Z,a-z,0-9), hyphen (-), and period (.)')
|
||||
})
|
||||
}
|
||||
|
||||
if (!(process.env.CI && process.platform === 'win32')) {
|
||||
darwinTest('helper app paths test', helperAppPathsTest)
|
||||
darwinTest('helper app paths test with app name needing sanitization', helperAppPathsTest, {name: '@username/package-name'}, '@username-package-name')
|
||||
|
||||
const iconBase = path.join(__dirname, 'fixtures', 'monochrome')
|
||||
const icnsPath = `${iconBase}.icns`
|
||||
|
||||
darwinTest('icon test: .icns specified', iconTest, icnsPath, icnsPath)
|
||||
// This test exists because the .icns file basename changed as of 0.37.4
|
||||
electron0374Test('icon test: Electron 0.37.4, .icns specified', iconTest, icnsPath, icnsPath)
|
||||
darwinTest('icon test: .ico specified (should replace with .icns)', iconTest, `${iconBase}.ico`, icnsPath)
|
||||
darwinTest('icon test: basename only (should add .icns)', iconTest, iconBase, icnsPath)
|
||||
|
||||
const extraInfoPath = path.join(__dirname, 'fixtures', 'extrainfo.plist')
|
||||
const extraInfoParams = plist.parse(fs.readFileSync(extraInfoPath).toString())
|
||||
|
||||
darwinTest('extendInfo by filename test', extendInfoTest, extraInfoPath)
|
||||
darwinTest('extendInfo by params test', extendInfoTest, extraInfoParams)
|
||||
|
||||
darwinTest('protocol/protocol-name argument test', (t, opts) => {
|
||||
opts.protocols = [
|
||||
{
|
||||
name: 'Foo',
|
||||
schemes: ['foo']
|
||||
},
|
||||
{
|
||||
name: 'Bar',
|
||||
schemes: ['bar', 'baz']
|
||||
}
|
||||
]
|
||||
|
||||
return packageAndParseInfoPlist(t, opts)
|
||||
.then(obj =>
|
||||
t.deepEqual(obj.CFBundleURLTypes, [{
|
||||
CFBundleURLName: 'Foo',
|
||||
CFBundleURLSchemes: ['foo']
|
||||
}, {
|
||||
CFBundleURLName: 'Bar',
|
||||
CFBundleURLSchemes: ['bar', 'baz']
|
||||
}], 'CFBundleURLTypes did not contain specified protocol schemes and names')
|
||||
)
|
||||
})
|
||||
|
||||
test('osxSign argument test: default args', t => {
|
||||
const args = true
|
||||
const signOpts = mac.createSignOpts(args, 'darwin', 'out', 'version')
|
||||
t.deepEqual(signOpts, {identity: null, app: 'out', platform: 'darwin', version: 'version'})
|
||||
})
|
||||
|
||||
test('osxSign argument test: identity=true sets autodiscovery mode', t => {
|
||||
const args = {identity: true}
|
||||
const signOpts = mac.createSignOpts(args, 'darwin', 'out', 'version')
|
||||
t.deepEqual(signOpts, {identity: null, app: 'out', platform: 'darwin', version: 'version'})
|
||||
})
|
||||
|
||||
test('osxSign argument test: entitlements passed to electron-osx-sign', t => {
|
||||
const args = {entitlements: 'path-to-entitlements'}
|
||||
const signOpts = mac.createSignOpts(args, 'darwin', 'out', 'version')
|
||||
t.deepEqual(signOpts, {app: 'out', platform: 'darwin', version: 'version', entitlements: args.entitlements})
|
||||
})
|
||||
|
||||
test('osxSign argument test: app not overwritten', t => {
|
||||
const args = {app: 'some-other-path'}
|
||||
const signOpts = mac.createSignOpts(args, 'darwin', 'out', 'version')
|
||||
t.deepEqual(signOpts, {app: 'out', platform: 'darwin', version: 'version'})
|
||||
})
|
||||
|
||||
test('osxSign argument test: platform not overwritten', t => {
|
||||
const args = {platform: 'mas'}
|
||||
const signOpts = mac.createSignOpts(args, 'darwin', 'out', 'version')
|
||||
t.deepEqual(signOpts, {app: 'out', platform: 'darwin', version: 'version'})
|
||||
})
|
||||
|
||||
test('osxSign argument test: binaries not set', t => {
|
||||
const args = {binaries: ['binary1', 'binary2']}
|
||||
const signOpts = mac.createSignOpts(args, 'darwin', 'out', 'version')
|
||||
t.deepEqual(signOpts, {app: 'out', platform: 'darwin', version: 'version'})
|
||||
})
|
||||
|
||||
darwinTest('codesign test', (t, opts) => {
|
||||
opts.osxSign = {identity: 'Developer CodeCert'}
|
||||
|
||||
let appPath
|
||||
|
||||
return packager(opts)
|
||||
.then(paths => {
|
||||
appPath = path.join(paths[0], opts.name + '.app')
|
||||
return fs.stat(appPath)
|
||||
}).then(stats => {
|
||||
t.true(stats.isDirectory(), 'The expected .app directory should exist')
|
||||
return exec(`codesign -v ${appPath}`)
|
||||
}).then(
|
||||
(stdout, stderr) => t.pass('codesign should verify successfully'),
|
||||
err => {
|
||||
const notFound = err && err.code === 127
|
||||
|
||||
if (notFound) {
|
||||
console.log('codesign not installed; skipped')
|
||||
} else {
|
||||
throw err
|
||||
}
|
||||
}
|
||||
)
|
||||
})
|
||||
|
||||
darwinTest('binary naming test', binaryNameTest)
|
||||
darwinTest('sanitized binary naming test', binaryNameTest, {name: '@username/package-name'}, '@username-package-name')
|
||||
darwinTest('executableName test', binaryNameTest, {executableName: 'app-name', name: 'MyAppName'}, 'app-name', 'MyAppName')
|
||||
|
||||
darwinTest('CFBundleName is the sanitized app name and CFBundleDisplayName is the non-sanitized app name', (t, opts) => {
|
||||
const appBundleIdentifier = 'com.electron.username-package-name'
|
||||
const expectedSanitizedName = '@username-package-name'
|
||||
|
||||
let plistPath
|
||||
|
||||
opts.name = '@username/package-name'
|
||||
|
||||
return packager(opts)
|
||||
.then(paths => {
|
||||
plistPath = path.join(paths[0], `${expectedSanitizedName}.app`, 'Contents', 'Info.plist')
|
||||
return fs.stat(plistPath)
|
||||
}).then(stats => {
|
||||
t.true(stats.isFile(), 'The expected Info.plist file should exist')
|
||||
return fs.readFile(plistPath, 'utf8')
|
||||
}).then(file => {
|
||||
const obj = plist.parse(file)
|
||||
t.is(typeof obj.CFBundleDisplayName, 'string', 'CFBundleDisplayName should be a string')
|
||||
t.is(obj.CFBundleDisplayName, opts.name, 'CFBundleDisplayName should reflect opts.name')
|
||||
t.is(typeof obj.CFBundleName, 'string', 'CFBundleName should be a string')
|
||||
t.is(obj.CFBundleName, expectedSanitizedName, 'CFBundleName should reflect a sanitized opts.name')
|
||||
t.is(typeof obj.CFBundleIdentifier, 'string', 'CFBundleIdentifier should be a string')
|
||||
t.is(/^[a-zA-Z0-9-.]*$/.test(obj.CFBundleIdentifier), true, 'CFBundleIdentifier should allow only alphanumeric (A-Z,a-z,0-9), hyphen (-), and period (.)')
|
||||
return t.is(obj.CFBundleIdentifier, appBundleIdentifier, 'CFBundleIdentifier should reflect the sanitized opts.name')
|
||||
})
|
||||
})
|
||||
|
||||
darwinTest('app and build version test', appVersionTest, '1.1.0', '1.1.0.1234')
|
||||
darwinTest('app version test', appVersionTest, '1.1.0')
|
||||
darwinTest('app and build version integer test', appVersionTest, 12, 1234)
|
||||
darwinTest('infer app version from package.json test', (t, opts) =>
|
||||
packageAndParseInfoPlist(t, opts)
|
||||
.then(obj => {
|
||||
t.is(obj.CFBundleVersion, '4.99.101', 'CFBundleVersion should reflect package.json version')
|
||||
return t.is(obj.CFBundleShortVersionString, '4.99.101', 'CFBundleShortVersionString should reflect package.json version')
|
||||
})
|
||||
)
|
||||
|
||||
darwinTest('app categoryType test', (t, opts) => {
|
||||
const appCategoryType = 'public.app-category.developer-tools'
|
||||
opts.appCategoryType = appCategoryType
|
||||
|
||||
return packageAndParseInfoPlist(t, opts)
|
||||
.then(obj => t.is(obj.LSApplicationCategoryType, appCategoryType, 'LSApplicationCategoryType should reflect opts.appCategoryType'))
|
||||
})
|
||||
|
||||
darwinTest('app bundle test', appBundleTest, 'com.electron.basetest')
|
||||
darwinTest('app bundle (w/ special characters) test', appBundleTest, 'com.electron."bãśè tëßt!@#$%^&*()?\'')
|
||||
darwinTest('app bundle app-bundle-id fallback test', appBundleTest)
|
||||
|
||||
darwinTest('app bundle framework symlink test', (t, opts) => {
|
||||
let frameworkPath
|
||||
|
||||
return packager(opts)
|
||||
.then(paths => {
|
||||
frameworkPath = path.join(paths[0], `${opts.name}.app`, 'Contents', 'Frameworks', 'Electron Framework.framework')
|
||||
return fs.stat(frameworkPath)
|
||||
}).then(stats => {
|
||||
t.true(stats.isDirectory(), 'Expected Electron Framework.framework to be a directory')
|
||||
return fs.lstat(path.join(frameworkPath, 'Electron Framework'))
|
||||
}).then(stats => {
|
||||
t.true(stats.isSymbolicLink(), 'Expected Electron Framework.framework/Electron Framework to be a symlink')
|
||||
return fs.lstat(path.join(frameworkPath, 'Versions', 'Current'))
|
||||
}).then(stats => t.true(stats.isSymbolicLink(), 'Expected Electron Framework.framework/Versions/Current to be a symlink'))
|
||||
})
|
||||
|
||||
darwinTest('app helpers bundle test', appHelpersBundleTest, 'com.electron.basetest.helper')
|
||||
darwinTest('app helpers bundle (w/ special characters) test', appHelpersBundleTest, 'com.electron."bãśè tëßt!@#$%^&*()?\'.hęłpėr')
|
||||
darwinTest('app helpers bundle helper-bundle-id fallback to app-bundle-id test', appHelpersBundleTest, null, 'com.electron.basetest')
|
||||
darwinTest('app helpers bundle helper-bundle-id fallback to app-bundle-id (w/ special characters) test', appHelpersBundleTest, null, 'com.electron."bãśè tëßt!!@#$%^&*()?\'')
|
||||
darwinTest('app helpers bundle helper-bundle-id & app-bundle-id fallback test', appHelpersBundleTest)
|
||||
|
||||
darwinTest('appCopyright/NSHumanReadableCopyright test', (t, baseOpts) => {
|
||||
const copyright = 'Copyright © 2003–2015 Organization. All rights reserved.'
|
||||
const opts = Object.assign({}, baseOpts, {appCopyright: copyright})
|
||||
|
||||
return packageAndParseInfoPlist(t, opts)
|
||||
.then(info => t.is(info.NSHumanReadableCopyright, copyright, 'NSHumanReadableCopyright should reflect opts.appCopyright'))
|
||||
})
|
||||
|
||||
darwinTest('app named Electron packaged successfully', (t, baseOpts) => {
|
||||
const opts = Object.assign({}, baseOpts, {name: 'Electron'})
|
||||
let appPath
|
||||
|
||||
return packager(opts)
|
||||
.then(paths => {
|
||||
appPath = path.join(paths[0], 'Electron.app')
|
||||
return fs.stat(appPath)
|
||||
}).then(stats => {
|
||||
t.true(stats.isDirectory(), 'The Electron.app folder exists')
|
||||
return fs.stat(path.join(appPath, 'Contents', 'MacOS', 'Electron'))
|
||||
}).then(stats => t.true(stats.isFile(), 'The Electron.app/Contents/MacOS/Electron binary exists'))
|
||||
})
|
||||
}
|
4
node_modules/electron-packager/test/fixtures/basic-renamed-to-electron/index.html
generated
vendored
Normal file
4
node_modules/electron-packager/test/fixtures/basic-renamed-to-electron/index.html
generated
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>Hello, world!</body>
|
||||
</html>
|
24
node_modules/electron-packager/test/fixtures/basic-renamed-to-electron/main.js
generated
vendored
Normal file
24
node_modules/electron-packager/test/fixtures/basic-renamed-to-electron/main.js
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
'use strict'
|
||||
|
||||
const app = require('app')
|
||||
const BrowserWindow = require('browser-window')
|
||||
let mainWindow
|
||||
|
||||
app.on('window-all-closed', function () {
|
||||
app.quit()
|
||||
})
|
||||
|
||||
app.on('ready', function () {
|
||||
mainWindow = new BrowserWindow({
|
||||
center: true,
|
||||
title: 'Basic Test',
|
||||
width: 800,
|
||||
height: 600
|
||||
})
|
||||
|
||||
mainWindow.loadUrl('file://' + require('path').resolve(__dirname, 'index.html'))
|
||||
|
||||
mainWindow.on('closed', function () {
|
||||
mainWindow = null
|
||||
})
|
||||
})
|
12
node_modules/electron-packager/test/fixtures/basic-renamed-to-electron/package.json
generated
vendored
Normal file
12
node_modules/electron-packager/test/fixtures/basic-renamed-to-electron/package.json
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"main": "main.js",
|
||||
"productName": "MainJS",
|
||||
"description": "A test of the renamed from `electron-prebuilt` to `electron`",
|
||||
"dependencies": {
|
||||
"electron-prebuilt": "1.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"electron": "1.3.1",
|
||||
"electron-prebuilt": "1.3.0"
|
||||
}
|
||||
}
|
0
node_modules/electron-packager/test/fixtures/basic/dir_to_unpack/file1.txt
generated
vendored
Normal file
0
node_modules/electron-packager/test/fixtures/basic/dir_to_unpack/file1.txt
generated
vendored
Normal file
2
node_modules/electron-packager/test/fixtures/basic/electron-packager/readme.txt
generated
vendored
Normal file
2
node_modules/electron-packager/test/fixtures/basic/electron-packager/readme.txt
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
This file exists to test ability to ignore paths under app, without also
|
||||
ignoring the entire app folder due to a match above it (#54 / #55).
|
1
node_modules/electron-packager/test/fixtures/basic/file_to_unpack.pac
generated
vendored
Normal file
1
node_modules/electron-packager/test/fixtures/basic/file_to_unpack.pac
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
This file is used for testing asar unpack option
|
0
node_modules/electron-packager/test/fixtures/basic/ignore.o
generated
vendored
Normal file
0
node_modules/electron-packager/test/fixtures/basic/ignore.o
generated
vendored
Normal file
0
node_modules/electron-packager/test/fixtures/basic/ignore.obj
generated
vendored
Normal file
0
node_modules/electron-packager/test/fixtures/basic/ignore.obj
generated
vendored
Normal file
0
node_modules/electron-packager/test/fixtures/basic/ignore/this.txt
generated
vendored
Normal file
0
node_modules/electron-packager/test/fixtures/basic/ignore/this.txt
generated
vendored
Normal file
1
node_modules/electron-packager/test/fixtures/basic/ignorethis.txt
generated
vendored
Normal file
1
node_modules/electron-packager/test/fixtures/basic/ignorethis.txt
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
|
4
node_modules/electron-packager/test/fixtures/basic/index.html
generated
vendored
Normal file
4
node_modules/electron-packager/test/fixtures/basic/index.html
generated
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>Hello, world!</body>
|
||||
</html>
|
24
node_modules/electron-packager/test/fixtures/basic/main.js
generated
vendored
Normal file
24
node_modules/electron-packager/test/fixtures/basic/main.js
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
'use strict'
|
||||
|
||||
const app = require('app')
|
||||
const BrowserWindow = require('browser-window')
|
||||
let mainWindow
|
||||
|
||||
app.on('window-all-closed', function () {
|
||||
app.quit()
|
||||
})
|
||||
|
||||
app.on('ready', function () {
|
||||
mainWindow = new BrowserWindow({
|
||||
center: true,
|
||||
title: 'Basic Test',
|
||||
width: 800,
|
||||
height: 600
|
||||
})
|
||||
|
||||
mainWindow.loadUrl('file://' + require('path').resolve(__dirname, 'index.html'))
|
||||
|
||||
mainWindow.on('closed', function () {
|
||||
mainWindow = null
|
||||
})
|
||||
})
|
16
node_modules/electron-packager/test/fixtures/basic/package.json
generated
vendored
Normal file
16
node_modules/electron-packager/test/fixtures/basic/package.json
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"main": "main.js",
|
||||
"version": "4.99.101",
|
||||
"productName": "MainJS",
|
||||
"dependencies": {
|
||||
"@types/node": "^8.0.0",
|
||||
"run-series": "^1.1.1"
|
||||
},
|
||||
"//": "ncp used to test https://github.com/electron-userland/electron-packager/pull/186",
|
||||
"///": "(a module (with zero dependencies) that creates a file in node_modules/.bin)",
|
||||
"devDependencies": {
|
||||
"ncp": "^2.0.0",
|
||||
"run-waterfall": "^1.1.1",
|
||||
"electron-prebuilt": "0.35.6"
|
||||
}
|
||||
}
|
1
node_modules/electron-packager/test/fixtures/data1.txt
generated
vendored
Normal file
1
node_modules/electron-packager/test/fixtures/data1.txt
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
This is a text file.
|
4
node_modules/electron-packager/test/fixtures/el-0374/index.html
generated
vendored
Normal file
4
node_modules/electron-packager/test/fixtures/el-0374/index.html
generated
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>Hello, world!</body>
|
||||
</html>
|
24
node_modules/electron-packager/test/fixtures/el-0374/main.js
generated
vendored
Normal file
24
node_modules/electron-packager/test/fixtures/el-0374/main.js
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
'use strict'
|
||||
|
||||
const app = require('app')
|
||||
const BrowserWindow = require('browser-window')
|
||||
let mainWindow
|
||||
|
||||
app.on('window-all-closed', function () {
|
||||
app.quit()
|
||||
})
|
||||
|
||||
app.on('ready', function () {
|
||||
mainWindow = new BrowserWindow({
|
||||
center: true,
|
||||
title: 'Basic Test',
|
||||
width: 800,
|
||||
height: 600
|
||||
})
|
||||
|
||||
mainWindow.loadUrl('file://' + require('path').resolve(__dirname, 'index.html'))
|
||||
|
||||
mainWindow.on('closed', function () {
|
||||
mainWindow = null
|
||||
})
|
||||
})
|
12
node_modules/electron-packager/test/fixtures/el-0374/package.json
generated
vendored
Normal file
12
node_modules/electron-packager/test/fixtures/el-0374/package.json
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"main": "main.js",
|
||||
"productName": "MainJS",
|
||||
"dependencies": {
|
||||
"run-series": "^1.1.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"ncp": "^2.0.0",
|
||||
"run-waterfall": "^1.1.1",
|
||||
"electron-prebuilt": "0.37.4"
|
||||
}
|
||||
}
|
4
node_modules/electron-packager/test/fixtures/electron-in-dependencies/index.html
generated
vendored
Normal file
4
node_modules/electron-packager/test/fixtures/electron-in-dependencies/index.html
generated
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>Hello, world!</body>
|
||||
</html>
|
1
node_modules/electron-packager/test/fixtures/electron-in-dependencies/main.js
generated
vendored
Normal file
1
node_modules/electron-packager/test/fixtures/electron-in-dependencies/main.js
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
'use strict'
|
8
node_modules/electron-packager/test/fixtures/electron-in-dependencies/package.json
generated
vendored
Normal file
8
node_modules/electron-packager/test/fixtures/electron-in-dependencies/package.json
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"main": "main.js",
|
||||
"productName": "MainJS",
|
||||
"description": "Removing electron from dependencies",
|
||||
"dependencies": {
|
||||
"electron": "1.3.1"
|
||||
}
|
||||
}
|
30
node_modules/electron-packager/test/fixtures/extrainfo.plist
generated
vendored
Normal file
30
node_modules/electron-packager/test/fixtures/extrainfo.plist
generated
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>0.0.0</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>x.y.z.z.y</string>
|
||||
<key>LSApplicationCategoryType</key>
|
||||
<string>public.app-category.games</string>
|
||||
<key>TestKeyString</key>
|
||||
<string>String data</string>
|
||||
<key>TestKeyBool</key>
|
||||
<true/>
|
||||
<key>TestKeyInt</key>
|
||||
<integer>12345</integer>
|
||||
<key>TestKeyArray</key>
|
||||
<array>
|
||||
<string>public.content</string>
|
||||
<string>public.data</string>
|
||||
</array>
|
||||
<key>TestKeyDict</key>
|
||||
<dict>
|
||||
<key>Number</key>
|
||||
<integer>98765</integer>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>0.0.0</string>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
9
node_modules/electron-packager/test/fixtures/infer-bad-fields/package.json
generated
vendored
Normal file
9
node_modules/electron-packager/test/fixtures/infer-bad-fields/package.json
generated
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"productName": "InferBadFields",
|
||||
"dependencies": {
|
||||
"run-series": "^1.1.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"electron-prebuilt": false
|
||||
}
|
||||
}
|
7
node_modules/electron-packager/test/fixtures/infer-electron-prebuilt-compile/package.json
generated
vendored
Normal file
7
node_modules/electron-packager/test/fixtures/infer-electron-prebuilt-compile/package.json
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"main": "main.js",
|
||||
"productName": "MainJS",
|
||||
"devDependencies": {
|
||||
"electron-prebuilt-compile": "1.4.15"
|
||||
}
|
||||
}
|
2
node_modules/electron-packager/test/fixtures/infer-malformed-json/package.json
generated
vendored
Normal file
2
node_modules/electron-packager/test/fixtures/infer-malformed-json/package.json
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
{
|
||||
"productName": "InferMalformedJSON",
|
5
node_modules/electron-packager/test/fixtures/infer-missing-fields/package.json
generated
vendored
Normal file
5
node_modules/electron-packager/test/fixtures/infer-missing-fields/package.json
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"run-series": "^1.1.1"
|
||||
}
|
||||
}
|
7
node_modules/electron-packager/test/fixtures/infer-missing-version-only/package.json
generated
vendored
Normal file
7
node_modules/electron-packager/test/fixtures/infer-missing-version-only/package.json
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"main": "main.js",
|
||||
"productName": "MainJS",
|
||||
"devDependencies": {
|
||||
"electron": "1.3.1"
|
||||
}
|
||||
}
|
7
node_modules/electron-packager/test/fixtures/infer-non-specific-electron-prebuilt-compile/package.json
generated
vendored
Normal file
7
node_modules/electron-packager/test/fixtures/infer-non-specific-electron-prebuilt-compile/package.json
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"main": "main.js",
|
||||
"productName": "MainJS",
|
||||
"devDependencies": {
|
||||
"electron-prebuilt-compile": "^1.4.15"
|
||||
}
|
||||
}
|
9
node_modules/electron-packager/test/fixtures/infer-win32metadata/package.json
generated
vendored
Normal file
9
node_modules/electron-packager/test/fixtures/infer-win32metadata/package.json
generated
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"main": "main.js",
|
||||
"productName": "MainJS",
|
||||
"author": "Foo Bar <foo.bar@example.com>",
|
||||
"description": "Some description",
|
||||
"devDependencies": {
|
||||
"electron-prebuilt-compile": "1.4.15"
|
||||
}
|
||||
}
|
BIN
node_modules/electron-packager/test/fixtures/monochrome.icns
generated
vendored
Normal file
BIN
node_modules/electron-packager/test/fixtures/monochrome.icns
generated
vendored
Normal file
Binary file not shown.
BIN
node_modules/electron-packager/test/fixtures/monochrome.ico
generated
vendored
Normal file
BIN
node_modules/electron-packager/test/fixtures/monochrome.ico
generated
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
80
node_modules/electron-packager/test/hooks.js
generated
vendored
Normal file
80
node_modules/electron-packager/test/hooks.js
generated
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
'use strict'
|
||||
|
||||
const config = require('./config.json')
|
||||
const hooks = require('../hooks')
|
||||
const packager = require('..')
|
||||
const test = require('ava')
|
||||
const util = require('./_util')
|
||||
|
||||
function hookTest (wantHookCalled, hookName, t, opts) {
|
||||
let hookCalled = false
|
||||
opts.dir = util.fixtureSubdir('basic')
|
||||
opts.electronVersion = config.version
|
||||
opts.arch = 'ia32'
|
||||
opts.platform = 'all'
|
||||
|
||||
opts[hookName] = [(buildPath, electronVersion, platform, arch, callback) => {
|
||||
hookCalled = true
|
||||
t.is(electronVersion, opts.electronVersion, `${hookName} electronVersion should be the same as the options object`)
|
||||
t.is(arch, opts.arch, `${hookName} arch should be the same as the options object`)
|
||||
callback()
|
||||
}]
|
||||
|
||||
// 2 packages will be built during this test
|
||||
return packager(opts)
|
||||
.then(finalPaths => {
|
||||
t.is(finalPaths.length, 2, 'packager call should resolve with expected number of paths')
|
||||
t.is(wantHookCalled, hookCalled, `${hookName} methods ${wantHookCalled ? 'should' : 'should not'} have been called`)
|
||||
return util.verifyPackageExistence(finalPaths)
|
||||
}).then(exists => t.deepEqual(exists, [true, true], 'Packages should be generated for both 32-bit platforms'))
|
||||
}
|
||||
|
||||
function createHookTest (hookName) {
|
||||
util.packagerTest(`platform=all test (one arch) (${hookName} hook)`,
|
||||
(t, opts) => hookTest(true, hookName, t, opts))
|
||||
}
|
||||
|
||||
createHookTest('afterCopy')
|
||||
createHookTest('afterPrune')
|
||||
createHookTest('afterExtract')
|
||||
|
||||
test('promisifyHooks executes functions in parallel', t => {
|
||||
let output = '0'
|
||||
const timeoutFunc = (number, msTimeout) => {
|
||||
return done => {
|
||||
setTimeout(() => {
|
||||
output += ` ${number}`
|
||||
done()
|
||||
}, msTimeout)
|
||||
}
|
||||
}
|
||||
const testHooks = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map(number =>
|
||||
timeoutFunc(number, number % 2 === 0 ? 1000 : 0)
|
||||
)
|
||||
|
||||
return hooks.promisifyHooks(testHooks)
|
||||
.then(() => t.not(output, '0 1 2 3 4 5 6 7 8 9 10', 'should not be in sequential order'))
|
||||
})
|
||||
|
||||
test('serialHooks executes functions serially', t => {
|
||||
let output = '0'
|
||||
const timeoutFunc = (number, msTimeout) => {
|
||||
return () => new Promise(resolve => { // eslint-disable-line promise/avoid-new
|
||||
setTimeout(() => {
|
||||
output += ` ${number}`
|
||||
resolve()
|
||||
}, msTimeout)
|
||||
})
|
||||
}
|
||||
const testHooks = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map(number =>
|
||||
timeoutFunc(number, number % 2 === 0 ? 1000 : 0)
|
||||
)
|
||||
|
||||
return hooks.serialHooks(testHooks)(() => output)
|
||||
.then(result => t.is(result, '0 1 2 3 4 5 6 7 8 9 10', 'should be in sequential order'))
|
||||
})
|
||||
|
||||
util.packagerTest('prune hook does not get called when prune=false', (t, opts) => {
|
||||
opts.prune = false
|
||||
return hookTest(false, 'afterPrune', t, opts)
|
||||
})
|
113
node_modules/electron-packager/test/ignore.js
generated
vendored
Normal file
113
node_modules/electron-packager/test/ignore.js
generated
vendored
Normal file
@@ -0,0 +1,113 @@
|
||||
'use strict'
|
||||
|
||||
const common = require('../common')
|
||||
const fs = require('fs-extra')
|
||||
const ignore = require('../ignore')
|
||||
const path = require('path')
|
||||
const packager = require('..')
|
||||
const test = require('ava')
|
||||
const util = require('./_util')
|
||||
|
||||
function ignoreTest (t, opts, ignorePattern, ignoredFile) {
|
||||
opts.dir = util.fixtureSubdir('basic')
|
||||
if (ignorePattern) {
|
||||
opts.ignore = ignorePattern
|
||||
}
|
||||
|
||||
const targetDir = path.join(t.context.tempDir, 'result')
|
||||
ignore.generateIgnores(opts)
|
||||
|
||||
return fs.copy(opts.dir, targetDir, {
|
||||
dereference: false,
|
||||
filter: ignore.userIgnoreFilter(opts)
|
||||
}).then(() => fs.pathExists(path.join(targetDir, 'package.json')))
|
||||
.then(exists => {
|
||||
t.true(exists, 'The expected output directory should exist and contain files')
|
||||
return fs.pathExists(path.join(targetDir, ignoredFile))
|
||||
}).then(exists => t.false(exists, `Ignored file '${ignoredFile}' should not exist in copied directory`))
|
||||
}
|
||||
|
||||
function ignoreOutDirTest (t, opts, distPath) {
|
||||
opts.name = 'ignoreOutDirTest'
|
||||
opts.dir = t.context.workDir
|
||||
|
||||
// we don't use path.join here to avoid normalizing
|
||||
const outDir = opts.dir + path.sep + distPath
|
||||
opts.out = outDir
|
||||
|
||||
return fs.copy(util.fixtureSubdir('basic'), t.context.workDir, {
|
||||
dereference: true,
|
||||
stopOnErr: true,
|
||||
filter: file => { return path.basename(file) !== 'node_modules' }
|
||||
}).then(() =>
|
||||
// create out dir before packager (real world issue - when second run includes unignored out dir)
|
||||
fs.ensureDir(outDir)
|
||||
).then(() =>
|
||||
// create file to ensure that directory will be not ignored because empty
|
||||
fs.open(path.join(outDir, 'ignoreMe'), 'w')
|
||||
).then(fd => fs.close(fd))
|
||||
.then(() => packager(opts))
|
||||
.then(() => fs.pathExists(path.join(outDir, common.generateFinalBasename(opts), util.generateResourcesPath(opts), 'app', path.basename(outDir))))
|
||||
.then(exists => t.false(exists, 'Out dir must not exist in output app directory'))
|
||||
}
|
||||
|
||||
function ignoreImplicitOutDirTest (t, opts) {
|
||||
opts.name = 'ignoreImplicitOutDirTest'
|
||||
opts.dir = t.context.workDir
|
||||
delete opts.out
|
||||
|
||||
const testFilename = 'ignoreMe'
|
||||
let previousPackedResultDir
|
||||
|
||||
return fs.copy(util.fixtureSubdir('basic'), t.context.workDir, {
|
||||
dereference: true,
|
||||
stopOnErr: true,
|
||||
filter: file => { return path.basename(file) !== 'node_modules' }
|
||||
}).then(() => {
|
||||
previousPackedResultDir = path.join(opts.dir, `${common.sanitizeAppName(opts.name)}-linux-ia32`)
|
||||
return fs.ensureDir(previousPackedResultDir)
|
||||
}).then(() =>
|
||||
// create file to ensure that directory will be not ignored because empty
|
||||
fs.open(path.join(previousPackedResultDir, testFilename), 'w')
|
||||
).then(fd => fs.close(fd))
|
||||
.then(() => packager(opts))
|
||||
.then(() => fs.pathExists(path.join(opts.dir, common.generateFinalBasename(opts), util.generateResourcesPath(opts), 'app', testFilename)))
|
||||
.then(exists => t.false(exists, 'Out dir must not exist in output app directory'))
|
||||
}
|
||||
|
||||
test('generateIgnores ignores the generated temporary directory only on Linux', t => {
|
||||
const tmpdir = '/foo/bar'
|
||||
const expected = path.join(tmpdir, 'electron-packager')
|
||||
let opts = {tmpdir}
|
||||
|
||||
ignore.generateIgnores(opts)
|
||||
|
||||
// Array.prototype.includes is added (not behind a feature flag) in Node 6
|
||||
if (process.platform === 'linux') {
|
||||
t.false(opts.ignore.indexOf(expected) === -1, 'temporary dir in opts.ignore')
|
||||
} else {
|
||||
t.true(opts.ignore.indexOf(expected) === -1, 'temporary dir not in opts.ignore')
|
||||
}
|
||||
})
|
||||
|
||||
test('generateOutIgnores ignores all possible platform/arch permutations', (t) => {
|
||||
const ignores = ignore.generateOutIgnores({name: 'test'})
|
||||
t.is(ignores.length, util.allPlatformArchCombosCount)
|
||||
})
|
||||
|
||||
util.testSinglePlatformParallel('ignore default test: .o files', ignoreTest, null, 'ignore.o')
|
||||
util.testSinglePlatformParallel('ignore default test: .obj files', ignoreTest, null, 'ignore.obj')
|
||||
util.testSinglePlatformParallel('ignore test: string in array', ignoreTest, ['ignorethis'],
|
||||
'ignorethis.txt')
|
||||
util.testSinglePlatformParallel('ignore test: string', ignoreTest, 'ignorethis', 'ignorethis.txt')
|
||||
util.testSinglePlatformParallel('ignore test: RegExp', ignoreTest, /ignorethis/, 'ignorethis.txt')
|
||||
util.testSinglePlatformParallel('ignore test: Function', ignoreTest,
|
||||
file => file.match(/ignorethis/), 'ignorethis.txt')
|
||||
util.testSinglePlatformParallel('ignore test: string with slash', ignoreTest, 'ignore/this',
|
||||
path.join('ignore', 'this.txt'))
|
||||
util.testSinglePlatformParallel('ignore test: only match subfolder of app', ignoreTest,
|
||||
'electron-packager', path.join('electron-packager', 'readme.txt'))
|
||||
util.testSinglePlatform('ignore out dir test', ignoreOutDirTest, 'ignoredOutDir')
|
||||
util.testSinglePlatform('ignore out dir test: unnormalized path', ignoreOutDirTest,
|
||||
'./ignoredOutDir')
|
||||
util.testSinglePlatform('ignore out dir test: implicit path', ignoreImplicitOutDirTest)
|
19
node_modules/electron-packager/test/index.js
generated
vendored
Normal file
19
node_modules/electron-packager/test/index.js
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
'use strict'
|
||||
|
||||
require('./_util')
|
||||
|
||||
require('./basic')
|
||||
require('./asar')
|
||||
require('./cli')
|
||||
require('./ignore')
|
||||
require('./infer')
|
||||
require('./hooks')
|
||||
require('./prune')
|
||||
require('./targets')
|
||||
require('./win32')
|
||||
|
||||
if (process.platform !== 'win32') {
|
||||
// Perform additional tests specific to building for OS X
|
||||
require('./darwin')
|
||||
require('./mas')
|
||||
}
|
121
node_modules/electron-packager/test/infer.js
generated
vendored
Normal file
121
node_modules/electron-packager/test/infer.js
generated
vendored
Normal file
@@ -0,0 +1,121 @@
|
||||
'use strict'
|
||||
|
||||
const fs = require('fs-extra')
|
||||
const getMetadataFromPackageJSON = require('../infer')
|
||||
const packager = require('..')
|
||||
const path = require('path')
|
||||
const pkgUp = require('pkg-up')
|
||||
const util = require('./_util')
|
||||
|
||||
function inferElectronVersionTest (t, opts, fixture, packageName) {
|
||||
delete opts.electronVersion
|
||||
opts.dir = util.fixtureSubdir(fixture)
|
||||
|
||||
return getMetadataFromPackageJSON([], opts, opts.dir)
|
||||
.then(() => {
|
||||
const packageJSON = require(path.join(opts.dir, 'package.json'))
|
||||
return t.is(opts.electronVersion, packageJSON.devDependencies[packageName], `The version should be inferred from installed ${packageName} version`)
|
||||
})
|
||||
}
|
||||
|
||||
function copyFixtureToTempDir (t, fixtureSubdir) {
|
||||
const tmpdir = path.join(t.context.tempDir, fixtureSubdir)
|
||||
const fixtureDir = util.fixtureSubdir(fixtureSubdir)
|
||||
const tmpdirPkg = pkgUp.sync(path.join(tmpdir, '..'))
|
||||
|
||||
if (tmpdirPkg) {
|
||||
throw new Error(`Found package.json in parent of temp directory, which will interfere with test results. Please remove package.json at ${tmpdirPkg}`)
|
||||
}
|
||||
|
||||
return fs.emptyDir(tmpdir)
|
||||
.then(() => fs.copy(fixtureDir, tmpdir))
|
||||
.then(() => tmpdir)
|
||||
}
|
||||
|
||||
function inferFailureTest (t, opts, fixtureSubdir) {
|
||||
return copyFixtureToTempDir(t, fixtureSubdir)
|
||||
.then(dir => {
|
||||
delete opts.name
|
||||
delete opts.electronVersion
|
||||
opts.dir = dir
|
||||
|
||||
return t.throws(packager(opts))
|
||||
})
|
||||
}
|
||||
|
||||
function inferMissingVersionTest (t, opts) {
|
||||
return copyFixtureToTempDir(t, 'infer-missing-version-only')
|
||||
.then(dir => {
|
||||
delete opts.electronVersion
|
||||
opts.dir = dir
|
||||
|
||||
return getMetadataFromPackageJSON([], opts, dir)
|
||||
}).then(() => {
|
||||
const packageJSON = require(path.join(opts.dir, 'package.json'))
|
||||
return t.is(opts.electronVersion, packageJSON.devDependencies['electron'], 'The version should be inferred from installed electron module version')
|
||||
})
|
||||
}
|
||||
|
||||
function testInferWin32metadata (t, opts, expected, assertionMessage) {
|
||||
return copyFixtureToTempDir(t, 'infer-win32metadata')
|
||||
.then(dir => {
|
||||
opts.dir = dir
|
||||
|
||||
return getMetadataFromPackageJSON(['win32'], opts, dir)
|
||||
}).then(() => t.deepEqual(opts.win32metadata, expected, assertionMessage))
|
||||
}
|
||||
|
||||
function testInferWin32metadataAuthorObject (t, opts, author, expected, assertionMessage) {
|
||||
let packageJSONFilename
|
||||
|
||||
delete opts.name
|
||||
|
||||
return copyFixtureToTempDir(t, 'infer-win32metadata')
|
||||
.then(dir => {
|
||||
opts.dir = dir
|
||||
|
||||
packageJSONFilename = path.join(dir, 'package.json')
|
||||
return fs.readJson(packageJSONFilename)
|
||||
}).then(packageJSON => {
|
||||
packageJSON.author = author
|
||||
return fs.writeJson(packageJSONFilename, packageJSON)
|
||||
}).then(() => getMetadataFromPackageJSON(['win32'], opts, opts.dir))
|
||||
.then(() => t.deepEqual(opts.win32metadata, expected, assertionMessage))
|
||||
}
|
||||
|
||||
util.testSinglePlatformParallel('infer using `electron-prebuilt` package', inferElectronVersionTest, 'basic', 'electron-prebuilt')
|
||||
util.testSinglePlatformParallel('infer using `electron-prebuilt-compile` package', inferElectronVersionTest, 'infer-electron-prebuilt-compile', 'electron-prebuilt-compile')
|
||||
util.testSinglePlatformParallel('infer using `electron` package only', inferMissingVersionTest)
|
||||
util.testSinglePlatformParallel('infer where `electron` version is preferred over `electron-prebuilt`', inferElectronVersionTest, 'basic-renamed-to-electron', 'electron')
|
||||
util.testSinglePlatformParallel('infer win32metadata', (t, opts) => {
|
||||
const expected = {CompanyName: 'Foo Bar'}
|
||||
|
||||
return testInferWin32metadata(t, opts, expected, 'win32metadata matches package.json values')
|
||||
})
|
||||
util.testSinglePlatformParallel('do not infer win32metadata if it already exists', (t, opts) => {
|
||||
opts.win32metadata = {CompanyName: 'Existing'}
|
||||
const expected = Object.assign({}, opts.win32metadata)
|
||||
|
||||
return testInferWin32metadata(t, opts, expected, 'win32metadata did not update with package.json values')
|
||||
})
|
||||
util.testSinglePlatformParallel('infer win32metadata when author is an object', (t, opts) => {
|
||||
const author = {
|
||||
name: 'Foo Bar Object',
|
||||
email: 'foobar@example.com'
|
||||
}
|
||||
const expected = {CompanyName: 'Foo Bar Object'}
|
||||
|
||||
return testInferWin32metadataAuthorObject(t, opts, author, expected, 'win32metadata did not update with package.json values')
|
||||
})
|
||||
util.testSinglePlatformParallel('do not infer win32metadata.CompanyName when author is an object without a name', (t, opts) => {
|
||||
const author = {
|
||||
email: 'foobar@example.com'
|
||||
}
|
||||
const expected = {}
|
||||
|
||||
return testInferWin32metadataAuthorObject(t, opts, author, expected, 'win32metadata.CompanyName should not have been inferred')
|
||||
})
|
||||
util.testSinglePlatformParallel('infer missing fields test', inferFailureTest, 'infer-missing-fields')
|
||||
util.testSinglePlatformParallel('infer with bad fields test', inferFailureTest, 'infer-bad-fields')
|
||||
util.testSinglePlatformParallel('infer with malformed JSON test', inferFailureTest, 'infer-malformed-json')
|
||||
util.testSinglePlatformParallel('infer using a non-specific `electron-prebuilt-compile` package version', inferFailureTest, 'infer-non-specific-electron-prebuilt-compile')
|
58
node_modules/electron-packager/test/mas.js
generated
vendored
Normal file
58
node_modules/electron-packager/test/mas.js
generated
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
'use strict'
|
||||
|
||||
const fs = require('fs-extra')
|
||||
const packager = require('..')
|
||||
const path = require('path')
|
||||
const plist = require('plist')
|
||||
const util = require('./_util')
|
||||
|
||||
if (!(process.env.CI && process.platform === 'win32')) {
|
||||
const masOpts = {
|
||||
name: 'masTest',
|
||||
dir: util.fixtureSubdir('basic'),
|
||||
electronVersion: '2.0.0-beta.1',
|
||||
arch: 'x64',
|
||||
platform: 'mas'
|
||||
}
|
||||
|
||||
util.packagerTest('warn if building for mas and not signing', (t, baseOpts) => {
|
||||
const warningLog = console.warn
|
||||
let output = ''
|
||||
console.warn = message => { output += message }
|
||||
|
||||
const finalize = err => {
|
||||
console.warn = warningLog
|
||||
if (err) throw err
|
||||
}
|
||||
|
||||
return packager(Object.assign({}, baseOpts, masOpts))
|
||||
.then(() =>
|
||||
t.truthy(output.match(/signing is required for mas builds/), 'the correct warning is emitted')
|
||||
).then(finalize)
|
||||
.catch(finalize)
|
||||
})
|
||||
|
||||
util.packagerTest('update Login Helper if it exists', (t, baseOpts) => {
|
||||
let contentsPath
|
||||
let plistPath
|
||||
const helperName = `${masOpts.name} Login Helper`
|
||||
return packager(Object.assign({}, baseOpts, masOpts))
|
||||
.then(paths => {
|
||||
contentsPath = path.join(paths[0], `${masOpts.name}.app`, 'Contents', 'Library', 'LoginItems', `${helperName}.app`, 'Contents')
|
||||
return fs.pathExists(contentsPath)
|
||||
}).then(exists => {
|
||||
t.true(exists, 'renamed Login Helper app exists')
|
||||
plistPath = path.join(contentsPath, 'Info.plist')
|
||||
return fs.pathExists(contentsPath)
|
||||
}).then(exists => {
|
||||
t.true(exists, 'Login Helper Info.plist exists')
|
||||
return fs.readFile(plistPath, 'utf8')
|
||||
}).then(plistXML => {
|
||||
const plistData = plist.parse(plistXML)
|
||||
t.is(plistData.CFBundleExecutable, helperName, 'CFBundleExecutable is renamed Login Helper')
|
||||
t.is(plistData.CFBundleName, helperName, 'CFBundleName is renamed Login Helper')
|
||||
t.is(plistData.CFBundleIdentifier, 'com.electron.mastest.loginhelper')
|
||||
return fs.pathExists(path.join(contentsPath, 'MacOS', helperName))
|
||||
}).then(exists => t.true(exists, 'renamed Login Helper executable exists'))
|
||||
})
|
||||
}
|
65
node_modules/electron-packager/test/prune.js
generated
vendored
Normal file
65
node_modules/electron-packager/test/prune.js
generated
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
'use strict'
|
||||
|
||||
const fs = require('fs-extra')
|
||||
const path = require('path')
|
||||
const prune = require('../prune')
|
||||
const test = require('ava')
|
||||
const util = require('./_util')
|
||||
|
||||
function checkDependency (t, resourcesPath, moduleName, moduleExists) {
|
||||
const assertion = moduleExists ? 'should' : 'should NOT'
|
||||
const message = `module dependency '${moduleName}' ${assertion} exist under app/node_modules`
|
||||
const modulePath = path.join(resourcesPath, 'app', 'node_modules', moduleName)
|
||||
return fs.pathExists(modulePath)
|
||||
.then(exists => t.is(moduleExists, exists, message))
|
||||
.then(() => modulePath)
|
||||
}
|
||||
|
||||
function assertDependencyExists (t, resourcesPath, moduleName) {
|
||||
return checkDependency(t, resourcesPath, moduleName, true)
|
||||
.then(modulePath => fs.stat(modulePath))
|
||||
.then(stats => t.true(stats.isDirectory(), 'module is a directory'))
|
||||
}
|
||||
|
||||
function createPruneOptionTest (t, baseOpts, prune, testMessage) {
|
||||
const opts = Object.assign({}, baseOpts, {
|
||||
name: 'pruneTest',
|
||||
dir: util.fixtureSubdir('basic'),
|
||||
prune: prune
|
||||
})
|
||||
|
||||
let resourcesPath
|
||||
|
||||
return util.packageAndEnsureResourcesPath(t, opts)
|
||||
.then(generatedResourcesPath => {
|
||||
resourcesPath = generatedResourcesPath
|
||||
return assertDependencyExists(t, resourcesPath, 'run-series')
|
||||
}).then(() => assertDependencyExists(t, resourcesPath, '@types/node'))
|
||||
.then(() => checkDependency(t, resourcesPath, 'run-waterfall', !prune))
|
||||
.then(() => checkDependency(t, resourcesPath, 'electron-prebuilt', !prune))
|
||||
}
|
||||
|
||||
util.testSinglePlatform('prune test', (t, baseOpts) => {
|
||||
return createPruneOptionTest(t, baseOpts, true, 'package.json devDependency should NOT exist under app/node_modules')
|
||||
})
|
||||
|
||||
util.testSinglePlatform('prune electron in dependencies', (t, baseOpts) => {
|
||||
const opts = Object.assign({}, baseOpts, {
|
||||
name: 'pruneElectronTest',
|
||||
dir: util.fixtureSubdir('electron-in-dependencies')
|
||||
})
|
||||
|
||||
return util.packageAndEnsureResourcesPath(t, opts)
|
||||
.then(resourcesPath => checkDependency(t, resourcesPath, 'electron', false))
|
||||
})
|
||||
|
||||
util.testSinglePlatform('prune: false test', createPruneOptionTest, false,
|
||||
'package.json devDependency should exist under app/node_modules')
|
||||
|
||||
test('isModule only detects modules inside a node_modules parent folder', t =>
|
||||
prune.isModule(util.fixtureSubdir(path.join('prune-is-module', 'node_modules', 'module')))
|
||||
.then(isModule => {
|
||||
t.true(isModule, 'module folder should be detected as module')
|
||||
return prune.isModule(util.fixtureSubdir(path.join('prune-is-module', 'node_modules', 'module', 'not-module')))
|
||||
}).then(isModule => t.false(isModule, 'not-module folder should not be detected as module'))
|
||||
)
|
133
node_modules/electron-packager/test/targets.js
generated
vendored
Normal file
133
node_modules/electron-packager/test/targets.js
generated
vendored
Normal file
@@ -0,0 +1,133 @@
|
||||
'use strict'
|
||||
|
||||
const config = require('./config.json')
|
||||
const sinon = require('sinon')
|
||||
const targets = require('../targets')
|
||||
const test = require('ava')
|
||||
const util = require('./_util')
|
||||
|
||||
function createMultiTargetOptions (extraOpts) {
|
||||
return Object.assign({
|
||||
name: 'targetTest',
|
||||
dir: util.fixtureSubdir('basic'),
|
||||
electronVersion: config.version
|
||||
}, extraOpts)
|
||||
}
|
||||
|
||||
function testMultiTarget (testcaseDescription, extraOpts, expectedPackageCount, packageExistenceMessage) {
|
||||
test(testcaseDescription, t => {
|
||||
const opts = createMultiTargetOptions(extraOpts)
|
||||
const platforms = targets.validateListFromOptions(opts, 'platform')
|
||||
const archs = targets.validateListFromOptions(opts, 'arch')
|
||||
const combinations = targets.createPlatformArchPairs(opts, platforms, archs)
|
||||
|
||||
t.is(combinations.length, expectedPackageCount, packageExistenceMessage)
|
||||
})
|
||||
}
|
||||
|
||||
function testCombinations (testcaseDescription, arch, platform) {
|
||||
testMultiTarget(testcaseDescription, {arch: arch, platform: platform}, 4,
|
||||
'Packages should be generated for all combinations of specified archs and platforms')
|
||||
}
|
||||
|
||||
test('allOfficialArchsForPlatformAndVersion is undefined for unknown platforms', t => {
|
||||
t.is(targets.allOfficialArchsForPlatformAndVersion('unknown', '1.0.0'), undefined)
|
||||
})
|
||||
|
||||
test('allOfficialArchsForPlatformAndVersion returns the correct arches for a known platform', t => {
|
||||
t.deepEqual(targets.allOfficialArchsForPlatformAndVersion('darwin', '1.0.0'), ['x64'])
|
||||
})
|
||||
|
||||
test('allOfficialArchsForPlatformAndVersion returns arm64 when the correct version is specified', t => {
|
||||
t.not(targets.allOfficialArchsForPlatformAndVersion('linux', '1.8.0').indexOf('arm64'), -1,
|
||||
'should be found when version is >= 1.8.0')
|
||||
t.is(targets.allOfficialArchsForPlatformAndVersion('linux', '1.7.0').indexOf('arm64'), -1,
|
||||
'should not be found when version is < 1.8.0')
|
||||
})
|
||||
|
||||
test('allOfficialArchsForPlatformAndVersion returns mips64el when the correct version is specified', t => {
|
||||
t.not(targets.allOfficialArchsForPlatformAndVersion('linux', '1.8.2').indexOf('mips64el'), -1,
|
||||
'should be found when version is >= 1.8.2-beta.5')
|
||||
t.is(targets.allOfficialArchsForPlatformAndVersion('linux', '1.8.0').indexOf('mips64el'), -1,
|
||||
'should not be found when version is < 1.8.2-beta.5')
|
||||
})
|
||||
|
||||
test('validateListFromOptions does not take non-Array/String values', t => {
|
||||
targets.supported.digits = new Set(['64', '65'])
|
||||
t.false(targets.validateListFromOptions({digits: 64}, 'digits') instanceof Array,
|
||||
'should not be an Array')
|
||||
delete targets.supported.digits
|
||||
})
|
||||
|
||||
test('validateListFromOptions works for armv7l host and target arch', t => {
|
||||
sinon.stub(process, 'arch').value('arm')
|
||||
sinon.stub(process, 'config').value({variables: {arm_version: '7'}})
|
||||
|
||||
t.deepEqual(targets.validateListFromOptions({}, 'arch'), ['armv7l'])
|
||||
|
||||
sinon.restore()
|
||||
})
|
||||
|
||||
testMultiTarget('build for all available official targets', {all: true, electronVersion: '1.8.2'},
|
||||
util.allPlatformArchCombosCount,
|
||||
'Packages should be generated for all possible platforms')
|
||||
testMultiTarget('build for all available official targets for a version without arm64 or mips64el support',
|
||||
{all: true},
|
||||
util.allPlatformArchCombosCount - 2,
|
||||
'Packages should be generated for all possible platforms (except arm64 and mips64el)')
|
||||
testMultiTarget('platform=all (one arch)', {arch: 'ia32', platform: 'all'}, 2,
|
||||
'Packages should be generated for both 32-bit platforms')
|
||||
testMultiTarget('arch=all test (one platform)', {arch: 'all', platform: 'linux'}, 3,
|
||||
'Packages should be generated for all expected architectures')
|
||||
|
||||
testCombinations('multi-platform / multi-arch test, from arrays', ['ia32', 'x64'], ['linux', 'win32'])
|
||||
testCombinations('multi-platform / multi-arch test, from strings', 'ia32,x64', 'linux,win32')
|
||||
testCombinations('multi-platform / multi-arch test, from strings with spaces', 'ia32, x64', 'linux, win32')
|
||||
|
||||
test('fails with invalid arch', util.invalidOptionTest({
|
||||
arch: 'z80',
|
||||
platform: 'linux'
|
||||
}))
|
||||
test('fails with invalid platform', util.invalidOptionTest({
|
||||
arch: 'ia32',
|
||||
platform: 'dos'
|
||||
}))
|
||||
|
||||
test('hostArch detects incorrectly configured armv7l Node', t => {
|
||||
sinon.stub(targets, 'unameArch').returns('armv7l')
|
||||
sinon.stub(process, 'arch').value('arm')
|
||||
sinon.stub(process, 'config').value({variables: {arm_version: '6'}})
|
||||
|
||||
t.is(targets.hostArch(), 'armv7l')
|
||||
|
||||
sinon.restore()
|
||||
})
|
||||
|
||||
test('hostArch detects correctly configured armv7l Node', t => {
|
||||
sinon.stub(process, 'arch').value('arm')
|
||||
sinon.stub(process, 'config').value({variables: {arm_version: '7'}})
|
||||
|
||||
t.is(targets.hostArch(), 'armv7l')
|
||||
|
||||
sinon.restore()
|
||||
})
|
||||
|
||||
test('hostArch cannot determine ARM version', t => {
|
||||
sinon.stub(process, 'arch').value('arm')
|
||||
sinon.stub(process, 'config').value({variables: {arm_version: '99'}})
|
||||
|
||||
t.is(targets.hostArch(), 'arm')
|
||||
|
||||
sinon.restore()
|
||||
})
|
||||
|
||||
testMultiTarget('invalid official combination', {arch: 'ia32', platform: 'darwin'}, 0, 'Package should not be generated for invalid official combination')
|
||||
testMultiTarget('platform=linux and arch=arm64 with a supported official Electron version', {arch: 'arm64', platform: 'linux', electronVersion: '1.8.0'}, 1, 'Package should be generated for arm64')
|
||||
testMultiTarget('platform=linux and arch=arm64 with an unsupported official Electron version', {arch: 'arm64', platform: 'linux'}, 0, 'Package should not be generated for arm64')
|
||||
testMultiTarget('platform=linux and arch=mips64el with a supported official Electron version', {arch: 'mips64el', platform: 'linux', electronVersion: '1.8.2-beta.5'}, 1, 'Package should be generated for mips64el')
|
||||
testMultiTarget('platform=linux and arch=mips64el with an unsupported official Electron version', {arch: 'mips64el', platform: 'linux'}, 0, 'Package should not be generated for mips64el')
|
||||
testMultiTarget('platform=linux and arch=mips64el with an unsupported official Electron version (2.0.0)', {arch: 'mips64el', platform: 'linux', electronVersion: '2.0.0'}, 0, 'Package should not be generated for mips64el')
|
||||
testMultiTarget('unofficial arch', {arch: 'z80', platform: 'linux', download: {mirror: 'mirror'}}, 1,
|
||||
'Package should be generated for non-standard arch from non-official mirror')
|
||||
testMultiTarget('unofficial platform', {arch: 'ia32', platform: 'minix', download: {mirror: 'mirror'}}, 1,
|
||||
'Package should be generated for non-standard platform from non-official mirror')
|
215
node_modules/electron-packager/test/win32.js
generated
vendored
Normal file
215
node_modules/electron-packager/test/win32.js
generated
vendored
Normal file
@@ -0,0 +1,215 @@
|
||||
'use strict'
|
||||
|
||||
const config = require('./config.json')
|
||||
const fs = require('fs-extra')
|
||||
const packager = require('..')
|
||||
const path = require('path')
|
||||
const test = require('ava')
|
||||
const util = require('./_util')
|
||||
const win32 = require('../win32')
|
||||
|
||||
const win32Opts = {
|
||||
name: 'basicTest',
|
||||
dir: util.fixtureSubdir('basic'),
|
||||
electronVersion: config.version,
|
||||
arch: 'x64',
|
||||
platform: 'win32'
|
||||
}
|
||||
|
||||
function generateRceditOptionsSansIcon (opts) {
|
||||
return new win32.App(opts).generateRceditOptionsSansIcon()
|
||||
}
|
||||
|
||||
function generateVersionStringTest (metadataProperties, extraOpts, expectedValues, assertionMsgs) {
|
||||
return t => {
|
||||
const opts = Object.assign({}, win32Opts, extraOpts)
|
||||
const rcOpts = generateRceditOptionsSansIcon(opts)
|
||||
|
||||
metadataProperties = [].concat(metadataProperties)
|
||||
expectedValues = [].concat(expectedValues)
|
||||
assertionMsgs = [].concat(assertionMsgs)
|
||||
metadataProperties.forEach((property, i) => {
|
||||
const value = expectedValues[i]
|
||||
const msg = assertionMsgs[i]
|
||||
if (property === 'version-string') {
|
||||
for (const subkey in value) {
|
||||
t.is(rcOpts[property][subkey], value[subkey], `${msg} (${subkey})`)
|
||||
}
|
||||
} else {
|
||||
t.is(rcOpts[property], value, msg)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function setFileVersionTest (buildVersion) {
|
||||
const appVersion = '4.99.101.0'
|
||||
const opts = {
|
||||
appVersion: appVersion,
|
||||
buildVersion: buildVersion
|
||||
}
|
||||
|
||||
return generateVersionStringTest(
|
||||
['product-version', 'file-version'],
|
||||
opts,
|
||||
[appVersion, buildVersion],
|
||||
['Product version should match app version',
|
||||
'File version should match build version']
|
||||
)
|
||||
}
|
||||
|
||||
function setProductVersionTest (appVersion) {
|
||||
return generateVersionStringTest(
|
||||
['product-version', 'file-version'],
|
||||
{ appVersion: appVersion },
|
||||
[appVersion, appVersion],
|
||||
['Product version should match app version',
|
||||
'File version should match app version']
|
||||
)
|
||||
}
|
||||
|
||||
function setCopyrightTest (appCopyright) {
|
||||
const opts = {
|
||||
appCopyright: appCopyright
|
||||
}
|
||||
|
||||
return generateVersionStringTest('version-string', opts, {LegalCopyright: appCopyright}, 'Legal copyright should match app copyright')
|
||||
}
|
||||
|
||||
function setCopyrightAndCompanyNameTest (appCopyright, companyName) {
|
||||
const opts = {
|
||||
appCopyright: appCopyright,
|
||||
win32metadata: {
|
||||
CompanyName: companyName
|
||||
}
|
||||
}
|
||||
|
||||
return generateVersionStringTest(
|
||||
'version-string',
|
||||
opts,
|
||||
{LegalCopyright: appCopyright, CompanyName: companyName},
|
||||
'Legal copyright should match app copyright and Company name should match win32metadata value'
|
||||
)
|
||||
}
|
||||
|
||||
function setRequestedExecutionLevelTest (requestedExecutionLevel) {
|
||||
const opts = {
|
||||
win32metadata: {
|
||||
'requested-execution-level': requestedExecutionLevel
|
||||
}
|
||||
}
|
||||
|
||||
return generateVersionStringTest(
|
||||
'requested-execution-level',
|
||||
opts,
|
||||
requestedExecutionLevel,
|
||||
'requested-execution-level in win32metadata should match rcOpts value'
|
||||
)
|
||||
}
|
||||
|
||||
function setApplicationManifestTest (applicationManifest) {
|
||||
const opts = {
|
||||
win32metadata: {
|
||||
'application-manifest': applicationManifest
|
||||
}
|
||||
}
|
||||
|
||||
return generateVersionStringTest(
|
||||
'application-manifest',
|
||||
opts,
|
||||
applicationManifest,
|
||||
'application-manifest in win32metadata should match rcOpts value'
|
||||
)
|
||||
}
|
||||
|
||||
function setCompanyNameTest (companyName) {
|
||||
const opts = {
|
||||
win32metadata: {
|
||||
CompanyName: companyName
|
||||
}
|
||||
}
|
||||
|
||||
return generateVersionStringTest('version-string',
|
||||
opts,
|
||||
{CompanyName: companyName},
|
||||
`Company name should match win32metadata value`)
|
||||
}
|
||||
|
||||
test('better error message when wine is not found', (t) => {
|
||||
let err = Error('spawn wine ENOENT')
|
||||
err.code = 'ENOENT'
|
||||
err.syscall = 'spawn wine'
|
||||
|
||||
t.is(err.message, 'spawn wine ENOENT')
|
||||
err = win32.updateWineMissingException(err)
|
||||
t.not(err.message, 'spawn wine ENOENT')
|
||||
})
|
||||
|
||||
test('error message unchanged when error not about wine', t => {
|
||||
let errNotEnoent = Error('unchanged')
|
||||
errNotEnoent.code = 'ESOMETHINGELSE'
|
||||
errNotEnoent.syscall = 'spawn wine'
|
||||
|
||||
t.is(errNotEnoent.message, 'unchanged')
|
||||
errNotEnoent = win32.updateWineMissingException(errNotEnoent)
|
||||
t.is(errNotEnoent.message, 'unchanged')
|
||||
|
||||
let errNotSpawnWine = Error('unchanged')
|
||||
errNotSpawnWine.code = 'ENOENT'
|
||||
errNotSpawnWine.syscall = 'spawn foo'
|
||||
|
||||
t.is(errNotSpawnWine.message, 'unchanged')
|
||||
errNotSpawnWine = win32.updateWineMissingException(errNotSpawnWine)
|
||||
t.is(errNotSpawnWine.message, 'unchanged')
|
||||
})
|
||||
|
||||
test('win32metadata defaults', t => {
|
||||
const opts = { name: 'Win32 App' }
|
||||
const rcOpts = generateRceditOptionsSansIcon(opts)
|
||||
|
||||
t.is(rcOpts['version-string'].FileDescription, opts.name, 'default FileDescription')
|
||||
t.is(rcOpts['version-string'].InternalName, opts.name, 'default InternalName')
|
||||
t.is(rcOpts['version-string'].OriginalFilename, 'Win32 App.exe', 'default OriginalFilename')
|
||||
t.is(rcOpts['version-string'].ProductName, opts.name, 'default ProductName')
|
||||
})
|
||||
|
||||
util.packagerTest('win32 executable name is based on sanitized app name', (t, opts) => {
|
||||
Object.assign(opts, win32Opts, { name: '@username/package-name' })
|
||||
|
||||
return packager(opts)
|
||||
.then(paths => {
|
||||
t.is(1, paths.length, '1 bundle created')
|
||||
const appExePath = path.join(paths[0], '@username-package-name.exe')
|
||||
return fs.pathExists(appExePath)
|
||||
}).then(exists => t.true(exists, 'The sanitized EXE filename should exist'))
|
||||
})
|
||||
|
||||
util.packagerTest('win32 executable name uses executableName when available', (t, opts) => {
|
||||
Object.assign(opts, win32Opts, { name: 'PackageName', executableName: 'my-package' })
|
||||
|
||||
return packager(opts)
|
||||
.then(paths => {
|
||||
t.is(1, paths.length, '1 bundle created')
|
||||
const appExePath = path.join(paths[0], 'my-package.exe')
|
||||
return fs.pathExists(appExePath)
|
||||
}).then(exists => t.true(exists, 'the executableName-based filename should exist'))
|
||||
})
|
||||
|
||||
util.packagerTest('win32 icon set', (t, opts) => {
|
||||
Object.assign(opts, win32Opts, { executableName: 'iconTest', arch: 'ia32', icon: path.join(__dirname, 'fixtures', 'monochrome') })
|
||||
|
||||
return packager(opts)
|
||||
.then(paths => {
|
||||
t.is(1, paths.length, '1 bundle created')
|
||||
const appExePath = path.join(paths[0], 'iconTest.exe')
|
||||
return fs.pathExists(appExePath)
|
||||
}).then(exists => t.true(exists, 'the Electron executable should exist'))
|
||||
})
|
||||
|
||||
test('win32 build version sets FileVersion test', setFileVersionTest('2.3.4.5'))
|
||||
test('win32 app version sets ProductVersion test', setProductVersionTest('5.4.3.2'))
|
||||
test('win32 app copyright sets LegalCopyright test', setCopyrightTest('Copyright Bar'))
|
||||
test('win32 set LegalCopyright and CompanyName test', setCopyrightAndCompanyNameTest('Copyright Bar', 'MyCompany LLC'))
|
||||
test('win32 set CompanyName test', setCompanyNameTest('MyCompany LLC'))
|
||||
test('win32 set requested-execution-level test', setRequestedExecutionLevelTest('asInvoker'))
|
||||
test('win32 set application-manifest test', setApplicationManifestTest('/path/to/manifest.xml'))
|
Reference in New Issue
Block a user