1use super::{
2 any_state::{AnyResult, AnyState},
3 const_state::ConstState,
4 json_state::JsonState,
5 path::{concat, split},
6 root_state::{RootState, RootStatus},
7 shared::{JsonElement, ModuleCache, ParseError, ParseResult, ParsingStatus},
8};
9use crate::{
10 common::default::default,
11 mem::manager::Manager,
12 tokenizer::{tokenize, JsonToken},
13};
14use io_trait::Io;
15
16pub struct Context<'a, M: Manager, I: Io> {
17 manager: M,
18 io: &'a I,
19 path: String,
20 module_cache: &'a mut ModuleCache<M::Dealloc>,
21}
22
23impl<'a, M: Manager, I: Io> Context<'a, M, I> {
24 pub fn new(
25 manager: M,
26 io: &'a I,
27 path: String,
28 module_cache: &'a mut ModuleCache<M::Dealloc>,
29 ) -> Self {
30 Context {
31 manager,
32 io,
33 path,
34 module_cache,
35 }
36 }
37}
38
39fn const_state_parse<M: Manager + 'static, I: Io>(
40 const_state: ConstState<M>,
41 context: &mut Context<M, I>,
42 token: JsonToken<M::Dealloc>,
43) -> JsonState<M> {
44 match token {
45 JsonToken::Semicolon => todo!(),
46 _ => {
47 let result = any_state_parse(const_state.state, context, token);
48 match result {
49 AnyResult::Continue(state) => JsonState::ParseConst(ConstState {
50 key: const_state.key,
51 state,
52 }),
53 AnyResult::Success(mut success) => {
54 success.state.consts.insert(const_state.key, success.value);
55 JsonState::ParseRoot(RootState {
56 status: RootStatus::Initial,
57 state: success.state,
58 new_line: false,
59 })
60 }
61 AnyResult::Error(error) => JsonState::Error(error),
62 }
63 }
64 }
65}
66
67fn any_state_parse_for_module<M: Manager + 'static, I: Io>(
68 any_state: AnyState<M>,
69 context: &mut Context<M, I>,
70 token: JsonToken<M::Dealloc>,
71) -> JsonState<M> {
72 let result = any_state_parse(any_state, context, token);
73 match result {
74 AnyResult::Continue(state) => JsonState::ParseModule(state),
75 AnyResult::Success(success) => JsonState::Result(ParseResult {
76 data_type: success.state.data_type,
77 any: success.value,
78 }),
79 AnyResult::Error(error) => JsonState::Error(error),
80 }
81}
82
83fn any_state_parse_import_value<M: Manager + 'static, I: Io>(
84 any_state: AnyState<M>,
85 context: &mut Context<M, I>,
86 token: JsonToken<M::Dealloc>,
87) -> AnyResult<M> {
88 match token {
89 JsonToken::String(s) => {
90 let current_path = concat(split(&context.path).0, s.as_str());
91 if let Some(any) = context.module_cache.complete.get(¤t_path) {
92 return AnyResult::Continue(AnyState {
93 status: ParsingStatus::ImportEnd,
94 current: JsonElement::Any(any.clone()),
95 ..any_state
96 });
97 }
98 if context.module_cache.progress.contains(¤t_path) {
99 return AnyResult::Error(ParseError::CircularDependency);
100 }
101 context.module_cache.progress.insert(current_path.clone());
102 let read_result = context.io.read_to_string(current_path.as_str());
103 match read_result {
104 Ok(s) => {
105 let tokens = tokenize(context.manager, s);
106 let res = parse_with_tokens(context, tokens.into_iter());
107 match res {
108 Ok(r) => {
109 context.module_cache.progress.remove(¤t_path);
110 context
111 .module_cache
112 .complete
113 .insert(current_path, r.any.clone());
114 AnyResult::Continue(AnyState {
115 status: ParsingStatus::ImportEnd,
116 current: JsonElement::Any(r.any),
117 ..any_state
118 })
119 }
120 Err(e) => AnyResult::Error(e),
121 }
122 }
123 Err(_) => AnyResult::<M>::Error(ParseError::CannotReadFile),
124 }
125 }
126 _ => AnyResult::Error(ParseError::WrongRequireStatement),
127 }
128}
129
130fn any_state_parse<M: Manager + 'static, I: Io>(
131 any_state: AnyState<M>,
132 context: &mut Context<M, I>,
133 token: JsonToken<M::Dealloc>,
134) -> AnyResult<M> {
135 match any_state.status {
136 ParsingStatus::Initial | ParsingStatus::ObjectColon => {
137 any_state.parse_value(context.manager, token)
138 }
139 ParsingStatus::ArrayBegin => any_state.parse_array_begin(context.manager, token),
140 ParsingStatus::ArrayValue => any_state.parse_array_value(context.manager, token),
141 ParsingStatus::ArrayComma => any_state.parse_array_comma(context.manager, token),
142 ParsingStatus::ObjectBegin => any_state.parse_object_begin(context.manager, token),
143 ParsingStatus::ObjectKey => any_state.parse_object_key(token),
144 ParsingStatus::ObjectValue => any_state.parse_object_next(context.manager, token),
145 ParsingStatus::ObjectComma => any_state.parse_object_comma(context.manager, token),
146 ParsingStatus::ImportBegin => any_state.parse_import_begin(token),
147 ParsingStatus::ImportValue => any_state_parse_import_value(any_state, context, token),
148 ParsingStatus::ImportEnd => any_state.parse_import_end(token),
149 }
150}
151
152fn root_state_parse<M: Manager + 'static, I: Io>(
153 root_state: RootState<M>,
154 context: &mut Context<M, I>,
155 token: JsonToken<M::Dealloc>,
156) -> JsonState<M> {
157 let (json_state, import) = root_state.parse(context.manager, token);
158 match import {
159 None => json_state,
160 Some((id, module)) => match json_state {
161 JsonState::ParseRoot(mut root_state) => {
162 let current_path = concat(split(&context.path).0, module.as_str());
163 if let Some(any) = context.module_cache.complete.get(¤t_path) {
164 root_state.state.consts.insert(id, any.clone());
165 return JsonState::ParseRoot(RootState {
166 status: RootStatus::Initial,
167 state: root_state.state,
168 new_line: false,
169 });
170 }
171 if context.module_cache.progress.contains(¤t_path) {
172 return JsonState::Error(ParseError::CircularDependency);
173 }
174 context.module_cache.progress.insert(current_path.clone());
175 let read_result = context.io.read_to_string(current_path.as_str());
176 match read_result {
177 Ok(s) => {
178 let tokens = tokenize(context.manager, s);
179 let res = parse_with_tokens(context, tokens.into_iter());
180 match res {
181 Ok(r) => {
182 context.module_cache.progress.remove(¤t_path);
183 context
184 .module_cache
185 .complete
186 .insert(current_path, r.any.clone());
187 root_state.state.consts.insert(id, r.any);
188 JsonState::ParseRoot(RootState {
189 status: RootStatus::Initial,
190 state: root_state.state,
191 new_line: false,
192 })
193 }
194 Err(e) => JsonState::Error(e),
195 }
196 }
197 Err(_) => JsonState::Error(ParseError::CannotReadFile),
198 }
199 }
200 _ => panic!("JsonState::ParseRoot expected when root_state.parse returns import"),
201 },
202 }
203}
204
205fn json_state_push<M: Manager + 'static, I: Io>(
206 json_state: JsonState<M>,
207 context: &mut Context<M, I>,
208 token: JsonToken<M::Dealloc>,
209) -> JsonState<M> {
210 if let JsonToken::NewLine = token {
211 return match json_state {
212 JsonState::ParseRoot(state) => root_state_parse(state, context, token),
213 _ => json_state,
214 };
215 }
216 match json_state {
217 JsonState::ParseRoot(state) => root_state_parse(state, context, token),
218 JsonState::Result(_) => JsonState::Error(ParseError::UnexpectedToken),
219 JsonState::ParseModule(state) => any_state_parse_for_module(state, context, token),
220 JsonState::ParseConst(state) => const_state_parse(state, context, token),
221 _ => json_state,
222 }
223}
224
225pub fn parse<M: Manager + 'static, I: Io>(
226 context: &mut Context<M, I>,
227) -> Result<ParseResult<M::Dealloc>, ParseError> {
228 context.module_cache.progress.insert(context.path.clone());
229 let read_result = context.io.read_to_string(context.path.as_str());
230 match read_result {
231 Ok(s) => {
232 let tokens = tokenize(context.manager, s);
233 parse_with_tokens(context, tokens.into_iter())
234 }
235 Err(_) => Err(ParseError::CannotReadFile),
236 }
237}
238
239pub fn parse_with_tokens<M: Manager + 'static, I: Io>(
240 context: &mut Context<M, I>,
241 iter: impl Iterator<Item = JsonToken<M::Dealloc>>,
242) -> Result<ParseResult<M::Dealloc>, ParseError> {
243 let mut state = JsonState::ParseRoot(RootState {
244 status: RootStatus::Initial,
245 state: default(),
246 new_line: true,
247 });
248 for token in iter {
249 state = json_state_push(state, context, token);
250 }
251 state.end()
252}
253
254#[cfg(test)]
255mod test {
256 use io_test::VirtualIo;
257 use io_trait::Io;
258 use wasm_bindgen_test::wasm_bindgen_test;
259
260 use crate::{
261 common::default::default,
262 js::{
263 js_array::JsArrayRef,
264 js_bigint::{from_u64, new_bigint, JsBigintRef, Sign},
265 js_object::JsObjectRef,
266 js_string::JsStringRef,
267 type_::Type,
268 },
269 mem::{global::GLOBAL, local::Local, manager::Manager},
270 tokenizer::{tokenize, ErrorType, JsonToken},
271 };
272
273 use super::super::{parser::parse, path::concat, shared::DataType};
274
275 use super::{parse_with_tokens, Context, ModuleCache, ParseError, ParseResult};
276
277 fn virtual_io() -> VirtualIo {
278 VirtualIo::new(&[])
279 }
280
281 fn create_test_context<'a, M: Manager>(
282 manager: M,
283 io: &'a VirtualIo,
284 module_cache: &'a mut ModuleCache<M::Dealloc>,
285 ) -> Context<'a, M, VirtualIo> {
286 Context::new(manager, io, default(), module_cache)
287 }
288
289 fn parse_with_virtual_io<M: Manager + 'static>(
290 manager: M,
291 iter: impl Iterator<Item = JsonToken<M::Dealloc>>,
292 ) -> Result<ParseResult<M::Dealloc>, ParseError> {
293 parse_with_tokens(
294 &mut create_test_context(manager, &virtual_io(), &mut default()),
295 iter,
296 )
297 }
298
299 fn test_global() {
300 let _ = {
301 let global = GLOBAL;
302 parse_with_tokens(
303 &mut create_test_context(global, &virtual_io(), &mut default()),
304 [].into_iter(),
305 )
306 };
307 }
308
309 #[test]
310 #[wasm_bindgen_test]
311 fn test_json() {
312 let json_str = include_str!("../../test/test-json.json");
313 let tokens = tokenize(GLOBAL, json_str.to_owned());
314 let result = parse_with_virtual_io(GLOBAL, tokens.into_iter());
315 assert!(result.is_ok());
316 assert_eq!(result.unwrap().data_type, DataType::Json);
317 }
318
319 #[test]
320 #[wasm_bindgen_test]
321 fn test_djs() {
322 let json_str = include_str!("../../test/test-djs.d.cjs");
323 let tokens = tokenize(GLOBAL, json_str.to_owned());
324 let result = parse_with_virtual_io(GLOBAL, tokens.into_iter());
325 assert!(result.is_ok());
326 assert_eq!(result.unwrap().data_type, DataType::Cjs);
327
328 let json_str = include_str!("../../test/test-djs.d.mjs");
329 let tokens = tokenize(GLOBAL, json_str.to_owned());
330 let result = parse_with_virtual_io(GLOBAL, tokens.into_iter());
331 assert!(result.is_ok());
332 assert_eq!(result.unwrap().data_type, DataType::Mjs);
333 }
334
335 #[test]
336 #[wasm_bindgen_test]
337 fn test_const() {
338 test_const_with_manager(GLOBAL);
339 }
340
341 fn test_const_with_manager<M: Manager + 'static>(manager: M) {
342 let json_str = include_str!("../../test/test-const.d.cjs");
343 let tokens = tokenize(manager, json_str.to_owned());
344 let result = parse_with_virtual_io(manager, tokens.into_iter());
345 assert!(result.is_ok());
346 let result_unwrap = result
347 .unwrap()
348 .any
349 .try_move::<JsArrayRef<M::Dealloc>>()
350 .unwrap();
351 let items = result_unwrap.items();
352 let item0 = items[0].clone();
353 assert_eq!(item0.try_move(), Ok(2.0));
354 let item1 = items[1].clone();
355 assert_eq!(item1.try_move(), Ok(2.0));
356
357 let json_str = include_str!("../../test/test-const-error.d.cjs.txt");
358 let tokens = tokenize(manager, json_str.to_owned());
359 let result = parse_with_virtual_io(manager, tokens.into_iter());
360 assert!(result.is_err());
361
362 let json_str = include_str!("../../test/test-const-error-new-line.d.cjs.txt");
363 let tokens = tokenize(manager, json_str.to_owned());
364 let result = parse_with_virtual_io(manager, tokens.into_iter());
365 assert!(result.is_err());
366 assert_eq!(result.unwrap_err(), ParseError::NewLineExpected);
367 }
368
369 #[test]
370 #[wasm_bindgen_test]
371 fn test_stack() {
372 test_stack_with_manager(GLOBAL);
373 }
374
375 fn test_stack_with_manager<M: Manager + 'static>(manager: M) {
376 let json_str = include_str!("../../test/test-stack.d.cjs");
377 let tokens = tokenize(manager, json_str.to_owned());
378 let result = parse_with_virtual_io(manager, tokens.into_iter());
379 assert!(result.is_ok());
380 let result_unwrap = result
381 .unwrap()
382 .any
383 .try_move::<JsArrayRef<M::Dealloc>>()
384 .unwrap();
385 let items = result_unwrap.items();
386 let item0 = items[0].clone();
387 let result_unwrap = item0.try_move::<JsObjectRef<M::Dealloc>>().unwrap();
388 let items = result_unwrap.items();
389 let (key0, value0) = items[0].clone();
390 let key0_items = key0.items();
391 assert_eq!(key0_items, [0x61]);
392 let result_unwrap = value0.try_move::<JsArrayRef<M::Dealloc>>().unwrap();
393 let items = result_unwrap.items();
394 let item0 = items[0].clone();
395 assert_eq!(item0.get_type(), Type::Null);
396 }
397
398 #[test]
399 #[wasm_bindgen_test]
400 fn test_import() {
401 test_import_with_manager(GLOBAL);
402 }
403
404 fn test_import_with_manager<M: Manager + 'static>(manager: M) {
405 let io: VirtualIo = VirtualIo::new(&[]);
406
407 let main = include_str!("../../test/test_import_main.d.cjs");
408 let main_path = "test_import_main.d.cjs";
410 io.write(main_path, main.as_bytes()).unwrap();
411
412 let module = include_str!("../../test/test_import_module.d.cjs");
413 let module_path = "test_import_module.d.cjs";
414 io.write(module_path, module.as_bytes()).unwrap();
415
416 let mut mc = default();
417 let mut context = Context::new(
418 manager,
419 &io,
420 concat(io.current_dir().unwrap().as_str(), main_path),
421 &mut mc,
422 );
423
424 let result = parse(&mut context);
425 assert!(result.is_ok());
426 let result_unwrap = result
427 .unwrap()
428 .any
429 .try_move::<JsArrayRef<M::Dealloc>>()
430 .unwrap();
431 let items = result_unwrap.items();
432 let item0 = items[0].clone();
433 assert_eq!(item0.try_move(), Ok(3.0));
434
435 let io: VirtualIo = VirtualIo::new(&[]);
436
437 let main = include_str!("../../test/test_import_main.d.mjs");
438 let main_path = "test_import_main.d.mjs";
440 io.write(main_path, main.as_bytes()).unwrap();
441
442 let module = include_str!("../../test/test_import_module.d.mjs");
443 let module_path = "test_import_module.d.mjs";
444 io.write(module_path, module.as_bytes()).unwrap();
445
446 let mut mc = default();
447 let mut context = Context::new(
448 manager,
449 &io,
450 concat(io.current_dir().unwrap().as_str(), main_path),
451 &mut mc,
452 );
453
454 let result = parse(&mut context);
455 assert!(result.is_ok());
456 let result_unwrap = result
457 .unwrap()
458 .any
459 .try_move::<JsArrayRef<M::Dealloc>>()
460 .unwrap();
461 let items = result_unwrap.items();
462 let item0 = items[0].clone();
463 assert_eq!(item0.try_move(), Ok(4.0));
464 }
465
466 #[test]
467 #[wasm_bindgen_test]
468 fn test_cache() {
469 test_cache_with_manager(GLOBAL);
470 }
471
472 fn test_cache_with_manager<M: Manager + 'static>(manager: M) {
473 let io: VirtualIo = VirtualIo::new(&[]);
474
475 let main = include_str!("../../test/test_cache_main.d.cjs");
476 let main_path = "test_cache_main.d.cjs";
477 io.write(main_path, main.as_bytes()).unwrap();
478
479 let module_b = include_str!("../../test/test_cache_b.d.cjs");
480 let module_b_path = "test_cache_b.d.cjs";
481 io.write(module_b_path, module_b.as_bytes()).unwrap();
482
483 let module_c = include_str!("../../test/test_cache_c.d.cjs");
484 let module_c_path = "test_cache_c.d.cjs";
485 io.write(module_c_path, module_c.as_bytes()).unwrap();
486
487 let mut mc = default();
488 let mut context = Context::new(
489 manager,
490 &io,
491 concat(io.current_dir().unwrap().as_str(), main_path),
492 &mut mc,
493 );
494
495 let result = parse(&mut context);
496 assert!(result.is_ok());
497 let result_unwrap = result
498 .unwrap()
499 .any
500 .try_move::<JsArrayRef<M::Dealloc>>()
501 .unwrap();
502 let items = result_unwrap.items();
503 let item0 = items[0].clone();
504 assert_eq!(item0.try_move(), Ok(1.0));
505 let item1 = items[1].clone();
506 assert_eq!(item1.try_move(), Ok(1.0));
507
508 let io: VirtualIo = VirtualIo::new(&[]);
509
510 let main = include_str!("../../test/test_cache_main.d.mjs");
511 let main_path = "test_cache_main.d.mjs";
512 io.write(main_path, main.as_bytes()).unwrap();
513
514 let module_b = include_str!("../../test/test_cache_b.d.mjs");
515 let module_b_path = "test_cache_b.d.mjs";
516 io.write(module_b_path, module_b.as_bytes()).unwrap();
517
518 let module_c = include_str!("../../test/test_cache_c.d.mjs");
519 let module_c_path = "test_cache_c.d.mjs";
520 io.write(module_c_path, module_c.as_bytes()).unwrap();
521
522 let mut mc = default();
523 let mut context = Context::new(
524 manager,
525 &io,
526 concat(io.current_dir().unwrap().as_str(), main_path),
527 &mut mc,
528 );
529
530 let result = parse(&mut context);
531 assert!(result.is_ok());
532 let result_unwrap = result
533 .unwrap()
534 .any
535 .try_move::<JsArrayRef<M::Dealloc>>()
536 .unwrap();
537 let items = result_unwrap.items();
538 let item0 = items[0].clone();
539 assert_eq!(item0.try_move(), Ok(2.0));
540 let item1 = items[1].clone();
541 assert_eq!(item1.try_move(), Ok(2.0));
542 }
543
544 #[test]
545 #[wasm_bindgen_test]
546 fn test_circular_error() {
547 test_circular_error_with_manager(GLOBAL);
548 }
549
550 fn test_circular_error_with_manager<M: Manager + 'static>(manager: M) {
551 let io: VirtualIo = VirtualIo::new(&[]);
552
553 let main = include_str!("../../test/test_circular_1.d.cjs.txt");
554 let main_path = "test_circular_1.d.cjs.txt";
555 io.write(main_path, main.as_bytes()).unwrap();
556
557 let module = include_str!("../../test/test_circular_2.d.cjs.txt");
558 let module_path = "test_circular_2.d.cjs.txt";
559 io.write(module_path, module.as_bytes()).unwrap();
560
561 let mut mc = default();
562 let mut context = Context::new(
563 manager,
564 &io,
565 concat(io.current_dir().unwrap().as_str(), main_path),
566 &mut mc,
567 );
568
569 let result = parse(&mut context);
570 assert!(result.is_err());
571 assert_eq!(result.unwrap_err(), ParseError::CircularDependency);
572
573 let io: VirtualIo = VirtualIo::new(&[]);
574
575 let main = include_str!("../../test/test_circular_1.d.mjs.txt");
576 let main_path = "test_circular_1.d.mjs.txt";
577 io.write(main_path, main.as_bytes()).unwrap();
578
579 let module = include_str!("../../test/test_circular_2.d.mjs.txt");
580 let module_path = "test_circular_2.d.mjs.txt";
581 io.write(module_path, module.as_bytes()).unwrap();
582
583 let mut mc = default();
584 let mut context = Context::new(
585 manager,
586 &io,
587 concat(io.current_dir().unwrap().as_str(), main_path),
588 &mut mc,
589 );
590
591 let result = parse(&mut context);
592 assert!(result.is_err());
593 assert_eq!(result.unwrap_err(), ParseError::CircularDependency);
594 }
595
596 #[test]
597 #[wasm_bindgen_test]
598 fn test_import_error() {
599 test_import_error_with_manager(GLOBAL);
600 }
601
602 fn test_import_error_with_manager<M: Manager + 'static>(manager: M) {
603 let io: VirtualIo = VirtualIo::new(&[]);
604
605 let main = include_str!("../../test/test_import_error.d.cjs.txt");
606 let main_path = "test_import_error.d.cjs.txt";
608 io.write(main_path, main.as_bytes()).unwrap();
609
610 let module = include_str!("../../test/test_import_module.d.mjs");
611 let module_path = "test_import_module.d.mjs";
612 io.write(module_path, module.as_bytes()).unwrap();
613
614 let mut mc = default();
615 let mut context = Context::new(
616 manager,
617 &io,
618 concat(io.current_dir().unwrap().as_str(), main_path),
619 &mut mc,
620 );
621
622 let result = parse(&mut context);
623 assert!(result.is_err());
624 assert_eq!(result.unwrap_err(), ParseError::UnexpectedToken);
625
626 let io: VirtualIo = VirtualIo::new(&[]);
627
628 let main = include_str!("../../test/test_import_error.d.mjs.txt");
629 let main_path = "test_import_error.d.mjs.txt";
631 io.write(main_path, main.as_bytes()).unwrap();
632
633 let module = include_str!("../../test/test_import_module.d.cjs");
634 let module_path = "test_import_module.d.cjs";
635 io.write(module_path, module.as_bytes()).unwrap();
636
637 let mut mc = default();
638 let mut context = Context::new(
639 manager,
640 &io,
641 concat(io.current_dir().unwrap().as_str(), main_path),
642 &mut mc,
643 );
644
645 let result = parse(&mut context);
646 assert!(result.is_err());
647 assert_eq!(result.unwrap_err(), ParseError::UnexpectedToken);
648 }
649
650 #[test]
651 #[wasm_bindgen_test]
652 fn test_trailing_comma() {
653 let json_str = include_str!("../../test/test-trailing-comma.d.cjs");
654 let tokens = tokenize(GLOBAL, json_str.to_owned());
655 let result = parse_with_virtual_io(GLOBAL, tokens.into_iter());
656 assert!(result.is_ok());
657 }
658
659 #[test]
660 #[wasm_bindgen_test]
661 fn test_check_sizes() {
662 {
663 let tokens = [
664 JsonToken::ObjectBegin,
665 JsonToken::String(String::from("k")),
666 JsonToken::Colon,
667 JsonToken::ObjectBegin,
668 JsonToken::ObjectEnd,
669 JsonToken::ObjectEnd,
670 ];
671 {
672 let result = parse_with_virtual_io(GLOBAL, tokens.into_iter());
673 assert!(result.is_ok());
674 let _result_unwrap = result.unwrap();
675 }
676 }
678 }
679
680 #[test]
681 #[wasm_bindgen_test]
682 fn test_check_sizes2() {
683 let local = Local::default();
684 {
685 let tokens = [
686 JsonToken::ObjectBegin,
687 JsonToken::String(String::from("k")),
688 JsonToken::Colon,
689 JsonToken::ObjectBegin,
690 JsonToken::ObjectEnd,
691 JsonToken::ObjectEnd,
692 ];
693 {
694 let result = parse_with_virtual_io(GLOBAL, tokens.into_iter());
695 assert!(result.is_ok());
696 let result_unwrap = result.unwrap().any;
697 let _result_unwrap = result_unwrap.try_move::<JsObjectRef<_>>();
698 }
699 assert_eq!(local.size(), 0);
700 }
701 }
702
703 #[test]
704 #[wasm_bindgen_test]
705 fn test_data_type() {
706 let tokens = [JsonToken::Id(String::from("null"))];
707 let result = parse_with_virtual_io(GLOBAL, tokens.into_iter());
708 assert!(result.is_ok());
709 assert_eq!(result.unwrap().data_type, DataType::Json);
710 }
711
712 #[test]
713 #[wasm_bindgen_test]
714 fn test_export_block() {
715 let tokens = [
716 JsonToken::Id(String::from("export")),
717 JsonToken::Id(String::from("default")),
718 JsonToken::Id(String::from("null")),
719 ];
720 let result = parse_with_virtual_io(GLOBAL, tokens.into_iter());
721 assert!(result.is_ok());
722 assert_eq!(result.unwrap().data_type, DataType::Mjs);
723
724 let tokens = [
725 JsonToken::Id(String::from("module")),
726 JsonToken::Dot,
727 JsonToken::Id(String::from("exports")),
728 JsonToken::Equals,
729 JsonToken::Id(String::from("null")),
730 ];
731 let result = parse_with_virtual_io(GLOBAL, tokens.into_iter());
732 assert!(result.is_ok());
733 assert_eq!(result.unwrap().data_type, DataType::Cjs);
734 }
735
736 #[test]
737 #[wasm_bindgen_test]
738 fn test_id_in_objects() {
739 let tokens = [
740 JsonToken::Id(String::from("export")),
741 JsonToken::Id(String::from("default")),
742 JsonToken::ObjectBegin,
743 JsonToken::Id(String::from("key")),
744 JsonToken::Colon,
745 JsonToken::Number(0.0),
746 JsonToken::ObjectEnd,
747 ];
748 let result = parse_with_virtual_io(GLOBAL, tokens.into_iter());
749 assert!(result.is_ok());
750 let result_unwrap = result.unwrap().any.try_move::<JsObjectRef<_>>().unwrap();
751 let items = result_unwrap.items();
752 let (key0, value0) = items[0].clone();
753 let key0_items = key0.items();
754 assert_eq!(key0_items, [0x6b, 0x65, 0x79]);
755 assert_eq!(value0.try_move(), Ok(0.0));
756
757 let tokens = [
758 JsonToken::ObjectBegin,
759 JsonToken::Id(String::from("key")),
760 JsonToken::Colon,
761 JsonToken::Number(0.0),
762 JsonToken::ObjectEnd,
763 ];
764 let result = parse_with_virtual_io(GLOBAL, tokens.into_iter());
765 assert!(result.is_err());
766 }
767
768 #[test]
769 #[wasm_bindgen_test]
770 fn test_valid_global() {
771 test_valid_with_manager(GLOBAL);
772 }
773
774 fn test_valid_with_manager<M: Manager + 'static>(manager: M) {
775 let tokens = [JsonToken::Id(String::from("null"))];
776 let result = parse_with_virtual_io(manager, tokens.into_iter());
777 assert!(result.is_ok());
778 assert_eq!(result.unwrap().any.get_type(), Type::Null);
779
780 let tokens = [JsonToken::Id(String::from("true"))];
781 let result = parse_with_virtual_io(manager, tokens.into_iter());
782 assert!(result.is_ok());
783 assert_eq!(result.unwrap().any.try_move(), Ok(true));
784
785 let tokens = [JsonToken::Id(String::from("false"))];
786 let result = parse_with_virtual_io(manager, tokens.into_iter());
787 assert!(result.is_ok());
788 assert_eq!(result.unwrap().any.try_move(), Ok(false));
789
790 let tokens = [JsonToken::Number(0.1)];
791 let result = parse_with_virtual_io(manager, tokens.into_iter());
792 assert!(result.is_ok());
793 assert_eq!(result.unwrap().any.try_move(), Ok(0.1));
794
795 let tokens = [JsonToken::String(String::from("abc"))];
796 let result = parse_with_virtual_io(manager, tokens.into_iter());
797 assert!(result.is_ok());
798 let result = result.unwrap().any.try_move::<JsStringRef<M::Dealloc>>();
799 assert!(result.is_ok());
800 let result = result.unwrap();
801 let items = result.items();
802 assert_eq!(items, [0x61, 0x62, 0x63]);
803
804 let tokens = [JsonToken::BigInt(from_u64(manager, Sign::Positive, 1))];
805 let result = parse_with_virtual_io(manager, tokens.into_iter());
806 assert!(result.is_ok());
807 let result = result.unwrap().any.try_move::<JsBigintRef<M::Dealloc>>();
808 assert!(result.is_ok());
809 let result = result.unwrap();
810 assert_eq!(result.header_len(), 1);
811 let items = result.items();
812 assert_eq!(items, [0x1]);
813
814 let tokens = [JsonToken::BigInt(new_bigint(
815 manager,
816 Sign::Negative,
817 [2, 3],
818 ))];
819 let result = parse_with_virtual_io(manager, tokens.into_iter());
820 assert!(result.is_ok());
821 let result = result.unwrap().any.try_move::<JsBigintRef<M::Dealloc>>();
822 assert!(result.is_ok());
823 let result = result.unwrap();
824 assert_eq!(result.header_len(), -2);
825 let items = result.items();
826 assert_eq!(items, [0x2, 0x3]);
827
828 let tokens = [JsonToken::ArrayBegin, JsonToken::ArrayEnd];
829 let result = parse_with_virtual_io(manager, tokens.into_iter());
830 assert!(result.is_ok());
831 let result_unwrap = result
832 .unwrap()
833 .any
834 .try_move::<JsArrayRef<M::Dealloc>>()
835 .unwrap();
836 let items = result_unwrap.items();
837 assert!(items.is_empty());
838
839 let tokens = [
840 JsonToken::ArrayBegin,
841 JsonToken::Number(1.0),
842 JsonToken::Comma,
843 JsonToken::Id(String::from("true")),
844 JsonToken::ArrayEnd,
845 ];
846 let result = parse_with_virtual_io(manager, tokens.into_iter());
847 assert!(result.is_ok());
848 let result_unwrap = result
849 .unwrap()
850 .any
851 .try_move::<JsArrayRef<M::Dealloc>>()
852 .unwrap();
853 let items = result_unwrap.items();
854 let item0 = items[0].clone();
855 assert_eq!(item0.try_move(), Ok(1.0));
856 let item1 = items[1].clone();
857 assert_eq!(item1.try_move(), Ok(true));
858
859 let tokens = [
860 JsonToken::ArrayBegin,
861 JsonToken::Number(1.0),
862 JsonToken::Comma,
863 JsonToken::Id(String::from("true")),
864 JsonToken::Comma,
865 JsonToken::ArrayEnd,
866 ];
867 let result = parse_with_virtual_io(manager, tokens.into_iter());
868 assert!(result.is_ok());
869
870 let tokens = [
871 JsonToken::ObjectBegin,
872 JsonToken::String(String::from("k1")),
873 JsonToken::Colon,
874 JsonToken::Number(1.0),
875 JsonToken::Comma,
876 JsonToken::String(String::from("k0")),
877 JsonToken::Colon,
878 JsonToken::Number(0.0),
879 JsonToken::Comma,
880 JsonToken::String(String::from("k2")),
881 JsonToken::Colon,
882 JsonToken::Number(2.0),
883 JsonToken::ObjectEnd,
884 ];
885 let result = parse_with_virtual_io(manager, tokens.into_iter());
886 assert!(result.is_ok());
887 let result_unwrap = result
888 .unwrap()
889 .any
890 .try_move::<JsObjectRef<M::Dealloc>>()
891 .unwrap();
892 let items = result_unwrap.items();
893 let (key0, value0) = items[0].clone();
894 let key0_items = key0.items();
895 assert_eq!(key0_items, [0x6b, 0x30]);
896 assert_eq!(value0.try_move(), Ok(0.0));
897 let (key1, value1) = items[1].clone();
898 let key1_items = key1.items();
899 assert_eq!(key1_items, [0x6b, 0x31]);
900 assert_eq!(value1.try_move(), Ok(1.0));
901 let (key2, value2) = items[2].clone();
902 let key2_items = key2.items();
903 assert_eq!(key2_items, [0x6b, 0x32]);
904 assert_eq!(value2.try_move(), Ok(2.0));
905
906 let tokens = [JsonToken::ObjectBegin, JsonToken::ObjectEnd];
907 let result = parse_with_virtual_io(manager, tokens.into_iter());
908 assert!(result.is_ok());
909 let result_unwrap = result
910 .unwrap()
911 .any
912 .try_move::<JsObjectRef<M::Dealloc>>()
913 .unwrap();
914 let items = result_unwrap.items();
915 assert!(items.is_empty());
916 let tokens = [
917 JsonToken::ObjectBegin,
918 JsonToken::String(String::from("k")),
919 JsonToken::Colon,
920 JsonToken::ObjectBegin,
921 JsonToken::ObjectEnd,
922 JsonToken::ObjectEnd,
923 ];
924 {
925 let result = parse_with_virtual_io(manager, tokens.into_iter());
926 assert!(result.is_ok());
927 let result_unwrap = result.unwrap();
928 let result_unwrap = result_unwrap
929 .any
930 .try_move::<JsObjectRef<M::Dealloc>>()
931 .unwrap();
932 let items = result_unwrap.items();
933 let (_, value0) = items[0].clone();
934 let value0_unwrap = value0.try_move::<JsObjectRef<M::Dealloc>>().unwrap();
935 let value0_items = value0_unwrap.items();
936 assert!(value0_items.is_empty());
937 }
938 }
939
940 #[test]
941 #[wasm_bindgen_test]
942 fn test_invalid_global() {
943 test_invalid_with_manager(GLOBAL);
944 }
945
946 fn test_invalid_with_manager<M: Manager + 'static>(manager: M) {
947 let tokens = [];
948 let result = parse_with_virtual_io(manager, tokens.into_iter());
949 assert!(result.is_err());
950
951 let tokens = [JsonToken::ErrorToken(ErrorType::InvalidNumber)];
952 let result = parse_with_virtual_io(manager, tokens.into_iter());
953 assert!(result.is_err());
954
955 let tokens = [JsonToken::ArrayBegin, JsonToken::Comma, JsonToken::ArrayEnd];
956 let result = parse_with_virtual_io(manager, tokens.into_iter());
957 assert!(result.is_err());
958
959 let tokens = [
960 JsonToken::ArrayBegin,
961 JsonToken::Number(0.0),
962 JsonToken::Number(1.0),
963 JsonToken::ArrayEnd,
964 ];
965 let result = parse_with_virtual_io(manager, tokens.into_iter());
966 assert!(result.is_err());
967
968 let tokens = [
969 JsonToken::ArrayBegin,
970 JsonToken::Number(0.0),
971 JsonToken::Comma,
972 JsonToken::Comma,
973 JsonToken::Number(1.0),
974 JsonToken::ArrayEnd,
975 ];
976 let result = parse_with_virtual_io(manager, tokens.into_iter());
977 assert!(result.is_err());
978
979 let tokens = [
980 JsonToken::ArrayBegin,
981 JsonToken::ArrayEnd,
982 JsonToken::ArrayEnd,
983 ];
984 let result = parse_with_virtual_io(manager, tokens.into_iter());
985 assert!(result.is_err());
986
987 let tokens = [JsonToken::ArrayBegin, JsonToken::String(String::default())];
988 let result = parse_with_virtual_io(manager, tokens.into_iter());
989 assert!(result.is_err());
990
991 let tokens = [
992 JsonToken::ArrayBegin,
993 JsonToken::Comma,
994 JsonToken::Number(1.0),
995 JsonToken::ArrayEnd,
996 ];
997 let result = parse_with_virtual_io(manager, tokens.into_iter());
998 assert!(result.is_err());
999
1000 let tokens = [JsonToken::ArrayBegin, JsonToken::Colon, JsonToken::ArrayEnd];
1001 let result = parse_with_virtual_io(manager, tokens.into_iter());
1002 assert!(result.is_err());
1003
1004 let tokens = [JsonToken::ArrayEnd];
1005 let result = parse_with_virtual_io(manager, tokens.into_iter());
1006 assert!(result.is_err());
1007
1008 let tokens = [
1009 JsonToken::ObjectBegin,
1010 JsonToken::Comma,
1011 JsonToken::ObjectEnd,
1012 ];
1013 let result = parse_with_virtual_io(manager, tokens.into_iter());
1014 assert!(result.is_err());
1015
1016 let tokens = [
1017 JsonToken::ObjectBegin,
1018 JsonToken::Number(0.0),
1019 JsonToken::Comma,
1020 JsonToken::Number(1.0),
1021 JsonToken::ObjectEnd,
1022 ];
1023 let result = parse_with_virtual_io(manager, tokens.into_iter());
1024 assert!(result.is_err());
1025
1026 let tokens = [
1027 JsonToken::ObjectBegin,
1028 JsonToken::String(String::from("key")),
1029 JsonToken::Number(0.0),
1030 JsonToken::ObjectEnd,
1031 ];
1032 let result = parse_with_virtual_io(manager, tokens.into_iter());
1033 assert!(result.is_err());
1034
1035 let tokens = [
1036 JsonToken::ObjectBegin,
1037 JsonToken::String(String::from("key")),
1038 JsonToken::Colon,
1039 JsonToken::Colon,
1040 JsonToken::Number(0.0),
1041 JsonToken::ObjectEnd,
1042 ];
1043 let result = parse_with_virtual_io(manager, tokens.into_iter());
1044 assert!(result.is_err());
1045
1046 let tokens = [
1047 JsonToken::ObjectBegin,
1048 JsonToken::String(String::from("key0")),
1049 JsonToken::Colon,
1050 JsonToken::Number(0.0),
1051 JsonToken::Comma,
1052 JsonToken::Comma,
1053 JsonToken::String(String::from("key1")),
1054 JsonToken::Colon,
1055 JsonToken::Number(1.0),
1056 JsonToken::ObjectEnd,
1057 ];
1058 let result = parse_with_virtual_io(manager, tokens.into_iter());
1059 assert!(result.is_err());
1060
1061 let tokens = [
1062 JsonToken::ObjectBegin,
1063 JsonToken::ObjectEnd,
1064 JsonToken::ObjectEnd,
1065 ];
1066 let result = parse_with_virtual_io(manager, tokens.into_iter());
1067 assert!(result.is_err());
1068
1069 let tokens = [
1070 JsonToken::ObjectBegin,
1071 JsonToken::String(String::from("key")),
1072 JsonToken::Colon,
1073 JsonToken::Number(0.0),
1074 ];
1075 let result = parse_with_virtual_io(manager, tokens.into_iter());
1076 assert!(result.is_err());
1077
1078 let tokens = [
1079 JsonToken::ObjectBegin,
1080 JsonToken::Comma,
1081 JsonToken::String(String::from("key")),
1082 JsonToken::Colon,
1083 JsonToken::Number(0.0),
1084 JsonToken::ObjectEnd,
1085 ];
1086 let result = parse_with_virtual_io(manager, tokens.into_iter());
1087 assert!(result.is_err());
1088
1089 let tokens = [JsonToken::ObjectEnd];
1090 let result = parse_with_virtual_io(manager, tokens.into_iter());
1091 assert!(result.is_err());
1092
1093 let tokens = [
1094 JsonToken::ArrayBegin,
1095 JsonToken::ObjectBegin,
1096 JsonToken::ArrayEnd,
1097 JsonToken::ObjectEnd,
1098 ];
1099 let result = parse_with_virtual_io(manager, tokens.into_iter());
1100 assert!(result.is_err());
1101
1102 let tokens = [
1103 JsonToken::ObjectBegin,
1104 JsonToken::ArrayBegin,
1105 JsonToken::ObjectEnd,
1106 JsonToken::ArrayEnd,
1107 ];
1108 let result = parse_with_virtual_io(manager, tokens.into_iter());
1109 assert!(result.is_err());
1110 }
1111}