idlize
232 строки · 6.8 Кб
1/*
2* Copyright (c) 2022-2023 Huawei Device Co., Ltd.
3* Licensed under the Apache License, Version 2.0 (the "License");
4* you may not use this file except in compliance with the License.
5* You may obtain a copy of the License at
6*
7* http://www.apache.org/licenses/LICENSE-2.0
8*
9* Unless required by applicable law or agreed to in writing, software
10* distributed under the License is distributed on an "AS IS" BASIS,
11* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12* See the License for the specific language governing permissions and
13* limitations under the License.
14*/
15
16import * as path from 'path'
17import * as fs from 'fs'
18import { assert } from "chai"
19import * as child from "child_process"
20
21export function testsForDirectories(goldenDir: string, otherDir: string) {
22const files = collectFiles(goldenDir)
23console.log(files)
24
25return files.map(file => () => test(file, () => {
26const golden = path.resolve(goldenDir, file)
27const other = path.resolve(otherDir, file)
28assertEqualFiles(golden, other)
29}))
30}
31
32export function assertGeneratedEqualsGolden(filename: string) {
33const goldenFile = path.resolve("./test/golden", filename)
34const generatedFile = path.resolve("./test/generated", filename)
35return assertEqualFiles(goldenFile, generatedFile)
36}
37
38function assertEqualFiles(goldenFilePath: string, otherFilePath: string) {
39const golden = fs.readFileSync(goldenFilePath, "utf-8")
40const other = fs.readFileSync(otherFilePath, "utf-8")
41
42return assert.equal(golden, other)
43}
44
45export function collectFiles(root: string): string[] {
46if (!fs.existsSync(root)) {
47throw new Error(`No such directory ${root}`)
48}
49
50let files: string[] = []
51
52function traverse(directory: string) {
53const dirents = fs.readdirSync(directory, { withFileTypes: true }) as fs.Dirent[]
54
55dirents.forEach(dirent => {
56const name = dirent.name
57const fullPath = path.resolve(directory, name)
58
59if (dirent.isFile()) {
60const relative = path.relative(root, fullPath)
61files.push(relative)
62}
63if (dirent.isDirectory()) {
64traverse(fullPath)
65}
66})
67}
68traverse(root)
69return files
70}
71
72export function copy(from: string, to: string, files: string[],
73sourceToEts: boolean = false, erasePath: boolean = false, etsFileExtension: boolean = false, makeModule: boolean = false): string[] {
74
75let newFiles: string[] = []
76files.forEach(file => {
77if (!file.endsWith('.ts') && !file.endsWith('.ets')) {
78return
79}
80
81const fromPath = path.join(from, file)
82
83let content = fileContent(fromPath, sourceToEts)
84if (makeModule) {
85content += ' export {}'
86}
87
88let writePath = file
89if (erasePath) {
90writePath = writePath.split(path.sep).pop()!
91}
92writePath = path.join(to, writePath)
93writePath = etsFileExtension ? writePath.replace(".ts", ".ets") : writePath
94
95if (!fs.existsSync(writePath)) {
96newFiles.push(file)
97}
98forceWriteFile(writePath, content)
99})
100return newFiles
101}
102
103function fileContent(fromPath: string, isEts: boolean) {
104if (!isEts) {
105return fs.readFileSync(fromPath)
106}
107const module = require(fromPath)
108if (module?.source === undefined) {
109throw new Error(`Failed to runtime import ${fromPath}`)
110}
111
112return module.source
113}
114
115function forceWriteFile(filePath: string, content: string) {
116const folders = filePath.split(path.sep).slice(0, -1)
117
118forceWriteFolders(folders)
119
120fs.writeFileSync(filePath, content)
121}
122
123function forceWriteFolders(folders: string | string[]) {
124if (typeof(folders) == "string") {
125folders = folders.split(path.sep)
126}
127
128if (folders.length == 0) {
129return
130}
131folders.reduce((last, folder) => {
132const folderPath = last + path.sep + folder
133if (!fs.existsSync(folderPath)) {
134fs.mkdirSync(folderPath)
135}
136return folderPath
137})
138}
139
140class DirectoriesManager {
141
142private readonly root = this.initRoot()
143
144private initRoot() {
145const initDir = process.env.INIT_CWD
146if (initDir === undefined) {
147throw new Error(`Launch only from npm run`)
148}
149return initDir
150}
151
152constructor() {
153if (!this.root.includes('ets-plugin')) {
154throw new Error(`
155Launch only from subdirectory of koala-ui/ets-plugin
156`.trim())
157}
158this.root = this.root.split('ets-plugin')[0] + 'ets-plugin' // sets root to .../something/ets-plugin
159
160const dirs = [this.testsDir, this.goldenSpecificationDir, this.testPagesDir]
161dirs.forEach((dir) => {
162if (!fs.existsSync(dir)) {
163forceWriteFolders(dir)
164}
165})
166}
167
168get testsDir() {
169return path.resolve(this.root, './test/ets/specification')
170}
171
172get testPagesDir() {
173return path.resolve(this.root, './test/ets/specification/test/pages')
174}
175
176get goldenSpecificationDir() {
177return path.resolve(this.root, './test/golden/specification/')
178}
179
180get generatedDir() {
181return path.resolve(this.root, './test/generated/specification/')
182}
183
184private get repoPath() {
185return path.resolve(this.root, './test/specification/ets2bundle/')
186}
187
188getOrDownloadSpecificationTestsDir() {
189const dir = path.resolve(this.repoPath, './compiler/test/utForPartialUpdate')
190this.downloadDeveloptoolsEts2Bundle(dir)
191return dir
192}
193
194getOrDownloadSpecificationPagesDir() {
195const dir = path.resolve(this.repoPath, './compiler/test/pages')
196this.downloadDeveloptoolsEts2Bundle(dir)
197return dir
198}
199
200private downloadDeveloptoolsEts2Bundle(dir: string) {
201if (fs.existsSync(dir)) {
202console.log(`Found ${dir}, no need to download or patch`)
203return
204}
205
206const cloneTo = path.resolve(this.root, './test/specification/')
207
208if (!fs.existsSync(this.repoPath)) {
209this.run(
210cloneTo,
211`git clone --depth 1 https://_:bVGsDK-34ViNC37AZY5a@rnd-gitlab-msc.huawei.com/rus-os-team/koala-ui/ets2bundle.git`,
212)
213}
214
215this.run(
216this.repoPath,
217`git apply ../patches/*.patch`
218)
219
220if (!fs.existsSync(dir)) {
221throw new Error(`Somehow ${dir} still doesn't exist after cloning repo. Check developtoolsEts2Bundle files layout`)
222}
223}
224
225private run(where: string, ...commands: string[]) {
226commands.forEach(cmd =>
227child.execSync(`cd ${where} && ${cmd}`, { stdio: 'inherit' })
228)
229}
230}
231
232export const directoriesManager = new DirectoriesManager()
233