use super::*;

pub(super) const P0050_FIXTURES: &[Fixture] = &[
    Fixture {
        label: "files/P0050_01.uc",
        source: "{\n    local int A\n}\n",
    },
    Fixture {
        label: "files/P0050_02.uc",
        source: "{\n    local string \n\n}\n",
    },
    Fixture {
        label: "files/P0050_03.uc",
        source: "{\n    local class<Actor> ActorClass\n}\n",
    },
    Fixture {
        label: "files/P0050_04.uc",
        source: "{\n    local int A, B\n    local float C;\n}\n",
    },
];

#[test]
fn check_p0050_fixtures() {
    let runs = run_fixtures(P0050_FIXTURES);

    assert_eq!(runs.get("files/P0050_01.uc").unwrap().len(), 1);
    assert_eq!(runs.get("files/P0050_02.uc").unwrap().len(), 2);
    assert_eq!(runs.get("files/P0050_03.uc").unwrap().len(), 1);
    assert_eq!(runs.get("files/P0050_04.uc").unwrap().len(), 1);

    assert_diagnostic(
        &runs.get_any("files/P0050_01.uc"),
        &ExpectedDiagnostic {
            headline: "missing `;` after local variable declaration",
            severity: Severity::Error,
            code: Some("P0050"),
            primary_label: Some(ExpectedLabel {
                span: TokenSpan {
                    start: TokenPosition(9),
                    end: TokenPosition(9),
                },
                message: "expected `;` before `}`",
            }),
            secondary_labels: &[ExpectedLabel {
                span: TokenSpan {
                    start: TokenPosition(7),
                    end: TokenPosition(7),
                },
                message: "declaration ends here",
            }],
            help: None,
            notes: &[],
        },
    );

    assert_diagnostic(
        &runs.get_by_code("files/P0050_02.uc", "P0050"),
        &ExpectedDiagnostic {
            headline: "missing `;` after local variable declaration",
            severity: Severity::Error,
            code: Some("P0050"),
            primary_label: Some(ExpectedLabel {
                span: TokenSpan {
                    start: TokenPosition(9),
                    end: TokenPosition(9),
                },
                message: "expected `;` before `}`",
            }),
            secondary_labels: &[ExpectedLabel {
                span: TokenSpan {
                    start: TokenPosition(3),
                    end: TokenPosition(3),
                },
                message: "local variable declaration starts here",
            }],
            help: None,
            notes: &[],
        },
    );

    assert_diagnostic(
        &runs.get_any("files/P0050_03.uc"),
        &ExpectedDiagnostic {
            headline: "missing `;` after local variable declaration",
            severity: Severity::Error,
            code: Some("P0050"),
            primary_label: Some(ExpectedLabel {
                span: TokenSpan {
                    start: TokenPosition(12),
                    end: TokenPosition(12),
                },
                message: "expected `;` before `}`",
            }),
            secondary_labels: &[ExpectedLabel {
                span: TokenSpan {
                    start: TokenPosition(10),
                    end: TokenPosition(10),
                },
                message: "declaration ends here",
            }],
            help: None,
            notes: &[],
        },
    );

    assert_diagnostic(
        &runs.get_any("files/P0050_04.uc"),
        &ExpectedDiagnostic {
            headline: "missing `;` after local variable declaration",
            severity: Severity::Error,
            code: Some("P0050"),
            primary_label: Some(ExpectedLabel {
                span: TokenSpan {
                    start: TokenPosition(13),
                    end: TokenPosition(13),
                },
                message: "expected `;` before this declaration",
            }),
            secondary_labels: &[ExpectedLabel {
                span: TokenSpan {
                    start: TokenPosition(10),
                    end: TokenPosition(10),
                },
                message: "declaration ends here",
            }],
            help: None,
            notes: &[],
        },
    );
}

pub(super) const P0051_FIXTURES: &[Fixture] = &[
    Fixture {
        label: "files/P0051_01.uc",
        source: "{\n    local int;\n}\n",
    },
    Fixture {
        label: "files/P0051_02.uc",
        source: "{\n    local\n        string\n    ;\n}\n",
    },
    Fixture {
        label: "files/P0051_03.uc",
        source: "{\n    local\n        class<Actor>\n\n    ;\n}\n",
    },
    Fixture {
        label: "files/P0051_04.uc",
        source: "{\n    local\n\n        class<\nActor\n>\n\n    \n}\n",
    },
];

