UNPKG

8.5 kBPlain TextView Raw
1import {
2 chalk,
3 fs,
4 PROJECT_CONFIG,
5 shouldUseCnpm,
6 shouldUseYarn
7} from '@tarojs/helper'
8import { exec } from 'child_process'
9import * as path from 'path'
10
11import { getPkgVersion } from '../util'
12import { run } from './utils'
13
14const runUpdate = run('update', ['commands/update'])
15const lastestVersion = getPkgVersion()
16
17jest.mock('child_process', () => {
18 const exec = jest.fn()
19 exec.mockReturnValue({
20 stdout: {
21 on () {}
22 },
23 stderr: {
24 on () {}
25 }
26 })
27 return {
28 __esModule: true,
29 exec
30 }
31})
32
33jest.mock('ora', () => {
34 const ora = jest.fn()
35 ora.mockReturnValue({
36 start () {
37 return {
38 stop () {},
39 warn () {},
40 succeed (){}
41 }
42 }
43 })
44 return ora
45})
46
47jest.mock('@tarojs/helper', () => {
48 const helper = jest.requireActual('@tarojs/helper')
49 const fs = helper.fs
50 return {
51 __esModule: true,
52 ...helper,
53 shouldUseCnpm: jest.fn(),
54 shouldUseYarn: jest.fn(),
55 chalk: {
56 red: jest.fn(),
57 green () {}
58 },
59 fs: {
60 ...fs,
61 writeJson: jest.fn()
62 }
63 }
64})
65
66jest.mock('latest-version', () => () => lastestVersion)
67
68function updatePkg (pkgPath: string, version: string) {
69 let packageMap = require(pkgPath)
70 packageMap = {
71 ...packageMap,
72 dependencies: {
73 ...packageMap.dependencies,
74 '@tarojs/shared': version,
75 '@tarojs/taro': version,
76 '@tarojs/cli': version,
77 '@tarojs/components': version,
78 '@tarojs/api': version,
79 '@tarojs/taro-h5': version,
80 '@tarojs/helper': version,
81 '@tarojs/taro-loader': version,
82 '@tarojs/mini-runner': version,
83 '@tarojs/react': version,
84 '@tarojs/router': version,
85 '@tarojs/runner-utils': version,
86 '@tarojs/runtime': version,
87 '@tarojs/service': version,
88 '@tarojs/webpack-runner': version,
89 '@tarojs/with-weapp': version,
90 '@tarojs/taroize': version,
91 '@tarojs/plugin-platform-weapp': version,
92 '@tarojs/plugin-platform-alipay': version,
93 '@tarojs/plugin-platform-swan': version,
94 '@tarojs/plugin-platform-tt': version,
95 '@tarojs/plugin-platform-jd': version,
96 '@tarojs/plugin-platform-qq': version,
97 '@tarojs/plugin-platform-h5': version
98 },
99 devDependencies: {
100 ...packageMap.devDependencies,
101 'babel-preset-taro': version,
102 'eslint-config-taro': version,
103 'babel-plugin-transform-taroapi': version,
104 'postcss-plugin-constparse': version,
105 'postcss-pxtransform': version
106 }
107 }
108 return packageMap
109}
110
111describe('update', () => {
112 const execMocked = (exec as unknown) as jest.Mock<any>
113 const shouldUseCnpmMocked = shouldUseCnpm as jest.Mock<any>
114 const shouldUseYarnMocked = shouldUseYarn as jest.Mock<any>
115 const writeJson = fs.writeJson as jest.Mock<any>
116
117 beforeEach(() => {
118 shouldUseCnpmMocked.mockReturnValue(false)
119 shouldUseYarnMocked.mockReturnValue(false)
120 })
121
122 afterEach(() => {
123 execMocked.mockClear()
124 shouldUseCnpmMocked.mockReset()
125 shouldUseYarnMocked.mockReset()
126 writeJson.mockClear()
127 })
128
129 it('should log errors', async () => {
130 const spy = jest.spyOn(console, 'log')
131 spy.mockImplementation(() => {})
132 await runUpdate('', {
133 options: {
134 npm: 'npm',
135 disableGlobalConfig: true
136 }
137 })
138 expect(spy).toBeCalledTimes(3)
139 spy.mockRestore()
140 })
141
142 it('should update self', async () => {
143 await runUpdate('', {
144 args: ['self'],
145 options: {
146 npm: 'npm',
147 disableGlobalConfig: true
148 }
149 })
150 expect(execMocked).toBeCalledWith(`npm i -g @tarojs/cli@${lastestVersion}`)
151 })
152
153 it('should update self using yarn', async () => {
154 shouldUseCnpmMocked.mockReturnValue(true)
155 await runUpdate('', {
156 args: ['self'],
157 options: {
158 npm: 'yarn',
159 disableGlobalConfig: true
160 }
161 })
162 expect(execMocked).toBeCalledWith(`yarn global add @tarojs/cli@${lastestVersion}`)
163 })
164
165 it('should update self using pnpm', async () => {
166 shouldUseCnpmMocked.mockReturnValue(true)
167 await runUpdate('', {
168 args: ['self'],
169 options: {
170 npm: 'pnpm',
171 disableGlobalConfig: true
172 }
173 })
174 expect(execMocked).toBeCalledWith(`pnpm add -g @tarojs/cli@${lastestVersion}`)
175 })
176
177 it('should update self using cnpm', async () => {
178 shouldUseCnpmMocked.mockReturnValue(true)
179 await runUpdate('', {
180 args: ['self'],
181 options: {
182 npm: 'cnpm',
183 disableGlobalConfig: true
184 }
185 })
186 expect(execMocked).toBeCalledWith(`cnpm i -g @tarojs/cli@${lastestVersion}`)
187 })
188
189 it('should update self to specific version', async () => {
190 const version = '3.0.0-beta.0'
191 await runUpdate('', {
192 args: ['self', version],
193 options: {
194 npm: 'npm',
195 disableGlobalConfig: true
196 }
197 })
198 expect(execMocked).toBeCalledWith(`npm i -g @tarojs/cli@${version}`)
199 })
200
201 it('should throw when there isn\'t a Taro project', async () => {
202 const chalkMocked = (chalk.red as unknown) as jest.Mock<any>
203 const exitSpy = jest.spyOn(process, 'exit')
204 const logSpy = jest.spyOn(console, 'log')
205 exitSpy.mockImplementation(() => {
206 throw new Error()
207 })
208 logSpy.mockImplementation(() => {})
209 try {
210 await runUpdate('', {
211 args: ['project'],
212 options: {
213 npm: 'npm',
214 disableGlobalConfig: true
215 }
216 })
217 } catch (error) {} // eslint-disable-line no-empty
218 expect(exitSpy).toBeCalledWith(1)
219 expect(chalkMocked).toBeCalledWith(`找不到项目配置文件 ${PROJECT_CONFIG},请确定当前目录是 Taro 项目根目录!`)
220 exitSpy.mockRestore()
221 logSpy.mockRestore()
222 })
223
224 it('should update project', async () => {
225 const appPath = path.resolve(__dirname, 'fixtures/default')
226 const pkgPath = path.join(appPath, 'package.json')
227 const packageMap = updatePkg(pkgPath, lastestVersion)
228
229 const logSpy = jest.spyOn(console, 'log')
230 logSpy.mockImplementation(() => {})
231
232 await runUpdate(appPath, {
233 args: ['project'],
234 options: {
235 npm: 'npm',
236 disableGlobalConfig: true
237 }
238 })
239 expect(writeJson.mock.calls[0][0]).toEqual(pkgPath)
240 expect(writeJson.mock.calls[0][1]).toEqual(packageMap)
241 expect(execMocked).toBeCalledWith('npm install')
242
243 logSpy.mockRestore()
244 })
245
246 it('should update project to specific version', async () => {
247 const version = '3.0.0-beta.4'
248 const appPath = path.resolve(__dirname, 'fixtures/default')
249 const pkgPath = path.join(appPath, 'package.json')
250 const packageMap = updatePkg(pkgPath, version)
251
252 const logSpy = jest.spyOn(console, 'log')
253 logSpy.mockImplementation(() => {})
254
255 await runUpdate(appPath, {
256 args: ['project', version],
257 options: {
258 npm: 'npm',
259 disableGlobalConfig: true
260 }
261 })
262 expect(writeJson.mock.calls[0][0]).toEqual(pkgPath)
263 expect(writeJson.mock.calls[0][1]).toEqual(packageMap)
264 expect(execMocked).toBeCalledWith('npm install')
265
266 logSpy.mockRestore()
267 })
268
269 it('should update project with yarn', async () => {
270 const appPath = path.resolve(__dirname, 'fixtures/default')
271
272 const logSpy = jest.spyOn(console, 'log')
273 logSpy.mockImplementation(() => {})
274 shouldUseYarnMocked.mockReturnValue(true)
275
276 await runUpdate(appPath, {
277 args: ['project'],
278 options: {
279 npm: 'yarn',
280 disableGlobalConfig: true
281 }
282 })
283 expect(execMocked).toBeCalledWith('yarn install')
284
285 logSpy.mockRestore()
286 })
287
288 it('should update project with pnpm', async () => {
289 const appPath = path.resolve(__dirname, 'fixtures/default')
290
291 const logSpy = jest.spyOn(console, 'log')
292 logSpy.mockImplementation(() => {})
293 shouldUseCnpmMocked.mockReturnValue(true)
294
295 await runUpdate(appPath, {
296 args: ['project'],
297 options: {
298 npm: 'pnpm',
299 disableGlobalConfig: true
300 }
301 })
302 expect(execMocked).toBeCalledWith('pnpm install')
303
304 logSpy.mockRestore()
305 })
306
307 it('should update project with cnpm', async () => {
308 const appPath = path.resolve(__dirname, 'fixtures/default')
309
310 const logSpy = jest.spyOn(console, 'log')
311 logSpy.mockImplementation(() => {})
312 shouldUseCnpmMocked.mockReturnValue(true)
313
314 await runUpdate(appPath, {
315 args: ['project'],
316 options: {
317 npm: 'cnpm',
318 disableGlobalConfig: true
319 }
320 })
321 expect(execMocked).toBeCalledWith('cnpm install')
322
323 logSpy.mockRestore()
324 })
325})