11import fs from 'fs' ;
22import JavaProps from '../src/java-props' ;
3- import { convertLine } from '../src/utils' ;
3+ import { decodeLine , encodeLine } from '../src/utils' ;
44
55describe ( 'parse' , ( ) => {
66 it ( 'validate test.properties' , async ( ) => {
77 const res = JSON . parse ( fs . readFileSync ( __dirname + '/test.properties-result.json' , 'utf8' ) ) ;
8- const props = await JavaProps . parse ( fs . readFileSync ( __dirname + '/test.properties' , 'utf8' ) ) ;
8+ const props = JavaProps . parse ( fs . readFileSync ( __dirname + '/test.properties' , 'utf8' ) ) ;
99 expect ( props ) . toEqual ( res ) ;
1010 } ) ;
1111
@@ -29,42 +29,123 @@ describe('parse', () => {
2929 } ) ;
3030} ) ;
3131
32- describe ( 'utils.convertLine' , ( ) => {
33- const converts : any = {
34- t : '\t' ,
35- r : '\r' ,
36- n : '\n' ,
37- f : '\f' ,
32+ describe ( 'stringify' , ( ) => {
33+ const expectConvertBack = ( props : any ) => {
34+ const newProps = JavaProps . parse ( JavaProps . stringify ( props ) ) ;
35+ expect ( newProps ) . toEqual ( props ) ;
3836 } ;
37+
38+ it ( 'convert back test.properties' , async ( ) => {
39+ expectConvertBack ( JavaProps . parse ( fs . readFileSync ( __dirname + '/test.properties' , 'utf8' ) ) ) ;
40+ } ) ;
41+
42+ it ( 'must handle spacings' , async ( ) => {
43+ expectConvertBack ( { ' key' : 'value' } ) ;
44+ expectConvertBack ( { 'key' : ' value' } ) ;
45+ expectConvertBack ( { 'key ' : 'value' } ) ;
46+ expectConvertBack ( { 'key' : 'value ' } ) ;
47+ expectConvertBack ( { ' ke:y= ' : ' = \\nval\\ue\n ' } ) ;
48+ } ) ;
49+
50+ it ( 'must skip non-own properties' , async ( ) => {
51+ const obj = { 'key' : 'value' } ;
52+ ( Object . prototype as any ) . notAKey = 'x' ;
53+ expect ( JavaProps . stringify ( obj ) ) . toBe ( 'key: value\n' ) ;
54+ } ) ;
55+
56+ it ( 'must handle null-prototype objects' , async ( ) => {
57+ const obj = Object . create ( null ) ;
58+ obj . key = 'value' ;
59+ expect ( JavaProps . stringify ( obj ) ) . toBe ( 'key: value\n' ) ;
60+ } ) ;
61+ } ) ;
62+
63+ const converts : any = {
64+ t : '\t' ,
65+ r : '\r' ,
66+ n : '\n' ,
67+ f : '\f' ,
68+ } ;
69+
70+ describe ( 'utils.decodeLine' , ( ) => {
3971 for ( const char in converts ) {
4072 if ( converts . hasOwnProperty ( char ) ) {
4173 const repl = converts [ char ] ;
42- it ( 'must convert \\' + char , ( ) => {
43- expect ( convertLine ( 'abc\\' + char + 'def\\' + char + 'ghi' ) ) . toBe ( 'abc' + repl + 'def' + repl + 'ghi' ) ;
74+ it ( 'must decode \\' + char , ( ) => {
75+ expect ( decodeLine ( 'abc\\' + char + 'def\\' + char + 'ghi' ) ) . toBe ( 'abc' + repl + 'def' + repl + 'ghi' ) ;
4476 } ) ;
4577 }
4678 }
4779
4880 it ( 'must remove useless escapes' , ( ) => {
49- expect ( convertLine ( 'a\\bc\\def\\\\' ) ) . toBe ( 'abcdef\\' ) ;
81+ expect ( decodeLine ( 'a\\bc\\def\\\\' ) ) . toBe ( 'abcdef\\' ) ;
5082 } ) ;
5183
5284 it ( 'must replace \\uxxxx' , ( ) => {
53- expect ( convertLine ( '\\u0058 \\u2764' ) ) . toBe ( 'X ❤' ) ;
54- expect ( convertLine ( '\\u00580' ) ) . toBe ( 'X0' ) ;
55- expect ( convertLine ( '\\u0058A\\u2764Test' ) ) . toBe ( 'XA❤Test' ) ;
56- expect ( convertLine ( '\\u002F \\u002f' ) ) . toBe ( '/ /' ) ;
85+ expect ( decodeLine ( '\\u0058 \\u2764' ) ) . toBe ( 'X ❤' ) ;
86+ expect ( decodeLine ( '\\u00580' ) ) . toBe ( 'X0' ) ;
87+ expect ( decodeLine ( '\\u0058A\\u2764Test' ) ) . toBe ( 'XA❤Test' ) ;
88+ expect ( decodeLine ( '\\u002F \\u002f' ) ) . toBe ( '/ /' ) ;
5789 } ) ;
5890
5991 it ( 'must throw on malformed \\uxxxx' , ( ) => {
60- expect ( ( ) => convertLine ( '\\u' ) ) . toThrow ( ) ;
61- expect ( ( ) => convertLine ( '\\u58' ) ) . toThrow ( ) ;
62- expect ( ( ) => convertLine ( '\\u27g4' ) ) . toThrow ( ) ;
92+ expect ( ( ) => decodeLine ( '\\u' ) ) . toThrow ( ) ;
93+ expect ( ( ) => decodeLine ( '\\u58' ) ) . toThrow ( ) ;
94+ expect ( ( ) => decodeLine ( '\\u27g4' ) ) . toThrow ( ) ;
6395 } ) ;
6496
6597 it ( 'must not replace escaped' , ( ) => {
66- expect ( convertLine ( 'test\\nand\\\\n \\\\\\n' ) ) . toBe ( 'test\nand\\n \\\n' ) ;
67- expect ( convertLine ( 'abc \\\\u0000' ) ) . toBe ( 'abc \\u0000' ) ;
68- expect ( convertLine ( 'abc \\\\uxxxx' ) ) . toBe ( 'abc \\uxxxx' ) ;
98+ expect ( decodeLine ( 'test\\nand\\\\n \\\\\\n' ) ) . toBe ( 'test\nand\\n \\\n' ) ;
99+ expect ( decodeLine ( 'abc \\\\u0000' ) ) . toBe ( 'abc \\u0000' ) ;
100+ expect ( decodeLine ( 'abc \\\\uxxxx' ) ) . toBe ( 'abc \\uxxxx' ) ;
69101 } ) ;
70102} ) ;
103+
104+ const origEncodeLine = encodeLine ;
105+ for ( const isKey of [ false , true ] ) {
106+ const encodeLine = ( line : string ) => origEncodeLine ( line , isKey ) ;
107+ describe ( 'utils.encodeLine (isKey=' + isKey + ')' , ( ) => {
108+ for ( const char in converts ) {
109+ if ( converts . hasOwnProperty ( char ) ) {
110+ const repl = converts [ char ] ;
111+ it ( 'must encode \\' + char , ( ) => {
112+ expect ( encodeLine ( 'abc' + repl + 'def' + repl + 'ghi' ) ) . toBe ( 'abc\\' + char + 'def\\' + char + 'ghi' ) ;
113+ } ) ;
114+ }
115+ }
116+
117+ it ( 'must escape special chars' , ( ) => {
118+ expect ( encodeLine ( '!# :=\\' ) ) . toBe ( isKey ? '\\!\\#\\ \\:\\=\\\\' : '!# :=\\\\' ) ;
119+ } ) ;
120+
121+ if ( ! isKey ) {
122+ it ( 'must escape beginning space' , ( ) => {
123+ expect ( encodeLine ( ' abc def ghi jkl ' ) ) . toBe ( '\\ abc def ghi jkl ' ) ;
124+ } ) ;
125+ }
126+
127+ it ( 'must not escape normal chars' , ( ) => {
128+ let str = '' ;
129+ for ( let cc = 33 ; cc < 127 ; ++ cc ) {
130+ const c = String . fromCharCode ( cc ) ;
131+ if ( c === '\\' || ( isKey && ( c === '!' || c === '#' || c === ' ' || c === ':' || c === '=' ) ) ) {
132+ continue ;
133+ }
134+ str += c ;
135+ }
136+ expect ( encodeLine ( str ) ) . toBe ( str ) ;
137+ } ) ;
138+
139+ it ( 'must encode others unicode chars' , ( ) => {
140+ expect ( encodeLine ( '\0' ) ) . toBe ( '\\u0000' ) ;
141+ expect ( encodeLine ( '\u0014' ) ) . toBe ( '\\u0014' ) ;
142+ expect ( encodeLine ( '\u007F' ) ) . toBe ( '\\u007F' ) ;
143+ expect ( encodeLine ( 'é' ) ) . toBe ( '\\u00E9' ) ;
144+ expect ( encodeLine ( '👑' ) ) . toBe ( '\\uD83D\\uDC51' ) ;
145+ expect ( encodeLine ( String . fromCharCode ( 15 ) ) ) . toBe ( '\\u000F' ) ;
146+ expect ( encodeLine ( String . fromCharCode ( 255 ) ) ) . toBe ( '\\u00FF' ) ;
147+ expect ( encodeLine ( String . fromCharCode ( 4095 ) ) ) . toBe ( '\\u0FFF' ) ;
148+ expect ( encodeLine ( String . fromCharCode ( 65535 ) ) ) . toBe ( '\\uFFFF' ) ;
149+ } ) ;
150+ } ) ;
151+ }
0 commit comments