#[test]
fn check_p0051_fixtures() {
    let runs = run_fixtures(P0051_FIXTURES);

    assert_eq!(runs.get("files/P0051_01.uc").unwrap().len(), 1);
    assert_eq!(runs.get("files/P0051_02.uc").unwrap().len(), 1);
    assert_eq!(runs.get("files/P0051_03.uc").unwrap().len(), 1);
    assert_eq!(runs.get("files/P0051_04.uc").unwrap().len(), 2);

    assert_diagnostic(
        &runs.get_by_code("files/P0051_01.uc", "P0051"),
        &ExpectedDiagnostic {
            headline: "expected at least one variable name in variable declaration",
            severity: Severity::Error,
            code: Some("P0051"),
            primary_label: Some(ExpectedLabel {
                span: TokenSpan {
                    start: TokenPosition(6),
                    end: TokenPosition(6),
                },
                message: "expected variable name before `;`",
            }),
            secondary_labels: &[],
            help: None,
            notes: &[],
        },
    );

    assert_diagnostic(
        &runs.get_by_code("files/P0051_02.uc", "P0051"),
        &ExpectedDiagnostic {
            headline: "expected at least one variable name in variable declaration",
            severity: Severity::Error,
            code: Some("P0051"),
            primary_label: Some(ExpectedLabel {
                span: TokenSpan {
                    start: TokenPosition(9),
                    end: TokenPosition(9),
                },
                message: "expected variable name before `;`",
            }),
            secondary_labels: &[
                ExpectedLabel {
                    span: TokenSpan {
                        start: TokenPosition(3),
                        end: TokenPosition(3),
                    },
                    message: "variable declaration starts here",
                },
                ExpectedLabel {
                    span: TokenSpan {
                        start: TokenPosition(6),
                        end: TokenPosition(6),
                    },
                    message: "after this type, a variable name was expected",
                },
            ],
            help: None,
            notes: &[],
        },
    );

    assert_diagnostic(
        &runs.get_by_code("files/P0051_03.uc", "P0051"),
        &ExpectedDiagnostic {
            headline: "expected at least one variable name in variable declaration",
            severity: Severity::Error,
            code: Some("P0051"),
            primary_label: Some(ExpectedLabel {
                span: TokenSpan {
                    start: TokenPosition(13),
                    end: TokenPosition(13),
                },
                message: "expected variable name before `;`",
            }),
            secondary_labels: &[
                ExpectedLabel {
                    span: TokenSpan {
                        start: TokenPosition(3),
                        end: TokenPosition(3),
                    },
                    message: "variable declaration starts here",
                },
                ExpectedLabel {
                    span: TokenSpan {
                        start: TokenPosition(6),
                        end: TokenPosition(9),
                    },
                    message: "after this type, a variable name was expected",
                },
            ],
            help: None,
            notes: &[],
        },
    );

    assert_diagnostic(
        &runs.get_by_code("files/P0051_04.uc", "P0051"),
        &ExpectedDiagnostic {
            headline: "expected at least one variable name in variable declaration",
            severity: Severity::Error,
            code: Some("P0051"),
            primary_label: Some(ExpectedLabel {
                span: TokenSpan {
                    start: TokenPosition(17),
                    end: TokenPosition(17),
                },
                message: "expected variable name before `}`",
            }),
            secondary_labels: &[
                ExpectedLabel {
                    span: TokenSpan {
                        start: TokenPosition(3),
                        end: TokenPosition(3),
                    },
                    message: "variable declaration starts here",
                },
                ExpectedLabel {
                    span: TokenSpan {
                        start: TokenPosition(7),
                        end: TokenPosition(12),
                    },
                    message: "after this type, a variable name was expected",
                },
            ],
            help: None,
            notes: &[],
        },
    );

    assert_diagnostic(
        &runs.get_by_code("files/P0051_04.uc", "P0050"),
        &ExpectedDiagnostic {
            headline: "missing `;` after local variable declaration",
            severity: Severity::Error,
            code: Some("P0050"),
            primary_label: Some(ExpectedLabel {
                span: TokenSpan {
                    start: TokenPosition(17),
                    end: TokenPosition(17),
                },
                message: "expected `;` before `}`",
            }),
            secondary_labels: &[ExpectedLabel {
                span: TokenSpan {
                    start: TokenPosition(3),
                    end: TokenPosition(3),
                },
                message: "local variable declaration starts here",
            }],
            help: None,
            notes: &[],
        },
    );
}

