Skip to content

Commit 5438dd3

Browse files
committed
chore: added more tests
Thanks https://github.com/Avansai/properties-file for the sample
1 parent 59d279c commit 5438dd3

File tree

2 files changed

+152
-2
lines changed

2 files changed

+152
-2
lines changed

fixtures/test-all.properties

+72
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
# You are reading a comment in ".properties" file.
2+
! The exclamation mark can also be used for comments.
3+
# Lines with "properties" contain a key and a value separated by a delimiting character.
4+
# There are 3 types of delimiting characters: '=' (equal), ':' (colon) and whitespace characters other
5+
# than carriage returns and newlines: ' ' (space), \t (tab) and \f (formfeed).
6+
website = https://en.wikipedia.org/
7+
language : English
8+
topic .properties file
9+
category file format
10+
# A word on a line will just create a key with no value.
11+
empty
12+
orLikeThis =
13+
evenLikeThis\\
14+
# Likewise, if a line starts with a delimiter, it will create a value without a key.
15+
= This line has no key.
16+
: So does this line.
17+
# Whitespace characters between the key, the value and the delimiter are ignored.
18+
# This means that the following entries are equivalent (other than for readability).
19+
hello=hello
20+
hello = hello
21+
hello = hello
22+
# Keys with the same name will be overwritten by the key that is the closest to the end of a file.
23+
# For example the final value for "duplicateKey" will be "second".
24+
duplicateKey = first
25+
duplicateKey = second
26+
# To use the delimiter characters inside a key, you need to escape them with a \.
27+
# However, there is no need to do this in the value.
28+
keyWithDelimiters\:\=\ = This is the value for the key "keyWithDelimiters:= "
29+
# Adding a \ at the end of a line means that the value continues to the next line.
30+
multiline = This line \
31+
continues \
32+
on 3 lines
33+
# You can also do the same for keys, even if there is no real reason to do this.
34+
# In the following example, the value for "multilineKey" will be "this is a multiline key".
35+
multiline\
36+
Key this is a multiline key
37+
# If you want your value to include a \, it should be escaped by another \.
38+
path = c:\\wiki\\templates
39+
# This means that if the number of \ at the end of the line is even, the next line is not included in the value.
40+
# In the following example, the value for "evenKey" is "This is on one line\".
41+
evenKey = This is on one line\\
42+
# This line is a normal comment and is not included in the value for "evenKey"
43+
# If the number of \ is odd, then the next line is included in the value.
44+
# In the following example, the value for "oddKey" is "This is line one and\#This is line two".
45+
oddKey = This is line one and\\\
46+
# This is line two
47+
# This also applies with keys.
48+
# In the following example, the value for "keyWitheven\" is "this colon is not escaped".
49+
keyWitheven\\:this colon is not escaped
50+
# White space characters are removed before each line, but trailing spaces aren't.
51+
noWhiteSpace = The key will be "noWhiteSpace" without any whitespace.
52+
# Make sure to add your spaces before your \ if you need them on the next line.
53+
# In the following example, the value for "welcome" is "Welcome to Wikipedia! ".
54+
welcome = Welcome to \
55+
Wikipedia!
56+
# You can have empty lines, where all white space characters will be ignored.
57+
58+
# You can also have whitespace before comments.
59+
60+
# If you need to add carriage returns and newlines, they need to be escaped using \r and \n respectively.
61+
# You can also optionally escape tabs with \t for readability purposes.
62+
# \f (formfeed) can also be escaped even if it's not really useful.
63+
valueWithEscapes = This is a newline\n, a carriage return\r, a tab\t and a formfeed\f.
64+
# Using \ in front of non-escape characters will remove them from the output.
65+
# In the following example, the value for "keyWithBackslashes" is "This has random backslashes".
66+
keyWith\Backslashes = This\ has ran\d\o\m backslashes
67+
# You can also use Unicode escape characters, limited to 2 bytes or 65,535 characters.
68+
# In the following example, the value for "encodedHelloInJapanese" is "?????".
69+
encodedHelloInJapanese = \u3053\u3093\u306b\u3061\u306f
70+
# Using \u without being followed by four hexadecimal digits will throw an exception.
71+
# But with more modern file encodings like UTF-8, you can directly use supported characters.
72+
helloInJapanese = ?????

src/properties.spec.ts

