// Copyright 2022 The GRADIS Project Contributors // SPDX-License-Identifier: Apache-2.0 // SPDX-FileContributor: Lucas Hinderberger // // Each abovementioned SPDX-FileContributor has contributed to and/or modified this file. // Please add your name and email address to the list above, if you publish modifications. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. use std::ops::Deref; use std::str; use lazy_static::lazy_static; use maplit::hashset; use gradiff::codec::{decode_from_str, encode_to_str, Attribute, Change, Chunk, CreateChange, File, FileHeader, FormatVersion, Identifier, ParameterPath, RGBAColor, SetChange, Timestamp, UTCOffset, Value}; use gradiff::model::{ArrowLineStyle, ArrowTipStyle, BoundingBox, BoxAnchorPositionX, BoxAnchorPositionY, BoxCorners, Diagram, DiagramObject, DiagramObjectCommon, FontStyle, Point, PointDerivationSide, TextHAlignment, TextVAlignment}; const TWO_BOXES_WITH_ARROW_DIAGRAM_BYTES: &[u8] = include_bytes!("two_boxes_with_arrow.gdff"); //REUSE-IgnoreStart lazy_static! { static ref TWO_BOXES_WITH_ARROW_DIAGRAM: File = File::new( FileHeader::new( Some(" Copyright 2022 The GRADIS Project Contributors\n SPDX-License-Identifier: CC0-1.0\n SPDX-FileContributor: Lucas Hinderberger \n\n Each abovementioned SPDX-FileContributor has contributed to and/or modified this file.\n Please add your name and email address to the list above, if you publish modifications.".to_string()), FormatVersion{major: 0, minor: 1} ), vec![ Chunk::new( vec![ Attribute{key: "Author".parse().unwrap(), value: Value::String("John Doe ".to_string())}, Attribute{key: "Timestamp".parse().unwrap(), value: Value::Timestamp(Timestamp::new(2022, 8, 30, 17, 30, 0, 0, UTCOffset::Zulu).unwrap())} ], vec![ Change::Create(CreateChange::new("canvas".parse().unwrap(), "Canvas".parse().unwrap(), vec![Value::Number(100.0.try_into().unwrap()), Value::Number(100.0.try_into().unwrap())])), Change::Create(CreateChange::new("ptBoxHelloAnchor".parse().unwrap(), "PointAbsolute".parse().unwrap(), vec![Value::Number(30.0.try_into().unwrap()), Value::Number(70.0.try_into().unwrap())])), Change::Create(CreateChange::new("boxHello".parse().unwrap(), "Box".parse().unwrap(), vec![Value::Identifier("ptBoxHelloAnchor".parse().unwrap()), Value::Number(40.0.try_into().unwrap()), Value::Number(40.0.try_into().unwrap())])), Change::Set(SetChange::new(ParameterPath("boxHello".parse().unwrap(), "Text".parse().unwrap()), Value::String("Hello World!".to_string()))) ] ), Chunk::new( vec![ Attribute{key: "Author".parse().unwrap(), value: Value::String("John Doe ".to_string())}, Attribute{key: "Timestamp".parse().unwrap(), value: Value::Timestamp(Timestamp::new(2022, 8, 30, 17, 45, 0, 0, UTCOffset::Zulu).unwrap())} ], vec![ Change::Set(SetChange::new(ParameterPath("boxHello".parse().unwrap(), "Height".parse().unwrap()), Value::Number(20.0.try_into().unwrap()))), Change::Set(SetChange::new(ParameterPath("boxHello".parse().unwrap(), "Width".parse().unwrap()), Value::Number(50.0.try_into().unwrap()))), Change::Set(SetChange::new(ParameterPath("ptBoxHelloAnchor".parse().unwrap(), "X".parse().unwrap()), Value::Number(25.0.try_into().unwrap()))), Change::Set(SetChange::new(ParameterPath("ptBoxHelloAnchor".parse().unwrap(), "Y".parse().unwrap()), Value::Number(90.0.try_into().unwrap()))), Change::Create(CreateChange::new("ptBoxBonjourAnchor".parse().unwrap(), "PointAbsolute".parse().unwrap(), vec![Value::Number(25.0.try_into().unwrap()), Value::Number(30.0.try_into().unwrap())])), Change::Create(CreateChange::new("boxBonjour".parse().unwrap(), "Box".parse().unwrap(), vec![Value::Identifier("ptBoxBonjourAnchor".parse().unwrap()), Value::Number(50.0.try_into().unwrap()), Value::Number(20.0.try_into().unwrap())])), Change::Set(SetChange::new(ParameterPath("boxBonjour".parse().unwrap(), "Text".parse().unwrap()), Value::String("Bonjour Le Monde!".to_string()))) ] ), Chunk::new( vec![ Attribute{key: "Author".parse().unwrap(), value: Value::String("John Doe ".to_string())}, Attribute{key: "Timestamp".parse().unwrap(), value: Value::Timestamp(Timestamp::new(2022, 8, 30, 17, 50, 0, 0, UTCOffset::Zulu).unwrap())} ], vec![ Change::Create(CreateChange::new("ptArrowSrc".parse().unwrap(), "PointDerivedFromSide".parse().unwrap() ,vec![Value::Identifier("boxHello".parse().unwrap()), Value::String("Bottom".to_string())])), Change::Create(CreateChange::new("ptArrowDest".parse().unwrap(), "PointDerivedFromSide".parse().unwrap() ,vec![Value::Identifier("boxBonjour".parse().unwrap()), Value::String("Top".to_string())])), Change::Create(CreateChange::new("arrow".parse().unwrap(), "Arrow".parse().unwrap() ,vec![Value::Identifier("ptArrowSrc".parse().unwrap()), Value::Identifier("ptArrowDest".parse().unwrap())])), Change::Create(CreateChange::new("ptArrowMiddle".parse().unwrap(), "PointDerivedFromArrow".parse().unwrap() ,vec![Value::Identifier("arrow".parse().unwrap()), Value::Number(0.0.try_into().unwrap())])), Change::Create(CreateChange::new("lblTranslatesTo".parse().unwrap(), "LabelBox".parse().unwrap() ,vec![Value::Identifier("ptArrowMiddle".parse().unwrap()), Value::Number(30.0.try_into().unwrap()), Value::Number(10.0.try_into().unwrap()), Value::String("translates to".to_string())])), Change::Set(SetChange::new(ParameterPath("lblTranslatesTo".parse().unwrap(), "BackgroundColor".parse().unwrap()), Value::Color(RGBAColor{r: 0xff, g: 0xff, b: 0xff, a: 0xff}))) ] ) ] ); } //REUSE-IgnoreEnd #[test] fn two_boxes_with_arrow_diagram_can_be_de_and_encoded() { let expected_encoded = str::from_utf8(TWO_BOXES_WITH_ARROW_DIAGRAM_BYTES).unwrap(); let actual_encoded = encode_to_str(&*TWO_BOXES_WITH_ARROW_DIAGRAM).unwrap(); let actual_decoded: File = decode_from_str(expected_encoded).unwrap(); assert_eq!(expected_encoded, actual_encoded); assert_eq!(&*TWO_BOXES_WITH_ARROW_DIAGRAM, &actual_decoded); for n in 1..10 { let actual_decoded_trailing_lfs: File = decode_from_str((expected_encoded.to_string() + "\n".repeat(n).as_str()).as_str()).unwrap(); assert_eq!(&*TWO_BOXES_WITH_ARROW_DIAGRAM, &actual_decoded_trailing_lfs); } } #[test] fn two_boxes_with_arrow_diagram_is_processed_correctly() { let parsed_file: File = str::from_utf8(TWO_BOXES_WITH_ARROW_DIAGRAM_BYTES).unwrap().parse().unwrap(); let mut diagram = Diagram::new(); for chunk in parsed_file.chunks().iter() { for change in chunk.changes().iter() { diagram.apply_change(change).unwrap(); } } let view = diagram.view(); assert_eq!(10, view.objects().len()); assert_eq!(9, view.dependent_object_ids().len()); let canvas_name: Identifier = "canvas".parse().unwrap(); let box_hello_name: Identifier = "boxHello".parse().unwrap(); let box_bonjour_name: Identifier = "boxBonjour".parse().unwrap(); let pt_arrow_middle_name: Identifier = "ptArrowMiddle".parse().unwrap(); let pt_arrow_src_name: Identifier = "ptArrowSrc".parse().unwrap(); let pt_arrow_dest_name: Identifier = "ptArrowDest".parse().unwrap(); let pt_box_hello_anchor_name: Identifier = "ptBoxHelloAnchor".parse().unwrap(); let pt_box_bonjour_anchor_name: Identifier = "ptBoxBonjourAnchor".parse().unwrap(); let arrow_name: Identifier = "arrow".parse().unwrap(); let lbl_translates_to_name: Identifier = "lblTranslatesTo".parse().unwrap(); let raw_canvas = view.objects().get(&canvas_name).unwrap().borrow(); let canvas = match raw_canvas.deref() { DiagramObject::Canvas(obj) => obj, _ => panic!("canvas is not a Canvas") }; let raw_box_hello = view.objects().get(&box_hello_name).unwrap().borrow(); let box_hello = match raw_box_hello.deref() { DiagramObject::Box(obj) => obj, _ => panic!("boxHello is not a Box") }; let raw_box_bonjour = view.objects().get(&box_bonjour_name).unwrap().borrow(); let box_bonjour = match raw_box_bonjour.deref() { DiagramObject::Box(obj) => obj, _ => panic!("boxBonjour is not a Box") }; let raw_pt_arrow_middle = view.objects().get(&pt_arrow_middle_name).unwrap().borrow(); let pt_arrow_middle = match raw_pt_arrow_middle.deref() { DiagramObject::Point(outer) => match outer { Point::DerivedFromArrow(obj) => obj, _ => panic!("ptarrowMiddle is not a DerivedFromArrow") }, _ => panic!("ptarrowMiddle is not a Point") }; let raw_pt_arrow_src = view.objects().get(&pt_arrow_src_name).unwrap().borrow(); let pt_arrow_src = match raw_pt_arrow_src.deref() { DiagramObject::Point(outer) => match outer { Point::DerivedFromSide(obj) => obj, _ => panic!("ptArrowSrc is not a PointDerivedFromSide") }, _ => panic!("ptArrowSrc is not a Point") }; let raw_pt_arrow_dest = view.objects().get(&pt_arrow_dest_name).unwrap().borrow(); let pt_arrow_dest = match raw_pt_arrow_dest.deref() { DiagramObject::Point(outer) => match outer { Point::DerivedFromSide(obj) => obj, _ => panic!("ptArrowDest is not a PointDerivedFromSide") }, _ => panic!("ptArrowDest is not a Point") }; let raw_pt_box_hello_anchor = view.objects().get(&pt_box_hello_anchor_name).unwrap().borrow(); let pt_box_hello_anchor = match raw_pt_box_hello_anchor.deref() { DiagramObject::Point(outer) => match outer { Point::Absolute(obj) => obj, _ => panic!("ptBoxHelloAnchor is not a PointAbsolute") }, _ => panic!("ptBoxHelloAnchor is not a Point") }; let raw_pt_box_bonjour_anchor = view.objects().get(&pt_box_bonjour_anchor_name).unwrap().borrow(); let pt_box_bonjour_anchor = match raw_pt_box_bonjour_anchor.deref() { DiagramObject::Point(outer) => match outer { Point::Absolute(obj) => obj, _ => panic!("ptboxBonjourAnchor is not a PointAbsolute") }, _ => panic!("ptboxBonjourAnchor is not a Point") }; let raw_arrow = view.objects().get(&arrow_name).unwrap().borrow(); let arrow = match raw_arrow.deref() { DiagramObject::Arrow(obj) => obj, _ => panic!("arrow is not an Arrow") }; let raw_lbl_translates_to = view.objects().get(&lbl_translates_to_name).unwrap().borrow(); let lbl_translates_to = match raw_lbl_translates_to.deref() { DiagramObject::Box(obj) => obj, _ => panic!("lblTranslatesTo is not a Box") }; assert_eq!(canvas.width(), 100.0); assert_eq!(canvas.height(), 100.0); assert_eq!(canvas.background_color(), &RGBAColor{r: 0xff, g: 0xff, b: 0xff, a: 0xff}); assert_eq!(raw_canvas.bounding_box(), BoundingBox{top_left: (0.0, 100.0), bottom_right: (100.0, 0.0)}); assert_eq!(raw_canvas.metadata().canvas_id(), None); assert_eq!(raw_canvas.metadata().object_id(), &canvas_name); assert!(raw_canvas.metadata().dependency_ids().is_empty()); assert_eq!(view.dependent_object_ids().get(&canvas_name).unwrap(), &hashset!{box_hello_name.clone(), box_bonjour_name.clone(), pt_arrow_middle_name.clone(), pt_arrow_src_name.clone(), pt_arrow_dest_name.clone(), pt_box_hello_anchor_name.clone(), pt_box_bonjour_anchor_name.clone(), arrow_name.clone(), lbl_translates_to_name.clone()}); assert_eq!(pt_box_hello_anchor.x(), 25.0); assert_eq!(pt_box_hello_anchor.y(), 90.0); assert_eq!(pt_box_hello_anchor.position(), (25.0, 90.0)); assert_eq!(raw_pt_box_hello_anchor.bounding_box(), BoundingBox{top_left: (25.0, 90.0), bottom_right: (25.0, 90.0)}); assert_eq!(raw_pt_box_hello_anchor.metadata().canvas_id(), Some(&canvas_name)); assert_eq!(raw_pt_box_hello_anchor.metadata().object_id(), &pt_box_hello_anchor_name); assert_eq!(raw_pt_box_hello_anchor.metadata().dependency_ids(), &hashset!{canvas_name.clone()}); assert_eq!(view.dependent_object_ids().get(&pt_box_hello_anchor_name).unwrap(), &hashset!{box_hello_name.clone()}); assert_eq!(box_hello.anchor_point_id(), &pt_box_hello_anchor_name); assert_eq!(box_hello.anchor_position_x(), BoxAnchorPositionX::Left); assert_eq!(box_hello.anchor_position_y(), BoxAnchorPositionY::Top); assert_eq!(box_hello.width(), 50.0); assert_eq!(box_hello.height(), 20.0); assert_eq!(box_hello.background_color(), &RGBAColor{r: 0xff, g: 0xff, b: 0xff, a: 0xff}); assert_eq!(box_hello.border_color(), &RGBAColor{r: 0x00, g: 0x00, b: 0x00, a: 0xff}); assert_eq!(box_hello.border_thickness(), 0.5); assert_eq!(box_hello.font_family(), "sans-serif"); assert_eq!(box_hello.font_size(), 12.0); assert_eq!(box_hello.font_stretch(), 1.0); assert_eq!(box_hello.font_style(), FontStyle::Normal); assert_eq!(box_hello.font_weight(), 400.0); assert_eq!(box_hello.line_height(), 1.0); assert_eq!(box_hello.padding_bottom(), 4.0); assert_eq!(box_hello.padding_left(), 4.0); assert_eq!(box_hello.padding_right(), 4.0); assert_eq!(box_hello.padding_top(), 4.0); assert_eq!(box_hello.text(), "Hello World!"); assert_eq!(box_hello.text_color(), &RGBAColor{r: 0x00, g: 0x00, b: 0x00, a: 0xff}); assert_eq!(box_hello.text_h_alignment(), TextHAlignment::Center); assert_eq!(box_hello.text_v_alignment(), TextVAlignment::Center); assert_eq!(box_hello.corners(), BoxCorners{a: (25.0, 90.0), b: (25.0, 70.0), c: (75.0, 70.0), d: (75.0, 90.0)}); assert_eq!(raw_box_hello.bounding_box(), BoundingBox{top_left: (24.75, 90.25), bottom_right: (75.25, 69.75)}); assert_eq!(raw_box_hello.metadata().canvas_id(), Some(&canvas_name)); assert_eq!(raw_box_hello.metadata().object_id(), &box_hello_name); assert_eq!(raw_box_hello.metadata().dependency_ids(), &hashset!{canvas_name.clone(), pt_box_hello_anchor_name.clone()}); assert_eq!(view.dependent_object_ids().get(&box_hello_name).unwrap(), &hashset!{pt_arrow_src_name.clone()}); assert_eq!(pt_box_bonjour_anchor.x(), 25.0); assert_eq!(pt_box_bonjour_anchor.y(), 30.0); assert_eq!(pt_box_bonjour_anchor.position(), (25.0, 30.0)); assert_eq!(raw_pt_box_bonjour_anchor.bounding_box(), BoundingBox{top_left: (25.0, 30.0), bottom_right: (25.0, 30.0)}); assert_eq!(raw_pt_box_bonjour_anchor.metadata().canvas_id(), Some(&canvas_name)); assert_eq!(raw_pt_box_bonjour_anchor.metadata().object_id(), &pt_box_bonjour_anchor_name); assert_eq!(raw_pt_box_bonjour_anchor.metadata().dependency_ids(), &hashset!{canvas_name.clone()}); assert_eq!(view.dependent_object_ids().get(&pt_box_bonjour_anchor_name).unwrap(), &hashset!{box_bonjour_name.clone()}); assert_eq!(box_bonjour.anchor_point_id(), &pt_box_bonjour_anchor_name); assert_eq!(box_bonjour.anchor_position_x(), BoxAnchorPositionX::Left); assert_eq!(box_bonjour.anchor_position_y(), BoxAnchorPositionY::Top); assert_eq!(box_bonjour.width(), 50.0); assert_eq!(box_bonjour.height(), 20.0); assert_eq!(box_bonjour.background_color(), &RGBAColor{r: 0xff, g: 0xff, b: 0xff, a: 0xff}); assert_eq!(box_bonjour.border_color(), &RGBAColor{r: 0x00, g: 0x00, b: 0x00, a: 0xff}); assert_eq!(box_bonjour.border_thickness(), 0.5); assert_eq!(box_bonjour.font_family(), "sans-serif"); assert_eq!(box_bonjour.font_size(), 12.0); assert_eq!(box_bonjour.font_stretch(), 1.0); assert_eq!(box_bonjour.font_style(), FontStyle::Normal); assert_eq!(box_bonjour.font_weight(), 400.0); assert_eq!(box_bonjour.line_height(), 1.0); assert_eq!(box_bonjour.padding_bottom(), 4.0); assert_eq!(box_bonjour.padding_left(), 4.0); assert_eq!(box_bonjour.padding_right(), 4.0); assert_eq!(box_bonjour.padding_top(), 4.0); assert_eq!(box_bonjour.text(), "Bonjour Le Monde!"); assert_eq!(box_bonjour.text_color(), &RGBAColor{r: 0x00, g: 0x00, b: 0x00, a: 0xff}); assert_eq!(box_bonjour.text_h_alignment(), TextHAlignment::Center); assert_eq!(box_bonjour.text_v_alignment(), TextVAlignment::Center); assert_eq!(box_bonjour.corners(), BoxCorners{a: (25.0, 30.0), b: (25.0, 10.0), c: (75.0, 10.0), d: (75.0, 30.0)}); assert_eq!(raw_box_bonjour.bounding_box(), BoundingBox{top_left: (24.75, 30.25), bottom_right: (75.25, 9.75)}); assert_eq!(raw_box_bonjour.metadata().canvas_id(), Some(&canvas_name)); assert_eq!(raw_box_bonjour.metadata().object_id(), &box_bonjour_name); assert_eq!(raw_box_bonjour.metadata().dependency_ids(), &hashset!{canvas_name.clone(), pt_box_bonjour_anchor_name.clone()}); assert_eq!(view.dependent_object_ids().get(&box_bonjour_name).unwrap(), &hashset!{pt_arrow_dest_name.clone()}); assert_eq!(pt_arrow_src.parent_id(), &box_hello_name); assert_eq!(pt_arrow_src.side(), PointDerivationSide::Bottom); assert_eq!(pt_arrow_src.offset_x(), 0.0); assert_eq!(pt_arrow_src.offset_y(), 0.0); assert_eq!(pt_arrow_src.position(), (50.0, 69.75)); assert_eq!(raw_pt_arrow_src.bounding_box(), BoundingBox{top_left: (50.0, 69.75), bottom_right: (50.0, 69.75)}); assert_eq!(raw_pt_arrow_src.metadata().canvas_id(), Some(&canvas_name)); assert_eq!(raw_pt_arrow_src.metadata().object_id(), &pt_arrow_src_name); assert_eq!(raw_pt_arrow_src.metadata().dependency_ids(), &hashset!{canvas_name.clone(), box_hello_name.clone()}); assert_eq!(view.dependent_object_ids().get(&pt_arrow_src_name).unwrap(), &hashset!{arrow_name.clone()}); assert_eq!(pt_arrow_dest.parent_id(), &box_bonjour_name); assert_eq!(pt_arrow_dest.side(), PointDerivationSide::Top); assert_eq!(pt_arrow_dest.offset_x(), 0.0); assert_eq!(pt_arrow_dest.offset_y(), 0.0); assert_eq!(pt_arrow_dest.position(), (50.0, 30.25)); assert_eq!(raw_pt_arrow_dest.bounding_box(), BoundingBox{top_left: (50.0, 30.25), bottom_right: (50.0, 30.25)}); assert_eq!(raw_pt_arrow_dest.metadata().canvas_id(), Some(&canvas_name)); assert_eq!(raw_pt_arrow_dest.metadata().object_id(), &pt_arrow_dest_name); assert_eq!(raw_pt_arrow_dest.metadata().dependency_ids(), &hashset!{canvas_name.clone(), box_bonjour_name.clone()}); assert_eq!(view.dependent_object_ids().get(&pt_arrow_dest_name).unwrap(), &hashset!{arrow_name.clone()}); assert_eq!(arrow.points(), &vec![pt_arrow_src_name.clone(), pt_arrow_dest_name.clone()]); assert_eq!(arrow.end_tip_color(), &RGBAColor{r: 0x00, g: 0x00, b: 0x00, a: 0xff}); assert_eq!(arrow.end_tip_scale(), 1.0); assert_eq!(arrow.end_tip_style(), ArrowTipStyle::EquilateralTriangle); assert_eq!(arrow.line_color(), &RGBAColor{r: 0x00, g: 0x00, b: 0x00, a: 0xff}); assert_eq!(arrow.line_style(), ArrowLineStyle::Solid); assert_eq!(arrow.line_thickness(), 0.5); assert_eq!(arrow.start_tip_color(), &RGBAColor{r: 0x00, g: 0x00, b: 0x00, a: 0xff}); assert_eq!(arrow.start_tip_scale(), 1.0); assert_eq!(arrow.start_tip_style(), ArrowTipStyle::None); assert_eq!(raw_arrow.bounding_box(), BoundingBox{top_left: (47.5, 72.25), bottom_right: (52.5, 27.75)}); assert_eq!(raw_arrow.metadata().canvas_id(), Some(&canvas_name)); assert_eq!(raw_arrow.metadata().object_id(), &arrow_name); assert_eq!(raw_arrow.metadata().dependency_ids(), &hashset!{canvas_name.clone(), pt_arrow_src_name.clone(), pt_arrow_dest_name.clone()}); assert_eq!(view.dependent_object_ids().get(&arrow_name).unwrap(), &hashset!{pt_arrow_middle_name.clone()}); assert_eq!(pt_arrow_middle.arrow_id(), &arrow_name); assert_eq!(pt_arrow_middle.leg(), 0); assert_eq!(pt_arrow_middle.offset_lateral(), 0.0); assert_eq!(pt_arrow_middle.offset_longitudinal(), 0.0); assert_eq!(pt_arrow_middle.position(), (50.0, 50.0)); assert_eq!(raw_pt_arrow_middle.bounding_box(), BoundingBox{top_left: (50.0, 50.0), bottom_right: (50.0, 50.0)}); assert_eq!(raw_pt_arrow_middle.metadata().canvas_id(), Some(&canvas_name)); assert_eq!(raw_pt_arrow_middle.metadata().object_id(), &pt_arrow_middle_name); assert_eq!(raw_pt_arrow_middle.metadata().dependency_ids(), &hashset!{canvas_name.clone(), arrow_name.clone()}); assert_eq!(view.dependent_object_ids().get(&pt_arrow_middle_name).unwrap(), &hashset!{lbl_translates_to_name.clone()}); assert_eq!(lbl_translates_to.anchor_point_id(), &pt_arrow_middle_name); assert_eq!(lbl_translates_to.anchor_position_x(), BoxAnchorPositionX::Center); assert_eq!(lbl_translates_to.anchor_position_y(), BoxAnchorPositionY::Center); assert_eq!(lbl_translates_to.width(), 30.0); assert_eq!(lbl_translates_to.height(), 10.0); assert_eq!(lbl_translates_to.background_color(), &RGBAColor{r: 0xff, g: 0xff, b: 0xff, a: 0xff}); assert_eq!(lbl_translates_to.border_color(), &RGBAColor{r: 0x00, g: 0x00, b: 0x00, a: 0xff}); assert_eq!(lbl_translates_to.border_thickness(), 0.0); assert_eq!(lbl_translates_to.font_family(), "sans-serif"); assert_eq!(lbl_translates_to.font_size(), 12.0); assert_eq!(lbl_translates_to.font_stretch(), 1.0); assert_eq!(lbl_translates_to.font_style(), FontStyle::Normal); assert_eq!(lbl_translates_to.font_weight(), 400.0); assert_eq!(lbl_translates_to.line_height(), 1.0); assert_eq!(lbl_translates_to.padding_bottom(), 0.0); assert_eq!(lbl_translates_to.padding_left(), 0.0); assert_eq!(lbl_translates_to.padding_right(), 0.0); assert_eq!(lbl_translates_to.padding_top(), 0.0); assert_eq!(lbl_translates_to.text(), "translates to"); assert_eq!(lbl_translates_to.text_color(), &RGBAColor{r: 0x00, g: 0x00, b: 0x00, a: 0xff}); assert_eq!(lbl_translates_to.text_h_alignment(), TextHAlignment::Center); assert_eq!(lbl_translates_to.text_v_alignment(), TextVAlignment::Center); assert_eq!(lbl_translates_to.corners(), BoxCorners{a: (35.0, 55.0), b: (35.0, 45.0), c: (65.0, 45.0), d: (65.0, 55.0)}); assert_eq!(raw_lbl_translates_to.bounding_box(), BoundingBox{top_left: (35.0, 55.0), bottom_right: (65.0, 45.0)}); assert_eq!(raw_lbl_translates_to.metadata().canvas_id(), Some(&canvas_name)); assert_eq!(raw_lbl_translates_to.metadata().object_id(), &lbl_translates_to_name); assert_eq!(raw_lbl_translates_to.metadata().dependency_ids(), &hashset!{canvas_name.clone(), pt_arrow_middle_name.clone()}); }