pub(super) const P0052_FIXTURES: &[Fixture] = &[
    Fixture {
        label: "files/P0052_01.uc",
        source: "{\n    local int , A;\n}\n",
    },
    Fixture {
        label: "files/P0052_02.uc",
        source: "{\n    local\n        int\n        A,\n    ;\n}\n",
    },
    Fixture {
        label: "files/P0052_03.uc",
        source: "{\n    local string First,\n        ,,,,,\n        Second;\n}\n",
    },
    Fixture {
        label: "files/P0052_04.uc",
        source: "{\n    local\n        class<\nActor\n>\n        ActorClass,\n\n    ;\n}\n",
    },
];

#[test]
fn check_p0052_fixtures() {
    let runs = run_fixtures(P0052_FIXTURES);

    assert_eq!(runs.get("files/P0052_01.uc").unwrap().len(), 1);
    assert_eq!(runs.get("files/P0052_02.uc").unwrap().len(), 1);
    assert_eq!(runs.get("files/P0052_03.uc").unwrap().len(), 1);
    assert_eq!(runs.get("files/P0052_04.uc").unwrap().len(), 1);

    assert_diagnostic(
        &runs.get_by_code("files/P0052_01.uc", "P0052"),
        &ExpectedDiagnostic {
            headline: "expected variable name before `,`",
            severity: Severity::Error,
            code: Some("P0052"),
            primary_label: Some(ExpectedLabel {
                span: TokenSpan {
                    start: TokenPosition(7),
                    end: TokenPosition(7),
                },
                message: "unexpected `,`",
            }),
            secondary_labels: &[],
            help: None,
            notes: &[],
        },
    );

    assert_diagnostic(
        &runs.get_by_code("files/P0052_02.uc", "P0052"),
        &ExpectedDiagnostic {
            headline: "expected variable name after `,`",
            severity: Severity::Error,
            code: Some("P0052"),
            primary_label: Some(ExpectedLabel {
                span: TokenSpan {
                    start: TokenPosition(13),
                    end: TokenPosition(13),
                },
                message: "expected variable name before `;`",
            }),
            secondary_labels: &[
                ExpectedLabel {
                    span: TokenSpan {
                        start: TokenPosition(3),
                        end: TokenPosition(3),
                    },
                    message: "variable declaration starts here",
                },
                ExpectedLabel {
                    span: TokenSpan {
                        start: TokenPosition(10),
                        end: TokenPosition(10),
                    },
                    message: "after this `,`, another variable name was expected",
                },
            ],
            help: None,
            notes: &[],
        },
    );

    assert_diagnostic(
        &runs.get_by_code("files/P0052_03.uc", "P0052"),
        &ExpectedDiagnostic {
            headline: "expected variable name after `,`",
            severity: Severity::Error,
            code: Some("P0052"),
            primary_label: Some(ExpectedLabel {
                span: TokenSpan {
                    start: TokenPosition(11),
                    end: TokenPosition(15),
                },
                message: "empty variable declarators are not allowed",
            }),
            secondary_labels: &[ExpectedLabel {
                span: TokenSpan {
                    start: TokenPosition(8),
                    end: TokenPosition(8),
                },
                message: "after this `,`, another variable name was expected",
            }],
            help: None,
            notes: &[],
        },
    );

    assert_diagnostic(
        &runs.get_by_code("files/P0052_04.uc", "P0052"),
        &ExpectedDiagnostic {
            headline: "expected variable name after `,`",
            severity: Severity::Error,
            code: Some("P0052"),
            primary_label: Some(ExpectedLabel {
                span: TokenSpan {
                    start: TokenPosition(19),
                    end: TokenPosition(19),
                },
                message: "expected variable name before `;`",
            }),
            secondary_labels: &[
                ExpectedLabel {
                    span: TokenSpan {
                        start: TokenPosition(3),
                        end: TokenPosition(3),
                    },
                    message: "variable declaration starts here",
                },
                ExpectedLabel {
                    span: TokenSpan {
                        start: TokenPosition(15),
                        end: TokenPosition(15),
                    },
                    message: "after this `,`, another variable name was expected",
                },
            ],
            help: None,
            notes: &[],
        },
    );
}

