diff --git a/main.ts b/main.ts index 5bde430..d61210c 100644 --- a/main.ts +++ b/main.ts @@ -20,7 +20,8 @@ function convertEnumToObject(enumDeclaration: EnumDeclaration): void { const name = member.getName(); const comment = member.getLeadingCommentRanges()[0]?.getText(); const initializer = member.getInitializer(); - const value = initializer ? initializer.getText() : member.getValue(); + // TODO mode should be configurable to support enums with implicit numeric values + const value = initializer ? initializer.getText() : `"${name}"`; const keyValue = `${name}: ${value}`; return comment ? comment + "\n " + keyValue : keyValue; }) diff --git a/main_test.ts b/main_test.ts index a0b94c3..d317760 100644 --- a/main_test.ts +++ b/main_test.ts @@ -171,10 +171,10 @@ const compass: Direction[] = [ ];`; const expectedOutput = `const Direction = { - North: 0, - South: 1, - East: 2, - West: 3, + North: "North", + South: "South", + East: "East", + West: "West", } as const; type DirectionType = typeof Direction[keyof typeof Direction]; @@ -313,9 +313,9 @@ const Status = { type StatusType = typeof Status[keyof typeof Status]; const Priority = { - Low: 0, - Medium: 1, - High: 2, + Low: "Low", + Medium: "Medium", + High: "High", } as const; type PriorityType = typeof Priority[keyof typeof Priority]; @@ -696,132 +696,48 @@ Deno.test("comprehensive enum transformation - full sample", async () => { } }); -// TODO LAZINESS START -Deno.test.ignore( +Deno.test( "enum usage in destructuring and object patterns", async () => { const utils = new TestUtils(); const testFile = "destructuring_test.ts"; try { - const originalContent = `enum Theme { - Light = "light", - Dark = "dark", - Auto = "auto" -} - -enum Size { - Small = "sm", - Medium = "md", - Large = "lg" -} - -interface ComponentProps { - theme: Theme; - size: Size; - disabled?: boolean; -} - -function createComponent({ - theme = Theme.Light, - size = Size.Medium, - disabled = false -}: Partial = {}): ComponentProps { - return { theme, size, disabled }; -} - -const config = { - defaultTheme: Theme.Dark, - availableSizes: [Size.Small, Size.Medium, Size.Large], - themeColors: { - [Theme.Light]: "#ffffff", - [Theme.Dark]: "#000000", - [Theme.Auto]: "inherit" - } -}; - -const { defaultTheme, availableSizes } = config; - -function handleThemeChange(newTheme: Theme): void { - const themes: Record void> = { - [Theme.Light]: () => console.log("Switching to light theme"), - [Theme.Dark]: () => console.log("Switching to dark theme"), - [Theme.Auto]: () => console.log("Using system theme") - }; - - themes[newTheme]?.(); -}`; + const originalContent = await Deno.readTextFile( + "spec/object-patterns.in.ts", + ); + const expectedOutput = await Deno.readTextFile( + "spec/object-patterns.out.ts", + ); await utils.createTestFile(testFile, originalContent); const result = await utils.runAndReadCodemod(testFile); await checkTsFile(testFile); - assertEquals(result, "todo"); + assertEquals(result, expectedOutput); } finally { await utils.cleanup(); } }, ); -Deno.test.ignore( +Deno.test( "enum usage in template literals and conditionals", async () => { const utils = new TestUtils(); const testFile = "templates_conditionals_test.ts"; try { - const originalContent = `enum LogLevel { - Debug = 0, - Info = 1, - Warning = 2, - Error = 3 -} - -enum Environment { - Development = "dev", - Staging = "staging", - Production = "prod" -} - -class Logger { - constructor( - private level: LogLevel = LogLevel.Info, - private env: Environment = Environment.Development - ) {} - - log(level: LogLevel, message: string): void { - if (level >= this.level) { - const prefix = \`[\${Environment[this.env] || this.env}][\${LogLevel[level]}]\`; - console.log(\`\${prefix} \${message}\`); - } - } - - debug(msg: string) { this.log(LogLevel.Debug, msg); } - info(msg: string) { this.log(LogLevel.Info, msg); } - warn(msg: string) { this.log(LogLevel.Warning, msg); } - error(msg: string) { this.log(LogLevel.Error, msg); } -} - -function getLogLevelName(level: LogLevel): string { - return level === LogLevel.Debug ? "Debug Mode" : - level === LogLevel.Info ? "Information" : - level === LogLevel.Warning ? "Warning!" : - level === LogLevel.Error ? "ERROR!" : "Unknown"; -} - -const logger = new Logger( - LogLevel.Warning, - Environment.Production -); - -const isProduction = logger['env'] === Environment.Production; -const isDevelopment = logger['env'] === Environment.Development; - -logger.error(\`Critical error in \${Environment.Production} environment\`);`; + const originalContent = await Deno.readTextFile( + "spec/template-literal.in.ts", + ); + const expectedOutput = await Deno.readTextFile( + "spec/template-literal.out.ts", + ); await utils.createTestFile(testFile, originalContent); const result = await utils.runAndReadCodemod(testFile); await checkTsFile(testFile); - assertEquals(result, "todo"); + assertEquals(result, expectedOutput); } finally { await utils.cleanup(); } diff --git a/spec/object-patterns.in.ts b/spec/object-patterns.in.ts new file mode 100644 index 0000000..21077a1 --- /dev/null +++ b/spec/object-patterns.in.ts @@ -0,0 +1,47 @@ +enum Theme { + Light = "light", + Dark = "dark", + Auto = "auto" +} + +enum Size { + Small = "sm", + Medium = "md", + Large = "lg" +} + +interface ComponentProps { + theme: Theme; + size: Size; + disabled?: boolean; +} + +function createComponent({ + theme = Theme.Light, + size = Size.Medium, + disabled = false +}: Partial = {}): ComponentProps { + return { theme, size, disabled }; +} + +const config = { + defaultTheme: Theme.Dark, + availableSizes: [Size.Small, Size.Medium, Size.Large], + themeColors: { + [Theme.Light]: "#ffffff", + [Theme.Dark]: "#000000", + [Theme.Auto]: "inherit" + } +}; + +const { defaultTheme, availableSizes } = config; + +function handleThemeChange(newTheme: Theme): void { + const themes: Record void> = { + [Theme.Light]: () => console.log("Switching to light theme"), + [Theme.Dark]: () => console.log("Switching to dark theme"), + [Theme.Auto]: () => console.log("Using system theme") + }; + + themes[newTheme]?.(); +} \ No newline at end of file diff --git a/spec/object-patterns.out.ts b/spec/object-patterns.out.ts new file mode 100644 index 0000000..567dd9d --- /dev/null +++ b/spec/object-patterns.out.ts @@ -0,0 +1,49 @@ +const Theme = { + Light: "light", + Dark: "dark", + Auto: "auto", +} as const; +type ThemeType = typeof Theme[keyof typeof Theme]; + +const Size = { + Small: "sm", + Medium: "md", + Large: "lg", +} as const; +type SizeType = typeof Size[keyof typeof Size]; + +interface ComponentProps { + theme: ThemeType; + size: SizeType; + disabled?: boolean; +} + +function createComponent({ + theme = Theme.Light, + size = Size.Medium, + disabled = false +}: Partial = {}): ComponentProps { + return { theme, size, disabled }; +} + +const config = { + defaultTheme: Theme.Dark, + availableSizes: [Size.Small, Size.Medium, Size.Large], + themeColors: { + [Theme.Light]: "#ffffff", + [Theme.Dark]: "#000000", + [Theme.Auto]: "inherit" + } +}; + +const { defaultTheme, availableSizes } = config; + +function handleThemeChange(newTheme: ThemeType): void { + const themes: Record void> = { + [Theme.Light]: () => console.log("Switching to light theme"), + [Theme.Dark]: () => console.log("Switching to dark theme"), + [Theme.Auto]: () => console.log("Using system theme") + }; + + themes[newTheme]?.(); +} \ No newline at end of file diff --git a/spec/template-literal.in.ts b/spec/template-literal.in.ts new file mode 100644 index 0000000..46d38dd --- /dev/null +++ b/spec/template-literal.in.ts @@ -0,0 +1,48 @@ +enum LogLevel { + Debug, + Info, + Warning, + Error +} + +enum Environment { + Development = "dev", + Staging = "staging", + Production = "prod" +} + +class Logger { + constructor( + private level: LogLevel = LogLevel.Info, + private env: Environment = Environment.Development + ) {} + + log(level: LogLevel, message: string): void { + if (level >= this.level) { + const prefix = `[${this.env || this.env}][${LogLevel[level]}]`; + console.log(`${prefix} ${message}`); + } + } + + debug(msg: string) { this.log(LogLevel.Debug, msg); } + info(msg: string) { this.log(LogLevel.Info, msg); } + warn(msg: string) { this.log(LogLevel.Warning, msg); } + error(msg: string) { this.log(LogLevel.Error, msg); } +} + +function getLogLevelName(level: LogLevel): string { + return level === LogLevel.Debug ? "Debug Mode" : + level === LogLevel.Info ? "Information" : + level === LogLevel.Warning ? "Warning!" : + level === LogLevel.Error ? "ERROR!" : "Unknown"; +} + +const logger = new Logger( + LogLevel.Warning, + Environment.Production +); + +const isProduction = logger['env'] === Environment.Production; +const isDevelopment = logger['env'] === Environment.Development; + +logger.error(`Critical error in ${Environment.Production} environment`); \ No newline at end of file diff --git a/spec/template-literal.out.ts b/spec/template-literal.out.ts new file mode 100644 index 0000000..548f9c0 --- /dev/null +++ b/spec/template-literal.out.ts @@ -0,0 +1,50 @@ +const LogLevel = { + Debug: "Debug", + Info: "Info", + Warning: "Warning", + Error: "Error", +} as const; +type LogLevelType = typeof LogLevel[keyof typeof LogLevel]; + +const Environment = { + Development: "dev", + Staging: "staging", + Production: "prod", +} as const; +type EnvironmentType = typeof Environment[keyof typeof Environment]; + +class Logger { + constructor( + private level: LogLevelType = LogLevel.Info, + private env: EnvironmentType = Environment.Development + ) {} + + log(level: LogLevelType, message: string): void { + if (level >= this.level) { + const prefix = `[${this.env || this.env}][${LogLevel[level]}]`; + console.log(`${prefix} ${message}`); + } + } + + debug(msg: string) { this.log(LogLevel.Debug, msg); } + info(msg: string) { this.log(LogLevel.Info, msg); } + warn(msg: string) { this.log(LogLevel.Warning, msg); } + error(msg: string) { this.log(LogLevel.Error, msg); } +} + +function getLogLevelName(level: LogLevelType): string { + return level === LogLevel.Debug ? "Debug Mode" : + level === LogLevel.Info ? "Information" : + level === LogLevel.Warning ? "Warning!" : + level === LogLevel.Error ? "ERROR!" : "Unknown"; +} + +const logger = new Logger( + LogLevel.Warning, + Environment.Production +); + +const isProduction = logger['env'] === Environment.Production; +const isDevelopment = logger['env'] === Environment.Development; + +logger.error(`Critical error in ${Environment.Production} environment`); \ No newline at end of file