Едно нещо, което не имплементирахме за домашно 2 беше Display trait, защото би трябвало да е сравнително прост и си имаше достатъчно други неща за имплементация. Но сега ще искаме да имплементирате даже 2 различни начина за display-ване на един Bigint.
Първо, дефиниция и парсене:
use std::str::FromStr;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Bigint {
pub digits: Vec<u8>,
}
impl FromStr for Bigint {
type Err = &'static str;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let mut digits = Vec::with_capacity(s.len());
for c in s.chars() {
if let Some(digit) = c.to_digit(10) {
digits.push(digit as u8);
} else {
return Err("Invalid input!");
}
}
Ok(Bigint { digits })
}
}
Даваме ви някаква проста готова имплементация, защото вече ги писахте, така че няма какво да ви караме да я мислите. Все пак, чувствайте се свободни да си я напишете както на вас ви харесва, стига да не чупи външния интерфейс, т.е. типовете, които връща. За нашите тестове, тази имплементация ще е достатъчна.
Забележете, че този Bigint няма знак -- не е особено предизвикателство да го напечатате, така че нека просто го изпуснем за опростяване.
Това, което очакваме да имплементирате е, първо, един Display:
use std::fmt;
use std::fmt::Write; // опционално, може да ви трябва, може би не, зависи какво правите.
impl fmt::Display for Bigint {
/// Форматира число като за хора, по най-простия начин -- просто показва цифрите една след
/// друга:
///
/// let bigint = Bigint::from_str("100000").unwrap();
/// println!("{}", bigint);
/// // => 100000
///
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
todo!()
}
}
Един проблем на този вид печатане е че може да е малко тегаво да разберете колко голямо е това число. Би било по-удобно да го напечатате с групички по 3 цифри, хиляди, милиони, и т.н. Но има само една имплементация за Display на един тип, нали?
Е, можем да решим този проблем сравнително лесно -- като си имплементираме нов тип, който държи reference към стария, но се форматира по различен начин:
pub struct Delimited<'a> {
bigint: &'a Bigint,
}
impl Bigint {
pub fn delimited(&self) -> Delimited {
Delimited { bigint: self }
}
}
impl<'a> fmt::Display for Delimited<'a> {
/// Форматира Bigint по малко по-човешки начин -- със запетайки на всеки 3 цифри (за да отделим хиляди, милиони и т.н.):
///
/// let bigint = Bigint::from_str("100000").unwrap();
/// println!("{}", bigint.delimited());
/// // => 100,000
///
/// let bigint = Bigint::from_str("100000000").unwrap();
/// println!("{}", bigint.delimited());
/// // => 100,000,000
///
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
todo!()
}
}
Както и друг път, полетата, които не са pub може да ги променяте и преименувате както решите. Единственото, което ще правим в нашите тестове, е да конструираме Bigint-ове с Bigint::from_str и да ги конвертираме до низове, използвайки format! макроса. Вие напишете конкретните имплементации на Display за двата типа, както са описани. Мислете за edge cases.
Compiling solution v0.1.0 (/tmp/d20201216-2274206-1jl2y54/solution)
Finished test [unoptimized + debuginfo] target(s) in 1.26s
Running target/debug/deps/solution_test-589a43f0f4b10ca3
running 3 tests
test solution_test::test_bigint_delimited_display ... ok
test solution_test::test_bigint_display ... ok
test solution_test::test_bigint_parsing ... ok
test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
let bigint = Bigint::from_str("100000").unwrap(); // => 100,000
println!("{}", bigint.delimited());
let bigint = Bigint::from_str("100000000").unwrap(); // => 100,000,000
println!("{}", bigint.delimited());
let bigint = Bigint::from_str("0").unwrap();
println!("{}", bigint.delimited());
let bigint = Bigint::from_str("1").unwrap();
println!("{}", bigint.delimited());
let bigint = Bigint::from_str("12").unwrap();
println!("{}", bigint.delimited());
let bigint = Bigint::from_str("123").unwrap();
println!("{}", bigint.delimited());
let bigint = Bigint::from_str("1234").unwrap();
println!("{}", bigint.delimited());
let bigint = Bigint::from_str("12345").unwrap();
println!("{}", bigint.delimited());
}
*/
Compiling solution v0.1.0 (/tmp/d20201216-2274206-11xwoht/solution)
Finished test [unoptimized + debuginfo] target(s) in 1.33s
Running target/debug/deps/solution_test-589a43f0f4b10ca3
running 3 tests
test solution_test::test_bigint_delimited_display ... ok
test solution_test::test_bigint_display ... ok
test solution_test::test_bigint_parsing ... ok
test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Compiling solution v0.1.0 (/tmp/d20201216-2274206-eaxxx/solution)
Finished test [unoptimized + debuginfo] target(s) in 1.41s
Running target/debug/deps/solution_test-589a43f0f4b10ca3
running 3 tests
test solution_test::test_bigint_delimited_display ... ok
test solution_test::test_bigint_display ... ok
test solution_test::test_bigint_parsing ... ok
test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Compiling solution v0.1.0 (/tmp/d20201216-2274206-3a0qbp/solution)
Finished test [unoptimized + debuginfo] target(s) in 1.50s
Running target/debug/deps/solution_test-589a43f0f4b10ca3
running 3 tests
test solution_test::test_bigint_delimited_display ... ok
test solution_test::test_bigint_display ... ok
test solution_test::test_bigint_parsing ... ok
test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Compiling solution v0.1.0 (/tmp/d20201216-2274206-3gq91x/solution)
warning: function is never used: `main`
--> src/lib.rs:71:4
|
71 | fn main() {
| ^^^^
|
= note: `#[warn(dead_code)]` on by default
warning: 1 warning emitted
Finished test [unoptimized + debuginfo] target(s) in 1.61s
Running target/debug/deps/solution_test-589a43f0f4b10ca3
running 3 tests
test solution_test::test_bigint_delimited_display ... ok
test solution_test::test_bigint_display ... ok
test solution_test::test_bigint_parsing ... ok
test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Compiling solution v0.1.0 (/tmp/d20201216-2274206-1x340vv/solution)
Finished test [unoptimized + debuginfo] target(s) in 1.46s
Running target/debug/deps/solution_test-589a43f0f4b10ca3
running 3 tests
test solution_test::test_bigint_delimited_display ... ok
test solution_test::test_bigint_display ... ok
test solution_test::test_bigint_parsing ... ok
test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Compiling solution v0.1.0 (/tmp/d20201216-2274206-13bucdd/solution)
Finished test [unoptimized + debuginfo] target(s) in 1.25s
Running target/debug/deps/solution_test-589a43f0f4b10ca3
running 3 tests
test solution_test::test_bigint_delimited_display ... ok
test solution_test::test_bigint_display ... ok
test solution_test::test_bigint_parsing ... ok
test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
/// Форматира число като за хора, по най-простия начин -- просто показва цифрите една след
/// друга:
///
/// let bigint = Bigint::from_str("100000").unwrap();
/// println!("{}", bigint);
/// // => 100000
///
fnfmt(&self,f:&mutfmt::Formatter)->fmt::Result{
letmutnum_str=String::new();
fornuminself.digits.iter(){
num_str.push_str(&num.to_string());
}
write!(f,"{}",num_str)
}
}
pubstructDelimited<'a>{
bigint:&'aBigint,
}
implBigint{
pubfndelimited(&self)->Delimited{
Delimited{bigint:self}
}
}
impl<'a>fmt::DisplayforDelimited<'a>{
/// Форматира Bigint по малко по-човешки начин -- със запетайки на всеки 3 цифри:
///
/// let bigint = Bigint::from_str("100000").unwrap();
/// println!("{}", bigint.delimited());
/// // => 100,000
///
/// let bigint = Bigint::from_str("100000000").unwrap();
/// println!("{}", bigint.delimited());
/// // => 100,000,000
///
fnfmt(&self,f:&mutfmt::Formatter)->fmt::Result{
letmutnum_str=String::new();
letmutcounter=self.bigint.digits.len();
fornuminself.bigint.digits.iter(){
counter=counter-1;
num_str.push_str(&num.to_string());
ifcounter%3==0&&counter!=0{
num_str.push_str(",");
}
}
write!(f,"{}",num_str)
}
}
Compiling solution v0.1.0 (/tmp/d20201216-2274206-muc1b1/solution)
Finished test [unoptimized + debuginfo] target(s) in 1.93s
Running target/debug/deps/solution_test-589a43f0f4b10ca3
running 3 tests
test solution_test::test_bigint_delimited_display ... ok
test solution_test::test_bigint_display ... ok
test solution_test::test_bigint_parsing ... ok
test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Compiling solution v0.1.0 (/tmp/d20201216-2274206-v7wati/solution)
Finished test [unoptimized + debuginfo] target(s) in 2.00s
Running target/debug/deps/solution_test-589a43f0f4b10ca3
running 3 tests
test solution_test::test_bigint_delimited_display ... ok
test solution_test::test_bigint_display ... ok
test solution_test::test_bigint_parsing ... ok
test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Compiling solution v0.1.0 (/tmp/d20201216-2274206-d8kgfu/solution)
Finished test [unoptimized + debuginfo] target(s) in 1.29s
Running target/debug/deps/solution_test-589a43f0f4b10ca3
running 3 tests
test solution_test::test_bigint_delimited_display ... ok
test solution_test::test_bigint_display ... ok
test solution_test::test_bigint_parsing ... ok
test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Compiling solution v0.1.0 (/tmp/d20201216-2274206-tcav4l/solution)
Finished test [unoptimized + debuginfo] target(s) in 1.33s
Running target/debug/deps/solution_test-589a43f0f4b10ca3
running 3 tests
test solution_test::test_bigint_delimited_display ... ok
test solution_test::test_bigint_display ... ok
test solution_test::test_bigint_parsing ... ok
test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Compiling solution v0.1.0 (/tmp/d20201216-2274206-3ngglv/solution)
Finished test [unoptimized + debuginfo] target(s) in 1.32s
Running target/debug/deps/solution_test-589a43f0f4b10ca3
running 3 tests
test solution_test::test_bigint_delimited_display ... ok
test solution_test::test_bigint_display ... ok
test solution_test::test_bigint_parsing ... ok
test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Compiling solution v0.1.0 (/tmp/d20201216-2274206-1ctopl0/solution)
Finished test [unoptimized + debuginfo] target(s) in 1.34s
Running target/debug/deps/solution_test-589a43f0f4b10ca3
running 3 tests
test solution_test::test_bigint_delimited_display ... ok
test solution_test::test_bigint_display ... ok
test solution_test::test_bigint_parsing ... ok
test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Compiling solution v0.1.0 (/tmp/d20201216-2274206-dc1y43/solution)
warning: unused import: `std::fmt::Write`
--> src/lib.rs:27:5
|
27 | use std::fmt::Write; // опционално, може да ви трябва, може би не, зависи какво правите.
| ^^^^^^^^^^^^^^^
|
= note: `#[warn(unused_imports)]` on by default
warning: function is never used: `main`
--> src/lib.rs:84:4
|
84 | fn main() {
| ^^^^
|
= note: `#[warn(dead_code)]` on by default
warning: 2 warnings emitted
Finished test [unoptimized + debuginfo] target(s) in 1.26s
Running target/debug/deps/solution_test-589a43f0f4b10ca3
running 3 tests
test solution_test::test_bigint_delimited_display ... FAILED
test solution_test::test_bigint_display ... ok
test solution_test::test_bigint_parsing ... ok
failures:
---- solution_test::test_bigint_delimited_display stdout ----
,thread 'main' panicked at 'assertion failed: `(left == right)`
left: `"1234"`,
right: `"1,234"`', tests/solution_test.rs:32:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
failures:
solution_test::test_bigint_delimited_display
test result: FAILED. 2 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out
error: test failed, to rerun pass '--test solution_test'
Compiling solution v0.1.0 (/tmp/d20201216-2274206-asa0sr/solution)
Finished test [unoptimized + debuginfo] target(s) in 1.39s
Running target/debug/deps/solution_test-589a43f0f4b10ca3
running 3 tests
test solution_test::test_bigint_delimited_display ... ok
test solution_test::test_bigint_display ... ok
test solution_test::test_bigint_parsing ... ok
test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Compiling solution v0.1.0 (/tmp/d20201216-2274206-1liaf62/solution)
warning: unnecessary parentheses around `if` condition
--> src/lib.rs:22:11
|
22 | if(digits.len() == 0) {
| ^^^^^^^^^^^^^^^^^^^ help: remove these parentheses
|
= note: `#[warn(unused_parens)]` on by default
warning: 1 warning emitted
Finished test [unoptimized + debuginfo] target(s) in 1.58s
Running target/debug/deps/solution_test-589a43f0f4b10ca3
running 3 tests
test solution_test::test_bigint_delimited_display ... ok
test solution_test::test_bigint_display ... ok
test solution_test::test_bigint_parsing ... ok
test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Compiling solution v0.1.0 (/tmp/d20201216-2274206-1knd7j2/solution)
Finished test [unoptimized + debuginfo] target(s) in 1.32s
Running target/debug/deps/solution_test-589a43f0f4b10ca3
running 3 tests
test solution_test::test_bigint_delimited_display ... ok
test solution_test::test_bigint_display ... ok
test solution_test::test_bigint_parsing ... ok
test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Compiling solution v0.1.0 (/tmp/d20201216-2274206-293uxf/solution)
Finished test [unoptimized + debuginfo] target(s) in 1.37s
Running target/debug/deps/solution_test-589a43f0f4b10ca3
running 3 tests
test solution_test::test_bigint_delimited_display ... ok
test solution_test::test_bigint_display ... ok
test solution_test::test_bigint_parsing ... ok
test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Compiling solution v0.1.0 (/tmp/d20201216-2274206-1oujiat/solution)
Finished test [unoptimized + debuginfo] target(s) in 1.41s
Running target/debug/deps/solution_test-589a43f0f4b10ca3
running 3 tests
test solution_test::test_bigint_delimited_display ... ok
test solution_test::test_bigint_display ... ok
test solution_test::test_bigint_parsing ... ok
test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Compiling solution v0.1.0 (/tmp/d20201216-2274206-blueo4/solution)
Finished test [unoptimized + debuginfo] target(s) in 1.52s
Running target/debug/deps/solution_test-589a43f0f4b10ca3
running 3 tests
test solution_test::test_bigint_delimited_display ... ok
test solution_test::test_bigint_display ... ok
test solution_test::test_bigint_parsing ... ok
test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Compiling solution v0.1.0 (/tmp/d20201216-2274206-fiyn26/solution)
Finished test [unoptimized + debuginfo] target(s) in 1.47s
Running target/debug/deps/solution_test-589a43f0f4b10ca3
running 3 tests
test solution_test::test_bigint_delimited_display ... ok
test solution_test::test_bigint_display ... ok
test solution_test::test_bigint_parsing ... ok
test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Compiling solution v0.1.0 (/tmp/d20201216-2274206-1rtzf/solution)
Finished test [unoptimized + debuginfo] target(s) in 1.22s
Running target/debug/deps/solution_test-589a43f0f4b10ca3
running 3 tests
test solution_test::test_bigint_delimited_display ... ok
test solution_test::test_bigint_display ... ok
test solution_test::test_bigint_parsing ... ok
test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Compiling solution v0.1.0 (/tmp/d20201216-2274206-cvzbmg/solution)
warning: function is never used: `main`
--> src/lib.rs:1:4
|
1 | fn main() {
| ^^^^
|
= note: `#[warn(dead_code)]` on by default
warning: 1 warning emitted
Finished test [unoptimized + debuginfo] target(s) in 1.33s
Running target/debug/deps/solution_test-589a43f0f4b10ca3
running 3 tests
test solution_test::test_bigint_delimited_display ... ok
test solution_test::test_bigint_display ... ok
test solution_test::test_bigint_parsing ... ok
test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Compiling solution v0.1.0 (/tmp/d20201216-2274206-tc8b8i/solution)
warning: unused import: `std::fmt::Write`
--> src/lib.rs:3:5
|
3 | use std::fmt::Write;
| ^^^^^^^^^^^^^^^
|
= note: `#[warn(unused_imports)]` on by default
warning: unused `std::result::Result` that must be used
--> src/lib.rs:31:13
|
31 | write!(f, "{}", c);
| ^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(unused_must_use)]` on by default
= note: this `Result` may be an `Err` variant, which should be handled
= note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
warning: unused `std::result::Result` that must be used
--> src/lib.rs:52:13
|
52 | write!(f, "{}", c);
| ^^^^^^^^^^^^^^^^^^^
|
= note: this `Result` may be an `Err` variant, which should be handled
= note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
warning: unused `std::result::Result` that must be used
--> src/lib.rs:54:17
|
54 | write!(f, ",");
| ^^^^^^^^^^^^^^^
|
= note: this `Result` may be an `Err` variant, which should be handled
= note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
warning: 4 warnings emitted
Finished test [unoptimized + debuginfo] target(s) in 1.28s
Running target/debug/deps/solution_test-589a43f0f4b10ca3
running 3 tests
test solution_test::test_bigint_delimited_display ... ok
test solution_test::test_bigint_display ... ok
test solution_test::test_bigint_parsing ... ok
test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Compiling solution v0.1.0 (/tmp/d20201216-2274206-19suymk/solution)
warning: unused import: `std::fmt::Write`
--> src/lib.rs:27:5
|
27 | use std::fmt::Write; // опционално, може да ви трябва, може би не, зависи какво правите.
| ^^^^^^^^^^^^^^^
|
= note: `#[warn(unused_imports)]` on by default
warning: 1 warning emitted
Finished test [unoptimized + debuginfo] target(s) in 1.37s
Running target/debug/deps/solution_test-589a43f0f4b10ca3
running 3 tests
test solution_test::test_bigint_delimited_display ... FAILED
test solution_test::test_bigint_display ... ok
test solution_test::test_bigint_parsing ... ok
failures:
---- solution_test::test_bigint_delimited_display stdout ----
thread 'main' panicked at 'assertion failed: `(left == right)`
left: `"12,"`,
right: `"12"`', tests/solution_test.rs:30:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
failures:
solution_test::test_bigint_delimited_display
test result: FAILED. 2 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out
error: test failed, to rerun pass '--test solution_test'
Compiling solution v0.1.0 (/tmp/d20201216-2274206-1vhelek/solution)
warning: unused import: `std::fmt::Write`
--> src/lib.rs:26:5
|
26 | use std::fmt::Write; // опционално, може да ви трябва, може би не, зависи какво правите.
| ^^^^^^^^^^^^^^^
|
= note: `#[warn(unused_imports)]` on by default
warning: unused `std::result::Result` that must be used
--> src/lib.rs:67:21
|
67 | write!(f, "{}", *val);
| ^^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(unused_must_use)]` on by default
= note: this `Result` may be an `Err` variant, which should be handled
= note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
warning: unused `std::result::Result` that must be used
--> src/lib.rs:95:25
|
95 | write!(f, "{}", *val);
| ^^^^^^^^^^^^^^^^^^^^^^
|
= note: this `Result` may be an `Err` variant, which should be handled
= note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
warning: unused `std::result::Result` that must be used
--> src/lib.rs:99:25
|
99 | write!(f, ",{}", *val);
| ^^^^^^^^^^^^^^^^^^^^^^^
|
= note: this `Result` may be an `Err` variant, which should be handled
= note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
warning: unused `std::result::Result` that must be used
--> src/lib.rs:102:25
|
102 | write!(f, "{}", *val);
| ^^^^^^^^^^^^^^^^^^^^^^
|
= note: this `Result` may be an `Err` variant, which should be handled
= note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
warning: 5 warnings emitted
Finished test [unoptimized + debuginfo] target(s) in 1.32s
Running target/debug/deps/solution_test-589a43f0f4b10ca3
running 3 tests
test solution_test::test_bigint_delimited_display ... ok
test solution_test::test_bigint_display ... ok
test solution_test::test_bigint_parsing ... ok
test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Compiling solution v0.1.0 (/tmp/d20201216-2274206-s9wu2v/solution)
Finished test [unoptimized + debuginfo] target(s) in 1.26s
Running target/debug/deps/solution_test-589a43f0f4b10ca3
running 3 tests
test solution_test::test_bigint_delimited_display ... ok
test solution_test::test_bigint_display ... ok
test solution_test::test_bigint_parsing ... ok
test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Compiling solution v0.1.0 (/tmp/d20201216-2274206-yrewuj/solution)
Finished test [unoptimized + debuginfo] target(s) in 1.28s
Running target/debug/deps/solution_test-589a43f0f4b10ca3
running 3 tests
test solution_test::test_bigint_delimited_display ... ok
test solution_test::test_bigint_display ... ok
test solution_test::test_bigint_parsing ... ok
test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Compiling solution v0.1.0 (/tmp/d20201216-2274206-1ygp0xx/solution)
warning: unused import: `std::fmt::Write`
--> src/lib.rs:2:5
|
2 | use std::fmt::Write;
| ^^^^^^^^^^^^^^^
|
= note: `#[warn(unused_imports)]` on by default
warning: 1 warning emitted
Finished test [unoptimized + debuginfo] target(s) in 1.28s
Running target/debug/deps/solution_test-589a43f0f4b10ca3
running 3 tests
test solution_test::test_bigint_delimited_display ... ok
test solution_test::test_bigint_display ... ok
test solution_test::test_bigint_parsing ... ok
test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out