pub(super) const P0053_FIXTURES: &[Fixture] = &[
    Fixture {
        label: "files/P0053_01.uc",
        source: "{\n    local int A B;\n}\n",
    },
    Fixture {
        label: "files/P0053_02.uc",
        source: "{\n    local\n        int\n        A\n        B;\n}\n",
    },
    Fixture {
        label: "files/P0053_03.uc",
        source: "{\n    local string\n        First\n\n        Second;\n}\n",
    },
    Fixture {
        label: "files/P0053_04.uc",
        source: "{\n    local\n        class<Actor>\n        ActorClass\n        OtherClass;\n}\n",
    },
];

#[test]
fn check_p0053_fixtures() {
    let runs = run_fixtures(P0053_FIXTURES);

    assert_eq!(runs.get("files/P0053_01.uc").unwrap().len(), 1);
    assert_eq!(runs.get("files/P0053_02.uc").unwrap().len(), 1);
    assert_eq!(runs.get("files/P0053_03.uc").unwrap().len(), 1);
    assert_eq!(runs.get("files/P0053_04.uc").unwrap().len(), 1);

    assert_diagnostic(
        &runs.get_by_code("files/P0053_01.uc", "P0053"),
        &ExpectedDiagnostic {
            headline: "missing `,` between variable declarators",
            severity: Severity::Error,
            code: Some("P0053"),
            primary_label: Some(ExpectedLabel {
                span: TokenSpan {
                    start: TokenPosition(9),
                    end: TokenPosition(9),
                },
                message: "expected `,` before `B`",
            }),
            secondary_labels: &[ExpectedLabel {
                span: TokenSpan {
                    start: TokenPosition(7),
                    end: TokenPosition(7),
                },
                message: "previous declarator ends here",
            }],
            help: None,
            notes: &[],
        },
    );

    assert_diagnostic(
        &runs.get_by_code("files/P0053_02.uc", "P0053"),
        &ExpectedDiagnostic {
            headline: "missing `,` between variable declarators",
            severity: Severity::Error,
            code: Some("P0053"),
            primary_label: Some(ExpectedLabel {
                span: TokenSpan {
                    start: TokenPosition(12),
                    end: TokenPosition(12),
                },
                message: "expected `,` before `B`",
            }),
            secondary_labels: &[
                ExpectedLabel {
                    span: TokenSpan {
                        start: TokenPosition(3),
                        end: TokenPosition(3),
                    },
                    message: "variable declaration starts here",
                },
                ExpectedLabel {
                    span: TokenSpan {
                        start: TokenPosition(9),
                        end: TokenPosition(9),
                    },
                    message: "previous declarator ends here",
                },
            ],
            help: None,
            notes: &[],
        },
    );

    assert_diagnostic(
        &runs.get_by_code("files/P0053_03.uc", "P0053"),
        &ExpectedDiagnostic {
            headline: "missing `,` between variable declarators",
            severity: Severity::Error,
            code: Some("P0053"),
            primary_label: Some(ExpectedLabel {
                span: TokenSpan {
                    start: TokenPosition(12),
                    end: TokenPosition(12),
                },
                message: "expected `,` before `Second`",
            }),
            secondary_labels: &[
                ExpectedLabel {
                    span: TokenSpan {
                        start: TokenPosition(3),
                        end: TokenPosition(3),
                    },
                    message: "variable declaration starts here",
                },
                ExpectedLabel {
                    span: TokenSpan {
                        start: TokenPosition(8),
                        end: TokenPosition(8),
                    },
                    message: "previous declarator ends here",
                },
            ],
            help: None,
            notes: &[],
        },
    );

    assert_diagnostic(
        &runs.get_by_code("files/P0053_04.uc", "P0053"),
        &ExpectedDiagnostic {
            headline: "missing `,` between variable declarators",
            severity: Severity::Error,
            code: Some("P0053"),
            primary_label: Some(ExpectedLabel {
                span: TokenSpan {
                    start: TokenPosition(15),
                    end: TokenPosition(15),
                },
                message: "expected `,` before `OtherClass`",
            }),
            secondary_labels: &[
                ExpectedLabel {
                    span: TokenSpan {
                        start: TokenPosition(3),
                        end: TokenPosition(3),
                    },
                    message: "variable declaration starts here",
                },
                ExpectedLabel {
                    span: TokenSpan {
                        start: TokenPosition(12),
                        end: TokenPosition(12),
                    },
                    message: "previous declarator ends here",
                },
            ],
            help: None,
            notes: &[],
        },
    );
}

