diff options
Diffstat (limited to 'deepcrow/src/lib.rs')
| -rw-r--r-- | deepcrow/src/lib.rs | 246 |
1 files changed, 0 insertions, 246 deletions
diff --git a/deepcrow/src/lib.rs b/deepcrow/src/lib.rs index b10cd03..b9a4ffe 100644 --- a/deepcrow/src/lib.rs +++ b/deepcrow/src/lib.rs | |||
| @@ -298,249 +298,3 @@ fn exec<'a>(input: &StatefulContext<'a>, tokens: &Vec<Token>, buf: &mut String) | |||
| 298 | Ok(()) | 298 | Ok(()) |
| 299 | } | 299 | } |
| 300 | 300 | ||
| 301 | #[cfg(test)] | ||
| 302 | mod tests { | ||
| 303 | use super::*; | ||
| 304 | |||
| 305 | use crate::lexer::*; | ||
| 306 | |||
| 307 | #[test] | ||
| 308 | fn lexing() { | ||
| 309 | let data = r#"Leading comment: [|view "basic" something="yeup"|>Hello there <|view|] Trailing text"#; | ||
| 310 | let ll = lexer::Lexer::new( &data ); | ||
| 311 | for sym in ll { | ||
| 312 | if let SymbolType::Error{what} = sym.symbol() { | ||
| 313 | println!("Error {}:{}: {:?}", sym.start().line, sym.start().column, what ); | ||
| 314 | break; | ||
| 315 | } else { | ||
| 316 | println!("Symbol: {:?}", sym ); | ||
| 317 | } | ||
| 318 | } | ||
| 319 | } | ||
| 320 | |||
| 321 | #[test] | ||
| 322 | fn parsing() { | ||
| 323 | let mut ct = DeepCrow::new(); | ||
| 324 | if let Err(e) = ct.load_static(r#"Here is a sample | ||
| 325 | [|view "index" theme="standard"|><html><body>Hi</body></html><|view|] | ||
| 326 | That was fun! now a placeholder: [|view "placeholder"|] and now one with an implicit [|view "simple"|>Body -> [|show content|] <- and end<|view|] aoeu | ||
| 327 | |||
| 328 | [|view "person" layout="simple"|>Welcome [|show person.last_name|], [|show person.first_name|]! It's lovely to see you again.<|view|] | ||
| 329 | |||
| 330 | Now with explicit outputs: | ||
| 331 | [|view "complex"|> | ||
| 332 | [|output "content"|> | ||
| 333 | Here's a [|show name|]. | ||
| 334 | <|output|] | ||
| 335 | [|output "sidebar"|> | ||
| 336 | What's up world? | ||
| 337 | <|output|] | ||
| 338 | [|output "footer"|> | ||
| 339 | Same, I guess! | ||
| 340 | <|output|] | ||
| 341 | <|view|]"#) { | ||
| 342 | println!("Error: {:?}", e ); | ||
| 343 | } else { | ||
| 344 | println!("It finished"); | ||
| 345 | if let Ok(v) = ct.render( | ||
| 346 | "person", | ||
| 347 | &Context::from([ | ||
| 348 | ("hi".to_string(),Value::String("hi".to_string())), | ||
| 349 | ("person".to_string(),Value::Dictionary(HashMap::from([ | ||
| 350 | ("first_name".to_string(), Value::String("Bob".to_string())), | ||
| 351 | ("last_name".to_string(), Value::String("Smith".to_string())), | ||
| 352 | ]))), | ||
| 353 | ]) | ||
| 354 | ) { | ||
| 355 | println!("View result: {:?}", v ); | ||
| 356 | } else { | ||
| 357 | println!("Error?"); | ||
| 358 | } | ||
| 359 | } | ||
| 360 | } | ||
| 361 | |||
| 362 | #[test] | ||
| 363 | fn loops() -> Result<()> { | ||
| 364 | let mut ct = DeepCrow::new(); | ||
| 365 | ct.load_static(r#"Looping code: | ||
| 366 | [|view "index"|>We will enumerate people here:[|loop people|> | ||
| 367 | - [|show last_name|], [|show first_name|][|if show_title |>: [|show title|] <|else|> **title redacted** <|if|] ::>[|loop tags|> [|show tag|]<|loop|] <:: <|loop|] | ||
| 368 | <|view|] | ||
| 369 | "#)?; | ||
| 370 | |||
| 371 | let ctx = Context::from([ | ||
| 372 | ("people".to_string(), vec![ | ||
| 373 | [ | ||
| 374 | ("first_name".into(), "Joe".into()), | ||
| 375 | ("last_name".into(), "Smith".into()), | ||
| 376 | ("show_title".into(), true.into()), | ||
| 377 | ("title".into(), "CEO".into()), | ||
| 378 | ("tags".into(), vec![ | ||
| 379 | Context::from([("tag".into(), "jerk".into()),]).into(), | ||
| 380 | Context::from([("tag".into(), "ugly".into()),]).into(), | ||
| 381 | ].into()), | ||
| 382 | ].into(), | ||
| 383 | [ | ||
| 384 | ("first_name".into(), "Chris".into()), | ||
| 385 | ("last_name".into(), "Perkens".into()), | ||
| 386 | ("show_title".into(), false.into()), | ||
| 387 | ("title".into(), "Baconeer".into()), | ||
| 388 | ("tags".into(), vec![ | ||
| 389 | Context::from([("tag".into(), "jerk".into()),]).into(), | ||
| 390 | Context::from([("tag".into(), "ugly".into()),]).into(), | ||
| 391 | ].into()), | ||
| 392 | ].into(), | ||
| 393 | [ | ||
| 394 | ("first_name".into(), "Will".into()), | ||
| 395 | ("last_name".into(), "Power".into()), | ||
| 396 | ("show_title".into(), false.into()), | ||
| 397 | ("title".into(), "CFO".into()), | ||
| 398 | ("tags".into(), vec![ | ||
| 399 | Context::from([("tag".into(), "jerk".into()),]).into(), | ||
| 400 | Context::from([("tag".into(), "ugly".into()),]).into(), | ||
| 401 | ].into()), | ||
| 402 | ].into(), | ||
| 403 | [ | ||
| 404 | ("first_name".into(), "Justin".into()), | ||
| 405 | ("last_name".into(), "Time".into()), | ||
| 406 | ("show_title".into(), true.into()), | ||
| 407 | ("title".into(), "CIO".into()), | ||
| 408 | ("tags".into(), vec![ | ||
| 409 | Context::from([("tag".into(), "jerk".into()),]).into(), | ||
| 410 | Context::from([("tag".into(), "ugly".into()),]).into(), | ||
| 411 | ].into()), | ||
| 412 | ].into(), | ||
| 413 | ].into()), | ||
| 414 | ]); | ||
| 415 | |||
| 416 | println!("View result: {}", ct.render("index", &ctx)? ); | ||
| 417 | |||
| 418 | Ok(()) | ||
| 419 | } | ||
| 420 | |||
| 421 | #[test] | ||
| 422 | fn conditional() -> Result<()> { | ||
| 423 | let mut ct = DeepCrow::new(); | ||
| 424 | ct.load_static(r#"Hi there | ||
| 425 | [|view "index"|> | ||
| 426 | Color: [|if is_red|> red <|elif is_blue |> blue <|else|> green <|if|] | ||
| 427 | <|view|]"#)?; | ||
| 428 | |||
| 429 | let ctx = Context::from([ | ||
| 430 | ("is_red".into(), false.into()), | ||
| 431 | ("is_blue".into(), false.into()), | ||
| 432 | ("color".into(), "purple".into()), | ||
| 433 | ]); | ||
| 434 | |||
| 435 | println!("View result: {}", ct.render("index", &ctx)? ); | ||
| 436 | |||
| 437 | Ok(()) | ||
| 438 | } | ||
| 439 | |||
| 440 | struct Item { | ||
| 441 | pub id: i32, | ||
| 442 | pub title: String, | ||
| 443 | pub body: String, | ||
| 444 | } | ||
| 445 | |||
| 446 | struct Person { | ||
| 447 | pub id: i32, | ||
| 448 | pub username: String, | ||
| 449 | pub name: String, | ||
| 450 | } | ||
| 451 | |||
| 452 | struct Page { | ||
| 453 | pub user: Person, | ||
| 454 | pub total_items: i32, | ||
| 455 | pub total_pages: i32, | ||
| 456 | pub cur_page: i32, | ||
| 457 | pub items: Vec<Item>, | ||
| 458 | } | ||
| 459 | |||
| 460 | impl Page { | ||
| 461 | fn new() -> Page { | ||
| 462 | Page { | ||
| 463 | user: Person { | ||
| 464 | id: 443, | ||
| 465 | username: "eichlan".into(), | ||
| 466 | name: "Mike".into(), | ||
| 467 | }, | ||
| 468 | total_items: 4000, | ||
| 469 | total_pages: 400, | ||
| 470 | cur_page: 35, | ||
| 471 | items: vec![ | ||
| 472 | Item{ | ||
| 473 | id: 123, | ||
| 474 | title: "hi".into(), | ||
| 475 | body: "body".into(), | ||
| 476 | }, | ||
| 477 | Item{ | ||
| 478 | id: 124, | ||
| 479 | title: "bye".into(), | ||
| 480 | body: "wooo".into(), | ||
| 481 | }, | ||
| 482 | Item{ | ||
| 483 | id: 125, | ||
| 484 | title: "ciao".into(), | ||
| 485 | body: "whatever".into(), | ||
| 486 | } | ||
| 487 | ], | ||
| 488 | } | ||
| 489 | } | ||
| 490 | } | ||
| 491 | |||
| 492 | impl<'a> MappedStructure<'a> for Page { | ||
| 493 | fn get_value(&'a self, id: &str) -> Option<MappedValue<'a>> { | ||
| 494 | match id { | ||
| 495 | "user" => Some(MappedValue::Struct(&self.user)), | ||
| 496 | "total_items" => Some(MappedValue::Int32(self.total_items)), | ||
| 497 | "total_pages" => Some(MappedValue::Int32(self.total_pages)), | ||
| 498 | "cur_page" => Some(MappedValue::Int32(self.cur_page)), | ||
| 499 | "items" => Some(MappedValue::<'a>::List(&self.items)), | ||
| 500 | _ => None, | ||
| 501 | } | ||
| 502 | } | ||
| 503 | } | ||
| 504 | |||
| 505 | impl<'a> MappedStructure<'a> for Person { | ||
| 506 | fn get_value(&'a self, id: &str) -> Option<MappedValue<'a>> { | ||
| 507 | match id { | ||
| 508 | "id" => Some(MappedValue::Int32(self.id)), | ||
| 509 | "username" => Some(MappedValue::String(&self.username)), | ||
| 510 | "name" => Some(MappedValue::String(&self.name)), | ||
| 511 | _ => None, | ||
| 512 | } | ||
| 513 | } | ||
| 514 | } | ||
| 515 | |||
| 516 | impl<'a> MappedStructure<'a> for Item { | ||
| 517 | fn get_value(&'a self, id: &str) -> Option<MappedValue<'a>> { | ||
| 518 | match id { | ||
| 519 | "id" => Some(MappedValue::Int32(self.id)), | ||
| 520 | "title" => Some(MappedValue::String(&self.title)), | ||
| 521 | "body" => Some(MappedValue::String(&self.body)), | ||
| 522 | _ => None, | ||
| 523 | } | ||
| 524 | } | ||
| 525 | } | ||
| 526 | |||
| 527 | #[test] | ||
| 528 | fn custom() -> Result<()> { | ||
| 529 | let page = Page::new(); | ||
| 530 | |||
| 531 | println!("{:?}", | ||
| 532 | page.get_value(&"total_pages") | ||
| 533 | ); | ||
| 534 | |||
| 535 | if let Some(MappedValue::List(l)) = page.get_value(&"items") { | ||
| 536 | l.for_each(&|x: &MappedValue, buf: &mut String| { | ||
| 537 | if let MappedValue::Struct(s) = x { | ||
| 538 | println!(" - {:?}", s.get_value(&"title")); | ||
| 539 | buf.push_str(&format!("{:?}",s.get_value(&"title"))); | ||
| 540 | } | ||
| 541 | Ok(()) | ||
| 542 | }).expect("loop"); | ||
| 543 | } | ||
| 544 | Ok(()) | ||
| 545 | } | ||
| 546 | } | ||
