Skip to content

Commit

Permalink
fix(sync): support scoped package typings
Browse files Browse the repository at this point in the history
  • Loading branch information
jeffijoe committed Oct 10, 2017
1 parent fccbf69 commit 213bb32
Show file tree
Hide file tree
Showing 16 changed files with 259 additions and 176 deletions.
4 changes: 4 additions & 0 deletions .prettierrc
@@ -0,0 +1,4 @@
{
"semi": false,
"singleQuote": true
}
25 changes: 13 additions & 12 deletions .vscode/settings.json
@@ -1,13 +1,14 @@
// Place your settings in this file to overwrite default and user settings.
{
"files.exclude": {
"**/.git": true,
"**/.svn": true,
"**/.hg": true,
"**/CVS": true,
"**/.DS_Store": true,
"node_modules": true,
"coverage": true,
"lib": true
}
}
// Place your settings in this file to overwrite default and user settings.
"editor.formatOnSave": true,
"files.exclude": {
"**/.git": true,
"**/.svn": true,
"**/.hg": true,
"**/CVS": true,
"**/.DS_Store": true,
"node_modules": true,
"coverage": true,
"lib": true
}
}
46 changes: 22 additions & 24 deletions package.json
Expand Up @@ -5,27 +5,30 @@
"engines": {
"node": ">=6.0.0"
},
"files": [
"lib",
"bin"
],
"files": ["lib", "bin"],
"bin": {
"typesync": "./bin/typesync"
},
"main": "lib/index.js",
"scripts": {
"clean": "rimraf lib",
"test": "jest",
"lint": "tslint 'src/**/*.ts'",
"lint": "tslint --fix 'src/**/*.ts' && yarn format",
"format": "prettier --write 'src/**/*.ts'",
"lint:watch": "nodemon --exec npm run lint -e ts,js",
"cover": "jest --coverage",
"coveralls": "jest --coverage && cat ./coverage/lcov.info | coveralls",
"build": "rimraf lib && tsc -p tsconfig.build.json --sourceMap --declaration",
"build":
"rimraf lib && tsc -p tsconfig.build.json --sourceMap --declaration",
"run-cli": "npm run build && node bin/typesync",
"do:publish": "npm run lint && npm run cover && npm run build && npm publish",
"release:patch": "npm version patch && npm run do:publish && git push --follow-tags",
"release:minor": "npm version minor && npm run do:publish && git push --follow-tags",
"release:prerelease": "npm version prerelease && npm run do:publish && git push --follow-tags"
"do:publish":
"npm run lint && npm run cover && npm run build && npm publish",
"release:patch":
"npm version patch && npm run do:publish && git push --follow-tags",
"release:minor":
"npm version minor && npm run do:publish && git push --follow-tags",
"release:prerelease":
"npm version prerelease && npm run do:publish && git push --follow-tags"
},
"repository": {
"type": "git",
Expand All @@ -40,16 +43,19 @@
"devDependencies": {
"@types/chalk": "^0.4.31",
"@types/detect-indent": "^5.0.0",
"@types/lodash": "^4.14.76",
"@types/node": "^8.0.31",
"@types/jest": "^21.1.2",
"@types/lodash": "^4.14.77",
"@types/node": "^8.0.33",
"@types/ora": "^1.3.1",
"@types/rimraf": "^2.0.2",
"coveralls": "^3.0.0",
"jest": "^21.2.1",
"nodemon": "^1.12.1",
"prettier": "^1.7.4",
"rimraf": "^2.6.2",
"ts-jest": "^21.0.1",
"ts-jest": "^21.1.1",
"tslint": "^5.7.0",
"tslint-config-prettier": "^1.5.0",
"tslint-config-standard": "^6.0.1",
"typescript": "^2.5.3"
},
Expand All @@ -63,21 +69,13 @@
"!src/fakes.ts",
"!src/types.ts"
],
"coveragePathIgnorePatterns": [
"/node_modules/"
],
"coveragePathIgnorePatterns": ["/node_modules/"],
"transform": {
".(ts|tsx)": "<rootDir>/node_modules/ts-jest/preprocessor.js"
},
"testRegex": "(/__tests__/.*\\.(test|spec))\\.(ts|tsx|js)$",
"testPathIgnorePatterns": [
"/lib/"
],
"moduleFileExtensions": [
"ts",
"tsx",
"js"
]
"testPathIgnorePatterns": ["/lib/"],
"moduleFileExtensions": ["ts", "tsx", "js"]
},
"dependencies": {
"awilix": "^2.8.1",
Expand Down
32 changes: 19 additions & 13 deletions src/__tests__/package-json-file-service.test.ts
Expand Up @@ -19,8 +19,9 @@ describe('package json file service', () => {

it('throws when file does not exist', async () => {
expect.assertions(1)
await subject.readPackageFile('nonexistent.json')
.catch((err) => expect(err.message).toMatch(/exist/i))
await subject
.readPackageFile('nonexistent.json')
.catch(err => expect(err.message).toMatch(/exist/i))
})
})

Expand Down Expand Up @@ -76,18 +77,23 @@ describe('package json file service', () => {
})
})

