test(e2e) add FS API tests (#521)

* fix(tauri.js) update e2e test

* test(e2e) add FS API tests

* fix(tauri.js) lint errors

* fix(tauri) clippy checks

* fix(test) use " instead of '
This commit is contained in:
Lucas Fernandes Nogueira
2020-03-29 23:41:45 -03:00
committed by GitHub
parent 4313b197ae
commit 7e2854007a
13 changed files with 179 additions and 101 deletions

View File

@@ -23,11 +23,15 @@ if (argv.help) {
process.exit(0)
}
const build = require('../dist/api/build')
async function run () {
const build = require('../dist/api/build')
build({
ctx: {
debug: argv.debug,
target: argv.target
}
})
await build({
ctx: {
debug: argv.debug,
target: argv.target
}
}).promise
}
run()

View File

@@ -20,10 +20,14 @@ if (argv.help) {
process.exit(0)
}
const dev = require('../dist/api/dev')
async function run () {
const dev = require('../dist/api/dev')
dev({
ctx: {
exitOnPanic: argv['exit-on-panic']
}
})
await dev({
ctx: {
exitOnPanic: argv['exit-on-panic']
}
}).promise
}
run()

View File

@@ -28,9 +28,6 @@ module.exports = {
'<rootDir>/test/jest/__tests__/**/*.spec.js',
'<rootDir>/test/jest/__tests__/**/*.test.js'
],
testPathIgnorePatterns: [
'(build|dev).spec.js'
],
moduleFileExtensions: ['ts', 'js', 'json'],
moduleNameMapper: {
'^~/(.*)$': '<rootDir>/$1',

View File

@@ -12,10 +12,10 @@
"scripts": {
"build": "webpack --progress",
"build-release": "yarn build --display none --progress false",
"test": "jest --runInBand --no-cache",
"test": "jest --runInBand --no-cache --testPathIgnorePatterns=\"(build|dev)\"",
"pretest": "yarn build",
"prepublishOnly": "yarn build-release",
"test:mac-local": "jest --runInBand",
"test:local": "jest --runInBand",
"lint": "eslint --ext ts ./src/**/*.ts",
"lint-fix": "eslint --fix --ext ts ./src/**/*.ts",
"lint:lockfile": "lockfile-lint --path yarn.lock --type yarn --validate-https --allowed-hosts npm yarn",

View File

@@ -3,6 +3,12 @@ import { join, normalize, resolve, sep } from 'path'
import logger from './logger'
const warn = logger('tauri', 'red')
function resolvePath(basePath: string, dir: string): string {
return dir.startsWith('/') || /^\S:/g.test(dir)
? dir
: resolve(basePath, dir)
}
const getAppDir = (): string => {
let dir = process.cwd()
let count = 0
@@ -24,8 +30,8 @@ const appDir = getAppDir()
const tauriDir = resolve(appDir, 'src-tauri')
const resolveDir = {
app: (dir: string) => resolve(appDir, dir),
tauri: (dir: string) => resolve(tauriDir, dir)
app: (dir: string) => resolvePath(appDir, dir),
tauri: (dir: string) => resolvePath(tauriDir, dir)
}
export { appDir, tauriDir, resolveDir as resolve }

View File

@@ -1,5 +1,4 @@
import { existsSync } from 'fs-extra'
import { resolve } from 'path'
import { TauriConfig } from 'types'
import merge from 'webpack-merge'
import logger from '../helpers/logger'
@@ -58,13 +57,19 @@ const getTauriConfig = (cfg: Partial<TauriConfig>): TauriConfig => {
const runningDevServer = config.build.devPath && config.build.devPath.startsWith('http')
if (!runningDevServer) {
config.build.devPath = resolve(appPaths.tauriDir, config.build.devPath)
config.build.devPath = appPaths.resolve.tauri(config.build.devPath)
process.env.TAURI_DIST_DIR = appPaths.resolve.app(config.build.devPath)
}
if (config.build.distDir) {
config.build.distDir = resolve(appPaths.tauriDir, config.build.distDir)
config.build.distDir = appPaths.resolve.tauri(config.build.distDir)
process.env.TAURI_DIST_DIR = appPaths.resolve.app(config.build.distDir)
}
if (!process.env.TAURI_DIST_DIR) {
error("Couldn't resolve the dist dir. Make sure you have `devPath` or `distDir` under tauri.conf.json > build")
process.exit(1)
}
process.env.TAURI_DIST_DIR = appPaths.resolve.app(config.build.distDir)
process.env.TAURI_DIR = appPaths.tauriDir
process.env.TAURI_CONFIG = JSON.stringify(config)

View File

@@ -13,6 +13,9 @@ function runBuildTest(tauriConfig) {
let success = false
const server = fixtureSetup.startServer(() => {
success = true
try {
process.kill(appPid)
} catch {}
// wait for the app process to be killed
setTimeout(resolve, 2000)
})
@@ -37,7 +40,7 @@ function runBuildTest(tauriConfig) {
reject("App didn't reply")
})
}
}, 2500)
}, 15000)
} catch (error) {
reject(error)
}

