Forráskód Böngészése

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 '
Lucas Fernandes Nogueira 5 éve
szülő
commit
7e2854007a

+ 11 - 7
cli/tauri.js/bin/tauri-build.js

@@ -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()

+ 10 - 6
cli/tauri.js/bin/tauri-dev.js

@@ -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()

+ 0 - 3
cli/tauri.js/jest.config.js

@@ -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',

+ 2 - 2
cli/tauri.js/package.json

@@ -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",

+ 8 - 2
cli/tauri.js/src/helpers/app-paths.ts

@@ -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 }

+ 9 - 4
cli/tauri.js/src/helpers/tauri-config.ts

@@ -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)
 

+ 4 - 1
cli/tauri.js/test/jest/__tests__/build.spec.js

@@ -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)
     }

+ 1 - 1
cli/tauri.js/test/jest/__tests__/template.spec.js

@@ -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, '../../../../..')
       })
 

+ 50 - 10
cli/tauri.js/test/jest/fixtures/app-test-setup.js

@@ -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', () => {
+          const json = JSON.parse(body)
+          addResponse(json)
+          res.writeHead(200)
+          res.end()
         })
+      }
+      if (req.url === '/error') {
         req.on('end', () => {
-          expect(JSON.parse(body)).toStrictEqual({
-            msg: 'TEST'
-          })
-          server.close(onReply)
+          res.writeHead(200)
+          res.end()
+          throw new Error(body)
         })
       }
     }

+ 75 - 5
cli/tauri.js/test/jest/fixtures/app/dist/index.html

@@ -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>
 

+ 0 - 54
cli/tauri.js/test/jest/fixtures/app/index.js

@@ -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)
-})

+ 6 - 3
cli/tauri.js/test/jest/fixtures/app/src-tauri/src/main.rs

@@ -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(())
         }
       }
     })

+ 2 - 2
tauri/src/endpoints/dialog.rs

@@ -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,