use github_graphql_node_count::{node_count, Variables};
fn no_variables() -> Variables {
Variables::new()
}
fn page(value: u32) -> Variables {
Variables::from([("page".to_string(), value)])
}
const NESTED_PATH: &str = r#"
query {
viewer {
repositories(first: 10) {
edges {
node {
issues(first: 5) {
edges { node { title } }
}
}
}
}
}
}
"#;
const NESTED_PATH_NODES: u64 = 60;
#[test]
fn a_nested_connection_multiplies_by_its_parents_page_size() {
assert_eq!(
node_count(NESTED_PATH, &no_variables()),
Ok(NESTED_PATH_NODES)
);
}
const SIBLING_PATHS: &str = r#"
query {
viewer {
repositories(first: 10) { edges { node { name } } }
followers(first: 7) { edges { node { login } } }
following(first: 3) { edges { node { login } } }
}
}
"#;
const SIBLING_PATHS_NODES: u64 = 20;
#[test]
fn sibling_connections_sum_rather_than_compete() {
assert_eq!(
node_count(SIBLING_PATHS, &no_variables()),
Ok(SIBLING_PATHS_NODES)
);
assert_ne!(node_count(SIBLING_PATHS, &no_variables()), Ok(10));
}
const SPREAD_FRAGMENT: &str = r#"
query {
viewer {
repositories(first: 10) {
edges { node { ...RepositoryIssues } }
}
}
}
fragment RepositoryIssues on Repository {
name
issues(first: 4) {
edges { node { title } }
}
}
"#;
const SPREAD_FRAGMENT_NODES: u64 = 50;
#[test]
fn a_spread_counts_the_fragment_it_names() {
assert_eq!(
node_count(SPREAD_FRAGMENT, &no_variables()),
Ok(SPREAD_FRAGMENT_NODES)
);
}
const INLINE_FRAGMENT_UNION: &str = r#"
query {
repository(owner: "nickderobertis", name: "onetaskgraph") {
issue(number: 235) {
timelineItems(first: 10) {
nodes {
... on CrossReferencedEvent {
source {
... on PullRequest {
comments(first: 5) { nodes { bodyHTML } }
}
}
}
... on LabeledEvent {
label { name }
}
}
}
}
}
}
"#;
const INLINE_FRAGMENT_UNION_NODES: u64 = 60;
#[test]
fn an_inline_fragment_on_a_union_counts_against_its_parent() {
assert_eq!(
node_count(INLINE_FRAGMENT_UNION, &no_variables()),
Ok(INLINE_FRAGMENT_UNION_NODES)
);
}
const NESTED_SPREADS: &str = r#"
query {
viewer { ...ViewerRepositories }
}
fragment ViewerRepositories on User {
repositories(first: 6) {
edges { node { ...RepositoryIssues } }
}
}
fragment RepositoryIssues on Repository {
issues(first: 2) {
edges { node { title } }
}
}
"#;
const NESTED_SPREADS_NODES: u64 = 18;
#[test]
fn a_spread_reached_through_another_spread_is_counted() {
assert_eq!(
node_count(NESTED_SPREADS, &no_variables()),
Ok(NESTED_SPREADS_NODES)
);
}
const VARIABLE_SPENT_TWICE: &str = r#"
query ViewerIssues($page: Int!) {
viewer {
repositories(first: $page) {
edges {
node {
issues(first: $page) {
edges { node { title } }
}
}
}
}
}
}
"#;
const VARIABLE_SPENT_TWICE_AT_3: u64 = 12;
const VARIABLE_SPENT_TWICE_AT_5: u64 = 30;
const VARIABLE_SPENT_TWICE_AT_9: u64 = 90;
#[test]
fn one_variable_spent_twice_moves_the_total_by_its_square() {
assert_eq!(
node_count(VARIABLE_SPENT_TWICE, &page(3)),
Ok(VARIABLE_SPENT_TWICE_AT_3)
);
assert_eq!(
node_count(VARIABLE_SPENT_TWICE, &page(5)),
Ok(VARIABLE_SPENT_TWICE_AT_5)
);
assert_eq!(
node_count(VARIABLE_SPENT_TWICE, &page(9)),
Ok(VARIABLE_SPENT_TWICE_AT_9)
);
for (n, total) in [
(3u64, VARIABLE_SPENT_TWICE_AT_3),
(5, VARIABLE_SPENT_TWICE_AT_5),
(9, VARIABLE_SPENT_TWICE_AT_9),
] {
assert_eq!(total, n + n * n);
}
}
const OUTER_FIRST_LITERAL: &str = r#"
query {
viewer {
repositories(first: 25) {
edges { node { issues(first: 4) { edges { node { title } } } } }
}
}
}
"#;
const OUTER_LAST_LITERAL: &str = r#"
query {
viewer {
repositories(last: 25) {
edges { node { issues(first: 4) { edges { node { title } } } } }
}
}
}
"#;
const OUTER_FIRST_VARIABLE: &str = r#"
query ViewerIssues($page: Int!) {
viewer {
repositories(first: $page) {
edges { node { issues(first: 4) { edges { node { title } } } } }
}
}
}
"#;
const OUTER_LAST_VARIABLE: &str = r#"
query ViewerIssues($page: Int!) {
viewer {
repositories(last: $page) {
edges { node { issues(first: 4) { edges { node { title } } } } }
}
}
}
"#;
const PAGE_ARGUMENT_NODES: u64 = 125;
#[test]
fn first_and_last_and_literal_and_variable_all_count_the_same() {
assert_eq!(
node_count(OUTER_FIRST_LITERAL, &no_variables()),
Ok(PAGE_ARGUMENT_NODES)
);
assert_eq!(
node_count(OUTER_LAST_LITERAL, &no_variables()),
Ok(PAGE_ARGUMENT_NODES)
);
assert_eq!(
node_count(OUTER_FIRST_VARIABLE, &page(25)),
Ok(PAGE_ARGUMENT_NODES)
);
assert_eq!(
node_count(OUTER_LAST_VARIABLE, &page(25)),
Ok(PAGE_ARGUMENT_NODES)
);
}
const BOTH_FIRST_AND_LAST: &str = r#"
query {
viewer {
repositories(first: 3, last: 30) {
edges { node { name } }
}
}
}
"#;
const BOTH_FIRST_AND_LAST_NODES: u64 = 30;
#[test]
fn a_field_supplying_both_first_and_last_takes_the_larger() {
assert_eq!(
node_count(BOTH_FIRST_AND_LAST, &no_variables()),
Ok(BOTH_FIRST_AND_LAST_NODES)
);
}
const NO_PAGE_SIZE_ANYWHERE: &str = r#"
query {
viewer {
login
repository(owner: "nickderobertis", name: "onevcs") {
name
issues { edges { node { title } } }
}
}
}
"#;
const NO_PAGE_SIZE_ANYWHERE_NODES: u64 = 0;
#[test]
fn a_document_with_no_page_size_costs_nothing_here() {
assert_eq!(
node_count(NO_PAGE_SIZE_ANYWHERE, &no_variables()),
Ok(NO_PAGE_SIZE_ANYWHERE_NODES)
);
}
const SHORTHAND_OPERATION: &str = r#"
{
viewer {
repositories(first: 3) { edges { node { name } } }
}
}
"#;
const SHORTHAND_OPERATION_NODES: u64 = 3;
#[test]
fn a_shorthand_operation_is_counted() {
assert_eq!(
node_count(SHORTHAND_OPERATION, &no_variables()),
Ok(SHORTHAND_OPERATION_NODES)
);
}
const MUTATION_OPERATION: &str = r#"
mutation AddComment($body: String!) {
addComment(input: { subjectId: "MDU6SXNzdWUx", body: $body }) {
commentEdge {
node {
reactions(first: 5) { nodes { content } }
}
}
}
}
"#;
const MUTATION_OPERATION_NODES: u64 = 5;
#[test]
fn a_mutation_is_counted_and_an_unreferenced_variable_need_not_be_bound() {
assert_eq!(
node_count(MUTATION_OPERATION, &no_variables()),
Ok(MUTATION_OPERATION_NODES)
);
}
const SUBSCRIPTION_OPERATION: &str = r#"
subscription WatchIssues {
issueEvents {
issue {
comments(first: 8) { nodes { bodyHTML } }
}
}
}
"#;
const SUBSCRIPTION_OPERATION_NODES: u64 = 8;
#[test]
fn a_subscription_is_counted() {
assert_eq!(
node_count(SUBSCRIPTION_OPERATION, &no_variables()),
Ok(SUBSCRIPTION_OPERATION_NODES)
);
}
const UNUSED_FRAGMENT: &str = r#"
query {
viewer {
repositories(first: 4) { edges { node { name } } }
}
}
fragment Unused on Repository {
issues(first: 100) { edges { node { title } } }
}
"#;
const UNUSED_FRAGMENT_NODES: u64 = 4;
#[test]
fn a_fragment_that_is_never_spread_is_not_counted() {
assert_eq!(
node_count(UNUSED_FRAGMENT, &no_variables()),
Ok(UNUSED_FRAGMENT_NODES)
);
}