function _writeFixture (withTrailingNewline = false): Promise<string> {
function _writeFixture(withTrailingNewline = false): Promise<string> {
const file = path.join(os.tmpdir(), `package-${Math.random()}.json`)
return writeFileAsync(file, JSON.stringify({
name: 'fony-package',
dependencies: {
package1: '^1.0.0'
}
}, null, 2) + (withTrailingNewline ? '\n' : '')).then(() => file)
return writeFileAsync(
file,
JSON.stringify(
{
name: 'fony-package',
dependencies: {
package1: '^1.0.0'
}
},
null,
2
) + (withTrailingNewline ? '\n' : '')
).then(() => file)
}

function cleanup (...files: string[]): Promise<any> {
return Promise.all(
files.map(f => unlinkAsync(f))
)
function cleanup(...files: string[]): Promise<any> {
return Promise.all(files.map(f => unlinkAsync(f)))
}
58 changes: 39 additions & 19 deletions src/__tests__/type-syncer.test.ts
Expand Up @@ -7,19 +7,29 @@ import {
} from '../types'
import { createTypeSyncer } from '../type-syncer'

const typedefs: ITypeDefinition[] = [{
typingsName: 'package1'
}, {
typingsName: 'package2'
}, {
typingsName: 'package3'
}, {
typingsName: 'package4'
}, {
typingsName: 'package5'
}]
const typedefs: ITypeDefinition[] = [
{
typingsName: 'package1'
},
{
typingsName: 'package2'
},
{
typingsName: 'package3'
},
{
typingsName: 'package4'
},
{
typingsName: 'package5'
},
// None for package6
{
typingsName: 'myorg__package7'
}
]

function buildSyncer () {
function buildSyncer() {
const typedefSource: ITypeDefinitionSource = {
fetch: jest.fn(() => Promise.resolve(typedefs)),
getLatestTypingsVersion: jest.fn(() => Promise.resolve('1.0.0'))
Expand All @@ -38,39 +48,49 @@ function buildSyncer () {
'@types/package4': '^1.0.0',
package4: '^1.0.0',
package5: '^1.0.0'
},
optionalDependencies: {
package6: '^1.0.0'
},
peerDependencies: {
'@myorg/package7': '^1.0.0'
}
}

return {
typedefSource,
packageService,
packageFile,
syncer: createTypeSyncer(
packageService,
typedefSource
)
syncer: createTypeSyncer(packageService, typedefSource)
}
}

describe('type syncer', () => {
it('adds new packages to the package.json', async () => {
const { syncer, packageService, typedefSource } = buildSyncer()
const result = await syncer.sync('package.json')
const writtenPackage = (packageService.writePackageFile as jest.Mock<any>).mock.calls[0][1] as IPackageFile
const writtenPackage = (packageService.writePackageFile as jest.Mock<any>)
.mock.calls[0][1] as IPackageFile
expect(writtenPackage.devDependencies).toEqual({
'@types/package1': '^1.0.0',
'@types/package3': '^1.0.0',
'@types/package4': '^1.0.0',
'@types/package5': '^1.0.0',
'@types/myorg__package7': '^1.0.0',
package4: '^1.0.0',
package5: '^1.0.0'
})
expect(result.newTypings.map(x => x.typingsName).sort()).toEqual(['package1', 'package3', 'package5'])
expect(result.newTypings.map(x => x.typingsName).sort()).toEqual([
'myorg__package7',
'package1',
'package3',
'package5'
])
})

it('does not write packages if options.dry is specified', async () => {
const { syncer, packageService, typedefSource } = buildSyncer()
const result = await syncer.sync('package.json', { dry: true })
expect((packageService.writePackageFile as jest.Mock<any>)).not.toBeCalled()
expect(packageService.writePackageFile as jest.Mock<any>).not.toBeCalled()
})
})
24 changes: 14 additions & 10 deletions src/__tests__/util.test.ts
Expand Up @@ -9,18 +9,19 @@ describe('util', () => {

describe('filterMap', () => {
it('filters out false values', () => {
expect(filterMap(
[1, 2, 3, 4],
(item) => item % 2 === 0 ? false : item + 1
)).toEqual([2, 4])
expect(
filterMap([1, 2, 3, 4], item => (item % 2 === 0 ? false : item + 1))
).toEqual([2, 4])
})
})

describe('mergeObjects', () => {
it('merges an array of objects', () => {
expect(mergeObjects(
[{ a: 1 }, { b: 2 }, { a: 3 }, { c: 4 }]
)).toEqual({ a: 3, b: 2, c: 4 })
expect(mergeObjects([{ a: 1 }, { b: 2 }, { a: 3 }, { c: 4 }])).toEqual({
a: 3,
b: 2,
c: 4
})
})
})

Expand All @@ -36,7 +37,8 @@ describe('util', () => {

describe('promisify', () => {
it('resolves when the callback is successful', async () => {
const original = (arg1: any, arg2: any, cb: Function) => cb(null, arg1 + arg2)
const original = (arg1: any, arg2: any, cb: Function) =>
cb(null, arg1 + arg2)
const promisified = promisify(original)
const result = await promisified(2, 2)
expect(result).toBe(4)
Expand All @@ -50,14 +52,16 @@ describe('util', () => {
})

it('rejects when the callback is not successful', async () => {
const original = (arg1: any, arg2: any, cb: Function) => cb(new Error('oh shit'), null)
const original = (arg1: any, arg2: any, cb: Function) =>
cb(new Error('oh shit'), null)
const promisified = promisify(original)
const err = await promisified(2, 2).catch(err => err)
expect(err.message).toBe('oh shit')
})

it('rejects when the callback is not successful even if only passed 1 param', async () => {
const original = (arg1: any, arg2: any, cb: Function) => cb(new Error('oh shit'))
const original = (arg1: any, arg2: any, cb: Function) =>
cb(new Error('oh shit'))
const promisified = promisify(original)
const err = await promisified(2, 2).catch(err => err)
expect(err.message).toBe('oh shit')
Expand Down
10 changes: 5 additions & 5 deletions src/cli-util.ts
Expand Up @@ -7,23 +7,23 @@ const ora = require('ora')
* Like regular console.log, but better.
* @param message
*/
export function log (message: string) {
export function log(message: string) {
console.log(`${chalk.white('»')} ${chalk.gray(message)}`)
}

/**
* Makes success feel even sweeter.
* @param text
*/
export function success (text: string) {
export function success(text: string) {
console.log(`${chalk.green('✔')} ${chalk.white(text)}`)
}

/**
* Logs an error all pretty.
* @param err
*/
export function error (err: Error | string) {
export function error(err: Error | string) {
const msg = err instanceof Error ? err.message : err
const stack = err instanceof Error ? `\nStack:\n${err.stack}` : ''
console.log(`${chalk.red('✖')} ${chalk.bgRed(chalk.white(msg))}${stack}`)
Expand All @@ -34,7 +34,7 @@ export function error (err: Error | string) {
* @param text
* @param fn
*/
export async function spinWhile<T> (text: string, fn: () => Promise<T>) {
export async function spinWhile<T>(text: string, fn: () => Promise<T>) {
const spinner = ora(' ' + chalk.gray(text)).start()
try {
return await fn()
Expand All @@ -47,7 +47,7 @@ export async function spinWhile<T> (text: string, fn: () => Promise<T>) {
* Super simple argument parser.
* @param argv
*/
export function parseArguments (argv: Array<string>): ICLIArguments {
export function parseArguments(argv: Array<string>): ICLIArguments {
const flags: { [key: string]: boolean } = {}
const args: Array<string> = []
for (const arg of argv) {
Expand Down

0 comments on commit 213bb32

Please sign in to comment.