use async_graphql::connection::*; use async_graphql::*; use serde_json::json; #[async_std::test] pub async fn test_slice_datasource() { struct Query; #[Object] impl Query { async fn values( &self, after: Option, before: Option, first: Option, last: Option, ) -> FieldResult> { const ROWS: &[&str] = &[ "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", ]; ROWS.query(after, before, first, last).await } } static QUERY: &str = r#" query( $after: String $before: String $first: Int $last: Int ) { values( after: $after before: $before first: $first last: $last ) { pageInfo { hasPreviousPage hasNextPage } edges { node } } } "#; async fn do_test( vars: serde_json::Value, (has_prev_page, has_next_page, nodes): (bool, bool, &[&str]), ) { let schema = Schema::new(Query, EmptyMutation, EmptySubscription); let query = QueryBuilder::new(QUERY).variables(Variables::parse_from_json(vars).unwrap()); let edges = nodes .iter() .map(|s| json!({ "node": s.to_owned() })) .collect::>(); assert_eq!( query.execute(&schema).await.unwrap().data, serde_json::json!({ "values": { "pageInfo": { "hasPreviousPage": has_prev_page, "hasNextPage": has_next_page, }, "edges": edges, }, }) ); } do_test( json!({ "after": null, "before": null, "first": 2, "last": null }), (false, true, &["a", "b"]), ) .await; do_test( json!({ "after": 1usize.encode_cursor().unwrap(), "before": null, "first": 2, "last": null }), (true, true, &["c", "d"]), ) .await; do_test( json!({ "after": 1usize.encode_cursor().unwrap(), "before": null, "first": 6, "last": null }), (true, true, &["c", "d", "e", "f", "g", "h"]), ) .await; do_test( json!({ "after": null, "before": null, "first": 3, "last": null }), (false, true, &["a", "b", "c"]), ) .await; do_test( json!({ "after": null, "before": null, "first": null, "last": 3 }), (true, false, &["x", "y", "z"]), ) .await; do_test( json!({ "after": null, "before": 1usize.encode_cursor().unwrap(), "first": 10, "last": null }), (false, true, &["a"]), ) .await; do_test( json!({ "after": null, "before": 1usize.encode_cursor().unwrap(), "first": null, "last": 10 }), (false, true, &["a"]), ) .await; } #[async_std::test] pub async fn test_datasource_additional_fields() { struct QueryRoot; struct Numbers; #[SimpleObject] struct ConnectionFields { total_count: i32, } #[SimpleObject] struct Diff { diff: i32, } #[DataSource] impl DataSource for Numbers { type CursorType = usize; type NodeType = i32; type ConnectionFieldsType = ConnectionFields; type EdgeFieldsType = Diff; async fn execute_query( &self, after: Option, before: Option, first: Option, last: Option, ) -> FieldResult< Connection< Self::CursorType, Self::NodeType, Self::ConnectionFieldsType, Self::EdgeFieldsType, >, > { let mut start = after.map(|after| after + 1).unwrap_or(0); let mut end = before.unwrap_or(10000); if let Some(first) = first { end = (start + first).min(end); } if let Some(last) = last { start = if last > end - start { end } else { end - last }; } let mut connection = Connection::with_additional_fields( start > 0, end < 10000, ConnectionFields { total_count: 10000 }, ); connection.append((start..end).into_iter().map(|n| { Edge::with_additional_fields( n, n as i32, Diff { diff: (10000 - n) as i32, }, ) })); Ok(connection) } } #[Object] impl QueryRoot { async fn numbers( &self, after: Option, before: Option, first: Option, last: Option, ) -> FieldResult> { Numbers.query(after, before, first, last).await } } let schema = Schema::new(QueryRoot, EmptyMutation, EmptySubscription); assert_eq!( schema .execute("{ numbers(first: 2) { totalCount edges { node diff } } }") .await .unwrap() .data, serde_json::json!({ "numbers": { "totalCount": 10000, "edges": [ {"node": 0, "diff": 10000}, {"node": 1, "diff": 9999}, ] }, }) ); assert_eq!( schema .execute("{ numbers(last: 2) { edges { node diff } } }") .await .unwrap() .data, serde_json::json!({ "numbers": { "edges": [ {"node": 9998, "diff": 2}, {"node": 9999, "diff": 1}, ] }, }) ); }