Skip to content

Commit e0570ad

Browse files
authored
Merge pull request #7 from koculu/escape-string-quotes
String formatter should escape quotes.
2 parents ac65192 + 06a7e1c commit e0570ad

4 files changed

Lines changed: 62 additions & 6 deletions

File tree

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
export function escapeQuotes(str: string, quotes: string) {
2+
if (!quotes) return str
3+
if (quotes == '"') return JSON.stringify(str)
4+
str = str.split(quotes).join('\\' + quotes)
5+
return `${quotes}${str}${quotes}`
6+
}

packages/printer/src/formatters/formatter.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { isString } from '@logpot/utils'
44
import { toColorizer } from '../consoleColor'
55
import { PrintContext } from '../printContext'
66
import { Printer } from '../printer'
7+
import { escapeQuotes } from './escapeQuotes'
78
import { getText } from './getText'
89

910
// A common interface for all formatters.
@@ -41,10 +42,8 @@ export class StringFormatter extends PrimitiveFormatter {
4142
return isString(value)
4243
}
4344
format(value: unknown, ctx: PrintContext) {
44-
return getText(
45-
ctx,
46-
toColorizer(ctx.colorConfig.string)(`${ctx.quotes}${value}${ctx.quotes}`)
47-
)
45+
const str = escapeQuotes(value as string, ctx.quotes)
46+
return getText(ctx, toColorizer(ctx.colorConfig.string)(str))
4847
}
4948
}
5049

@@ -147,7 +146,7 @@ export class DateFormatter extends PrimitiveFormatter {
147146
case 'epoch':
148147
return colorizer(date.getTime().toString())
149148
}
150-
return getText(ctx, colorizer(`${ctx.quotes}${str}${ctx.quotes}`))
149+
return getText(ctx, colorizer(escapeQuotes(str, ctx.quotes)))
151150
}
152151
}
153152

packages/printer/src/formatters/objectFormatter.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { isEmptyPlainObject, isPlainObject } from '@logpot/utils'
33
import { toColorizer } from '../consoleColor'
44
import { PrintContext } from '../printContext'
55
import { Printer } from '../printer'
6+
import { escapeQuotes } from './escapeQuotes'
67
import { IFormatter } from './formatter'
78
import { getText } from './getText'
89
import { ObjectFormatterConfig } from './objectFormatterConfig'
@@ -84,7 +85,7 @@ export class ObjectFormatter implements IFormatter {
8485
printer: Printer
8586
): string {
8687
const coloredKey = toColorizer(ctx.colorConfig.key)(
87-
`${ctx.quotes}${key}${ctx.quotes}`
88+
escapeQuotes(key, ctx.quotes)
8889
)
8990

9091
let indent = ctx.indent
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import { describe, expect, it } from 'vitest'
2+
3+
import { colorlessConfig } from '../colorConfig'
4+
import { PrintContext } from '../printContext'
5+
import { StringFormatter } from './formatter'
6+
7+
const makeCtx = (
8+
overrides: Partial<Pick<PrintContext, 'quotes'>> = {}
9+
): PrintContext => ({
10+
indent: '',
11+
maxIndent: 10,
12+
indentString: ' ',
13+
colorConfig: colorlessConfig,
14+
seen: new WeakSet(),
15+
quotes: overrides.quotes ?? '"',
16+
keys: [],
17+
prefix: '',
18+
})
19+
20+
describe('StringFormatter', () => {
21+
it('escapes double quotes when using double quotes', () => {
22+
const fmt = new StringFormatter()
23+
const ctx = makeCtx()
24+
const value = 'a "quote" b'
25+
const result = fmt.format(value, ctx)
26+
const expected = `${ctx.quotes}${value
27+
.split(ctx.quotes)
28+
.join(`\\${ctx.quotes}`)}${ctx.quotes}`
29+
expect(result).toBe(expected)
30+
})
31+
32+
it('escapes single quotes when using single quotes', () => {
33+
const fmt = new StringFormatter()
34+
const ctx = makeCtx({ quotes: "'" })
35+
const value = "a 'quote' b"
36+
const result = fmt.format(value, ctx)
37+
const expected = `${ctx.quotes}${value
38+
.split(ctx.quotes)
39+
.join(`\\${ctx.quotes}`)}${ctx.quotes}`
40+
expect(result).toBe(expected)
41+
})
42+
43+
it('does not escape when quotes are disabled', () => {
44+
const fmt = new StringFormatter()
45+
const ctx = makeCtx({ quotes: '' })
46+
const value = 'a "quote" b'
47+
const result = fmt.format(value, ctx)
48+
expect(result).toBe(value)
49+
})
50+
})

0 commit comments

Comments
 (0)