forked from use-ink/ink
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
The initial structure of the linting crate and tests
Nedeed for use-ink#1436
- Loading branch information
Georgiy Komarov
committed
Jun 26, 2023
1 parent
97f90ca
commit 7ca2cf7
Showing
5 changed files
with
210 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
// Copyright 2018-2023 Parity Technologies (UK) Ltd. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
use rustc_hir::Item; | ||
use rustc_lint::{ | ||
LateContext, | ||
LateLintPass, | ||
}; | ||
use rustc_session::{ | ||
declare_lint, | ||
declare_lint_pass, | ||
}; | ||
|
||
declare_lint! { | ||
/// **What it does:** Checks for ink! contracts that use | ||
/// the [`#[ink(topic)]`](https://use.ink/macros-attributes/topic) annotation with primitive | ||
/// number types. Topics are discrete events for which it makes sense to filter. Typical | ||
/// examples of fields that should be filtered are `AccountId`, `bool` or `enum` variants. | ||
/// | ||
/// **Why is this bad?** It typically doesn't make sense to annotate types like `u32` or `i32` | ||
/// as a topic, if those fields can take continuous values that could be anywhere between | ||
/// `::MIN` and `::MAX`. An example of a case where it doesn't make sense at all to have a | ||
/// topic on the storage field is something like `value: Balance` in the examle below. | ||
/// | ||
/// **Known problems:** | ||
/// | ||
/// **Example:** | ||
/// | ||
/// ```rust | ||
/// // Good | ||
/// // Filtering transactions based on source and destination addresses. | ||
/// #[ink(event)] | ||
/// pub struct Transaction { | ||
/// #[ink(topic)] | ||
/// src: Option<AccountId>, | ||
/// #[ink(topic)] | ||
/// dst: Option<AccountId>, | ||
/// value: Balance, | ||
/// } | ||
/// ``` | ||
/// | ||
/// ```rust | ||
/// // Bad | ||
/// // It typically makes no sense to filter `Balance`, since its value may varies from `::MAX` | ||
/// // to `::MIN`. | ||
/// #[ink(event)] | ||
/// pub struct Transaction { | ||
/// #[ink(topic)] | ||
/// src: Option<AccountId>, | ||
/// #[ink(topic)] | ||
/// dst: Option<AccountId>, | ||
/// #[ink(topic)] | ||
/// value: Balance, | ||
/// } | ||
/// ``` | ||
pub PRIMITIVE_TOPIC, | ||
Warn, | ||
"The `#[ink(topic)]` annotation should not be used with a number primitive" | ||
} | ||
|
||
declare_lint_pass!(PrimitiveTopic => [PRIMITIVE_TOPIC]); | ||
|
||
impl<'tcx> LateLintPass<'tcx> for PrimitiveTopic { | ||
fn check_item(&mut self, _cx: &LateContext<'tcx>, _item: &'tcx Item<'_>) { | ||
todo!() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
// #![cfg_attr(not(feature = "std"), no_std, no_main)] | ||
|
||
#[ink::contract] | ||
pub mod flipper { | ||
#[ink(storage)] | ||
pub struct Flipper { | ||
value: bool, | ||
} | ||
|
||
impl Flipper { | ||
/// Creates a new flipper smart contract initialized with the given value. | ||
#[ink(constructor)] | ||
pub fn new(init_value: bool) -> Self { | ||
Self { value: init_value } | ||
} | ||
|
||
/// Creates a new flipper smart contract initialized to `false`. | ||
#[ink(constructor)] | ||
pub fn new_default() -> Self { | ||
Self::new(Default::default()) | ||
} | ||
|
||
/// Flips the current value of the Flipper's boolean. | ||
#[ink(message)] | ||
pub fn flip(&mut self) { | ||
self.value = !self.value; | ||
} | ||
|
||
/// Returns the current value of the Flipper's boolean. | ||
#[ink(message)] | ||
pub fn get(&self) -> bool { | ||
self.value | ||
} | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
use super::*; | ||
|
||
#[ink::test] | ||
fn default_works() { | ||
let flipper = Flipper::new_default(); | ||
assert!(!flipper.get()); | ||
} | ||
|
||
#[ink::test] | ||
fn it_works() { | ||
let mut flipper = Flipper::new(false); | ||
assert!(!flipper.get()); | ||
flipper.flip(); | ||
assert!(flipper.get()); | ||
} | ||
} | ||
|
||
#[cfg(all(test, feature = "e2e-tests"))] | ||
mod e2e_tests { | ||
use super::*; | ||
|
||
type E2EResult<T> = std::result::Result<T, Box<dyn std::error::Error>>; | ||
|
||
#[ink_e2e::test] | ||
async fn it_works(mut client: ink_e2e::Client<C, E>) -> E2EResult<()> { | ||
// given | ||
let constructor = FlipperRef::new(false); | ||
let contract = client | ||
.instantiate("flipper", &ink_e2e::alice(), constructor, 0, None) | ||
.await | ||
.expect("instantiate failed"); | ||
let mut call = contract.call::<Flipper>(); | ||
|
||
let get = call.get(); | ||
let get_res = client.call_dry_run(&ink_e2e::bob(), &get, 0, None).await; | ||
assert!(matches!(get_res.return_value(), false)); | ||
|
||
// when | ||
let flip = call.flip(); | ||
let _flip_res = client | ||
.call(&ink_e2e::bob(), &flip, 0, None) | ||
.await | ||
.expect("flip failed"); | ||
|
||
// then | ||
let get = call.get(); | ||
let get_res = client.call_dry_run(&ink_e2e::bob(), &get, 0, None).await; | ||
assert!(matches!(get_res.return_value(), true)); | ||
|
||
Ok(()) | ||
} | ||
|
||
#[ink_e2e::test] | ||
async fn default_works(mut client: ink_e2e::Client<C, E>) -> E2EResult<()> { | ||
// given | ||
let constructor = FlipperRef::new_default(); | ||
|
||
// when | ||
let contract = client | ||
.instantiate("flipper", &ink_e2e::bob(), constructor, 0, None) | ||
.await | ||
.expect("instantiate failed"); | ||
let call = contract.call::<Flipper>(); | ||
|
||
// then | ||
let get = call.get(); | ||
let get_res = client.call_dry_run(&ink_e2e::bob(), &get, 0, None).await; | ||
assert!(matches!(get_res.return_value(), false)); | ||
|
||
Ok(()) | ||
} | ||
} | ||
} | ||
|
||
fn main() {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
thread 'rustc' panicked at 'not yet implemented', src/primitive_topic.rs:50:9 | ||
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace |