UNPKG

eslint-plugin-vibe-coder

Version:

ESLint plugin with custom rules to prevent common bad practices made by robots (and humans who code like robots)

284 lines (283 loc) 8.26 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); // @ts-expect-error No types published for @typescript-eslint/rule-tester const rule_tester_1 = require("@typescript-eslint/rule-tester"); const no_optional_properties_1 = require("./no-optional-properties"); // Provide afterAll for RuleTester compatibility with Mocha globalThis.afterAll = after; const ruleTester = new rule_tester_1.RuleTester({ parser: '@typescript-eslint/parser', parserOptions: { ecmaVersion: 2022, sourceType: 'module', ecmaFeatures: { jsx: true, }, }, }); describe('no-optional-properties', () => { it('should pass for valid cases', () => { const validCases = [ // Valid: Required properties { code: ` interface User { name: string; email: string; } `, }, { code: ` type Config = { port: number; host: string; } `, }, // Valid: Union types without undefined/null { code: ` interface User { role: 'admin' | 'user' | 'guest'; status: 'active' | 'inactive'; } `, }, // Valid: Complex types without optional { code: ` interface Product { id: string; name: string; price: number; category: 'electronics' | 'clothing' | 'books'; tags: string[]; metadata: Record<string, unknown>; } `, }, // Valid: Nested interfaces { code: ` interface Address { street: string; city: string; country: string; } interface Customer { id: string; name: string; address: Address; preferences: { theme: 'light' | 'dark'; language: 'en' | 'es' | 'fr'; }; } `, }, // Valid: Generic types { code: ` interface ApiResponse<T> { data: T; status: number; message: string; } `, }, // Valid: Function types { code: ` interface EventHandler { onSuccess: (data: unknown) => void; onError: (error: Error) => void; onComplete: () => void; } `, }, // Valid: Array types { code: ` interface Collection { items: string[]; count: number; isEmpty: boolean; } `, }, ]; ruleTester.run('eslint-plugin-vibe-coder/no-optional-properties', no_optional_properties_1.noOptionalProperties, { valid: validCases, invalid: [], }); }); it('should fail for invalid cases', () => { const invalidCases = [ // Invalid: Optional property { code: ` interface User { name?: string; email: string; } `, errors: [{ messageId: 'noOptionalProperty' }], }, { code: ` type Config = { port?: number; host: string; } `, errors: [{ messageId: 'noOptionalProperty' }], }, // Invalid: Union with undefined { code: ` interface User { name: string | undefined; email: string; } `, errors: [{ messageId: 'noOptionalProperty' }], }, // Invalid: Union with null { code: ` interface User { avatar: string | null; email: string; } `, errors: [{ messageId: 'noOptionalProperty' }], }, // Invalid: Optional property with comment (should still fail) { code: ` interface User { //optional: This field is only set after email verification verifiedAt?: Date; name: string; email: string; } `, errors: [{ messageId: 'noOptionalProperty' }], }, // Invalid: Multiple optional properties { code: ` interface FormData { firstName?: string; lastName?: string; email?: string; phone?: string; } `, errors: [ { messageId: 'noOptionalProperty' }, { messageId: 'noOptionalProperty' }, { messageId: 'noOptionalProperty' }, { messageId: 'noOptionalProperty' }, ], }, // Invalid: Complex union with undefined { code: ` interface ApiResponse { data: User[] | undefined; error: string | undefined; timestamp: number; } `, errors: [ { messageId: 'noOptionalProperty' }, { messageId: 'noOptionalProperty' }, ], }, // Invalid: Nested optional properties { code: ` interface Settings { theme: { primary?: string; secondary?: string; }; notifications: { email?: boolean; push?: boolean; }; } `, errors: [ { messageId: 'noOptionalProperty' }, { messageId: 'noOptionalProperty' }, { messageId: 'noOptionalProperty' }, { messageId: 'noOptionalProperty' }, ], }, // Invalid: Generic with optional { code: ` interface CacheEntry<T> { key: string; value?: T; expiresAt: number; } `, errors: [{ messageId: 'noOptionalProperty' }], }, // Invalid: Function with optional parameters { code: ` interface Callback { onSuccess?: (data: unknown) => void; onError?: (error: Error) => void; onComplete?: () => void; } `, errors: [ { messageId: 'noOptionalProperty' }, { messageId: 'noOptionalProperty' }, { messageId: 'noOptionalProperty' }, ], }, // Invalid: Array with optional elements { code: ` interface TodoList { items: (string | undefined)[]; completed: (boolean | null)[]; priority: number; } `, errors: [ { messageId: 'noOptionalProperty' }, { messageId: 'noOptionalProperty' }, ], }, // Invalid: Mixed valid and invalid { code: ` interface Mixed { required: string; optional?: number; alsoRequired: boolean; nullable: string | null; validUnion: 'a' | 'b' | 'c'; } `, errors: [ { messageId: 'noOptionalProperty' }, { messageId: 'noOptionalProperty' }, ], }, ]; ruleTester.run('eslint-plugin-vibe-coder/no-optional-properties', no_optional_properties_1.noOptionalProperties, { valid: [], invalid: invalidCases, }); }); }); //# sourceMappingURL=no-optional-properties.test.js.map