1 | const path = require('path')
|
2 | const fs = require('fs')
|
3 | const R = require('ramda')
|
4 | const { Either } = require('monet')
|
5 | const debug = require('debug')('spdt')
|
6 | const { getConfig } = require('./config')
|
7 |
|
8 |
|
9 | function recFindByExt(base, ext, files, result) {
|
10 | files = files || fs.readdirSync(base)
|
11 | result = result || []
|
12 |
|
13 | files.forEach((file) => {
|
14 | const newbase = path.join(base, file)
|
15 | if (fs.statSync(newbase).isDirectory()) {
|
16 | result = recFindByExt(newbase, ext, fs.readdirSync(newbase), result)
|
17 | } else {
|
18 |
|
19 | if (file.substr(-1 * (ext.length + 1)) === `.${ext}`) {
|
20 | result.push(newbase)
|
21 | }
|
22 | }
|
23 | })
|
24 | return result
|
25 | }
|
26 |
|
27 |
|
28 |
|
29 | const convertToRelative = R.curry((from, file) => path.relative(from, file))
|
30 | const generateCode = (file) => `require('${file}').default(
|
31 | storyGenerator,
|
32 | )`
|
33 |
|
34 | const requireStoryBookGenerator = `const {storyGenerator} = require('spdt')
|
35 | `
|
36 |
|
37 | function generateContentForStoryIndex(pathToSrc, pathToStories) {
|
38 | const fileList = recFindByExt(pathToSrc, 'story.js')
|
39 |
|
40 | const convertAndGenerate = R.compose(
|
41 | generateCode,
|
42 | convertToRelative(pathToStories),
|
43 | )
|
44 | const generatedCode = fileList.map(convertAndGenerate).join('\n')
|
45 | const content = requireStoryBookGenerator.concat(generatedCode, '\n')
|
46 | return {
|
47 | fileList,
|
48 | content,
|
49 | }
|
50 | }
|
51 |
|
52 | function writeFile(file, content) {
|
53 | try {
|
54 | fs.writeFileSync(file, content)
|
55 | return Either.Right(true)
|
56 | } catch (err) {
|
57 | return Either.Left(err)
|
58 | }
|
59 | }
|
60 |
|
61 | function generateStoryIndex(pathToSrc, pathToStories) {
|
62 | const config = getConfig()
|
63 | pathToSrc = pathToSrc || config.pathToSrc
|
64 | pathToStories = pathToStories || config.pathToStories
|
65 | debug(`generateStoryIndex config=${JSON.stringify(config)}`)
|
66 |
|
67 | const { content, fileList } = generateContentForStoryIndex(pathToSrc, pathToStories)
|
68 | const either = writeFile(`${pathToStories}/index.js`, content)
|
69 | return either.isLeft() ? either : Either.Right(fileList)
|
70 | }
|
71 |
|
72 |
|
73 | const requireTestGenerator = `const {testGenerator} = require('spdt/lib/test-generator')
|
74 | `
|
75 |
|
76 | const replaceStoryToFixture = (file) => file.replace('.story.', '.fixture.')
|
77 |
|
78 | const generateTestCode = (config, index) => `
|
79 | const fixtures${index} = require('${config.pathToFixture}')
|
80 | .default
|
81 |
|
82 | testGenerator({
|
83 | fixtures: fixtures${index},
|
84 | file: '${config.pathToFile}',
|
85 | componentName: '${config.componentName}',
|
86 | })
|
87 | `
|
88 |
|
89 | function capitalize(str) {
|
90 | const capitalizer = R.compose(
|
91 | R.join(''),
|
92 | R.juxt([
|
93 | R.compose(
|
94 | R.toUpper,
|
95 | R.head,
|
96 | ),
|
97 | R.tail,
|
98 | ]),
|
99 | )
|
100 |
|
101 | return R.ifElse(R.equals(null), R.identity, capitalizer)(str)
|
102 | }
|
103 |
|
104 | function toPascalCase(str) {
|
105 | const compose = R.compose(
|
106 | R.join(''),
|
107 | R.map(capitalize),
|
108 | R.split(/-|_|\s/),
|
109 | )
|
110 | return compose(str)
|
111 | }
|
112 |
|
113 | const getFileName = R.compose(
|
114 | toPascalCase,
|
115 | R.head,
|
116 | R.split('.'),
|
117 | R.last,
|
118 | R.split('/'),
|
119 | )
|
120 |
|
121 | function generateContentForTestIndex(pathToSrc, pathToTestIndex) {
|
122 | const fileList = recFindByExt(pathToSrc, 'story.js')
|
123 |
|
124 | const convertToRelativeFromTestIndex = convertToRelative(pathToTestIndex)
|
125 |
|
126 | const convertToConfig = (file) => ({
|
127 | pathToFixture: replaceStoryToFixture(convertToRelativeFromTestIndex(file)),
|
128 | pathToFile: convertToRelativeFromTestIndex(file),
|
129 | componentName: getFileName(file),
|
130 | })
|
131 |
|
132 | const convertAndGenerateTestCode = (file, index) => generateTestCode(convertToConfig(file), index)
|
133 |
|
134 | const e2eGeneratorContent = fileList.map(convertAndGenerateTestCode).join('')
|
135 | const content = requireTestGenerator.concat(e2eGeneratorContent)
|
136 | return {
|
137 | fileList,
|
138 | content,
|
139 | }
|
140 | }
|
141 |
|
142 | function generateTestIndex(pathToSrc, pathToTestIndex) {
|
143 | const config = getConfig()
|
144 | pathToSrc = pathToSrc || config.pathToSrc
|
145 | pathToTestIndex = pathToTestIndex || config.pathToTestIndex
|
146 | debug(`generateTestIndex config=${JSON.stringify(config)}`)
|
147 |
|
148 | const { content, fileList } = generateContentForTestIndex(pathToSrc, pathToTestIndex)
|
149 | const either = writeFile(`${pathToTestIndex}/${config.testIndexName}`, content)
|
150 | return either.isLeft() ? either : Either.Right(fileList)
|
151 | }
|
152 |
|
153 |
|
154 | module.exports = {
|
155 | capitalize,
|
156 | generateContentForStoryIndex,
|
157 | generateContentForTestIndex,
|
158 | generateStoryIndex,
|
159 | generateTestIndex,
|
160 | toPascalCase,
|
161 | }
|