pub(super) const P0054_FIXTURES: &[Fixture] = &[
    Fixture {
        label: "files/P0054_01.uc",
        source: "{\n    local int A[10;\n}\n",
    },
    Fixture {
        label: "files/P0054_02.uc",
        source: "{\n    local\n        int\n        A[\n            10\n        ;\n}\n",
    },
    Fixture {
        label: "files/P0054_03.uc",
        source: "{\n    local string\n        Names[\n            Count + 1\n        ;\n}\n",
    },
    Fixture {
        label: "files/P0054_04.uc",
        source: "{\n    local\n        class<Actor>\n        ActorClasses[\n            MaxActors\n        ;\n}\n",
    },
];

#[test]
fn check_p0054_fixtures() {
    let runs = run_fixtures(P0054_FIXTURES);

    assert_eq!(runs.get("files/P0054_01.uc").unwrap().len(), 1);
    assert_eq!(runs.get("files/P0054_02.uc").unwrap().len(), 1);
    assert_eq!(runs.get("files/P0054_03.uc").unwrap().len(), 1);
    assert_eq!(runs.get("files/P0054_04.uc").unwrap().len(), 1);

    assert_diagnostic(
        &runs.get_by_code("files/P0054_01.uc", "P0054"),
        &ExpectedDiagnostic {
            headline: "missing `]` to close array size expression",
            severity: Severity::Error,
            code: Some("P0054"),
            primary_label: Some(ExpectedLabel {
                span: TokenSpan {
                    start: TokenPosition(10),
                    end: TokenPosition(10),
                },
                message: "expected `]` before `;`",
            }),
            secondary_labels: &[],
            help: None,
            notes: &[],
        },
    );

    assert_diagnostic(
        &runs.get_by_code("files/P0054_02.uc", "P0054"),
        &ExpectedDiagnostic {
            headline: "missing `]` to close array size expression",
            severity: Severity::Error,
            code: Some("P0054"),
            primary_label: Some(ExpectedLabel {
                span: TokenSpan {
                    start: TokenPosition(10),
                    end: TokenPosition(16),
                },
                message: "expected `]` before `;`",
            }),
            secondary_labels: &[
                ExpectedLabel {
                    span: TokenSpan {
                        start: TokenPosition(3),
                        end: TokenPosition(3),
                    },
                    message: "variable declaration starts here",
                },
                ExpectedLabel {
                    span: TokenSpan {
                        start: TokenPosition(10),
                        end: TokenPosition(10),
                    },
                    message: "array size expression starts here",
                },
            ],
            help: None,
            notes: &[],
        },
    );

    assert_diagnostic(
        &runs.get_by_code("files/P0054_03.uc", "P0054"),
        &ExpectedDiagnostic {
            headline: "missing `]` to close array size expression",
            severity: Severity::Error,
            code: Some("P0054"),
            primary_label: Some(ExpectedLabel {
                span: TokenSpan {
                    start: TokenPosition(9),
                    end: TokenPosition(19),
                },
                message: "expected `]` before `;`",
            }),
            secondary_labels: &[
                ExpectedLabel {
                    span: TokenSpan {
                        start: TokenPosition(3),
                        end: TokenPosition(3),
                    },
                    message: "variable declaration starts here",
                },
                ExpectedLabel {
                    span: TokenSpan {
                        start: TokenPosition(9),
                        end: TokenPosition(9),
                    },
                    message: "array size expression starts here",
                },
            ],
            help: None,
            notes: &[],
        },
    );

    assert_diagnostic(
        &runs.get_by_code("files/P0054_04.uc", "P0054"),
        &ExpectedDiagnostic {
            headline: "missing `]` to close array size expression",
            severity: Severity::Error,
            code: Some("P0054"),
            primary_label: Some(ExpectedLabel {
                span: TokenSpan {
                    start: TokenPosition(13),
                    end: TokenPosition(19),
                },
                message: "expected `]` before `;`",
            }),
            secondary_labels: &[
                ExpectedLabel {
                    span: TokenSpan {
                        start: TokenPosition(3),
                        end: TokenPosition(3),
                    },
                    message: "variable declaration starts here",
                },
                ExpectedLabel {
                    span: TokenSpan {
                        start: TokenPosition(13),
                        end: TokenPosition(13),
                    },
                    message: "array size expression starts here",
                },
            ],
            help: None,
            notes: &[],
        },
    );
}

