rust/hedgewars-server/src/protocol/test.rs
changeset 14457 98ef2913ec73
parent 14415 06672690d71b
child 14783 b3adc030104b
equal deleted inserted replaced
14456:a077aac9df01 14457:98ef2913ec73
     1 use proptest::{
     1 use proptest::{
     2     test_runner::{TestRunner, Reason},
       
     3     arbitrary::{any, any_with, Arbitrary, StrategyFor},
     2     arbitrary::{any, any_with, Arbitrary, StrategyFor},
     4     strategy::{Strategy, BoxedStrategy, Just, Map}
     3     strategy::{BoxedStrategy, Just, Map, Strategy},
       
     4     test_runner::{Reason, TestRunner},
     5 };
     5 };
     6 
     6 
     7 use crate::server::coretypes::{GameCfg, TeamInfo, HedgehogInfo};
     7 use crate::server::coretypes::{GameCfg, HedgehogInfo, TeamInfo};
     8 
     8 
     9 use super::messages::{
     9 use super::messages::{HWProtocolMessage, HWProtocolMessage::*};
    10     HWProtocolMessage, HWProtocolMessage::*
       
    11 };
       
    12 
    10 
    13 // Due to inability to define From between Options
    11 // Due to inability to define From between Options
    14 trait Into2<T>: Sized { fn into2(self) -> T; }
    12 trait Into2<T>: Sized {
    15 impl <T> Into2<T> for T { fn into2(self) -> T { self } }
    13     fn into2(self) -> T;
       
    14 }
       
    15 impl<T> Into2<T> for T {
       
    16     fn into2(self) -> T {
       
    17         self
       
    18     }
       
    19 }
    16 impl Into2<Vec<String>> for Vec<Ascii> {
    20 impl Into2<Vec<String>> for Vec<Ascii> {
    17     fn into2(self) -> Vec<String> {
    21     fn into2(self) -> Vec<String> {
    18         self.into_iter().map(|x| x.0).collect()
    22         self.into_iter().map(|x| x.0).collect()
    19     }
    23     }
    20 }
    24 }
    21 impl Into2<String> for Ascii { fn into2(self) -> String { self.0 } }
    25 impl Into2<String> for Ascii {
    22 impl Into2<Option<String>> for Option<Ascii>{
    26     fn into2(self) -> String {
    23     fn into2(self) -> Option<String> { self.map(|x| {x.0}) }
    27         self.0
       
    28     }
       
    29 }
       
    30 impl Into2<Option<String>> for Option<Ascii> {
       
    31     fn into2(self) -> Option<String> {
       
    32         self.map(|x| x.0)
       
    33     }
    24 }
    34 }
    25 
    35 
    26 macro_rules! proto_msg_case {
    36 macro_rules! proto_msg_case {
    27     ($val: ident()) =>
    37     ($val: ident()) => {
    28         (Just($val));
    38         Just($val)
    29     ($val: ident($arg: ty)) =>
    39     };
    30         (any::<$arg>().prop_map(|v| {$val(v.into2())}));
    40     ($val: ident($arg: ty)) => {
    31     ($val: ident($arg1: ty, $arg2: ty)) =>
    41         any::<$arg>().prop_map(|v| $val(v.into2()))
    32         (any::<($arg1, $arg2)>().prop_map(|v| {$val(v.0.into2(), v.1.into2())}));
    42     };
    33     ($val: ident($arg1: ty, $arg2: ty, $arg3: ty)) =>
    43     ($val: ident($arg1: ty, $arg2: ty)) => {
    34         (any::<($arg1, $arg2, $arg3)>().prop_map(|v| {$val(v.0.into2(), v.1.into2(), v.2.into2())}));
    44         any::<($arg1, $arg2)>().prop_map(|v| $val(v.0.into2(), v.1.into2()))
       
    45     };
       
    46     ($val: ident($arg1: ty, $arg2: ty, $arg3: ty)) => {
       
    47         any::<($arg1, $arg2, $arg3)>().prop_map(|v| $val(v.0.into2(), v.1.into2(), v.2.into2()))
       
    48     };
    35 }
    49 }
    36 
    50 
    37 macro_rules! proto_msg_match {
    51 macro_rules! proto_msg_match {
    38     ($var: expr, def = $default: expr, $($num: expr => $constr: ident $res: tt),*) => (
    52     ($var: expr, def = $default: expr, $($num: expr => $constr: ident $res: tt),*) => (
    39         match $var {
    53         match $var {
    60 impl Arbitrary for GameCfg {
    74 impl Arbitrary for GameCfg {
    61     type Parameters = ();
    75     type Parameters = ();
    62 
    76 
    63     fn arbitrary_with(_args: <Self as Arbitrary>::Parameters) -> <Self as Arbitrary>::Strategy {
    77     fn arbitrary_with(_args: <Self as Arbitrary>::Parameters) -> <Self as Arbitrary>::Strategy {
    64         use crate::server::coretypes::GameCfg::*;
    78         use crate::server::coretypes::GameCfg::*;
    65         (0..10).no_shrink().prop_flat_map(|i| {
    79         (0..10)
    66             proto_msg_match!(i, def = FeatureSize(0),
    80             .no_shrink()
       
    81             .prop_flat_map(|i| {
       
    82                 proto_msg_match!(i, def = FeatureSize(0),
    67             0 => FeatureSize(u32),
    83             0 => FeatureSize(u32),
    68             1 => MapType(Ascii),
    84             1 => MapType(Ascii),
    69             2 => MapGenerator(u32),
    85             2 => MapGenerator(u32),
    70             3 => MazeSize(u32),
    86             3 => MazeSize(u32),
    71             4 => Seed(Ascii),
    87             4 => Seed(Ascii),
    73             6 => Ammo(Ascii, Option<Ascii>),
    89             6 => Ammo(Ascii, Option<Ascii>),
    74             7 => Scheme(Ascii, Vec<Ascii>),
    90             7 => Scheme(Ascii, Vec<Ascii>),
    75             8 => Script(Ascii),
    91             8 => Script(Ascii),
    76             9 => Theme(Ascii),
    92             9 => Theme(Ascii),
    77             10 => DrawnMap(Ascii))
    93             10 => DrawnMap(Ascii))
    78         }).boxed()
    94             })
       
    95             .boxed()
    79     }
    96     }
    80 
    97 
    81     type Strategy = BoxedStrategy<GameCfg>;
    98     type Strategy = BoxedStrategy<GameCfg>;
    82 }
    99 }
    83 
   100 
    84 impl Arbitrary for TeamInfo {
   101 impl Arbitrary for TeamInfo {
    85     type Parameters = ();
   102     type Parameters = ();
    86 
   103 
    87     fn arbitrary_with(_args: <Self as Arbitrary>::Parameters) -> <Self as Arbitrary>::Strategy {
   104     fn arbitrary_with(_args: <Self as Arbitrary>::Parameters) -> <Self as Arbitrary>::Strategy {
    88         ("[a-z]+", 0u8..127u8, "[a-z]+", "[a-z]+", "[a-z]+", "[a-z]+",  0u8..127u8)
   105         (
       
   106             "[a-z]+",
       
   107             0u8..127u8,
       
   108             "[a-z]+",
       
   109             "[a-z]+",
       
   110             "[a-z]+",
       
   111             "[a-z]+",
       
   112             0u8..127u8,
       
   113         )
    89             .prop_map(|(name, color, grave, fort, voice_pack, flag, difficulty)| {
   114             .prop_map(|(name, color, grave, fort, voice_pack, flag, difficulty)| {
    90                 fn hog(n: u8) -> HedgehogInfo {
   115                 fn hog(n: u8) -> HedgehogInfo {
    91                     HedgehogInfo { name: format!("hog{}", n), hat: format!("hat{}", n)}
   116                     HedgehogInfo {
       
   117                         name: format!("hog{}", n),
       
   118                         hat: format!("hat{}", n),
       
   119                     }
    92                 }
   120                 }
    93                 let hedgehogs = [hog(1), hog(2), hog(3), hog(4), hog(5), hog(6), hog(7), hog(8)];
   121                 let hedgehogs = [
       
   122                     hog(1),
       
   123                     hog(2),
       
   124                     hog(3),
       
   125                     hog(4),
       
   126                     hog(5),
       
   127                     hog(6),
       
   128                     hog(7),
       
   129                     hog(8),
       
   130                 ];
    94                 TeamInfo {
   131                 TeamInfo {
    95                     name, color, grave, fort,
   132                     name,
    96                     voice_pack, flag,difficulty,
   133                     color,
    97                     hedgehogs, hedgehogs_number: 0
   134                     grave,
       
   135                     fort,
       
   136                     voice_pack,
       
   137                     flag,
       
   138                     difficulty,
       
   139                     hedgehogs,
       
   140                     hedgehogs_number: 0,
    98                 }
   141                 }
    99             }).boxed()
   142             })
       
   143             .boxed()
   100     }
   144     }
   101 
   145 
   102     type Strategy = BoxedStrategy<TeamInfo>;
   146     type Strategy = BoxedStrategy<TeamInfo>;
   103 }
   147 }
   104 
   148 
   105 pub fn gen_proto_msg() -> BoxedStrategy<HWProtocolMessage> where {
   149 pub fn gen_proto_msg() -> BoxedStrategy<HWProtocolMessage> where {
   106     let res = (0..58).no_shrink().prop_flat_map(|i| {
   150     let res = (0..58).no_shrink().prop_flat_map(|i| {
   107         proto_msg_match!(i, def = Malformed,
   151         proto_msg_match!(i, def = Malformed,
   108         0 => Ping(),
   152             0 => Ping(),
   109         1 => Pong(),
   153             1 => Pong(),
   110         2 => Quit(Option<Ascii>),
   154             2 => Quit(Option<Ascii>),
   111         //3 => Cmd
   155             //3 => Cmd
   112         4 => Global(Ascii),
   156             4 => Global(Ascii),
   113         5 => Watch(Ascii),
   157             5 => Watch(Ascii),
   114         6 => ToggleServerRegisteredOnly(),
   158             6 => ToggleServerRegisteredOnly(),
   115         7 => SuperPower(),
   159             7 => SuperPower(),
   116         8 => Info(Ascii),
   160             8 => Info(Ascii),
   117         9 => Nick(Ascii),
   161             9 => Nick(Ascii),
   118         10 => Proto(u16),
   162             10 => Proto(u16),
   119         11 => Password(Ascii, Ascii),
   163             11 => Password(Ascii, Ascii),
   120         12 => Checker(u16, Ascii, Ascii),
   164             12 => Checker(u16, Ascii, Ascii),
   121         13 => List(),
   165             13 => List(),
   122         14 => Chat(Ascii),
   166             14 => Chat(Ascii),
   123         15 => CreateRoom(Ascii, Option<Ascii>),
   167             15 => CreateRoom(Ascii, Option<Ascii>),
   124         16 => JoinRoom(Ascii, Option<Ascii>),
   168             16 => JoinRoom(Ascii, Option<Ascii>),
   125         17 => Follow(Ascii),
   169             17 => Follow(Ascii),
   126         18 => Rnd(Vec<Ascii>),
   170             18 => Rnd(Vec<Ascii>),
   127         19 => Kick(Ascii),
   171             19 => Kick(Ascii),
   128         20 => Ban(Ascii, Ascii, u32),
   172             20 => Ban(Ascii, Ascii, u32),
   129         21 => BanIP(Ascii, Ascii, u32),
   173             21 => BanIP(Ascii, Ascii, u32),
   130         22 => BanNick(Ascii, Ascii, u32),
   174             22 => BanNick(Ascii, Ascii, u32),
   131         23 => BanList(),
   175             23 => BanList(),
   132         24 => Unban(Ascii),
   176             24 => Unban(Ascii),
   133         //25 => SetServerVar(ServerVar),
   177             //25 => SetServerVar(ServerVar),
   134         26 => GetServerVar(),
   178             26 => GetServerVar(),
   135         27 => RestartServer(),
   179             27 => RestartServer(),
   136         28 => Stats(),
   180             28 => Stats(),
   137         29 => Part(Option<Ascii>),
   181             29 => Part(Option<Ascii>),
   138         30 => Cfg(GameCfg),
   182             30 => Cfg(GameCfg),
   139         31 => AddTeam(Box<TeamInfo>),
   183             31 => AddTeam(Box<TeamInfo>),
   140         32 => RemoveTeam(Ascii),
   184             32 => RemoveTeam(Ascii),
   141         33 => SetHedgehogsNumber(Ascii, u8),
   185             33 => SetHedgehogsNumber(Ascii, u8),
   142         34 => SetTeamColor(Ascii, u8),
   186             34 => SetTeamColor(Ascii, u8),
   143         35 => ToggleReady(),
   187             35 => ToggleReady(),
   144         36 => StartGame(),
   188             36 => StartGame(),
   145         37 => EngineMessage(Ascii),
   189             37 => EngineMessage(Ascii),
   146         38 => RoundFinished(),
   190             38 => RoundFinished(),
   147         39 => ToggleRestrictJoin(),
   191             39 => ToggleRestrictJoin(),
   148         40 => ToggleRestrictTeams(),
   192             40 => ToggleRestrictTeams(),
   149         41 => ToggleRegisteredOnly(),
   193             41 => ToggleRegisteredOnly(),
   150         42 => RoomName(Ascii),
   194             42 => RoomName(Ascii),
   151         43 => Delegate(Ascii),
   195             43 => Delegate(Ascii),
   152         44 => TeamChat(Ascii),
   196             44 => TeamChat(Ascii),
   153         45 => MaxTeams(u8),
   197             45 => MaxTeams(u8),
   154         46 => Fix(),
   198             46 => Fix(),
   155         47 => Unfix(),
   199             47 => Unfix(),
   156         48 => Greeting(Ascii),
   200             48 => Greeting(Ascii),
   157         //49 => CallVote(Option<(String, Option<String>)>),
   201             //49 => CallVote(Option<(String, Option<String>)>),
   158         50 => Vote(bool),
   202             50 => Vote(bool),
   159         51 => ForceVote(bool),
   203             51 => ForceVote(bool),
   160         52 => Save(Ascii, Ascii),
   204             52 => Save(Ascii, Ascii),
   161         53 => Delete(Ascii),
   205             53 => Delete(Ascii),
   162         54 => SaveRoom(Ascii),
   206             54 => SaveRoom(Ascii),
   163         55 => LoadRoom(Ascii),
   207             55 => LoadRoom(Ascii),
   164         56 => Malformed(),
   208             56 => Malformed(),
   165         57 => Empty()
   209             57 => Empty()
   166     )});
   210         )
       
   211     });
   167     res.boxed()
   212     res.boxed()
   168 }
   213 }