Skip to content
This repository was archived by the owner on Jan 24, 2025. It is now read-only.

Commit ee71ef8

Browse files
Jesper Orbrakannimer
authored andcommitted
(docz-core) handle props on windows (#1151)
* fix(docz-core): test for setting props on * fix(docz-core): use unix path for keys and fast glob * fix(docz-core): normalize and use unix path on keys in props parser * chore(docz-core): move test helpers out of test folder * chore(e2e-tests): add test for checking props * fix(docz-core): use regular path in filesmap and update e2e test
1 parent 6348cb9 commit ee71ef8

File tree

14 files changed

+266
-24
lines changed

14 files changed

+266
-24
lines changed
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
---
2+
name: Alert
3+
menu: Components
4+
---
5+
6+
import { Playground, Props } from 'docz'
7+
import { Alert } from './Alert'
8+
9+
# Alert
10+
11+
## Properties
12+
13+
<Props of={Alert} />
14+
15+
## Basic usage
16+
17+
<Playground>
18+
<Alert>Some message</Alert>
19+
</Playground>
20+
21+
## Using different kinds
22+
23+
<Playground>
24+
<Alert kind="info">Some message</Alert>
25+
<Alert kind="positive">Some message</Alert>
26+
<Alert kind="negative">Some message</Alert>
27+
<Alert kind="warning">Some message</Alert>
28+
</Playground>
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import React, { SFC } from 'react'
2+
import styled from '@emotion/styled'
3+
4+
export type Kind = 'info' | 'positive' | 'negative' | 'warning'
5+
export type KindMap = Record<Kind, string>
6+
7+
const kinds: KindMap = {
8+
info: '#5352ED',
9+
positive: '#2ED573',
10+
negative: '#FF4757',
11+
warning: '#FFA502',
12+
}
13+
14+
export interface AlertProps {
15+
/**
16+
* Set this to change alert kind
17+
* @default info
18+
*/
19+
kind: 'info' | 'positive' | 'negative' | 'warning'
20+
}
21+
22+
const AlertStyled = styled('div')<AlertProps>`
23+
padding: 15px 20px;
24+
background: white;
25+
border-radius: 3px;
26+
color: white;
27+
background: ${({ kind = 'info' }) => kinds[kind]};
28+
`
29+
30+
export const Alert: SFC<AlertProps> = ({ kind, ...props }) => (
31+
<AlertStyled {...props} kind={kind} />
32+
)

core/docz-core/__fixtures__/Label.jsx

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import React from 'react'
2+
import t from 'prop-types'
3+
4+
const Label = ({ text, ...props }) => (
5+
<div className="label" {...props}>
6+
{text}
7+
</div>
8+
)
9+
10+
Label.propTypes = {
11+
/** A nice string */
12+
text: t.string,
13+
}
14+
15+
export default Label

core/docz-core/__fixtures__/Label.tsx

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import React, { SFC } from 'react'
2+
3+
export interface LabelProps {
4+
/**
5+
* Set this to do the thing
6+
* @default info
7+
*/
8+
text: string
9+
}
10+
11+
const Label: SFC<LabelProps> = ({ text, ...props }) => (
12+
<div className="label" {...props}>
13+
{text}
14+
</div>
15+
)
16+
17+
export default Label
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { Entries } from '../src/lib/Entries'
2+
import { getTestConfig } from '../src/test-utils'
3+
4+
describe('Entries', () => {
5+
test('get entries', async () => {
6+
const config = getTestConfig()
7+
const entries = new Entries(config)
8+
expect(entries).toBeTruthy()
9+
})
10+
})
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
import * as fs from 'fs-extra'
2+
import { getPattern, initial } from '../src/states/props'
3+
import { readCacheFile } from '../src/utils/docgen/typescript'
4+
import { getTestConfig, mockedParams } from '../src/test-utils'
5+
6+
describe('props', () => {
7+
beforeEach(() => {
8+
if (fs.existsSync('./.docz/.cache/propsParser.json')) {
9+
fs.unlinkSync('./.docz/.cache/propsParser.json')
10+
}
11+
})
12+
13+
describe('typescript', () => {
14+
test('should set props from typescript files', async () => {
15+
const config = getTestConfig()
16+
const pattern = getPattern(config)
17+
const data = initial(config, pattern)
18+
const params = mockedParams()
19+
await data(params)
20+
expect(params.getState().props.length).toBeGreaterThan(0)
21+
})
22+
23+
test('should set correct key on parsed typescript files', async () => {
24+
const config = getTestConfig()
25+
const pattern = getPattern(config)
26+
const data = initial(config, pattern)
27+
const params = mockedParams()
28+
await data(params)
29+
const expectedFirstPropName = '__fixtures__/Label.tsx'
30+
const firstProp = params.getState().props[0]
31+
expect(firstProp.key).toEqual(expectedFirstPropName)
32+
expect(firstProp.value).toBeTruthy()
33+
})
34+
})
35+
36+
describe('javascript', () => {
37+
test('should set correct key on parsed javascript files', async () => {
38+
const config = getTestConfig({ typescript: undefined })
39+
const pattern = getPattern(config)
40+
const data = initial(config, pattern)
41+
const params = mockedParams()
42+
await data(params)
43+
const expectedFirstPropName = '__fixtures__/Label.jsx'
44+
const firstProp = params.getState().props[0]
45+
expect(firstProp.key).toEqual(expectedFirstPropName)
46+
expect(firstProp.value).toBeTruthy()
47+
})
48+
49+
test('should set props from javascript files', async () => {
50+
const config = getTestConfig({ typescript: undefined })
51+
const pattern = getPattern(config)
52+
const data = initial(config, pattern)
53+
const params = mockedParams()
54+
await data(params)
55+
expect(params.getState().props.length).toBeGreaterThan(0)
56+
})
57+
58+
test('should have props on javascript files', async () => {
59+
const config = getTestConfig({ typescript: undefined })
60+
const pattern = getPattern(config)
61+
const data = initial(config, pattern)
62+
const params = mockedParams()
63+
await data(params)
64+
const firstProp = params.getState().props[0]
65+
expect(firstProp.value[0].props).toBeTruthy()
66+
})
67+
})
68+
69+
describe('cache', () => {
70+
test('should have empty cache on start', async () => {
71+
const cache = readCacheFile()
72+
expect(cache).toBeNull()
73+
})
74+
75+
test('should set cache on loading props', async () => {
76+
const cache = readCacheFile()
77+
expect(cache).toBeNull()
78+
const config = getTestConfig()
79+
const pattern = getPattern(config)
80+
const data = initial(config, pattern)
81+
const params = mockedParams()
82+
await data(params)
83+
expect(readCacheFile()).not.toBeNull()
84+
})
85+
})
86+
})

core/docz-core/src/states/props.ts

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@ import { get, propEq } from 'lodash/fp'
66

77
import * as paths from '../config/paths'
88
import { Config } from '../config/argv'
9-
import { docgen } from '../utils/docgen'
9+
import { docgen, unixPath } from '../utils/docgen'
1010
import { WATCH_IGNORE } from './config'
1111

12-
const getPattern = (config: Config) => {
12+
export const getPattern = (config: Config) => {
1313
const {
1414
ignore,
1515
src: source,
@@ -21,12 +21,16 @@ const getPattern = (config: Config) => {
2121
const root = paths.getRootDir(config)
2222
const srcDir = path.resolve(root, searchPath)
2323
const src = path.relative(root, srcDir)
24+
const filesPattern = path.join(
25+
src,
26+
ts ? '**/*.{ts,tsx,js,jsx,mjs}' : '**/*.{js,jsx,mjs}'
27+
)
2428

2529
return ignore
2630
.map(entry => typeof entry === 'string' && `!**/${entry}`)
2731
.filter(Boolean)
2832
.concat([
29-
path.join(src, ts ? '**/*.{ts,tsx,js,jsx,mjs}' : '**/*.{js,jsx,mjs}'),
33+
unixPath(filesPattern),
3034
'!**/node_modules',
3135
'!**/doczrc.js',
3236
]) as string[]
@@ -35,10 +39,12 @@ const getPattern = (config: Config) => {
3539
const removeFilepath = (items: any[], filepath: string) =>
3640
items.filter((item: any) => item.key !== filepath)
3741

38-
const initial = (config: Config, pattern: string[]) => async (p: Params) => {
42+
export const initial = (config: Config, pattern: string[]) => async (
43+
p: Params
44+
) => {
3945
const { filterComponents } = config
4046
const cwd = paths.getRootDir(config)
41-
const files = await fastglob(pattern, { cwd })
47+
const files = await fastglob(pattern, { cwd, caseSensitiveMatch: false })
4248
const filtered = filterComponents ? filterComponents(files) : files
4349
const metadata = await docgen(filtered, config)
4450
p.setState('props', metadata)
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import * as paths from '../config/paths'
2+
import yargs from 'yargs'
3+
import { setArgs, Config } from '../config/argv'
4+
import { Params } from '../lib/DataServer'
5+
import { getBaseConfig } from '../config/docz'
6+
7+
export const mockedParams = (): Params => {
8+
let data: any = {}
9+
return {
10+
getState: () => data,
11+
setState: (key: string, value: string) => (data[key] = value),
12+
}
13+
}
14+
15+
export const mockedArgv = () => {
16+
const yargsArgs: any = {
17+
argv: {},
18+
//@ts-ignore
19+
option: jest.fn().mockImplementation((key, value) => {
20+
yargs.argv[value.alias ? value.alias : key] = value.default
21+
return yargs
22+
}),
23+
}
24+
const { argv } = setArgs(yargsArgs)
25+
return argv
26+
}
27+
28+
export const getTestConfig = (overrides?: Partial<Config>): Config => {
29+
const argv = mockedArgv()
30+
return {
31+
//@ts-ignore
32+
...getBaseConfig(argv),
33+
paths,
34+
typescript: true,
35+
src: './__fixtures__',
36+
...overrides,
37+
}
38+
}

core/docz-core/src/utils/docgen/index.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@ import * as paths from '../../config/paths'
44
import { Config } from '../../config/argv'
55
import { jsParser } from './javascript'
66
import { tsParser } from './typescript'
7+
import { normalize } from 'path'
8+
9+
export const unixPath = (src: string): string => {
10+
return normalize(src).replace(/\\/g, '/')
11+
}
712

813
export const docgen = async (files: string[], config: Config) => {
914
const cwd = paths.getRootDir(config)

core/docz-core/src/utils/docgen/javascript.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@ import * as path from 'path'
33
import logger from 'signale'
44
import externalProptypesHandler from './externalProptypesHandler'
55
import actualNameHandler from 'react-docgen-actual-name-handler'
6-
import reactDocgen from 'react-docgen'
6+
import * as reactDocgen from 'react-docgen'
77

88
import { Config } from '../../config/argv'
99
import { getRootDir } from '../../config/paths'
10+
import { unixPath } from '.'
1011

1112
const throwError = (err: any) => {
1213
logger.fatal(`Error parsing static types`)
@@ -29,7 +30,7 @@ export const jsParser = (files: string[], config: Config) => {
2930
try {
3031
const code = fs.readFileSync(fullpath, { encoding: 'utf-8' })
3132
const props = reactDocgen.parse(code, resolver, handlers)
32-
return { key: path.normalize(filepath), value: props }
33+
return { key: unixPath(filepath), value: props }
3334
} catch (err) {
3435
if (config.debug) throwError(err)
3536
return null

0 commit comments

Comments
 (0)