chiark / gitweb /
changelog: document further make-release changes
[otter.git] / apitest / at-currency.rs
1 // Copyright 2020-2021 Ian Jackson and contributors to Otter
2 // SPDX-License-Identifier: AGPL-3.0-or-later
3 // There is NO WARRANTY.
4
5 use crate::*;
6
7 type Ctx = UsualCtx;
8
9 impl Session {
10   #[throws(Explode)]
11   fn move_money<PI:Idx>(&mut self,
12                         a_pieces: &mut Pieces<PI>, piece: PI,
13                         qty: i32, z: &str, pos: Pos) {
14     self.api_piece_op_single(PuSynch((&mut *a_pieces, piece)).id(), (
15       "multigrab", json!({ "n": qty, 'z': z })
16     ))?;
17
18     self.api_piece(GH::Ungrab, PuSynch((&mut *a_pieces, piece)), pos)?;
19   }
20 }
21
22 impl Ctx {
23   #[throws(Explode)]
24   fn multigrab(&mut self) {
25     let mut alice = self.connect_player(&self.alice)?;
26     let mut a_pieces = alice.pieces::<PIA>()?;
27
28     let bank = a_pieces.find_by_desc_glob("*400ƒ*");
29
30     let pile_pos = PosC::new(40,20);
31     let temp_pos = PosC::new(40,10);
32
33     alice.api_piece_op_single(PuSynch((&mut a_pieces, bank)).id(), (
34       "multigrab", json!({ "n": 50, 'z': "q000000000" })
35     ))?;
36     alice.synchu(&mut a_pieces)?;
37
38     let pile = bank;
39     let bank = a_pieces.find_by_desc_glob("* 350ƒ*");
40     a_pieces[pile].assert_desc_contains(" 50ƒ");
41
42     alice.api_piece(GH::Ungrab, PuSynch((&mut a_pieces, pile)), pile_pos)?;
43     alice.synchu(&mut a_pieces)?;
44
45     alice.move_money(&mut a_pieces, bank, 13, "t000000000", temp_pos)?;
46     let moved = bank;
47     alice.synchu(&mut a_pieces)?;
48     let bank = a_pieces.find_by_desc_glob("* 337ƒ*");
49     a_pieces[moved].assert_desc_contains(" 13ƒ");
50
51     alice.api_piece(GH::With, PuSynch((&mut a_pieces, moved)), pile_pos)?;
52     alice.synchu(&mut a_pieces)?;
53     assert!(a_pieces[moved].info.is_null());
54     a_pieces[pile].assert_desc_contains(" 63ƒ");
55
56     // This saves us some complaints
57     let _ = moved;
58     let _ = bank;
59     let _ = pile;
60   }
61
62   #[throws(Explode)]
63   fn occult(&mut self) {
64     self.clear_reset_to_demo()?;
65
66     let mut alice = self.connect_player(&self.alice)?;
67     let mut a_pieces = alice.pieces::<PIA>()?;
68
69     let mut bob = self.connect_player(&self.bob)?;
70
71     let hand = a_pieces.find_by_desc_glob(otter::hand::UNCLAIMED_HAND_DESC);
72     alice.api_piece(GH::With, PuSynch(&mut (&mut a_pieces, hand)),
73                     ("k", json!({ "opname": "claim",
74                                    "wrc": WRC::Unpredictable })))?;
75     let hand_pos = a_pieces[hand].pos;
76
77     alice.synchu(&mut a_pieces)?;
78
79     let tmoney = a_pieces.find_by_desc_glob("*400ƒ*");
80     let pubmoney_pos = a_pieces[tmoney].pos;
81
82     alice.move_money(&mut a_pieces, tmoney, 399, "u000000000", hand_pos)?;
83     alice.synchu(&mut a_pieces)?;
84     // old tmoney has 1f, current piece has 399
85
86     let div1_pos = (hand_pos + PosC::new(-30,-5))?;
87     alice.move_money(&mut a_pieces, tmoney, 99, "u010000000", div1_pos)?;
88     // in hand has 300, current piece, aside, has 99
89     
90     alice.move_money(&mut a_pieces, tmoney, 9, "u020000000", hand_pos)?;
91     alice.synchu(&mut a_pieces)?;
92     // aside has 90, in hand has 309 (original pos)
93
94     let tmoney = a_pieces.iter_enumerated().filter(|(_,p)| {
95       ! p.info.is_null() &&
96       p.pos == hand_pos &&
97       dbg!(p).info["desc"].as_str().unwrap().contains("ƒ")
98     }).collect_vec();
99     let tmoney = match &*tmoney { [p] => p.0, x => panic!("{:?}", &x) };
100
101     alice.move_money(&mut a_pieces, tmoney, 20, "u030000000", pubmoney_pos)?;
102     alice.synchu(&mut a_pieces)?;
103     // alice has 90 (aside) and 289.  Public got 20 and now has 21.
104
105     let expected = [1, 399, 20, 21];
106     let expected = expected.into_iter()
107       .map(|s| s.to_string())
108       .chain(iter::once("?".to_string()))
109       .collect_vec();
110
111     let mut qtys = vec![];
112     bob.synchx::<PIB,_>(None, None, |_session, gen, _k, v| v.tree_walk(|k,v| {
113       if let Some(s) = v.as_str() {
114         for m in regex!(
115           r#"(?x) ([0-9.?]*) (:?<tspan[^<>]*>)? ƒ "#
116         ).captures_iter(s) {
117           let qty = m.get(1).unwrap().as_str();
118           dbg!(gen, qty, k, s);
119           qtys.push(qty.to_string());
120           assert!(expected.iter().map(|s| &**s).contains(&qty));
121         }
122       }
123       Ok::<_,Void>(())
124     }).void_unwrap())?;
125
126     for exp in expected {
127       assert!(qtys.contains(&exp), "{:?}", exp);
128     }
129
130     let _ = &mut bob;
131     let _ = bob;
132   }
133 }
134
135 #[throws(Explode)]
136 fn tests(mut c: Ctx) {
137   test!(c, "multigrab",                     c.multigrab()              ?);
138   test!(c, "occult",                        c.occult()                 ?);
139 }
140
141 #[throws(Explode)]
142 pub fn main() {
143   tests(Ctx::setup()?)?;
144 }