pub(super) const P0055_FIXTURES: &[Fixture] = &[
    Fixture {
        label: "files/P0055_01.uc",
        source: "{\n    local int A\n\n[], B;\n}\n",
    },
    Fixture {
        label: "files/P0055_02.uc",
        source: "{\n    local\n        int\n        A[\n        ], B;\n}\n",
    },
    Fixture {
        label: "files/P0055_03.uc",
        source: "{\n    local string\n        Names\n[\n        ]\n        ,\n        OtherNames;\n}\n",
    },
    Fixture {
        label: "files/P0055_04.uc",
        source: "{\n    local\n        class<\nActor\n>\n        ActorClasses[\n        ], OtherActorClasses;\n}\n",
    },
];

#[test]
fn check_p0055_fixtures() {
    let runs = run_fixtures(P0055_FIXTURES);

    assert_eq!(runs.get("files/P0055_01.uc").unwrap().len(), 1);
    assert_eq!(runs.get("files/P0055_02.uc").unwrap().len(), 1);
    assert_eq!(runs.get("files/P0055_03.uc").unwrap().len(), 1);
    assert_eq!(runs.get("files/P0055_04.uc").unwrap().len(), 1);

    assert_diagnostic(
        &runs.get_by_code("files/P0055_01.uc", "P0055"),
        &ExpectedDiagnostic {
            headline: "expected array size expression for `A` between `[` and `]`",
            severity: Severity::Error,
            code: Some("P0055"),
            primary_label: Some(ExpectedLabel {
                span: TokenSpan {
                    start: TokenPosition(11),
                    end: TokenPosition(11),
                },
                message: "expected array size expression before `]`",
            }),
            secondary_labels: &[ExpectedLabel {
                span: TokenSpan {
                    start: TokenPosition(7),
                    end: TokenPosition(7),
                },
                message: "this variable has an array size suffix",
            }],
            help: None,
            notes: &[],
        },
    );

    assert_diagnostic(
        &runs.get_by_code("files/P0055_02.uc", "P0055"),
        &ExpectedDiagnostic {
            headline: "expected array size expression for `A` between `[` and `]`",
            severity: Severity::Error,
            code: Some("P0055"),
            primary_label: Some(ExpectedLabel {
                span: TokenSpan {
                    start: TokenPosition(10),
                    end: TokenPosition(13),
                },
                message: "expected array size expression before `]`",
            }),
            secondary_labels: &[ExpectedLabel {
                span: TokenSpan {
                    start: TokenPosition(10),
                    end: TokenPosition(10),
                },
                message: "after this `[`, an array size expression was expected",
            }],
            help: None,
            notes: &[],
        },
    );

    assert_diagnostic(
        &runs.get_by_code("files/P0055_03.uc", "P0055"),
        &ExpectedDiagnostic {
            headline: "expected array size expression for `Names` between `[` and `]`",
            severity: Severity::Error,
            code: Some("P0055"),
            primary_label: Some(ExpectedLabel {
                span: TokenSpan {
                    start: TokenPosition(10),
                    end: TokenPosition(13),
                },
                message: "expected array size expression before `]`",
            }),
            secondary_labels: &[
                ExpectedLabel {
                    span: TokenSpan {
                        start: TokenPosition(10),
                        end: TokenPosition(10),
                    },
                    message: "after this `[`, an array size expression was expected",
                },
                ExpectedLabel {
                    span: TokenSpan {
                        start: TokenPosition(8),
                        end: TokenPosition(8),
                    },
                    message: "this variable has an array size suffix",
                },
            ],
            help: None,
            notes: &[],
        },
    );

    assert_diagnostic(
        &runs.get_by_code("files/P0055_04.uc", "P0055"),
        &ExpectedDiagnostic {
            headline: "expected array size expression for `ActorClasses` between `[` and `]`",
            severity: Severity::Error,
            code: Some("P0055"),
            primary_label: Some(ExpectedLabel {
                span: TokenSpan {
                    start: TokenPosition(15),
                    end: TokenPosition(18),
                },
                message: "expected array size expression before `]`",
            }),
            secondary_labels: &[ExpectedLabel {
                span: TokenSpan {
                    start: TokenPosition(15),
                    end: TokenPosition(15),
                },
                message: "after this `[`, an array size expression was expected",
            }],
            help: None,
            notes: &[],
        },
    );
}

