From 72cffefb55f92a1a36a32f5728006ad5388ba019 Mon Sep 17 00:00:00 2001 From: Guy Carmeli Date: Sat, 15 Jun 2024 16:32:28 +0300 Subject: [PATCH] Mock file path resolving in tests + reintroduce subgraph test --- .../rules/framework/pathResolver.ts | 8 ++++ .../eslint-plugin-obsidian/rules/index.ts | 4 +- .../ASTFunctions.ts | 9 ++-- .../{createFunction.ts => createRule.ts} | 8 +++- .../unresolvedProviderDependencies/index.ts | 43 +++++++++++-------- .../tests/stubs/PathResolverStub.ts | 14 ++++++ .../unresolvedDependencies.test.ts | 31 +++++++------ 7 files changed, 78 insertions(+), 39 deletions(-) create mode 100644 packages/eslint-plugin-obsidian/rules/framework/pathResolver.ts rename packages/eslint-plugin-obsidian/rules/unresolvedProviderDependencies/{createFunction.ts => createRule.ts} (85%) create mode 100644 packages/eslint-plugin-obsidian/tests/stubs/PathResolverStub.ts diff --git a/packages/eslint-plugin-obsidian/rules/framework/pathResolver.ts b/packages/eslint-plugin-obsidian/rules/framework/pathResolver.ts new file mode 100644 index 00000000..6273c7c7 --- /dev/null +++ b/packages/eslint-plugin-obsidian/rules/framework/pathResolver.ts @@ -0,0 +1,8 @@ +import type { RuleContext } from '@typescript-eslint/utils/ts-eslint'; +import path = require('path') ; + +export class PathResolver { + public resolve(context: RuleContext, relativeFilePath: string) { + return path.join(path.dirname(context.getFilename()), `${relativeFilePath}.ts`); + } +} \ No newline at end of file diff --git a/packages/eslint-plugin-obsidian/rules/index.ts b/packages/eslint-plugin-obsidian/rules/index.ts index 59fbbca7..4710f590 100644 --- a/packages/eslint-plugin-obsidian/rules/index.ts +++ b/packages/eslint-plugin-obsidian/rules/index.ts @@ -1,7 +1,7 @@ -const { unresolvedProviderDependencies } = require('./unresolvedProviderDependencies'); +const { unresolvedProviderDependenciesGenerator } = require('./unresolvedProviderDependencies'); module.exports = { rules: { - 'unresolved-provider-dependencies': unresolvedProviderDependencies, + 'unresolved-provider-dependencies': unresolvedProviderDependenciesGenerator(), }, }; diff --git a/packages/eslint-plugin-obsidian/rules/unresolvedProviderDependencies/ASTFunctions.ts b/packages/eslint-plugin-obsidian/rules/unresolvedProviderDependencies/ASTFunctions.ts index 372c1538..cc119508 100644 --- a/packages/eslint-plugin-obsidian/rules/unresolvedProviderDependencies/ASTFunctions.ts +++ b/packages/eslint-plugin-obsidian/rules/unresolvedProviderDependencies/ASTFunctions.ts @@ -1,8 +1,8 @@ import { TSESTree } from '@typescript-eslint/types'; -import * as fs from 'fs'; import { parse } from '@typescript-eslint/parser'; -import path = require('path') ; import type { RuleContext } from '@typescript-eslint/utils/ts-eslint'; +import * as fs from 'fs'; +import { PathResolver } from '../framework/pathResolver'; export type MessageIds = 'unresolved-provider-dependencies'; @@ -30,6 +30,7 @@ export function getDependenciesFromSubgraphs( imports: TSESTree.ImportDeclaration[], subGraphs:string[], context:RuleContext<'unresolved-provider-dependencies', []>, + pathResolver: PathResolver, ) { const paths:Record[] = []; const dependencies: string[] = []; @@ -42,8 +43,8 @@ export function getDependenciesFromSubgraphs( }); paths.forEach((el) => { // eslint-disable-next-line dot-notation - const filePath = path.join(path.dirname(context.getFilename()), `${el['path']}.ts`); - const fileContent = fs.readFileSync(filePath, 'utf8'); + const filePath = pathResolver.resolve(context, el['path']); + const fileContent = fs.readFileSync(filePath, { encoding: 'utf8'}); const fileAST = parse( fileContent, { diff --git a/packages/eslint-plugin-obsidian/rules/unresolvedProviderDependencies/createFunction.ts b/packages/eslint-plugin-obsidian/rules/unresolvedProviderDependencies/createRule.ts similarity index 85% rename from packages/eslint-plugin-obsidian/rules/unresolvedProviderDependencies/createFunction.ts rename to packages/eslint-plugin-obsidian/rules/unresolvedProviderDependencies/createRule.ts index 9670929d..7993f314 100644 --- a/packages/eslint-plugin-obsidian/rules/unresolvedProviderDependencies/createFunction.ts +++ b/packages/eslint-plugin-obsidian/rules/unresolvedProviderDependencies/createRule.ts @@ -8,8 +8,12 @@ import { getDecoratorName, getPropertyDeclarations, } from './ASTFunctions'; +import type { PathResolver } from '../framework/pathResolver'; -export function create(context: RuleContext<'unresolved-provider-dependencies', []>) { +export function create( + context: RuleContext<'unresolved-provider-dependencies', []>, + pathResolver: PathResolver, +) { const imports:TSESTree.ImportDeclaration[] = []; const dependencies:string[] = []; @@ -24,7 +28,7 @@ export function create(context: RuleContext<'unresolved-provider-dependencies', if (decoratorNames.includes('Graph')) { const subGraphs = getSubGraphs(decorators); if (subGraphs.length > 0) { - dependencies.push(...getDependenciesFromSubgraphs(imports, subGraphs, context)); + dependencies.push(...getDependenciesFromSubgraphs(imports, subGraphs, context, pathResolver)); } dependencies.push(...mapFunctions(node)); dependencies.push(...getPropertyDeclarations(node)); diff --git a/packages/eslint-plugin-obsidian/rules/unresolvedProviderDependencies/index.ts b/packages/eslint-plugin-obsidian/rules/unresolvedProviderDependencies/index.ts index b9db3e19..b2b24573 100644 --- a/packages/eslint-plugin-obsidian/rules/unresolvedProviderDependencies/index.ts +++ b/packages/eslint-plugin-obsidian/rules/unresolvedProviderDependencies/index.ts @@ -1,26 +1,33 @@ import { ESLintUtils, type TSESLint } from '@typescript-eslint/utils'; -import { create } from './createFunction'; +import type { RuleContext } from '@typescript-eslint/utils/ts-eslint'; +import { create } from './createRule'; +import { PathResolver } from '../framework/pathResolver'; + +type Rule = TSESLint.RuleModule<'unresolved-provider-dependencies', []>; const createRule = ESLintUtils.RuleCreator( (name) => `https://wix-incubator.github.io/obsidian/docs/documentation/meta/eslint#${name}`, ); -type Rule = TSESLint.RuleModule<'unresolved-provider-dependencies', []>; - - -export const unresolvedProviderDependencies: Rule = createRule({ - create, - name: 'unresolved-provider-dependencies', - meta: { - docs: { - description: 'Dependencies must be defined in the graph or its subgraphs.', - recommended: 'strict', +export const unresolvedProviderDependenciesGenerator = ( + pathResolver: PathResolver = new PathResolver(), +) => { + return createRule({ + create: (context: RuleContext<'unresolved-provider-dependencies', []>) => { + return create(context, pathResolver); }, - messages: { - 'unresolved-provider-dependencies': 'Dependency {{ dependencyName }} is unresolved.', + name: 'unresolved-provider-dependencies', + meta: { + docs: { + description: 'Dependencies must be defined in the graph or its subgraphs.', + recommended: 'strict', + }, + messages: { + 'unresolved-provider-dependencies': 'Dependency {{ dependencyName }} is unresolved.', + }, + schema: [], + type: 'problem', }, - schema: [], - type: 'problem', - }, - defaultOptions: [], -}); + defaultOptions: [], + }) satisfies Rule; +}; \ No newline at end of file diff --git a/packages/eslint-plugin-obsidian/tests/stubs/PathResolverStub.ts b/packages/eslint-plugin-obsidian/tests/stubs/PathResolverStub.ts new file mode 100644 index 00000000..adf1f46c --- /dev/null +++ b/packages/eslint-plugin-obsidian/tests/stubs/PathResolverStub.ts @@ -0,0 +1,14 @@ +import type { RuleContext } from '@typescript-eslint/utils/ts-eslint'; +import path = require('path') ; +import { PathResolver } from '../../rules/framework/pathResolver'; + +export class PathResolverStub implements PathResolver { + public resolve(context: RuleContext, relativeFilePath: string): string { + switch(relativeFilePath) { + case './subgraph': + return `${context.cwd}/tests/unresolvedProviderDependencies/testUtils/subgraph.ts`; + default: + return path.join(path.dirname(context.getFilename()), `${relativeFilePath}.ts`); + } + } +} \ No newline at end of file diff --git a/packages/eslint-plugin-obsidian/tests/unresolvedProviderDependencies/unresolvedDependencies.test.ts b/packages/eslint-plugin-obsidian/tests/unresolvedProviderDependencies/unresolvedDependencies.test.ts index 61311407..a502dd19 100644 --- a/packages/eslint-plugin-obsidian/tests/unresolvedProviderDependencies/unresolvedDependencies.test.ts +++ b/packages/eslint-plugin-obsidian/tests/unresolvedProviderDependencies/unresolvedDependencies.test.ts @@ -1,18 +1,23 @@ import { RuleTester } from '@typescript-eslint/rule-tester'; -import { validGraphSimple } from './testUtils/validGraphs'; -import { unresolvedProviderDependencies } from '../../rules/unresolvedProviderDependencies'; +import { validGraphSimple, validGraphWithSubgraph } from './testUtils/validGraphs'; +import { unresolvedProviderDependenciesGenerator } from '../../rules/unresolvedProviderDependencies'; import { invalidGraph } from '../../rules/unresolvedProviderDependencies/invalidGraphs'; +import { PathResolverStub } from '../stubs/PathResolverStub'; const ruleTester = new RuleTester(); -ruleTester.run('unresolved-provider-dependencies', unresolvedProviderDependencies, { - valid: [validGraphSimple], - invalid: [ - { - code: invalidGraph, - errors: [{ - messageId: 'unresolved-provider-dependencies', - }], - }, - ], -}); +ruleTester.run( + 'unresolved-provider-dependencies', + unresolvedProviderDependenciesGenerator(new PathResolverStub()), + { + valid: [validGraphSimple, validGraphWithSubgraph], + invalid: [ + { + code: invalidGraph, + errors: [{ + messageId: 'unresolved-provider-dependencies', + }], + }, + ], + } +);