Skip to content

Commit

Permalink
feat: add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
hosseinmd committed Nov 19, 2021
1 parent ad18124 commit 3ac5466
Show file tree
Hide file tree
Showing 4 changed files with 348 additions and 1 deletion.
2 changes: 1 addition & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ module.exports = {
prefix: ["is", "should", "has", "can", "did", "will"],
filter: {
// you can expand this regex to add more allowed names
regex: "^([_]+[A-Z]+[_]+)$",
regex: "^[_]+.*$",
match: false,
},
},
Expand Down
185 changes: 185 additions & 0 deletions packages/core/src/tests/atomicStructure.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
import { parse } from "@babel/parser";
import babelTraverse, { Node, VisitNode } from "@babel/traverse";
import fs from "fs";
import { join, resolve } from "path";

/**
* Check AST tree for any (j|tsx?) files and set a file references for any
* import, require or dynamic import files.
*/
const parseFileASTTree = (
file: string,
importDeclaration: VisitNode<Node, any>,
) =>
babelTraverse(
parse(file, {
sourceType: "module",
plugins: [
"optionalChaining",
"classProperties",
"decorators-legacy",
"exportDefaultFrom",
"doExpressions",
"numericSeparator",
"dynamicImport",
"jsx",
"typescript",
],
}),
{
// Used for all ES6 import statements
ImportDeclaration: importDeclaration,
},
);

const components = [
"atoms",
"molecules",
"muscles",
"organisms",
"templates",
"pages",
];

const resolver = (...dirs: string[]) => resolve(__dirname, `../`, ...dirs);

function readRoot() {
return fs.readdirSync(resolver(""));
}

function getIndex(atomicName: string) {
return components.indexOf(atomicName);
}

function throwError(
value: string,
componentDir: string,
file: string,
line?: number,
) {
const lineInfo = line === undefined ? "" : `:${line}:0`;
const error = new Error(
`(Atomic Rules): ${
line ? "import" : "Position"
} is not correct in ${componentDir
.split(/[\\?]/)
.join("/")}/${file}${lineInfo} path at line ${value}
${componentDir}`,
);

error.stack = `Error:\nat (${resolver(componentDir, file)}${lineInfo})\n`;
test(componentDir, () =>
expect(() => {
throw error;
}).not.toThrow(),
);
}

function recursiveChecker(componentDir: string, atomicName: string) {
let isCorrectPosition = false;

const files = fs.readdirSync(resolver(componentDir));
files.forEach((file) => {
if (fs.lstatSync(resolver(componentDir, file)).isDirectory()) {
const _isCorrectPosition = recursiveChecker(
join(componentDir, file),
atomicName,
);
if (_isCorrectPosition) {
isCorrectPosition = true;
}
return;
}

if (!file.match(/(jsx?|tsx?)$/g)) {
return;
}

const content = fs.readFileSync(resolver(componentDir, file)).toString();
if (content.startsWith("//ignore-atomic")) return;

try {
parseFileASTTree(content, (path) => {
if (!path.node.source.value?.startsWith(".")) {
return;
}
const line = path.node.source.loc.start.line;

if (
join(componentDir, path.node.source.value).startsWith(atomicName) &&
!join(componentDir, path.node.source.value).startsWith(
join(...componentDir.split("\\").join("/").split("/").slice(0, 2)),
)
) {
throwError(path.node.source.value, componentDir, file, line);
return;
}

components.slice(getIndex(atomicName) + 1).forEach((topDir) => {
if (join(componentDir, path.node.source.value).startsWith(topDir)) {
throwError(path.node.source.value, componentDir, file, line);
}
});

if (
(components[getIndex(atomicName) - 1] &&
join(componentDir, path.node.source.value).startsWith(
components[getIndex(atomicName) - 1],
)) ||
join(componentDir, path.node.source.value).startsWith(
components[getIndex(atomicName)],
)
) {
isCorrectPosition = true;
}
});
} catch (error) {
(error as any).stack = `Error:\nat (${resolver(componentDir, file)})\n`;

test(componentDir, () =>
expect(() => {
throw error;
}).not.toThrow(),
);
}
});

return isCorrectPosition;
}

function check() {
describe("Atomic design structure", () => {
const atomicsDirs = readRoot();
atomicsDirs.forEach((atomicDir) => {
if (
getIndex(atomicDir) !== -1 &&
fs.lstatSync(resolver(atomicDir)).isDirectory()
) {
const componentsDirs = fs.readdirSync(resolver(atomicDir));
componentsDirs.forEach((componentDir) => {
if (fs.lstatSync(resolver(atomicDir, componentDir)).isFile()) {
return;
}

const isCorrectPosition = recursiveChecker(
join(atomicDir, componentDir),
atomicDir,
);

if (
!isCorrectPosition &&
components[getIndex(atomicDir)] !== "pages" &&
components[getIndex(atomicDir)] !== "atoms"
) {
throwError("", atomicDir, componentDir);
}
});
}
});
it("fake", () => {
expect(true).toBe(true);
});
});
}

