view data tests
This commit is contained in:
116
core/eslint-rules/domain-no-application.test.js
Normal file
116
core/eslint-rules/domain-no-application.test.js
Normal file
@@ -0,0 +1,116 @@
|
||||
const { RuleTester } = require('eslint');
|
||||
const rule = require('./domain-no-application');
|
||||
|
||||
const ruleTester = new RuleTester({
|
||||
parser: require.resolve('@typescript-eslint/parser'),
|
||||
parserOptions: {
|
||||
ecmaVersion: 2020,
|
||||
sourceType: 'module',
|
||||
ecmaFeatures: {
|
||||
jsx: false,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
ruleTester.run('domain-no-application', rule, {
|
||||
valid: [
|
||||
// Domain file importing from domain
|
||||
{
|
||||
filename: '/path/to/core/domain/user/User.ts',
|
||||
code: "import { UserId } from './UserId';",
|
||||
},
|
||||
// Domain file importing from shared
|
||||
{
|
||||
filename: '/path/to/core/domain/user/User.ts',
|
||||
code: "import { ValueObject } from '../shared/ValueObject';",
|
||||
},
|
||||
// Domain file importing from ports
|
||||
{
|
||||
filename: '/path/to/core/domain/user/User.ts',
|
||||
code: "import { UserRepository } from '../ports/UserRepository';",
|
||||
},
|
||||
// Non-domain file importing from application
|
||||
{
|
||||
filename: '/path/to/core/application/user/CreateUser.ts',
|
||||
code: "import { CreateUserCommand } from './CreateUserCommand';",
|
||||
},
|
||||
// Non-domain file importing from application
|
||||
{
|
||||
filename: '/path/to/core/application/user/CreateUser.ts',
|
||||
code: "import { UserService } from '../services/UserService';",
|
||||
},
|
||||
// Domain file with no imports
|
||||
{
|
||||
filename: '/path/to/core/domain/user/User.ts',
|
||||
code: "export class User {}",
|
||||
},
|
||||
// Domain file with multiple imports, none from application
|
||||
{
|
||||
filename: '/path/to/core/domain/user/User.ts',
|
||||
code: `
|
||||
import { UserId } from './UserId';
|
||||
import { UserName } from './UserName';
|
||||
import { ValueObject } from '../shared/ValueObject';
|
||||
`,
|
||||
},
|
||||
],
|
||||
|
||||
invalid: [
|
||||
// Domain file importing from application
|
||||
{
|
||||
filename: '/path/to/core/domain/user/User.ts',
|
||||
code: "import { CreateUserCommand } from '../application/user/CreateUserCommand';",
|
||||
errors: [
|
||||
{
|
||||
messageId: 'forbiddenImport',
|
||||
data: {
|
||||
source: '../application/user/CreateUserCommand',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
// Domain file importing from application with different path
|
||||
{
|
||||
filename: '/path/to/core/domain/user/User.ts',
|
||||
code: "import { UserService } from '../../application/services/UserService';",
|
||||
errors: [
|
||||
{
|
||||
messageId: 'forbiddenImport',
|
||||
data: {
|
||||
source: '../../application/services/UserService',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
// Domain file importing from application with absolute path
|
||||
{
|
||||
filename: '/path/to/core/domain/user/User.ts',
|
||||
code: "import { CreateUserCommand } from 'core/application/user/CreateUserCommand';",
|
||||
errors: [
|
||||
{
|
||||
messageId: 'forbiddenImport',
|
||||
data: {
|
||||
source: 'core/application/user/CreateUserCommand',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
// Domain file with multiple imports, one from application
|
||||
{
|
||||
filename: '/path/to/core/domain/user/User.ts',
|
||||
code: `
|
||||
import { UserId } from './UserId';
|
||||
import { CreateUserCommand } from '../application/user/CreateUserCommand';
|
||||
import { UserName } from './UserName';
|
||||
`,
|
||||
errors: [
|
||||
{
|
||||
messageId: 'forbiddenImport',
|
||||
data: {
|
||||
source: '../application/user/CreateUserCommand',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
||||
79
core/eslint-rules/index.test.js
Normal file
79
core/eslint-rules/index.test.js
Normal file
@@ -0,0 +1,79 @@
|
||||
const index = require('./index');
|
||||
|
||||
describe('eslint-rules index', () => {
|
||||
describe('rules', () => {
|
||||
it('should export no-index-files rule', () => {
|
||||
expect(index.rules['no-index-files']).toBeDefined();
|
||||
expect(index.rules['no-index-files'].meta).toBeDefined();
|
||||
expect(index.rules['no-index-files'].create).toBeDefined();
|
||||
});
|
||||
|
||||
it('should export no-framework-imports rule', () => {
|
||||
expect(index.rules['no-framework-imports']).toBeDefined();
|
||||
expect(index.rules['no-framework-imports'].meta).toBeDefined();
|
||||
expect(index.rules['no-framework-imports'].create).toBeDefined();
|
||||
});
|
||||
|
||||
it('should export domain-no-application rule', () => {
|
||||
expect(index.rules['domain-no-application']).toBeDefined();
|
||||
expect(index.rules['domain-no-application'].meta).toBeDefined();
|
||||
expect(index.rules['domain-no-application'].create).toBeDefined();
|
||||
});
|
||||
|
||||
it('should have exactly 3 rules', () => {
|
||||
expect(Object.keys(index.rules)).toHaveLength(3);
|
||||
});
|
||||
});
|
||||
|
||||
describe('configs', () => {
|
||||
it('should export recommended config', () => {
|
||||
expect(index.configs.recommended).toBeDefined();
|
||||
});
|
||||
|
||||
it('recommended config should have gridpilot-core-rules plugin', () => {
|
||||
expect(index.configs.recommended.plugins).toContain('gridpilot-core-rules');
|
||||
});
|
||||
|
||||
it('recommended config should enable all rules', () => {
|
||||
expect(index.configs.recommended.rules['gridpilot-core-rules/no-index-files']).toBe('error');
|
||||
expect(index.configs.recommended.rules['gridpilot-core-rules/no-framework-imports']).toBe('error');
|
||||
expect(index.configs.recommended.rules['gridpilot-core-rules/domain-no-application']).toBe('error');
|
||||
});
|
||||
|
||||
it('recommended config should have exactly 3 rules', () => {
|
||||
expect(Object.keys(index.configs.recommended.rules)).toHaveLength(3);
|
||||
});
|
||||
});
|
||||
|
||||
describe('rule metadata', () => {
|
||||
it('no-index-files should have correct metadata', () => {
|
||||
const rule = index.rules['no-index-files'];
|
||||
expect(rule.meta.type).toBe('problem');
|
||||
expect(rule.meta.docs.category).toBe('Best Practices');
|
||||
expect(rule.meta.docs.recommended).toBe(true);
|
||||
expect(rule.meta.fixable).toBe(null);
|
||||
expect(rule.meta.schema).toEqual([]);
|
||||
expect(rule.meta.messages.indexFile).toBeDefined();
|
||||
});
|
||||
|
||||
it('no-framework-imports should have correct metadata', () => {
|
||||
const rule = index.rules['no-framework-imports'];
|
||||
expect(rule.meta.type).toBe('problem');
|
||||
expect(rule.meta.docs.category).toBe('Architecture');
|
||||
expect(rule.meta.docs.recommended).toBe(true);
|
||||
expect(rule.meta.fixable).toBe(null);
|
||||
expect(rule.meta.schema).toEqual([]);
|
||||
expect(rule.meta.messages.frameworkImport).toBeDefined();
|
||||
});
|
||||
|
||||
it('domain-no-application should have correct metadata', () => {
|
||||
const rule = index.rules['domain-no-application'];
|
||||
expect(rule.meta.type).toBe('problem');
|
||||
expect(rule.meta.docs.category).toBe('Architecture');
|
||||
expect(rule.meta.docs.recommended).toBe(true);
|
||||
expect(rule.meta.fixable).toBe(null);
|
||||
expect(rule.meta.schema).toEqual([]);
|
||||
expect(rule.meta.messages.forbiddenImport).toBeDefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
166
core/eslint-rules/no-framework-imports.test.js
Normal file
166
core/eslint-rules/no-framework-imports.test.js
Normal file
@@ -0,0 +1,166 @@
|
||||
const { RuleTester } = require('eslint');
|
||||
const rule = require('./no-framework-imports');
|
||||
|
||||
const ruleTester = new RuleTester({
|
||||
parser: require.resolve('@typescript-eslint/parser'),
|
||||
parserOptions: {
|
||||
ecmaVersion: 2020,
|
||||
sourceType: 'module',
|
||||
ecmaFeatures: {
|
||||
jsx: false,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
ruleTester.run('no-framework-imports', rule, {
|
||||
valid: [
|
||||
// Import from domain
|
||||
{
|
||||
filename: '/path/to/core/domain/user/User.ts',
|
||||
code: "import { UserId } from './UserId';",
|
||||
},
|
||||
// Import from application
|
||||
{
|
||||
filename: '/path/to/core/application/user/CreateUser.ts',
|
||||
code: "import { CreateUserCommand } from './CreateUserCommand';",
|
||||
},
|
||||
// Import from shared
|
||||
{
|
||||
filename: '/path/to/core/shared/ValueObject.ts',
|
||||
code: "import { ValueObject } from './ValueObject';",
|
||||
},
|
||||
// Import from ports
|
||||
{
|
||||
filename: '/path/to/core/ports/UserRepository.ts',
|
||||
code: "import { User } from '../domain/user/User';",
|
||||
},
|
||||
// Import from external packages (not frameworks)
|
||||
{
|
||||
filename: '/path/to/core/domain/user/User.ts',
|
||||
code: "import { v4 as uuidv4 } from 'uuid';",
|
||||
},
|
||||
// Import from internal packages
|
||||
{
|
||||
filename: '/path/to/core/domain/user/User.ts',
|
||||
code: "import { SomeUtil } from '@core/shared/SomeUtil';",
|
||||
},
|
||||
// No imports
|
||||
{
|
||||
filename: '/path/to/core/domain/user/User.ts',
|
||||
code: "export class User {}",
|
||||
},
|
||||
// Multiple valid imports
|
||||
{
|
||||
filename: '/path/to/core/domain/user/User.ts',
|
||||
code: `
|
||||
import { UserId } from './UserId';
|
||||
import { UserName } from './UserName';
|
||||
import { ValueObject } from '../shared/ValueObject';
|
||||
`,
|
||||
},
|
||||
],
|
||||
|
||||
invalid: [
|
||||
// Import from @nestjs
|
||||
{
|
||||
filename: '/path/to/core/domain/user/User.ts',
|
||||
code: "import { Injectable } from '@nestjs/common';",
|
||||
errors: [
|
||||
{
|
||||
messageId: 'frameworkImport',
|
||||
data: {
|
||||
source: '@nestjs/common',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
// Import from @nestjs/core
|
||||
{
|
||||
filename: '/path/to/core/domain/user/User.ts',
|
||||
code: "import { Module } from '@nestjs/core';",
|
||||
errors: [
|
||||
{
|
||||
messageId: 'frameworkImport',
|
||||
data: {
|
||||
source: '@nestjs/core',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
// Import from express
|
||||
{
|
||||
filename: '/path/to/core/domain/user/User.ts',
|
||||
code: "import express from 'express';",
|
||||
errors: [
|
||||
{
|
||||
messageId: 'frameworkImport',
|
||||
data: {
|
||||
source: 'express',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
// Import from react
|
||||
{
|
||||
filename: '/path/to/core/domain/user/User.ts',
|
||||
code: "import React from 'react';",
|
||||
errors: [
|
||||
{
|
||||
messageId: 'frameworkImport',
|
||||
data: {
|
||||
source: 'react',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
// Import from next
|
||||
{
|
||||
filename: '/path/to/core/domain/user/User.ts',
|
||||
code: "import { useRouter } from 'next/router';",
|
||||
errors: [
|
||||
{
|
||||
messageId: 'frameworkImport',
|
||||
data: {
|
||||
source: 'next/router',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
// Import from @nestjs with subpath
|
||||
{
|
||||
filename: '/path/to/core/domain/user/User.ts',
|
||||
code: "import { Controller } from '@nestjs/common';",
|
||||
errors: [
|
||||
{
|
||||
messageId: 'frameworkImport',
|
||||
data: {
|
||||
source: '@nestjs/common',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
// Multiple framework imports
|
||||
{
|
||||
filename: '/path/to/core/domain/user/User.ts',
|
||||
code: `
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { UserId } from './UserId';
|
||||
import React from 'react';
|
||||
`,
|
||||
errors: [
|
||||
{
|
||||
messageId: 'frameworkImport',
|
||||
data: {
|
||||
source: '@nestjs/common',
|
||||
},
|
||||
},
|
||||
{
|
||||
messageId: 'frameworkImport',
|
||||
data: {
|
||||
source: 'react',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
||||
131
core/eslint-rules/no-index-files.test.js
Normal file
131
core/eslint-rules/no-index-files.test.js
Normal file
@@ -0,0 +1,131 @@
|
||||
const { RuleTester } = require('eslint');
|
||||
const rule = require('./no-index-files');
|
||||
|
||||
const ruleTester = new RuleTester({
|
||||
parser: require.resolve('@typescript-eslint/parser'),
|
||||
parserOptions: {
|
||||
ecmaVersion: 2020,
|
||||
sourceType: 'module',
|
||||
ecmaFeatures: {
|
||||
jsx: false,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
ruleTester.run('no-index-files', rule, {
|
||||
valid: [
|
||||
// Regular file in domain
|
||||
{
|
||||
filename: '/path/to/core/domain/user/User.ts',
|
||||
code: "export class User {}",
|
||||
},
|
||||
// Regular file in application
|
||||
{
|
||||
filename: '/path/to/core/application/user/CreateUser.ts',
|
||||
code: "export class CreateUser {}",
|
||||
},
|
||||
// Regular file in shared
|
||||
{
|
||||
filename: '/path/to/core/shared/ValueObject.ts',
|
||||
code: "export class ValueObject {}",
|
||||
},
|
||||
// Regular file in ports
|
||||
{
|
||||
filename: '/path/to/core/ports/UserRepository.ts',
|
||||
code: "export interface UserRepository {}",
|
||||
},
|
||||
// File with index in the middle of the path
|
||||
{
|
||||
filename: '/path/to/core/domain/user/index/User.ts',
|
||||
code: "export class User {}",
|
||||
},
|
||||
// File with index in the name but not at the end
|
||||
{
|
||||
filename: '/path/to/core/domain/user/indexHelper.ts',
|
||||
code: "export class IndexHelper {}",
|
||||
},
|
||||
// Root index.ts is allowed
|
||||
{
|
||||
filename: '/path/to/core/index.ts',
|
||||
code: "export * from './domain';",
|
||||
},
|
||||
// File with index.ts in the middle of the path
|
||||
{
|
||||
filename: '/path/to/core/domain/index/User.ts',
|
||||
code: "export class User {}",
|
||||
},
|
||||
],
|
||||
|
||||
invalid: [
|
||||
// index.ts in domain
|
||||
{
|
||||
filename: '/path/to/core/domain/user/index.ts',
|
||||
code: "export * from './User';",
|
||||
errors: [
|
||||
{
|
||||
messageId: 'indexFile',
|
||||
},
|
||||
],
|
||||
},
|
||||
// index.ts in application
|
||||
{
|
||||
filename: '/path/to/core/application/user/index.ts',
|
||||
code: "export * from './CreateUser';",
|
||||
errors: [
|
||||
{
|
||||
messageId: 'indexFile',
|
||||
},
|
||||
],
|
||||
},
|
||||
// index.ts in shared
|
||||
{
|
||||
filename: '/path/to/core/shared/index.ts',
|
||||
code: "export * from './ValueObject';",
|
||||
errors: [
|
||||
{
|
||||
messageId: 'indexFile',
|
||||
},
|
||||
],
|
||||
},
|
||||
// index.ts in ports
|
||||
{
|
||||
filename: '/path/to/core/ports/index.ts',
|
||||
code: "export * from './UserRepository';",
|
||||
errors: [
|
||||
{
|
||||
messageId: 'indexFile',
|
||||
},
|
||||
],
|
||||
},
|
||||
// index.ts with Windows path separator
|
||||
{
|
||||
filename: 'C:\\path\\to\\core\\domain\\user\\index.ts',
|
||||
code: "export * from './User';",
|
||||
errors: [
|
||||
{
|
||||
messageId: 'indexFile',
|
||||
},
|
||||
],
|
||||
},
|
||||
// index.ts at the start of path
|
||||
{
|
||||
filename: 'index.ts',
|
||||
code: "export * from './domain';",
|
||||
errors: [
|
||||
{
|
||||
messageId: 'indexFile',
|
||||
},
|
||||
],
|
||||
},
|
||||
// index.ts in nested directory
|
||||
{
|
||||
filename: '/path/to/core/domain/user/profile/index.ts',
|
||||
code: "export * from './Profile';",
|
||||
errors: [
|
||||
{
|
||||
messageId: 'indexFile',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
||||
Reference in New Issue
Block a user