//! > Test event variant not deriving starknet::Event.

//! > test_runner_name
test_abi_failure(expect_diagnostics: true)

//! > cairo_code
#[derive(Drop)]
struct A {}

#[starknet::contract]
mod test_contract {
    #[storage]
    struct Storage {}

    #[event]
    #[derive(Drop, starknet::Event)]
    enum Event {
        A: super::A,
    }
}

//! > expected_error
Event type must derive `starknet::Event`.

//! > expected_diagnostics
warning: Plugin diagnostic: Failed to generate ABI: Event type must derive `starknet::Event`.
 --> lib.cairo:12:9
        A: super::A,
        ^^^^^^^^^^^

error: Trait has no implementation in context: core::starknet::event::Event::<test::A>.
 --> lib.cairo:10:20
    #[derive(Drop, starknet::Event)]
                   ^^^^^^^^^^^^^^^

//! > ==========================================================================

//! > Test flat event variant which is not an enum.

//! > test_runner_name
test_abi_failure(expect_diagnostics: warnings_only)

//! > cairo_code
#[derive(Drop, starknet::Event)]
struct A {}

#[starknet::contract]
mod test_contract {
    #[storage]
    struct Storage {}

    #[event]
    #[derive(Drop, starknet::Event)]
    enum Event {
        #[flat]
        A: super::A,
    }
}

//! > expected_error
`starknet::Event` variant marked with `#[flat]` must be an enum.

//! > expected_diagnostics
warning: Plugin diagnostic: Failed to generate ABI: `starknet::Event` variant marked with `#[flat]` must be an enum.
 --> lib.cairo:12:9
        #[flat]
        ^^^^^^^

//! > ==========================================================================

//! > Test duplicate event selector.

//! > test_runner_name
test_abi_failure(expect_diagnostics: warnings_only)

//! > cairo_code
#[derive(Drop, starknet::Event)]
enum A {
    Dup: B,
}
#[derive(Drop, starknet::Event)]
struct B {}

#[starknet::contract]
mod test_contract {
    #[storage]
    struct Storage {}

    #[event]
    #[derive(Drop, starknet::Event)]
    enum Event {
        #[flat]
        A: super::A,
        Dup: super::B,
    }
}

//! > expected_error
Event `test::test_contract::Event` has duplicate selector `Dup`.

//! > expected_diagnostics
warning: Plugin diagnostic: Failed to generate ABI: Event `test::test_contract::Event` has duplicate selector `Dup`.
 --> lib.cairo:18:9
        Dup: super::B,
        ^^^^^^^^^^^^^

//! > ==========================================================================

//! > Test duplicate entry points with the same name.

//! > test_runner_name
test_abi_failure(expect_diagnostics: warnings_only)

//! > cairo_code
>>> file: test_data/interfaces.cairo

//! > expected_error
Duplicate entry point: 'foo'. This is not currently supported.

//! > expected_diagnostics
warning: Plugin diagnostic: Failed to generate ABI: Duplicate entry point: 'foo'. This is not currently supported.
 --> lib.cairo:56:5-57:57
      #[abi(embed_v0)]
 _____^
|     impl EmbeddedI1I2 = super::comp::I1I2<ContractState>;
|_________________________________________________________^

warning: Plugin diagnostic: Failed to generate ABI: Duplicate entry point: 'foo'. This is not currently supported.
 --> lib.cairo:58:5-59:55
      #[abi(embed_v0)]
 _____^
|     impl EmbeddedI2I = super::comp::I2I<ContractState>;
|_______________________________________________________^

warning: Plugin diagnostic: Failed to generate ABI: Duplicate entry point: 'foo'. This is not currently supported.
 --> lib.cairo:61:5-62:35
      #[external(v0)]
 _____^
|     fn foo(self: @ContractState) {}
|___________________________________^

//! > ==========================================================================

//! > Test embed impl of non-interface trait.

//! > test_runner_name
test_abi_failure(expect_diagnostics: warnings_only)

//! > cairo_code
trait NonInterfaceTrait<TContractState> {
    fn foo(self: @TContractState);
}

#[starknet::contract]
mod contract {
    #[storage]
    struct Storage {}

    #[abi(embed_v0)]
    impl Impl of super::NonInterfaceTrait<ContractState> {
        fn foo(self: @ContractState) {}
    }
}

//! > expected_error
An embedded impl must be an impl of a trait marked with #[starknet::interface].

//! > expected_diagnostics
warning: Plugin diagnostic: Failed to generate ABI: An embedded impl must be an impl of a trait marked with #[starknet::interface].
 --> lib.cairo:10:5-13:5
      #[abi(embed_v0)]
 _____^
| ...
|     }
|_____^

//! > ==========================================================================

//! > Test per-item impl of a starknet interface.

//! > test_runner_name
test_abi_failure(expect_diagnostics: warnings_only)

//! > cairo_code
#[starknet::interface]
trait InterfaceTrait<TContractState> {
    fn foo(self: @TContractState);
}

#[starknet::contract]
mod contract {
    #[storage]
    struct Storage {}

    #[abi(per_item)]
    impl Impl of super::InterfaceTrait<ContractState> {
        fn foo(self: @ContractState) {}
    }
}

//! > expected_error
An impl marked with #[abi(per_item)] can't be of a trait marked with #[starknet::interface].
    Consider using #[abi(embed_v0)] instead, or use a non-interface trait.

//! > expected_diagnostics
warning: Plugin diagnostic: Failed to generate ABI: An impl marked with #[abi(per_item)] can't be of a trait marked with #[starknet::interface].
    Consider using #[abi(embed_v0)] instead, or use a non-interface trait.
 --> lib.cairo:11:5-14:5
      #[abi(per_item)]
 _____^
| ...
|     }
|_____^

//! > ==========================================================================

//! > Test bad __validate_deploy__.

//! > test_runner_name
test_abi_failure(expect_diagnostics: warnings_only)

//! > cairo_code
#[starknet::contract(account)]
mod contract {
    #[storage]
    struct Storage {}

    #[abi(per_item)]
    #[generate_trait]
    impl Impl of Trait {
        #[constructor]
        fn constructor(
            ref self: ContractState, param_a: starknet::ClassHash, param_b: Array<felt252>,
        ) {}
        #[external(v0)]
        fn __validate_deploy__(
            self: @ContractState,
            class_hash: felt252,
            contract_address_salt: felt252,
            param_a: starknet::ClassHash,
            param_b: Array<u8>,
        ) {}
        #[external(v0)]
        fn __validate__(ref self: ContractState) {}
        #[external(v0)]
        fn __execute__(ref self: ContractState) {}
    }
}

//! > expected_error
`__validate_deploy__` entry point must match the constructor.

//! > expected_diagnostics
warning: Plugin diagnostic: Failed to generate ABI: `__validate_deploy__` entry point must match the constructor.
 --> lib.cairo:13:9-20:12
          #[external(v0)]
 _________^
| ...
|         ) {}
|____________^