View File

@@ -16,7 +16,7 @@ describe('[CLI] tauri.js template', () => {
const init = require('api/init')
init({
directory: process.cwd(),
force: true,
force: 'all',
tauriPath: resolve(__dirname, '../../../../..')
})

View File

@@ -5,6 +5,12 @@ const mockFixtureDir = path.resolve(__dirname, '../fixtures')
module.exports.fixtureDir = mockFixtureDir
function mockResolvePath (basePath, dir) {
return dir.startsWith('/') || /^\S:/g.test(dir)
? dir
: path.resolve(basePath, dir)
}
module.exports.initJest = (mockFixture) => {
jest.setTimeout(720000)
jest.mock('helpers/non-webpack-require', () => {
@@ -25,8 +31,8 @@ module.exports.initJest = (mockFixture) => {
appDir,
tauriDir,
resolve: {
app: dir => path.join(appDir, dir),
tauri: dir => path.join(tauriDir, dir)
app: dir => mockResolvePath(appDir, dir),
tauri: dir => mockResolvePath(tauriDir, dir)
}
}
})
@@ -34,8 +40,35 @@ module.exports.initJest = (mockFixture) => {
jest.spyOn(process, 'exit').mockImplementation(() => {})
}
module.exports.startServer = (onReply) => {
module.exports.startServer = (onSuccess) => {
const http = require('http')
const responses = {
writeFile: null,
readFile: null,
writeFileWithDir: null,
readFileWithDir: null,
readDir: null,
readDirWithDir: null,
copyFile: null,
copyFileWithDir: null,
createDir: null,
createDirWithDir: null,
removeDir: null,
removeDirWithDir: null,
renameFile: null,
renameFileWithDir: null,
removeFile: null,
renameFileWithDir: null,
listen: null
}
function addResponse (response) {
responses[response.cmd] = true
if (!Object.values(responses).some(c => c === null)) {
server.close(onSuccess)
}
}
const app = http.createServer((req, res) => {
// Set CORS headers
res.setHeader('Access-Control-Allow-Origin', '*')
@@ -50,16 +83,23 @@ module.exports.startServer = (onReply) => {
}
if (req.method === 'POST') {
let body = ''
req.on('data', chunk => {
body += chunk.toString()
})
if (req.url === '/reply') {
let body = ''
req.on('data', chunk => {
body += chunk.toString()
})
req.on('end', () => {
expect(JSON.parse(body)).toStrictEqual({
msg: 'TEST'
})
server.close(onReply)
const json = JSON.parse(body)
addResponse(json)
res.writeHead(200)
res.end()
})
}
if (req.url === '/error') {
req.on('end', () => {
res.writeHead(200)
res.end()
throw new Error(body)
})
}
}

View File

@@ -2,22 +2,92 @@
<html>
<body>
<script>
function notify(route, args) {
function callBackEnd (route, args) {
console.log(route)
console.log(args)
var xhr = new XMLHttpRequest()
xhr.onload = function () {
console.log(route, args, 'done', xhr.status)
}
xhr.onerror = function () {
console.log(route, args, 'error with ' + xhr.status)
}
xhr.open('POST', 'http://localhost:7000/' + route)
xhr.setRequestHeader('Content-type', 'application/json')
xhr.send(JSON.stringify(args))
}
function reply (args) {
return callBackEnd('reply', args)
}
function sendError (error) {
return callBackEnd('error', error)
}
function testFs (dir) {
var contents = 'TAURI E2E TEST FILE'
var commandSuffix = (dir ? 'WithDir' : '')
var options = {
dir: dir || null
}
return window.tauri.writeFile({
file: 'tauri-test.txt',
contents: contents
}, options).then(function (res) {
reply({ cmd: 'writeFile' + commandSuffix })
return window.tauri.readTextFile('tauri-test.txt', options).then(function (res) {
if (res === contents) {
reply({ cmd: 'readFile' + commandSuffix })
return window.tauri.readDir('.', options).then(res => {
reply({ cmd: 'readDir' + commandSuffix })
return window.tauri.copyFile('tauri-test.txt', 'tauri-test-copy.txt', options)
.then(function (res) {
reply({ cmd: 'copyFile' + commandSuffix })
return window.tauri.createDir('tauri-test-dir', options).then(function (res) {
reply({ cmd: 'createDir' + commandSuffix })
return window.tauri.removeDir('tauri-test-dir', options).then(function (res) {
reply({ cmd: 'removeDir' + commandSuffix })
})
}).then(function (res) {
return window.tauri.renameFile('tauri-test.txt', 'tauri.testt.txt', options).then(function (res) {
reply({ cmd: 'renameFile' + commandSuffix })
return Promise.all([
window.tauri.removeFile('tauri.testt.txt', options),
window.tauri.removeFile('tauri-test-copy.txt', options)
]).then(function (res) {
reply({ cmd: 'removeFile' + commandSuffix })
})
})
})
})
})
} else {
sendError('expected "' + contents + '" found "' + res + '"')
}
})
}).catch(sendError)
}
window.onTauriInit = function () {
window.tauri.listen('reply', function (res) {
notify('reply', res.payload)
reply({ cmd: 'listen' })
})
window.tauri.emit('hello')
testFs(null).then(function () {
testFs(window.tauri.Dir.Config)
})
setTimeout(function () {
window.tauri.invoke({ cmd: 'exit' })
}, 15000)
}
setTimeout(function () {
window.tauri.invoke({ cmd: 'exit' })
}, 1000)
</script>
</body>

View File

@@ -1,54 +0,0 @@
const express = require('express')
const cors = require('cors')
const app = express()
app.use(cors())
app.use(express.json())
const port = 7000
let appPid
app.post('/reply', (req, res) => {
if (req.body && req.body.msg !== 'TEST') {
throw new Error(`unexpected reply ${JSON.stringify(req.body)}`)
}
console.log('App event replied')
exit(0)
})
const server = app.listen(port, () => console.log(`Test listening on port ${port}!`))
const exit = code => {
server.close()
process.kill(appPid)
process.exit(code)
}
const path = require('path')
const dist = path.resolve(__dirname, 'dist')
const build = require('../cli/tauri.js/dist/api/build')
build({
build: {
devPath: dist
},
ctx: {
debug: true
},
tauri: {
embeddedServer: {
active: true
}
}
}).then(() => {
const spawn = require('../cli/tauri.js/dist/helpers/spawn').spawn
const artifactPath = path.resolve(__dirname, 'src-tauri/target/debug/app')
appPid = spawn(
process.platform === 'win32' ? `${artifactPath}.exe` : artifactPath.replace('debug/app', 'debug/./app'),
[],
null
)
// if it didn't reply, throw an error
setTimeout(() => {
throw new Error("App didn't reply")
}, 2000)
})

View File

@@ -6,16 +6,18 @@ extern crate serde_json;
fn main() {
tauri::AppBuilder::new()
.setup(|_webview| {
.setup(|_webview, _| {
let handle = _webview.handle();
tauri::event::listen(String::from("hello"), move |_| {
tauri::event::emit(&handle, String::from("reply"), "{ msg: 'TEST' }".to_string());
tauri::event::emit(&handle, String::from("reply"), Some("{ msg: 'TEST' }".to_string()));
});
})
.invoke_handler(|webview, arg| {
use cmd::Cmd::*;
match serde_json::from_str(arg) {
Err(_) => {}
Err(e) => {
Err(e.to_string())
}
Ok(command) => {
match command {
// definitions for your custom commands from Cmd here
@@ -23,6 +25,7 @@ fn main() {
webview.exit();
}
}
Ok(())
}
}
})

View File

@@ -27,7 +27,7 @@ pub fn open<T: 'static>(
select(options.filter, options.default_path)
};
response
.map(|r| map_response(r))
.map(map_response)
.map_err(|e| crate::ErrorKind::Dialog(e.to_string()).into())
},
callback,
@@ -45,7 +45,7 @@ pub fn save<T: 'static>(
webview,
move || {
save_file(options.filter, options.default_path)
.map(|r| map_response(r))
.map(map_response)
.map_err(|e| crate::ErrorKind::Dialog(e.to_string()).into())
},
callback,