diff --git a/packages/taro-h5/src/api/unsupportedApi/index.js b/packages/taro-h5/src/api/unsupportedApi/index.js index 61cdf17fbbb7..9e8524514d82 100644 --- a/packages/taro-h5/src/api/unsupportedApi/index.js +++ b/packages/taro-h5/src/api/unsupportedApi/index.js @@ -132,7 +132,7 @@ export const openDocument = temporarilyNotSupport('openDocument') // export const navigateTo = temporarilyNotSupport('navigateTo') // export const redirectTo = temporarilyNotSupport('redirectTo') // export const switchTab = temporarilyNotSupport('switchTab') -export const reLaunch = temporarilyNotSupport('reLaunch') +// export const reLaunch = temporarilyNotSupport('reLaunch') // 位置 export const getLocation = temporarilyNotSupport('getLocation') diff --git a/packages/taro-h5/types/index.d.ts b/packages/taro-h5/types/index.d.ts index bf7a554d5f34..0c5171427d93 100644 --- a/packages/taro-h5/types/index.d.ts +++ b/packages/taro-h5/types/index.d.ts @@ -49,6 +49,15 @@ declare namespace TaroH5 { refs: { [key: string]: any }; + $router: { + path: string; + scene: number; + query: { + [key: string]: string; + }; + shareTicket: string; + referrerInfo: {}; + }; } class PureComponent

