33import test from 'tape-six' ;
44import chain from 'stream-chain' ;
55
6- import { parser } from '../src/parser.js' ;
6+ import makeParser , { parser } from '../src/parser.js' ;
7+ import Assembler from '../src/assembler.js' ;
78
89import readString from './read-string.mjs' ;
910
10- test . asPromise ( 'smoke test ' , ( t , resolve , reject ) => {
11+ test . asPromise ( 'parser: streaming values ' , ( t , resolve , reject ) => {
1112 const input = '{"a": 1, "b": true, "c": ["d"]}' ,
1213 pipeline = chain ( [ readString ( input ) , parser ( { packValues : false } ) ] ) ,
1314 result = [ ] ;
@@ -16,26 +17,177 @@ test.asPromise('smoke test', (t, resolve, reject) => {
1617 pipeline . on ( 'error' , ( ) => reject ( ) ) ;
1718 pipeline . on ( 'end' , ( ) => {
1819 t . ok ( result . length === 20 ) ;
19- t . ok ( result [ 0 ] . name === 'startObject' ) ;
20- t . ok ( result [ 1 ] . name === 'startKey' ) ;
21- t . ok ( result [ 2 ] . name === 'stringChunk' && result [ 2 ] . val === 'a' ) ;
22- t . ok ( result [ 3 ] . name === 'endKey' ) ;
23- t . ok ( result [ 4 ] . name === 'startNumber' ) ;
24- t . ok ( result [ 5 ] . name === 'numberChunk' && result [ 5 ] . val === '1' ) ;
25- t . ok ( result [ 6 ] . name === 'endNumber' ) ;
26- t . ok ( result [ 7 ] . name === 'startKey' ) ;
27- t . ok ( result [ 8 ] . name === 'stringChunk' && result [ 8 ] . val === 'b' ) ;
28- t . ok ( result [ 9 ] . name === 'endKey' ) ;
29- t . ok ( result [ 10 ] . name === 'trueValue' && result [ 10 ] . val === true ) ;
30- t . ok ( result [ 11 ] . name === 'startKey' ) ;
31- t . ok ( result [ 12 ] . name === 'stringChunk' && result [ 12 ] . val === 'c' ) ;
32- t . ok ( result [ 13 ] . name === 'endKey' ) ;
33- t . ok ( result [ 14 ] . name === 'startArray' ) ;
34- t . ok ( result [ 15 ] . name === 'startString' ) ;
35- t . ok ( result [ 16 ] . name === 'stringChunk' && result [ 16 ] . val === 'd' ) ;
36- t . ok ( result [ 17 ] . name === 'endString' ) ;
37- t . ok ( result [ 18 ] . name === 'endArray' ) ;
38- t . ok ( result [ 19 ] . name === 'endObject' ) ;
20+ t . equal ( result [ 0 ] . name , 'startObject' ) ;
21+ t . equal ( result [ 1 ] . name , 'startKey' ) ;
22+ t . equal ( result [ 2 ] . name , 'stringChunk' ) ;
23+ t . equal ( result [ 2 ] . val , 'a' ) ;
24+ t . equal ( result [ 3 ] . name , 'endKey' ) ;
25+ t . equal ( result [ 4 ] . name , 'startNumber' ) ;
26+ t . equal ( result [ 5 ] . name , 'numberChunk' ) ;
27+ t . equal ( result [ 5 ] . val , '1' ) ;
28+ t . equal ( result [ 6 ] . name , 'endNumber' ) ;
29+ t . equal ( result [ 7 ] . name , 'startKey' ) ;
30+ t . equal ( result [ 8 ] . name , 'stringChunk' ) ;
31+ t . equal ( result [ 8 ] . val , 'b' ) ;
32+ t . equal ( result [ 9 ] . name , 'endKey' ) ;
33+ t . equal ( result [ 10 ] . name , 'trueValue' ) ;
34+ t . equal ( result [ 10 ] . val , true ) ;
35+ t . equal ( result [ 11 ] . name , 'startKey' ) ;
36+ t . equal ( result [ 12 ] . name , 'stringChunk' ) ;
37+ t . equal ( result [ 12 ] . val , 'c' ) ;
38+ t . equal ( result [ 13 ] . name , 'endKey' ) ;
39+ t . equal ( result [ 14 ] . name , 'startArray' ) ;
40+ t . equal ( result [ 15 ] . name , 'startString' ) ;
41+ t . equal ( result [ 16 ] . name , 'stringChunk' ) ;
42+ t . equal ( result [ 16 ] . val , 'd' ) ;
43+ t . equal ( result [ 17 ] . name , 'endString' ) ;
44+ t . equal ( result [ 18 ] . name , 'endArray' ) ;
45+ t . equal ( result [ 19 ] . name , 'endObject' ) ;
3946 resolve ( ) ;
4047 } ) ;
4148} ) ;
49+
50+ test . asPromise ( 'parser: packing values' , ( t , resolve , reject ) => {
51+ const input = '{"a": 1, "b": true, "c": ["d"]}' ,
52+ pipeline = chain ( [ readString ( input ) , parser ( ) ] ) ,
53+ result = [ ] ;
54+
55+ pipeline . on ( 'data' , chunk => result . push ( { name : chunk . name , val : chunk . value } ) ) ;
56+ pipeline . on ( 'error' , ( ) => reject ( ) ) ;
57+ pipeline . on ( 'end' , ( ) => {
58+ t . equal ( result . length , 25 ) ;
59+ t . equal ( result [ 0 ] . name , 'startObject' ) ;
60+ t . equal ( result [ 1 ] . name , 'startKey' ) ;
61+ t . equal ( result [ 2 ] . name , 'stringChunk' ) ;
62+ t . equal ( result [ 2 ] . val , 'a' ) ;
63+ t . equal ( result [ 3 ] . name , 'endKey' ) ;
64+ t . equal ( result [ 4 ] . name , 'keyValue' ) ;
65+ t . equal ( result [ 4 ] . val , 'a' ) ;
66+ t . equal ( result [ 5 ] . name , 'startNumber' ) ;
67+ t . equal ( result [ 6 ] . name , 'numberChunk' ) ;
68+ t . equal ( result [ 6 ] . val , '1' ) ;
69+ t . equal ( result [ 7 ] . name , 'endNumber' ) ;
70+ t . equal ( result [ 8 ] . name , 'numberValue' ) ;
71+ t . equal ( result [ 8 ] . val , '1' ) ;
72+ t . equal ( result [ 9 ] . name , 'startKey' ) ;
73+ t . equal ( result [ 10 ] . name , 'stringChunk' ) ;
74+ t . equal ( result [ 10 ] . val , 'b' ) ;
75+ t . equal ( result [ 11 ] . name , 'endKey' ) ;
76+ t . equal ( result [ 12 ] . name , 'keyValue' ) ;
77+ t . equal ( result [ 12 ] . val , 'b' ) ;
78+ t . equal ( result [ 13 ] . name , 'trueValue' ) ;
79+ t . equal ( result [ 13 ] . val , true ) ;
80+ t . equal ( result [ 14 ] . name , 'startKey' ) ;
81+ t . equal ( result [ 15 ] . name , 'stringChunk' ) ;
82+ t . equal ( result [ 15 ] . val , 'c' ) ;
83+ t . equal ( result [ 16 ] . name , 'endKey' ) ;
84+ t . equal ( result [ 17 ] . name , 'keyValue' ) ;
85+ t . equal ( result [ 17 ] . val , 'c' ) ;
86+ t . equal ( result [ 18 ] . name , 'startArray' ) ;
87+ t . equal ( result [ 19 ] . name , 'startString' ) ;
88+ t . equal ( result [ 20 ] . name , 'stringChunk' ) ;
89+ t . equal ( result [ 20 ] . val , 'd' ) ;
90+ t . equal ( result [ 21 ] . name , 'endString' ) ;
91+ t . equal ( result [ 22 ] . name , 'stringValue' ) ;
92+ t . equal ( result [ 22 ] . val , 'd' ) ;
93+ t . equal ( result [ 23 ] . name , 'endArray' ) ;
94+ t . equal ( result [ 24 ] . name , 'endObject' ) ;
95+ resolve ( ) ;
96+ } ) ;
97+ } ) ;
98+
99+ test . asPromise ( 'parser: packing no streaming values' , ( t , resolve , reject ) => {
100+ const input = '{"a": 1, "b": true, "c": ["d"], "e": -2, "f": 0}' ,
101+ pipeline = chain ( [ readString ( input ) , parser ( { streamValues : false } ) ] ) ,
102+ result = [ ] ;
103+
104+ pipeline . on ( 'data' , chunk => result . push ( { name : chunk . name , val : chunk . value } ) ) ;
105+ pipeline . on ( 'error' , ( ) => reject ( ) ) ;
106+ pipeline . on ( 'end' , ( ) => {
107+ t . equal ( result . length , 14 ) ;
108+ t . equal ( result [ 0 ] . name , 'startObject' ) ;
109+ t . equal ( result [ 1 ] . name , 'keyValue' ) ;
110+ t . equal ( result [ 1 ] . val , 'a' ) ;
111+ t . equal ( result [ 2 ] . name , 'numberValue' ) ;
112+ t . equal ( result [ 2 ] . val , '1' ) ;
113+ t . equal ( result [ 3 ] . name , 'keyValue' ) ;
114+ t . equal ( result [ 3 ] . val , 'b' ) ;
115+ t . equal ( result [ 4 ] . name , 'trueValue' ) ;
116+ t . equal ( result [ 4 ] . val , true ) ;
117+ t . equal ( result [ 5 ] . name , 'keyValue' ) ;
118+ t . equal ( result [ 5 ] . val , 'c' ) ;
119+ t . equal ( result [ 6 ] . name , 'startArray' ) ;
120+ t . equal ( result [ 7 ] . name , 'stringValue' ) ;
121+ t . equal ( result [ 7 ] . val , 'd' ) ;
122+ t . equal ( result [ 8 ] . name , 'endArray' ) ;
123+ t . equal ( result [ 9 ] . name , 'keyValue' ) ;
124+ t . equal ( result [ 9 ] . val , 'e' ) ;
125+ t . equal ( result [ 10 ] . name , 'numberValue' ) ;
126+ t . equal ( result [ 10 ] . val , '-2' ) ;
127+ t . equal ( result [ 11 ] . name , 'keyValue' ) ;
128+ t . equal ( result [ 11 ] . val , 'f' ) ;
129+ t . equal ( result [ 12 ] . name , 'numberValue' ) ;
130+ t . equal ( result [ 12 ] . val , '0' ) ;
131+ t . equal ( result [ 13 ] . name , 'endObject' ) ;
132+ resolve ( ) ;
133+ } ) ;
134+ } ) ;
135+
136+ const survivesRoundtrip = object => ( t , resolve , reject ) => {
137+ const input = JSON . stringify ( object ) ,
138+ pipeline = readString ( input ) . pipe ( makeParser ( ) ) ,
139+ assembler = Assembler . connectTo ( pipeline ) ;
140+
141+ pipeline . on ( 'error' , reject ) ;
142+ pipeline . on ( 'end' , ( ) => {
143+ t . deepEqual ( assembler . current , object ) ;
144+ resolve ( ) ;
145+ } ) ;
146+ } ;
147+
148+ const runSlidingWindowTest = quant => ( t , resolve , reject ) => {
149+ const object = {
150+ stringWithTabsAndNewlines : "Did it work?\nNo...\t\tI don't think so..." ,
151+ anArray : [ 1 , 2 , true , 'tabs?\t\t\t\u0001\u0002\u0003' , false ]
152+ } ,
153+ input = JSON . stringify ( object ) ,
154+ pipeline = readString ( input , quant ) . pipe ( makeParser ( ) ) ,
155+ assembler = Assembler . connectTo ( pipeline ) ;
156+
157+ pipeline . on ( 'error' , reject ) ;
158+ pipeline . on ( 'end' , ( ) => {
159+ t . deepEqual ( assembler . current , object ) ;
160+ resolve ( ) ;
161+ } ) ;
162+ } ;
163+
164+ const runJsonStreamingTest =
165+ ( len , sep = '' ) =>
166+ ( t , resolve , reject ) => {
167+ const objects = [ ] ;
168+ for ( let n = 0 ; n < len ; n += 1 ) {
169+ objects . push ( {
170+ stringWithTabsAndNewlines : "Did it work?\nNo...\t\tI don't think so..." ,
171+ anArray : [ n + 1 , n + 2 , true , 'tabs?\t\t\t\u0001\u0002\u0003' , false ] ,
172+ n
173+ } ) ;
174+ }
175+
176+ let json = [ ] ;
177+ for ( let n = 0 ; n < objects . length ; n += 1 ) {
178+ json . push ( JSON . stringify ( objects [ n ] ) ) ;
179+ }
180+
181+ const input = json . join ( sep ) ;
182+ const pipeline = readString ( input , 4 ) . pipe ( makeParser ( { jsonStreaming : true } ) ) ;
183+ const assembler = Assembler . connectTo ( pipeline ) ;
184+
185+ assembler . on ( 'done' , asm => {
186+ const { current : obj } = asm ;
187+ const { n} = obj ;
188+ t . deepEqual ( obj , objects [ n ] ) ;
189+ } ) ;
190+
191+ pipeline . on ( 'error' , reject ) ;
192+ pipeline . on ( 'end' , resolve ) ;
193+ } ;
0 commit comments