+80-2
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
1+
import * as fs from 'node:fs/promises'
12
import properties from '.'
23

34
describe('parse', () => {
45
it('should parse all lines', () => {
56
// Data
6-
const sample = 'registry=https://abcd\n#foo bar\n@scope:test=avx\n'
7+
const sample = 'registry=https://abcd\n#foo bar\r\n@scope:test=avx\rextra\r\n'
78

89
// Test
910
const result = properties.parse(sample)
1011
expect(result.lines).toEqual([
1112
'registry=https://abcd',
1213
'#foo bar',
13-
'@scope:test=avx'
14+
'@scope:test=avx',
15+
'extra'
1416
])
1517
})
1618
})
@@ -128,6 +130,19 @@ describe('data access', () => {
128130
expect(result).toBe(expected)
129131
})
130132

133+
it('should return last value of duplicate key', () => {
134+
const config: properties.Properties = {
135+
lines: [
136+
'key1=foo1',
137+
'key2=foo2',
138+
'key1=foo3'
139+
]
140+
}
141+
142+
const result = properties.get(config, 'key1')
143+
expect(result).toBe('foo3')
144+
})
145+
131146
it.each([
132147
['foo', 'bar', 'foo=bar'],
133148
['foo8:', 'bar8', 'foo8\\:=bar8'],
@@ -218,6 +233,22 @@ describe('data access', () => {
218233
])
219234
})
220235

236+
it('should remove duplicate keys on set', () => {
237+
const config: properties.Properties = {
238+
lines: [
239+
'key1=foo1',
240+
'key2=foo2',
241+
'key1=foo3'
242+
]
243+
}
244+
245+
properties.set(config, 'key1', 'test')
246+
expect(config.lines).toEqual([
247+
'key1=test',
248+
'key2=foo2'
249+
])
250+
})
251+
221252
it('should remove existing key with set undefined', () => {
222253
const config: properties.Properties = {
223254
lines: ['foo=bar']
@@ -234,6 +265,19 @@ describe('data access', () => {
234265
expect(config.lines).toEqual([])
235266
})
236267

268+
it('should remove all duplicate keys with remove', () => {
269+
const config: properties.Properties = {
270+
lines: [
271+
'key1=foo1',
272+
'key2=foo2',
273+
'key1=foo3'
274+
]
275+
}
276+
277+
properties.remove(config, 'key1')
278+
expect(config.lines).toEqual(['key2=foo2'])
279+
})
280+
237281
describe('list', () => {
238282
it('should list all key-value pairs', () => {
239283
const result = [...properties.list(sample)]
@@ -293,6 +337,40 @@ describe('data access', () => {
293337
['c', 'd']
294338
])
295339
})
340+
341+
it('should parse test file', async () => {
342+
const contents = await fs.readFile('../fixtures/test-all.properties', 'utf-8')
343+
344+
// Parse
345+
const result = properties.toMap(properties.parse(contents))
346+
347+
// Verify
348+
expect(result).toEqual({
349+
'': 'So does this line.',
350+
category: 'file format',
351+
duplicateKey: 'second',
352+
empty: '',
353+
encodedHelloInJapanese: 'こんにちは',
354+
evenKey: 'This is on one line\\',
355+
'evenLikeThis\\': '',
356+
hello: 'hello',
357+
helloInJapanese: 'こんにちは',
358+
keyWithBackslashes: 'This has random backslashes',
359+
'keyWithDelimiters:= ': 'This is the value for the key "keyWithDelimiters:= "',
360+
'keyWitheven\\': 'this colon is not escaped',
361+
language: 'English',
362+
multiline: 'This line continues on 3 lines',
363+
multilineKey: 'this is a multiline key',
364+
noWhiteSpace: 'The key will be "noWhiteSpace" without any whitespace. ',
365+
oddKey: 'This is line one and\\# This is line two',
366+
orLikeThis: '',
367+
path: 'c:\\wiki\\templates',
368+
topic: '.properties file',
369+
valueWithEscapes: 'This is a newline\n, a carriage return\r, a tab\t and a formfeed\f.',
370+
website: 'https://en.wikipedia.org/',
371+
welcome: 'Welcome to Wikipedia! '
372+
})
373+
})
296374
})
297375
})
298376

0 commit comments

Comments
 (0)