pub(super) const P0056_FIXTURES: &[Fixture] = &[
    Fixture {
        label: "files/P0056_01.uc",
        source: "{\n    local int A = ;\n}\n",
    },
    Fixture {
        label: "files/P0056_02.uc",
        source: "{\n    local\n        int\n        A\n            =\n        ;\n}\n",
    },
    Fixture {
        label: "files/P0056_03.uc",
        source: "{\n    local string\n        First\n            =        ,\n        Second;\n}\n",
    },
    Fixture {
        label: "files/P0056_04.uc",
        source: "{\n    local\n        class<\nActor\n>\n        ActorClass\n            =\n        , OtherActorClass;\n}\n",
    },
];

#[test]
fn check_p0056_fixtures() {
    let runs = run_fixtures(P0056_FIXTURES);

    assert_eq!(runs.get("files/P0056_01.uc").unwrap().len(), 1);
    assert_eq!(runs.get("files/P0056_02.uc").unwrap().len(), 1);
    assert_eq!(runs.get("files/P0056_03.uc").unwrap().len(), 1);
    assert_eq!(runs.get("files/P0056_04.uc").unwrap().len(), 1);

    assert_diagnostic(
        &runs.get_by_code("files/P0056_01.uc", "P0056"),
        &ExpectedDiagnostic {
            headline: "expected initializer expression for `A` after `=`, found `;`",
            severity: Severity::Error,
            code: Some("P0056"),
            primary_label: Some(ExpectedLabel {
                span: TokenSpan {
                    start: TokenPosition(11),
                    end: TokenPosition(11),
                },
                message: "unexpected `;`",
            }),
            secondary_labels: &[],
            help: None,
            notes: &[],
        },
    );

    assert_diagnostic(
        &runs.get_by_code("files/P0056_02.uc", "P0056"),
        &ExpectedDiagnostic {
            headline: "expected initializer expression for `A` after `=`, found `;`",
            severity: Severity::Error,
            code: Some("P0056"),
            primary_label: Some(ExpectedLabel {
                span: TokenSpan {
                    start: TokenPosition(15),
                    end: TokenPosition(15),
                },
                message: "unexpected `;`",
            }),
            secondary_labels: &[
                ExpectedLabel {
                    span: TokenSpan {
                        start: TokenPosition(12),
                        end: TokenPosition(12),
                    },
                    message: "after this `=`, an initializer expression was expected",
                },
                ExpectedLabel {
                    span: TokenSpan {
                        start: TokenPosition(9),
                        end: TokenPosition(9),
                    },
                    message: "initializer is for this variable",
                },
            ],
            help: None,
            notes: &[],
        },
    );

    assert_diagnostic(
        &runs.get_by_code("files/P0056_03.uc", "P0056"),
        &ExpectedDiagnostic {
            headline: "expected initializer expression for `First` after `=`, found `,`",
            severity: Severity::Error,
            code: Some("P0056"),
            primary_label: Some(ExpectedLabel {
                span: TokenSpan {
                    start: TokenPosition(13),
                    end: TokenPosition(13),
                },
                message: "unexpected `,`",
            }),
            secondary_labels: &[ExpectedLabel {
                span: TokenSpan {
                    start: TokenPosition(8),
                    end: TokenPosition(8),
                },
                message: "initializer is for this variable",
            }],
            help: None,
            notes: &[],
        },
    );

    assert_diagnostic(
        &runs.get_by_code("files/P0056_04.uc", "P0056"),
        &ExpectedDiagnostic {
            headline: "expected initializer expression for `ActorClass` after `=`, found `,`",
            severity: Severity::Error,
            code: Some("P0056"),
            primary_label: Some(ExpectedLabel {
                span: TokenSpan {
                    start: TokenPosition(20),
                    end: TokenPosition(20),
                },
                message: "unexpected `,`",
            }),
            secondary_labels: &[
                ExpectedLabel {
                    span: TokenSpan {
                        start: TokenPosition(17),
                        end: TokenPosition(17),
                    },
                    message: "after this `=`, an initializer expression was expected",
                },
                ExpectedLabel {
                    span: TokenSpan {
                        start: TokenPosition(14),
                        end: TokenPosition(14),
                    },
                    message: "initializer is for this variable",
                },
            ],
            help: None,
            notes: &[],
        },
    );
}