1 #![recursion_limit = "256"] 2 3 pub mod client; 4 pub mod server; 5 6 pub mod pb { 7 #![allow(dead_code)] 8 #![allow(unused_imports)] 9 include!(concat!(env!("OUT_DIR"), "/grpc.testing.rs")); 10 } 11 12 use std::{default, fmt, iter}; 13 14 pub fn trace_init() { 15 tracing_subscriber::fmt::init(); 16 } 17 18 pub fn client_payload(size: usize) -> pb::Payload { 19 pb::Payload { 20 r#type: default::Default::default(), 21 body: iter::repeat(0u8).take(size).collect(), 22 } 23 } 24 25 pub fn server_payload(size: usize) -> pb::Payload { 26 pb::Payload { 27 r#type: default::Default::default(), 28 body: iter::repeat(0u8).take(size).collect(), 29 } 30 } 31 32 impl pb::ResponseParameters { 33 fn with_size(size: i32) -> Self { 34 pb::ResponseParameters { 35 size, 36 ..Default::default() 37 } 38 } 39 } 40 41 fn response_length(response: &pb::StreamingOutputCallResponse) -> i32 { 42 match &response.payload { 43 Some(ref payload) => payload.body.len() as i32, 44 None => 0, 45 } 46 } 47 48 fn response_lengths(responses: &[pb::StreamingOutputCallResponse]) -> Vec<i32> { 49 responses.iter().map(&response_length).collect() 50 } 51 52 #[derive(Debug)] 53 pub enum TestAssertion { 54 Passed { 55 description: &'static str, 56 }, 57 Failed { 58 description: &'static str, 59 expression: &'static str, 60 why: Option<String>, 61 }, 62 } 63 64 impl TestAssertion { 65 pub fn is_failed(&self) -> bool { 66 matches!(self, TestAssertion::Failed { .. }) 67 } 68 } 69 70 impl fmt::Display for TestAssertion { 71 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 72 use console::{style, Emoji}; 73 match *self { 74 TestAssertion::Passed { ref description } => write!( 75 f, 76 "{check} {desc}", 77 check = style(Emoji("✔", "+")).green(), 78 desc = style(description).green(), 79 ), 80 TestAssertion::Failed { 81 ref description, 82 ref expression, 83 why: Some(ref why), 84 } => write!( 85 f, 86 "{check} {desc}\n in `{exp}`: {why}", 87 check = style(Emoji("✖", "x")).red(), 88 desc = style(description).red(), 89 exp = style(expression).red(), 90 why = style(why).red(), 91 ), 92 TestAssertion::Failed { 93 ref description, 94 ref expression, 95 why: None, 96 } => write!( 97 f, 98 "{check} {desc}\n in `{exp}`", 99 check = style(Emoji("✖", "x")).red(), 100 desc = style(description).red(), 101 exp = style(expression).red(), 102 ), 103 } 104 } 105 } 106 107 #[macro_export] 108 macro_rules! test_assert { 109 ($description:expr, $assertion:expr) => { 110 if $assertion { 111 $crate::TestAssertion::Passed { 112 description: $description, 113 } 114 } else { 115 TestAssertion::Failed { 116 description: $description, 117 expression: stringify!($assertion), 118 why: None, 119 } 120 } 121 }; 122 ($description:expr, $assertion:expr, $why:expr) => { 123 if $assertion { 124 $crate::TestAssertion::Passed { 125 description: $description, 126 } 127 } else { 128 $crate::TestAssertion::Failed { 129 description: $description, 130 expression: stringify!($assertion), 131 why: Some($why), 132 } 133 } 134 }; 135 } 136