export { check };
98 changes: 98 additions & 0 deletions packages/core/src/tests/jssStructure.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import fs from "fs";
import { join, resolve } from "path";

const components = [
"atoms",
"molecules",
"muscles",
"organisms",
"templates",
"pages",
];

const resolver = (...dirs: string[]) => resolve(__dirname, `../`, ...dirs);

function readRoot() {
return fs.readdirSync(resolver(""));
}

function getIndex(atomicName: string) {
return components.indexOf(atomicName);
}

function throwError(
value: string,
componentDir: string,
file: string,
atomicName: string,
) {
const error = new Error(
`(jss Rules): generateIndex parameter is not correct in ${componentDir
.split(/[\\?]/)
.join("/")}/${file} ${value}
expected to be => ${atomicName}`,
);

error.stack = `Error:\nat (${resolver(componentDir, file)})\n`;
test(componentDir, () =>
expect(() => {
throw error;
}).not.toThrow(),
);
}

function recursiveChecker(componentDir: string, atomicName: string) {
const files = fs.readdirSync(resolver(componentDir));
files.forEach((file) => {
if (fs.lstatSync(resolver(componentDir, file)).isDirectory()) {
recursiveChecker(join(componentDir, file), atomicName);

return;
}

if (!file.match(/(jsx?|tsx?)$/g)) {
return;
}

const content = fs.readFileSync(resolver(componentDir, file)).toString();

if (content.includes("generateIndex")) {
if (content.includes(`generateIndex("${atomicName}")`)) {
return;
} else {
throwError("", componentDir, file, atomicName);
// throw new Error(
// `generateIndex parameter is wrong at ${componentDir} expected to be *${atomicName}*`,
// );
}
} else {
return;
}
});
}

function check() {
const atomicsDirs = readRoot();
describe("jss design structure", () => {
atomicsDirs.forEach((atomicDir) => {
if (
getIndex(atomicDir) !== -1 &&
fs.lstatSync(resolver(atomicDir)).isDirectory()
) {
const componentsDirs = fs.readdirSync(resolver(atomicDir));
componentsDirs.forEach((componentDir) => {
if (fs.lstatSync(resolver(atomicDir, componentDir)).isFile()) {
return;
}

recursiveChecker(join(atomicDir, componentDir), atomicDir);
});
}
});
it("fake", () => {
expect(true).toBe(true);
});
});
}

export { check };
64 changes: 64 additions & 0 deletions packages/core/src/tests/persianChars.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
//@ts-nocheck
import fs from "fs";
import path from "path";

const resolver = (...dirs: string[]) => path.resolve(__dirname, `../`, ...dirs);

function readRoot() {
return fs.readdirSync(resolver(""));
}
function recursiveChecker(componentDir: string) {
const files = fs.readdirSync(resolver(componentDir));
files.forEach((file) => {
if (fs.lstatSync(resolver(componentDir, file)).isDirectory()) {
recursiveChecker(resolver(componentDir, file));
return;
}
const content = fs.readFileSync(resolver(componentDir, file)).toString();

if (content.split("\n")[0].includes("//ignore-localize")) return;

content.split("\n").forEach((line, index) => {
const matched = line.match(/[آ-ی]/g);

if (matched) {
const error = new Error(
`An error occured in ${componentDir
.split(/[\\?]/)
.join("/")}/${file}:${index + 1}:0 path at line ${line}`,
);
error.stack = `Error:\nat (${resolver(componentDir, file)}:${
index + 1
}:0)\n`;
test(componentDir, () =>
expect(() => {
throw error;
}).not.toThrow(),
);
}
});
});
}

function checkPersian() {
describe("Persian Characters Localizing", () => {
const rootDirectories = readRoot();
rootDirectories.forEach((rootDirectory) => {
if (fs.lstatSync(resolver(rootDirectory)).isDirectory()) {
const componentsDirs = fs.readdirSync(resolver(rootDirectory));
componentsDirs.forEach((componentsDir) => {
if (fs.lstatSync(resolver(rootDirectory, componentsDir)).isFile()) {
return;
}
recursiveChecker(path.join(rootDirectory, componentsDir));
});
}
});

it("fake", () => {
expect(true).toBe(true);
});
});
}

export { checkPersian };

0 comments on commit 3ac5466

Please sign in to comment.