extends Component { } diff --git a/packages/taro-router/__tests__/router.spec.tsx b/packages/taro-router/__tests__/router.spec.tsx deleted file mode 100644 index 31c153f99913..000000000000 --- a/packages/taro-router/__tests__/router.spec.tsx +++ /dev/null @@ -1,58 +0,0 @@ -import Nerv from 'nervjs' -import { Component } from '@tarojs/taro-h5' -import Router from '../src/router/router' -import createHistory from '../src/history/createHashHistory' -import { createLocation } from '../src/history/LocationUtils'; - -jest.mock('../src/history/createHashHistory') - -fdescribe('router component', () => { - let mockHistory - - beforeEach(() => { - mockHistory = createHistory() - }) - - it('should ', () => { - const ctn = document.createElement('div') - // const spy = jest.fn() - const url1 = '/pages/index/index' - const url2 = '/pages/about/index' - - class Page extends Component { - render () {} - } - - class RouterComponent extends Component { - render () { - return ( - - ) - } - } - - Nerv.render(, ctn) - - (history as any).notify({ - fromLocation: mockHistory.location, - toLocation: createLocation(url2, '1', mockHistory.location), - action: 'PUSH' - }) - - }) - - it('should be able to get $router property via this', () => { - - }); -}) diff --git a/packages/taro-router/jest.config.js b/packages/taro-router/jest.config.js index d51164bf68c1..352c5e73eeee 100644 --- a/packages/taro-router/jest.config.js +++ b/packages/taro-router/jest.config.js @@ -1,14 +1,8 @@ -const path = require('path') - module.exports = { preset: 'ts-jest', testEnvironment: 'jsdom', testURL: 'https://taro.aotu.io', globals: { window: true - }, - moduleNameMapper: { - 'nervjs': path.join(__dirname, 'node_modules', 'nervjs') - // 'nervjs': require.resolve('nervjs') } -}; \ No newline at end of file +} diff --git a/packages/taro-router/package.json b/packages/taro-router/package.json index 87cc98f960a3..f6d62e379b6c 100644 --- a/packages/taro-router/package.json +++ b/packages/taro-router/package.json @@ -11,10 +11,11 @@ "index.js" ], "scripts": { - "test": "jest", - "build": "rollup -c rollup.config.js", + "build": "npm run test && rollup -c rollup.config.js", "dev": "rollup -c rollup.config.js --watch", - "prepack": "npm run build" + "prepack": "npm run build", + "test": "jest", + "test:dev": "jest --watch" }, "repository": { "type": "git", diff --git a/packages/taro-router/__tests__/hashHistory.spec.ts b/packages/taro-router/src/__tests__/history-test.tsx similarity index 76% rename from packages/taro-router/__tests__/hashHistory.spec.ts rename to packages/taro-router/src/__tests__/history-test.tsx index 3e1b1a450576..43e0f2249f1f 100644 --- a/packages/taro-router/__tests__/hashHistory.spec.ts +++ b/packages/taro-router/src/__tests__/history-test.tsx @@ -1,16 +1,24 @@ -import { History } from '../src/utils/types' -import createHistory from '../src/history/createHashHistory' -import { createNavigateTo, createNavigateBack, createRedirectTo } from '../src/apis' +import { History } from '../utils/types' +import createHistory from '../history/createHistory' +import { createNavigateTo, createNavigateBack, createRedirectTo } from '../apis' let history: History beforeEach(() => { - history = createHistory() + history = createHistory({ + mode: 'browser', + basename: '/', + firstPagePath: '/pages/index/index', + customRoutes: { + '/index': '/pages/index/index', + '/about': '/pages/about/abtou' + } + }) }) -xdescribe('navigateTo/navigateBack/redirectTo', () => { +describe('navigateTo/navigateBack/redirectTo', () => { const location1 = { - pathname: '/', + path: '/pages/index/index', state: { key: '0' }, search: '', hash: '', @@ -19,7 +27,7 @@ xdescribe('navigateTo/navigateBack/redirectTo', () => { const url2 = '/pages/about/index?para=1' const location2 = { - pathname: '/pages/about/index', + path: '/pages/about/index', state: { key: '1' }, search: '?para=1', hash: '', @@ -30,7 +38,7 @@ xdescribe('navigateTo/navigateBack/redirectTo', () => { const url3 = '/pages/settings/index?para2=2' const location3 = { - pathname: '/pages/settings/index', + path: '/pages/settings/index', state: { key: '1' }, search: '?para2=2', hash: '', @@ -65,7 +73,7 @@ xdescribe('navigateTo/navigateBack/redirectTo', () => { // jsdom无法准确模拟history的全部功能,这里使用spy代替 const spy = spyOn(window.history, 'go') navigateBack({ delta: 1 }) - expect(spy).toHaveBeenCalledWith(1) + expect(spy).toHaveBeenCalledWith(-1) }) it('should notify listeners with proper params when calling redirectTo', () => { diff --git a/packages/taro-router/src/__tests__/router-test.tsx b/packages/taro-router/src/__tests__/router-test.tsx new file mode 100644 index 000000000000..6a2539944269 --- /dev/null +++ b/packages/taro-router/src/__tests__/router-test.tsx @@ -0,0 +1,140 @@ +import Taro from '@tarojs/taro-h5' +import Nerv from 'nervjs' + +import createHistory from '../history/createHistory' +import Router from '../router/router' + +let mockHistory + +window.scrollTo = jest.fn() +const wait = (timeout) => { + return new Promise((resolve, reject) => { + setTimeout(resolve, timeout) + }) +} + +beforeEach(() => { + mockHistory = createHistory({ + mode: 'browser', + basename: '/', + firstPagePath: '/pages/index/index', + customRoutes: { + '/pages/index/index': '/index', + '/pages/about/about': '/about' + } + }) +}) + +describe('router component', () => { + + it('should work!', async done => { + const url1 = '/pages/index/index' + const url2 = '/pages/about/index' + + class Base extends Taro.Component { + idx + render () { + return ( +

{this.idx}
+ ) + } + } + + const getPage = idx => { + return class Page extends Base { + idx = idx + } + } + + class RouterComponent extends Taro.Component { + render () { + return ( + Promise.resolve({ + default: getPage(0) + }), + isIndex: true + }, { + path: url2, + componentLoader: () => Promise.resolve({ + default: getPage(1) + }), + isIndex: false + }]} + customRoutes={{ + "/pages/index/index": "/index", + "/pages/about/index": "/about" + }} + /> + ) + } + } + + const routerComponent = + const getComputedStyle = window.getComputedStyle + Nerv.render(routerComponent, document.createElement('div')) + const dom = routerComponent.dom + + await wait(100) + expect(window.getComputedStyle(dom.childNodes[0]).display).toEqual('block') + Taro.navigateTo({ + url: '/pages/about/about' + }) + await wait(100) + expect(getComputedStyle(dom.childNodes[0]).display).toEqual('none') + expect(getComputedStyle(dom.childNodes[1]).display).toEqual('block') + done() + }) + + it('should be able to get $router property via this', async done => { + const url1 = '/pages/index/index' + const url2 = '/pages/about/index' + let routerParams + class Page extends Taro.Component { + render() { + routerParams = this.$router + return ( +
+ ) + } + } + const componentLoader = () => Promise.resolve({ + default: Page + }) + + class RouterComponent extends Taro.Component { + render () { + return ( + + ) + } + } + Nerv.render(, document.createElement('div')) + await wait(100) + expect(routerParams).toMatchObject({}) + Taro.navigateTo({ + url: '/pages/about/about' + }) + await wait(100) + expect(routerParams).toMatchObject({}) + done() + }) +}) diff --git a/packages/taro-router/src/apis/index.ts b/packages/taro-router/src/apis/index.ts index 310d9e72d164..95b88393f156 100644 --- a/packages/taro-router/src/apis/index.ts +++ b/packages/taro-router/src/apis/index.ts @@ -4,6 +4,7 @@ import invariant from 'invariant'; type SuccessCallback = (res: any) => any type FailCallback = (err: any) => any type CompleteCallback = () => any +type Result = { errMsg?: string } interface NavigateToOption { url: string @@ -27,53 +28,76 @@ interface RedirectToOption { } const createNavigateTo = (history: History) => { - return function ({ url }: NavigateToOption) { - - invariant(url, 'navigateTo must be called with a url') + return function ({ url }: NavigateToOption): Promise { + const res: Result = {} try { + invariant(url, 'navigateTo must be called with a url') if (/^(https?:)\/\//.test(url)) { - window.location.assign(url); - return + window.location.assign(url) + } else { + history.push(url) } - history.push(url) - return Promise.resolve() + res.errMsg = 'navigateTo:ok' + return Promise.resolve(res) } catch (e) { - return Promise.reject() + res.errMsg = `navigateTo:fail ${e.message}` + return Promise.reject(res) } } } const createNavigateBack = (history: History) => { return function (opts: NavigateBackOption = {}) { + const res: Result = {} try { const { delta = 1 } = opts - invariant(delta >= 0, 'navigateBack must be called with a delta greater than 0') history.go(-delta) - return Promise.resolve() + res.errMsg = 'navigateBack:ok' + return Promise.resolve(res) } catch (e) { - return Promise.reject() + res.errMsg = `navigateBack:fail ${e.message}` + return Promise.reject(res) } } } const createRedirectTo = (history: History) => { return function ({ url }: RedirectToOption) { - - invariant(url, 'redirectTo must be called with a url') + const res: Result = {} - if (/^(https?:)\/\//.test(url)) { - window.location.assign(url); + try { + invariant(url, 'redirectTo must be called with a url') + + if (/^(https?:)\/\//.test(url)) { + window.location.assign(url); + } else { + history.replace(url) + } + res.errMsg = 'redirectTo:ok' + return Promise.resolve(res) + } catch (e) { + res.errMsg = `redirectTo:fail ${e.message}` + return Promise.reject(res) } + } +} + +const createReLaunch = (history: History) => { + return function ({ url }) { + const res: Result = {} try { + history.go(-(history.length - 1)) history.replace(url) - return Promise.resolve() + res.errMsg = 'reLaunch:ok' + return Promise.resolve(res) } catch (e) { - return Promise.reject() + res.errMsg = `reLaunch:fail ${e.message}` + return Promise.reject(res) } } } -export { createNavigateTo, createNavigateBack, createRedirectTo } +export { createNavigateTo, createNavigateBack, createRedirectTo, createReLaunch } diff --git a/packages/taro-router/src/history/__mocks__/createHashHistory.ts b/packages/taro-router/src/history/__mocks__/createHistory.ts similarity index 67% rename from packages/taro-router/src/history/__mocks__/createHashHistory.ts rename to packages/taro-router/src/history/__mocks__/createHistory.ts index e85daf2d5d4a..d00f6b2826a1 100644 --- a/packages/taro-router/src/history/__mocks__/createHashHistory.ts +++ b/packages/taro-router/src/history/__mocks__/createHistory.ts @@ -1,9 +1,11 @@ -import { History } from '../../utils/types'; +import Taro from '@tarojs/taro-h5' + +import { History } from '../../utils/types' const initLocation = { hash: "", params: {}, - pathname: "/", + path: "/pages/index/index", search: "", state: {key: "0"} } @@ -26,6 +28,7 @@ const notify = (opts) => { }) } +Taro._set$router(initLocation) const history = { listen, @@ -33,4 +36,6 @@ const history = { notify } -export default () => history +export default () => { + return history +} diff --git a/packages/taro-router/src/router/router.tsx b/packages/taro-router/src/router/router.tsx index fabaa5a06afe..c6a579e684b9 100644 --- a/packages/taro-router/src/router/router.tsx +++ b/packages/taro-router/src/router/router.tsx @@ -4,7 +4,7 @@ import invariant from 'invariant'; import toPairs from 'lodash/toPairs'; import assign from 'lodash/assign'; -import { createNavigateBack, createNavigateTo, createRedirectTo } from '../apis'; +import { createNavigateBack, createNavigateTo, createRedirectTo, createReLaunch } from '../apis'; import Route from './route'; import * as Types from '../utils/types'; @@ -39,6 +39,7 @@ class Router extends Component { Taro.navigateTo = createNavigateTo(this.props.history) Taro.navigateBack = createNavigateBack(this.props.history) Taro.redirectTo = createRedirectTo(this.props.history) + Taro.reLaunch = createReLaunch(this.props.history) Taro.getCurrentPages = () => { return this.currentPages } diff --git a/packages/taro-router/src/utils/types.ts b/packages/taro-router/src/utils/types.ts index 6ed42e9f7b6b..685292346ce0 100644 --- a/packages/taro-router/src/utils/types.ts +++ b/packages/taro-router/src/utils/types.ts @@ -20,7 +20,7 @@ export interface RouteObj { path: Path; componentLoader: ComponentLoader; isIndex: boolean; - isRedirect: boolean; + isRedirect?: boolean; key?: string; } diff --git a/packages/taro-router/tsconfig.json b/packages/taro-router/tsconfig.json index 24ac33c3e63d..4cf451470c8c 100644 --- a/packages/taro-router/tsconfig.json +++ b/packages/taro-router/tsconfig.json @@ -3,6 +3,7 @@ "allowSyntheticDefaultImports": true, "allowJs": true, "baseUrl": ".", + "esModuleInterop": true, "experimentalDecorators": true, "jsx": "react", "jsxFactory": "Nerv.createElement", @@ -18,9 +19,13 @@ "sourceMap": false, "strictNullChecks": true, "target": "es2015", - "traceResolution": false + "traceResolution": false, + "types": ["jest"] }, "include": [ "./src" + ], + "excludee": [ + "./src/__tests__/" ] }