-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor: add tests and replace minimatch with picomatch (#248)
* test: add expo cli invocation tests * test: add expo manifest tests * test: add expo manifest plugin tests * test: add file path tests * refactor: replace `minimatch` with `picomatch` * refactor: mark `@expo/config-plugins` as test dependency * fix: do not return `null` for `./` as file directory
- Loading branch information
Showing
10 changed files
with
299 additions
and
23 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import { stub, type SinonStub } from 'sinon'; | ||
|
||
import * as spawn from '../../utils/spawn'; | ||
|
||
/** Mock spawn with a default empty device list response */ | ||
export function stubSpawn(result?: Partial<spawn.SpawnResult>) { | ||
const spawnStub = withSpawnResult(stub(spawn, 'spawn'), result); | ||
// @ts-expect-error | ||
spawnStub[Symbol.dispose] = () => spawnStub.restore(); | ||
return spawnStub as Disposable & typeof spawnStub; | ||
} | ||
|
||
export function withSpawnResult<T extends SinonStub>( | ||
spawnStub: T, | ||
result: Partial<spawn.SpawnResult> = {} | ||
) { | ||
spawnStub.returns(Promise.resolve(result)); | ||
return spawnStub; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
import { expect } from 'chai'; | ||
import { match } from 'sinon'; | ||
|
||
import { stubSpawn } from '../../__tests__/utils/spawn'; | ||
import { spawnExpoCli } from '../cli'; | ||
|
||
describe('spawnExpoCli', () => { | ||
it('executes spawn with `npx expo` command', async () => { | ||
using spawn = stubSpawn(); | ||
|
||
await spawnExpoCli('whoami', ['--json'], { stdio: 'inherit' }); | ||
|
||
expect(spawn).to.be.calledWith( | ||
'npx', | ||
match(['expo', 'whoami', '--json']), | ||
match({ stdio: 'inherit' }) | ||
); | ||
}); | ||
|
||
it('returns the output of spawned process', async () => { | ||
using _spawn = stubSpawn({ stdout: 'testuser' }); | ||
|
||
expect(await spawnExpoCli('whoami')).to.equal('testuser'); | ||
}); | ||
|
||
it('forces expo in non-interactive mode', async () => { | ||
using spawn = stubSpawn(); | ||
|
||
await spawnExpoCli('whoami'); | ||
|
||
expect(spawn).to.be.calledWith( | ||
'npx', | ||
match(['expo', 'whoami']), | ||
match({ env: match({ CI: 'true' }) }) | ||
); | ||
}); | ||
|
||
it('forces expo without telemetry', async () => { | ||
using spawn = stubSpawn(); | ||
|
||
await spawnExpoCli('whoami'); | ||
|
||
expect(spawn).to.be.calledWith( | ||
'npx', | ||
match(['expo', 'whoami']), | ||
match({ env: match({ EXPO_NO_TELEMETRY: 'true' }) }) | ||
); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
import { expect } from 'chai'; | ||
import picomatch from 'picomatch'; | ||
|
||
import { type ExpoConfig } from '../../packages/config'; | ||
import { manifestPattern, getFileReferences } from '../manifest'; | ||
|
||
describe('manifestPattern', () => { | ||
it('scheme is set to files', () => { | ||
expect(manifestPattern.scheme).to.equal('file'); | ||
}); | ||
|
||
it('language is set to json with comments', () => { | ||
expect(manifestPattern.language).to.equal('jsonc'); | ||
}); | ||
|
||
it('pattern includes all json variations of the Expo manifest', () => { | ||
const pattern = manifestPattern.pattern as string; | ||
const matcher = picomatch(pattern); | ||
|
||
expect(matcher('my-app/app.json')).to.be.true; | ||
expect(matcher('my-app/app.config.json')).to.be.true; | ||
}); | ||
}); | ||
|
||
describe('getFileReferences', () => { | ||
it('returns all local file references from manifest', () => { | ||
const manifest: ExpoConfig = { | ||
name: 'my-app', | ||
slug: 'my-app', | ||
icon: './assets/icon.png', | ||
splash: { | ||
image: '../assets/splash.png', | ||
backgroundColor: '#FFFFFF', | ||
resizeMode: 'cover', | ||
}, | ||
android: { | ||
adaptiveIcon: { | ||
foregroundImage: './assets/adaptive-icon.png', | ||
backgroundColor: '#FFFFFF', | ||
}, | ||
}, | ||
plugins: ['./plugins/local-plugin.js'], | ||
}; | ||
|
||
expect(getFileReferences(JSON.stringify({ expo: manifest }, null, 2))).to.deep.include.members([ | ||
{ filePath: './assets/icon.png', fileRange: { length: 17, offset: 71 } }, | ||
{ filePath: '../assets/splash.png', fileRange: { length: 20, offset: 123 } }, | ||
{ filePath: './assets/adaptive-icon.png', fileRange: { length: 26, offset: 286 } }, | ||
{ filePath: './plugins/local-plugin.js', fileRange: { length: 25, offset: 391 } }, | ||
]); | ||
}); | ||
}); |
Oops, something went wrong.