tangled
alpha
login
or
join now
eldridge.cam
/
cartography
0
fork
atom
Trading card city builder game?
0
fork
atom
overview
issues
pulls
pipelines
tests for deck watcher
eldridge.cam
1 month ago
43bbb55d
7a967673
verified
This commit was signed with the committer's
known signature
.
eldridge.cam
SSH Key Fingerprint:
SHA256:MAgO4sya2MgvdgUjSGKAO0lQ9X2HQp1Jb+x/Tpeeims=
+200
-6
5 changed files
expand all
collapse all
unified
split
.sqlx
query-47112e0da87c653526acf007a188f3c08ed6249f1f1788d83cadda77c1e492d4.json
query-e94fb2129b480b98c28887db72173c4222b3475cfc445f85c911fadc3557e014.json
packages
cartography
src
actor
deck_state
mod.rs
api
ws.rs
bus.rs
+32
.sqlx/query-47112e0da87c653526acf007a188f3c08ed6249f1f1788d83cadda77c1e492d4.json
···
1
1
+
{
2
2
+
"db_name": "PostgreSQL",
3
3
+
"query": "\n WITH inserted_card AS (\n INSERT INTO cards (card_type_id) VALUES ('bread-bakery') RETURNING *\n ),\n\n inserted_card_account AS (\n INSERT INTO card_accounts (card_id, account_id)\n SELECT id, 'foxfriends'\n FROM inserted_card\n )\n\n INSERT INTO tiles (id, tile_type_id, name)\n SELECT id, card_type_id, card_type_id\n FROM inserted_card\n RETURNING id, tile_type_id, name\n ",
4
4
+
"describe": {
5
5
+
"columns": [
6
6
+
{
7
7
+
"ordinal": 0,
8
8
+
"name": "id",
9
9
+
"type_info": "Int8"
10
10
+
},
11
11
+
{
12
12
+
"ordinal": 1,
13
13
+
"name": "tile_type_id",
14
14
+
"type_info": "Text"
15
15
+
},
16
16
+
{
17
17
+
"ordinal": 2,
18
18
+
"name": "name",
19
19
+
"type_info": "Text"
20
20
+
}
21
21
+
],
22
22
+
"parameters": {
23
23
+
"Left": []
24
24
+
},
25
25
+
"nullable": [
26
26
+
false,
27
27
+
false,
28
28
+
false
29
29
+
]
30
30
+
},
31
31
+
"hash": "47112e0da87c653526acf007a188f3c08ed6249f1f1788d83cadda77c1e492d4"
32
32
+
}
+32
.sqlx/query-e94fb2129b480b98c28887db72173c4222b3475cfc445f85c911fadc3557e014.json
···
1
1
+
{
2
2
+
"db_name": "PostgreSQL",
3
3
+
"query": "\n WITH inserted_card AS (\n INSERT INTO cards (card_type_id) VALUES ('rabbit') RETURNING *\n ),\n\n inserted_card_account AS (\n INSERT INTO card_accounts (card_id, account_id)\n SELECT id, 'foxfriends'\n FROM inserted_card\n )\n\n INSERT INTO citizens (id, species_id, name)\n SELECT id, card_type_id, card_type_id\n FROM inserted_card\n RETURNING id, species_id, name\n ",
4
4
+
"describe": {
5
5
+
"columns": [
6
6
+
{
7
7
+
"ordinal": 0,
8
8
+
"name": "id",
9
9
+
"type_info": "Int8"
10
10
+
},
11
11
+
{
12
12
+
"ordinal": 1,
13
13
+
"name": "species_id",
14
14
+
"type_info": "Text"
15
15
+
},
16
16
+
{
17
17
+
"ordinal": 2,
18
18
+
"name": "name",
19
19
+
"type_info": "Text"
20
20
+
}
21
21
+
],
22
22
+
"parameters": {
23
23
+
"Left": []
24
24
+
},
25
25
+
"nullable": [
26
26
+
false,
27
27
+
false,
28
28
+
false
29
29
+
]
30
30
+
},
31
31
+
"hash": "e94fb2129b480b98c28887db72173c4222b3475cfc445f85c911fadc3557e014"
32
32
+
}
+134
-4
packages/cartography/src/actor/deck_state/mod.rs
···
3
3
use crate::bus::{Bus, BusExt};
4
4
use crate::db::CardClass;
5
5
use kameo::prelude::*;
6
6
-
use serde::{Deserialize, Serialize};
7
6
use sqlx::PgPool;
8
7
use tokio::sync::mpsc::UnboundedSender;
9
8
10
10
-
#[derive(PartialEq, Clone, Debug, Serialize, Deserialize)]
9
9
+
#[derive(PartialEq, Clone, Debug, serde::Serialize, serde::Deserialize)]
11
10
pub struct Tile {
12
11
pub id: i64,
13
12
pub tile_type_id: String,
14
13
pub name: String,
15
14
}
16
15
17
17
-
#[derive(PartialEq, Clone, Debug, Serialize, Deserialize)]
16
16
+
#[derive(PartialEq, Clone, Debug, serde::Serialize, serde::Deserialize)]
18
17
pub struct Citizen {
19
18
pub id: i64,
20
19
pub species_id: String,
21
20
pub name: String,
22
21
}
23
22
24
24
-
#[derive(Serialize, Deserialize, Clone, Debug)]
23
23
+
#[derive(PartialEq, Clone, Default, Debug, kameo::Reply, serde::Serialize, serde::Deserialize)]
25
24
pub struct DeckState {
26
25
pub tiles: Vec<Tile>,
27
26
pub citizens: Vec<Citizen>,
···
168
167
ctx.stop();
169
168
}
170
169
}
170
170
+
171
171
+
#[cfg(test)]
172
172
+
mod tests {
173
173
+
use super::*;
174
174
+
use crate::actor::AddCardToDeck;
175
175
+
use crate::actor::player_socket::Response;
176
176
+
use crate::bus::{Bus, BusExt};
177
177
+
use crate::test::prelude::*;
178
178
+
use kameo::actor::Spawn;
179
179
+
use sqlx::PgPool;
180
180
+
use tokio::sync::mpsc::unbounded_channel;
181
181
+
182
182
+
struct GetState;
183
183
+
impl Message<GetState> for DeckWatcher {
184
184
+
type Reply = DeckState;
185
185
+
186
186
+
async fn handle(
187
187
+
&mut self,
188
188
+
_msg: GetState,
189
189
+
_ctx: &mut Context<Self, Self::Reply>,
190
190
+
) -> Self::Reply {
191
191
+
self.state.clone()
192
192
+
}
193
193
+
}
194
194
+
195
195
+
#[sqlx::test(
196
196
+
migrator = "MIGRATOR",
197
197
+
fixtures(path = "../../../fixtures", scripts("seed", "account"))
198
198
+
)]
199
199
+
async fn add_card_to_deck_tile(pool: PgPool) {
200
200
+
let (tx, mut rx) = unbounded_channel();
201
201
+
let bus = Bus::spawn_default();
202
202
+
let deck_watcher =
203
203
+
DeckWatcher::spawn((pool.clone(), tx, bus.clone(), "foxfriends".to_owned()));
204
204
+
205
205
+
matches!(rx.recv().await.unwrap(), Response::PutDeckState(..));
206
206
+
207
207
+
let card = sqlx::query_as!(
208
208
+
Tile,
209
209
+
r#"
210
210
+
WITH inserted_card AS (
211
211
+
INSERT INTO cards (card_type_id) VALUES ('bread-bakery') RETURNING *
212
212
+
),
213
213
+
214
214
+
inserted_card_account AS (
215
215
+
INSERT INTO card_accounts (card_id, account_id)
216
216
+
SELECT id, 'foxfriends'
217
217
+
FROM inserted_card
218
218
+
)
219
219
+
220
220
+
INSERT INTO tiles (id, tile_type_id, name)
221
221
+
SELECT id, card_type_id, card_type_id
222
222
+
FROM inserted_card
223
223
+
RETURNING id, tile_type_id, name
224
224
+
"#
225
225
+
)
226
226
+
.fetch_one(&pool)
227
227
+
.await
228
228
+
.unwrap();
229
229
+
230
230
+
bus.notify(AddCardToDeck {
231
231
+
account_id: "foxfriends".to_owned(),
232
232
+
card_id: card.id,
233
233
+
})
234
234
+
.await
235
235
+
.unwrap();
236
236
+
237
237
+
matches!(rx.recv().await.unwrap(), Response::PatchState(..));
238
238
+
239
239
+
assert_eq!(
240
240
+
deck_watcher.ask(GetState).await.unwrap(),
241
241
+
DeckState {
242
242
+
tiles: vec![card],
243
243
+
citizens: vec![],
244
244
+
}
245
245
+
)
246
246
+
}
247
247
+
248
248
+
#[sqlx::test(
249
249
+
migrator = "MIGRATOR",
250
250
+
fixtures(path = "../../../fixtures", scripts("seed", "account"))
251
251
+
)]
252
252
+
async fn add_card_to_deck_citizen(pool: PgPool) {
253
253
+
let (tx, mut rx) = unbounded_channel();
254
254
+
let bus = Bus::spawn_default();
255
255
+
let deck_watcher =
256
256
+
DeckWatcher::spawn((pool.clone(), tx, bus.clone(), "foxfriends".to_owned()));
257
257
+
258
258
+
matches!(rx.recv().await.unwrap(), Response::PutDeckState(..));
259
259
+
260
260
+
let card = sqlx::query_as!(
261
261
+
Citizen,
262
262
+
r#"
263
263
+
WITH inserted_card AS (
264
264
+
INSERT INTO cards (card_type_id) VALUES ('rabbit') RETURNING *
265
265
+
),
266
266
+
267
267
+
inserted_card_account AS (
268
268
+
INSERT INTO card_accounts (card_id, account_id)
269
269
+
SELECT id, 'foxfriends'
270
270
+
FROM inserted_card
271
271
+
)
272
272
+
273
273
+
INSERT INTO citizens (id, species_id, name)
274
274
+
SELECT id, card_type_id, card_type_id
275
275
+
FROM inserted_card
276
276
+
RETURNING id, species_id, name
277
277
+
"#
278
278
+
)
279
279
+
.fetch_one(&pool)
280
280
+
.await
281
281
+
.unwrap();
282
282
+
283
283
+
bus.notify(AddCardToDeck {
284
284
+
account_id: "foxfriends".to_owned(),
285
285
+
card_id: card.id,
286
286
+
})
287
287
+
.await
288
288
+
.unwrap();
289
289
+
290
290
+
matches!(rx.recv().await.unwrap(), Response::PatchState(..));
291
291
+
292
292
+
assert_eq!(
293
293
+
deck_watcher.ask(GetState).await.unwrap(),
294
294
+
DeckState {
295
295
+
tiles: vec![],
296
296
+
citizens: vec![card],
297
297
+
}
298
298
+
)
299
299
+
}
300
300
+
}
+1
-1
packages/cartography/src/api/ws.rs
···
60
60
.unwrap_or(JSON_PROTOCOL)
61
61
.to_owned();
62
62
ws.on_upgrade(move |socket: WebSocket| async move {
63
63
-
let _span = tracing::info_span!("websocket connection");
63
63
+
let _span = tracing::info_span!("websocket connection", protocol);
64
64
tracing::debug!("websocket connected");
65
65
let (ws_sender, ws_receiver) = socket.split();
66
66
futures::pin_mut!(ws_sender);
+1
-1
packages/cartography/src/bus.rs
···
43
43
.flatten()
44
44
.filter_map(|entry| entry.as_any().downcast_ref::<Recipient<T>>())
45
45
{
46
46
-
if let Err(error) = dbg!(recipient.tell(notification.clone()).await) {
46
46
+
if let Err(error) = recipient.tell(notification.clone()).await {
47
47
tracing::error!("bus failed to notify: {}", error);
48
48
}
49
49
}