added tests for checkbox

Also made every event type required by generic over any Iterator
This commit is contained in:
Lutetium-Vanadium 2021-06-20 20:45:33 +05:30
parent 08d2e1649b
commit 3123937e14
94 changed files with 2634 additions and 184 deletions

5
.cargo/config.toml Normal file
View File

@ -0,0 +1,5 @@
[alias]
tt = ["test", "--no-default-features", "--features=termion"]
review = ["insta", "review", "--color=never"]
snapshot = ["insta", "test", "--color=never"]
snapshott = ["insta", "test", "--color=never", "--no-default-features", "--features=termion"]

View File

@ -21,6 +21,10 @@ ahash = { version = "0.7", optional = true }
[dev-dependencies]
trybuild = { version = "1.0.42", features = ["diff"] }
insta = { version = "1.7.1", default-features = false }
rand = "0.8"
rand_chacha = "0.3"
csscolorparser = "0.4" # examples/input.rs
regex = "1.5" # examples/prompt_module.rs
fuzzy-matcher = "0.3" # examples/file.rs

View File

@ -0,0 +1,27 @@
---
source: tests/helpers/mod.rs
expression: self.backend
---
┌──────────────────────────────────────────────────┐
? checkbox (Press <space> to select, <a> to toggle│
 all, <i> to invert selection) │
✔ Choice 0 │
Separator 1 │
────────────── │
 ✔ Choice 3 │
✔ Choice 4 │
Separator 5 │
✔ Choice 6 │
✔ Choice 7 │
✔ Choice 8 │
✔ Choice 9 │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────┘

View File

@ -0,0 +1,27 @@
---
source: tests/helpers/mod.rs
expression: self.backend
---
┌──────────────────────────────────────────────────┐
? checkbox (Press <space> to select, <a> to toggle│
 all, <i> to invert selection) │
✔ Choice 0 │
Separator 1 │
────────────── │
 ✔ Choice 3 │
✔ Choice 4 │
Separator 5 │
✔ Choice 6 │
✔ Choice 7 │
✔ Choice 8 │
✔ Choice 9 │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────┘

View File

@ -0,0 +1,27 @@
---
source: tests/helpers/mod.rs
expression: self.backend
---
┌──────────────────────────────────────────────────┐
? checkbox (Press <space> to select, <a> to toggle│
 all, <i> to invert selection) │
✔ Choice 0 │
Separator 1 │
────────────── │
✔ Choice 3 │
✔ Choice 4 │
Separator 5 │
✔ Choice 6 │
✔ Choice 7 │
✔ Choice 8 │
 ✔ Choice 9 │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────┘

View File

@ -0,0 +1,27 @@
---
source: tests/helpers/mod.rs
expression: self.backend
---
┌──────────────────────────────────────────────────┐
? checkbox (Press <space> to select, <a> to toggle│
 all, <i> to invert selection) │
✔ Choice 0 │
Separator 1 │
────────────── │
✔ Choice 3 │
✔ Choice 4 │
Separator 5 │
✔ Choice 6 │
✔ Choice 7 │
✔ Choice 8 │
 ✔ Choice 9 │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────┘

View File

@ -0,0 +1,27 @@
---
source: tests/helpers/mod.rs
expression: self.backend
---
┌──────────────────────────────────────────────────┐
✔ checkbox · Choice 0, Choice 4, Choice 6, Choice │
7, Choice 8 │
  │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────┘

View File

@ -0,0 +1,27 @@
---
source: tests/helpers/mod.rs
expression: self.backend
---
┌──────────────────────────────────────────────────┐
? checkbox (Press <space> to select, <a> to toggle│
 all, <i> to invert selection) │
 ✔ Choice 0 │
Separator 1 │
────────────── │
✔ Choice 3 │
✔ Choice 4 │
Separator 5 │
✔ Choice 6 │
✔ Choice 7 │
✔ Choice 8 │
✔ Choice 9 │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────┘

View File

@ -0,0 +1,27 @@
---
source: tests/helpers/mod.rs
expression: self.backend
---
┌──────────────────────────────────────────────────┐
? checkbox (Press <space> to select, <a> to toggle│
 all, <i> to invert selection) │
✔ Choice 0 │
Separator 1 │
────────────── │
 ✔ Choice 3 │
✔ Choice 4 │
Separator 5 │
✔ Choice 6 │
✔ Choice 7 │
✔ Choice 8 │
✔ Choice 9 │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────┘

View File

@ -0,0 +1,27 @@
---
source: tests/helpers/mod.rs
expression: self.backend
---
┌──────────────────────────────────────────────────┐
? checkbox (Press <space> to select, <a> to toggle│
 all, <i> to invert selection) │
✔ Choice 0 │
Separator 1 │
────────────── │
 ✔ Choice 3 │
✔ Choice 4 │
Separator 5 │
✔ Choice 6 │
✔ Choice 7 │
✔ Choice 8 │
✔ Choice 9 │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────┘

View File

@ -0,0 +1,27 @@
---
source: tests/helpers/mod.rs
expression: self.backend
---
┌──────────────────────────────────────────────────┐
? checkbox (Press <space> to select, <a> to toggle│
 all, <i> to invert selection) │
✔ Choice 0 │
Separator 1 │
────────────── │
✔ Choice 3 │
✔ Choice 4 │
Separator 5 │
✔ Choice 6 │
✔ Choice 7 │
✔ Choice 8 │
 ✔ Choice 9 │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────┘

View File

@ -0,0 +1,27 @@
---
source: tests/helpers/mod.rs
expression: self.backend
---
┌──────────────────────────────────────────────────┐
? checkbox (Press <space> to select, <a> to toggle│
 all, <i> to invert selection) │
✔ Choice 0 │
Separator 1 │
────────────── │
✔ Choice 3 │
✔ Choice 4 │
Separator 5 │
✔ Choice 6 │
✔ Choice 7 │
✔ Choice 8 │
 ✔ Choice 9 │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────┘

View File

@ -0,0 +1,27 @@
---
source: tests/helpers/mod.rs
expression: self.backend
---
┌──────────────────────────────────────────────────┐
✔ checkbox · 3: Choice 3, 9: Choice 9 │
  │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────┘

View File

@ -0,0 +1,27 @@
---
source: tests/helpers/mod.rs
expression: self.backend
---
┌──────────────────────────────────────────────────┐
? checkbox (Press <space> to select, <a> to toggle│
 all, <i> to invert selection) │
 ✔ Choice 0 │
Separator 1 │
────────────── │
✔ Choice 3 │
✔ Choice 4 │
Separator 5 │
✔ Choice 6 │
✔ Choice 7 │
✔ Choice 8 │
✔ Choice 9 │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────┘

View File

@ -0,0 +1,27 @@
---
source: tests/helpers/mod.rs
expression: self.backend
---
┌──────────────────────────────────────────────────┐
? checkbox (Press <space> to select, <a> to toggle│
 all, <i> to invert selection) │
✔ Choice 0 │
Separator 1 │
────────────── │
 ✔ Choice 3 │
✔ Choice 4 │
Separator 5 │
✔ Choice 6 │
✔ Choice 7 │
✔ Choice 8 │
✔ Choice 9 │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────┘

View File

@ -0,0 +1,27 @@
---
source: tests/helpers/mod.rs
expression: self.backend
---
┌──────────────────────────────────────────────────┐
? checkbox (Press <space> to select, <a> to toggle│
 all, <i> to invert selection) │
✔ Choice 0 │
Separator 1 │
────────────── │
 ✔ Choice 3 │
✔ Choice 4 │
Separator 5 │
✔ Choice 6 │
✔ Choice 7 │
✔ Choice 8 │
✔ Choice 9 │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────┘

View File

@ -0,0 +1,27 @@
---
source: tests/helpers/mod.rs
expression: self.backend
---
┌──────────────────────────────────────────────────┐
? checkbox (Press <space> to select, <a> to toggle│
 all, <i> to invert selection) │
✔ Choice 0 │
Separator 1 │
────────────── │
 ✔ Choice 3 │
✔ Choice 4 │
Separator 5 │
✔ Choice 6 │
✔ Choice 7 │
✔ Choice 8 │
✔ Choice 9 │
✖ At least 2 items must be checked. 1 items... │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────┘

View File

@ -0,0 +1,27 @@
---
source: tests/helpers/mod.rs
expression: self.backend
---
┌──────────────────────────────────────────────────┐
? checkbox (Press <space> to select, <a> to toggle│
 all, <i> to invert selection) │
✔ Choice 0 │
Separator 1 │
────────────── │
✔ Choice 3 │
✔ Choice 4 │
Separator 5 │
✔ Choice 6 │
✔ Choice 7 │
✔ Choice 8 │
 ✔ Choice 9 │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────┘

View File

@ -0,0 +1,27 @@
---
source: tests/helpers/mod.rs
expression: self.backend
---
┌──────────────────────────────────────────────────┐
? checkbox (Press <space> to select, <a> to toggle│
 all, <i> to invert selection) │
✔ Choice 0 │
Separator 1 │
────────────── │
✔ Choice 3 │
✔ Choice 4 │
Separator 5 │
✔ Choice 6 │
✔ Choice 7 │
✔ Choice 8 │
 ✔ Choice 9 │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────┘

View File

@ -0,0 +1,27 @@
---
source: tests/helpers/mod.rs
expression: self.backend
---
┌──────────────────────────────────────────────────┐
✔ checkbox · Choice 3, Choice 9 │
  │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────┘

View File

@ -0,0 +1,27 @@
---
source: tests/helpers/mod.rs
expression: self.backend
---
┌──────────────────────────────────────────────────┐
? checkbox (Press <space> to select, <a> to toggle│
 all, <i> to invert selection) │
 ✔ Choice 0 │
Separator 1 │
────────────── │
✔ Choice 3 │
✔ Choice 4 │
Separator 5 │
✔ Choice 6 │
✔ Choice 7 │
✔ Choice 8 │
✔ Choice 9 │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────┘

View File

@ -0,0 +1,27 @@
---
source: src/question/checkbox/tests.rs
expression: backend
---
┌──────────────────────────────────────────────────┐
? message (Press <space> to select, <a> to to│
ggle all, <i> to invert selection) │
 ✔ Choice 0 │
Separator 1 │
────────────── │
✔ Choice 3 │
✔ Choice 4 │
Separator 5 │
✔ Choice 6 │
✔ Choice 7 │
✔ Choice 8 │
✔ Choice 9 │
  │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────┘

View File

@ -0,0 +1,27 @@
---
source: src/question/checkbox/tests.rs
expression: backend
---
┌──────────────────────────────────────────────────┐
? message (Press <space> to select, <a> to to│
ggle all, <i> to invert selection) │
 ✔ Choice 0 │
Separator 1 │
────────────── │
✔ Choice 3 │
✔ Choice 4 │
Separator 5 │
✔ Choice 6 │
✔ Choice 7 │
✔ Choice 8 │
✔ Choice 9 │
  │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────┘

View File

@ -0,0 +1,27 @@
---
source: src/question/checkbox/tests.rs
expression: backend
---
┌──────────────────────────────────────────────────┐
? message (Press <space> to select, <a> to to│
ggle all, <i> to invert selection) │
✔ Choice 0 │
Separator 1 │
────────────── │
 ✔ Choice 3 │
✔ Choice 4 │
Separator 5 │
✔ Choice 6 │
✔ Choice 7 │
✔ Choice 8 │
✔ Choice 9 │
  │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────┘

View File

@ -0,0 +1,27 @@
---
source: src/question/checkbox/tests.rs
expression: backend
---
┌──────────────────────────────────────────────────┐
? message (Press <space> to select, <a> to to│
ggle all, <i> to invert selection) │
✔ Choice 0 │
Separator 1 │
────────────── │
 ✔ Choice 3 │
✔ Choice 4 │
Separator 5 │
✔ Choice 6 │
✔ Choice 7 │
✔ Choice 8 │
✔ Choice 9 │
  │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────┘

View File

@ -0,0 +1,27 @@
---
source: src/question/checkbox/tests.rs
expression: backend
---
┌──────────────────────────────────────────────────┐
? message (Press <space> to select, <a> to to│
ggle all, <i> to invert selection) │
✔ Choice 0 │
Separator 1 │
────────────── │
 ✔ Choice 3 │
✔ Choice 4 │
Separator 5 │
✔ Choice 6 │
✔ Choice 7 │
✔ Choice 8 │
✔ Choice 9 │
  │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────┘

View File

@ -0,0 +1,27 @@
---
source: src/question/checkbox/tests.rs
expression: backend
---
┌──────────────────────────────────────────────────┐
? message (Press <space> to select, <a> to to│
ggle all, <i> to invert selection) │
 ✔ Choice 0 │
Separator 1 │
────────────── │
✔ Choice 3 │
✔ Choice 4 │
Separator 5 │
✔ Choice 6 │
✔ Choice 7 │
✔ Choice 8 │
✔ Choice 9 │
  │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────┘

View File

@ -0,0 +1,27 @@
---
source: src/question/checkbox/tests.rs
expression: backend
---
┌──────────────────────────────────────────────────┐
? message (Press <space> to select, <a> to to│
ggle all, <i> to invert selection) │
 ✔ Choice 0 │
Separator 1 │
────────────── │
✔ Choice 3 │
✔ Choice 4 │
Separator 5 │
✔ Choice 6 │
✔ Choice 7 │
✔ Choice 8 │
✔ Choice 9 │
✔ Choice 10 │
✔ Choice 11 │
Separator 12 │
✔ Choice 13 │
(Move up and down to reveal more choices) │
  │
│ │
│ │
└──────────────────────────────────────────────────┘

View File

@ -0,0 +1,27 @@
---
source: src/question/checkbox/tests.rs
expression: backend
---
┌──────────────────────────────────────────────────┐
? message (Press <space> to select, <a> to to│
ggle all, <i> to invert selection) │
 ✔ Choice 0 │
Separator 1 │
────────────── │
✔ Choice 3 │
✔ Choice 4 │
Separator 5 │
✔ Choice 6 │
✔ Choice 7 │
✔ Choice 8 │
✔ Choice 9 │
✔ Choice 10 │
✔ Choice 11 │
Separator 12 │
✔ Choice 13 │
(Move up and down to reveal more choices) │
  │
│ │
│ │
└──────────────────────────────────────────────────┘

View File

@ -0,0 +1,27 @@
---
source: src/question/checkbox/tests.rs
expression: backend
---
┌──────────────────────────────────────────────────┐
? message (Press <space> to select, <a> to to│
ggle all, <i> to invert selection) │
✔ Choice 0 │
Separator 1 │
────────────── │
 ✔ Choice 3 │
✔ Choice 4 │
Separator 5 │
✔ Choice 6 │
✔ Choice 7 │
✔ Choice 8 │
✔ Choice 9 │
✔ Choice 10 │
✔ Choice 11 │
Separator 12 │
✔ Choice 13 │
(Move up and down to reveal more choices) │
  │
│ │
│ │
└──────────────────────────────────────────────────┘

View File

@ -0,0 +1,27 @@
---
source: src/question/checkbox/tests.rs
expression: backend
---
┌──────────────────────────────────────────────────┐
? message (Press <space> to select, <a> to to│
ggle all, <i> to invert selection) │
✔ Choice 0 │
Separator 1 │
────────────── │
 ✔ Choice 3 │
✔ Choice 4 │
Separator 5 │
✔ Choice 6 │
✔ Choice 7 │
✔ Choice 8 │
✔ Choice 9 │
✔ Choice 10 │
✔ Choice 11 │
Separator 12 │
✔ Choice 13 │
(Move up and down to reveal more choices) │
  │
│ │
│ │
└──────────────────────────────────────────────────┘

View File

@ -0,0 +1,27 @@
---
source: src/question/checkbox/tests.rs
expression: backend
---
┌──────────────────────────────────────────────────┐
? message (Press <space> to select, <a> to to│
ggle all, <i> to invert selection) │
✔ Choice 0 │
Separator 1 │
────────────── │
 ✔ Choice 3 │
✔ Choice 4 │
Separator 5 │
✔ Choice 6 │
✔ Choice 7 │
✔ Choice 8 │
✔ Choice 9 │
✔ Choice 10 │
✔ Choice 11 │
Separator 12 │
✔ Choice 13 │
(Move up and down to reveal more choices) │
  │
│ │
│ │
└──────────────────────────────────────────────────┘

View File

@ -0,0 +1,27 @@
---
source: src/question/checkbox/tests.rs
expression: backend
---
┌──────────────────────────────────────────────────┐
? message (Press <space> to select, <a> to to│
ggle all, <i> to invert selection) │
 ✔ Choice 0 │
Separator 1 │
────────────── │
✔ Choice 3 │
✔ Choice 4 │
Separator 5 │
✔ Choice 6 │
✔ Choice 7 │
✔ Choice 8 │
✔ Choice 9 │
✔ Choice 10 │
✔ Choice 11 │
Separator 12 │
✔ Choice 13 │
(Move up and down to reveal more choices) │
  │
│ │
│ │
└──────────────────────────────────────────────────┘

View File

@ -0,0 +1,27 @@
---
source: src/question/checkbox/tests.rs
expression: backend
---
┌──────────────────────────────────────────────────┐
? message (Press <space> to select, <a> to to│
ggle all, <i> to invert selection) │
 ✔ Choice 0 │
Separator 1 │
────────────── │
✔ Choice 3 │
✔ Choice 4 │
Separator 5 │
✔ Choice 6 │
✔ Choice 7 │
✔ Choice 8 │
✔ Choice 9 │
  │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────┘

View File

@ -0,0 +1,27 @@
---
source: src/question/checkbox/tests.rs
expression: backend
---
┌──────────────────────────────────────────────────┐
? message (Press <space> to select, <a> to to│
ggle all, <i> to invert selection) │
✔ Choice 0 │
Separator 1 │
────────────── │
 ✔ Choice 3 │
✔ Choice 4 │
Separator 5 │
✔ Choice 6 │
✔ Choice 7 │
✔ Choice 8 │
✔ Choice 9 │
  │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────┘

View File

@ -0,0 +1,27 @@
---
source: src/question/checkbox/tests.rs
expression: backend
---
┌──────────────────────────────────────────────────┐
? message (Press <space> to select, <a> to to│
ggle all, <i> to invert selection) │
✔ Choice 0 │
Separator 1 │
────────────── │
 ✔ Choice 3 │
✔ Choice 4 │
Separator 5 │
✔ Choice 6 │
✔ Choice 7 │
✔ Choice 8 │
✔ Choice 9 │
  │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────┘

View File

@ -0,0 +1,27 @@
---
source: src/question/checkbox/tests.rs
expression: backend
---
┌──────────────────────────────────────────────────┐
? message (Press <space> to select, <a> to to│
ggle all, <i> to invert selection) │
✔ Choice 0 │
Separator 1 │
────────────── │
 ✔ Choice 3 │
✔ Choice 4 │
Separator 5 │
✔ Choice 6 │
✔ Choice 7 │
✔ Choice 8 │
✔ Choice 9 │
  │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────┘

View File

@ -0,0 +1,27 @@
---
source: src/question/checkbox/tests.rs
expression: backend
---
┌──────────────────────────────────────────────────┐
? message (Press <space> to select, <a> to to│
ggle all, <i> to invert selection) │
✔ Choice 0 │
Separator 1 │
────────────── │
 ✔ Choice 3 │
✔ Choice 4 │
Separator 5 │
✔ Choice 6 │
✔ Choice 7 │
✔ Choice 8 │
✔ Choice 9 │
  │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────┘

View File

@ -0,0 +1,27 @@
---
source: src/question/checkbox/tests.rs
expression: backend
---
┌──────────────────────────────────────────────────┐
? message (Press <space> to select, <a> to to│
ggle all, <i> to invert selection) │
 ✔ Choice 0 │
Separator 1 │
────────────── │
✔ Choice 3 │
✔ Choice 4 │
Separator 5 │
✔ Choice 6 │
✔ Choice 7 │
✔ Choice 8 │
✔ Choice 9 │
  │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────┘

View File

@ -56,7 +56,7 @@ impl Iterator for Events {
}
}
pub struct TestEvents<E: Iterator<Item = KeyEvent>> {
pub struct TestEvents<E> {
events: E,
}

View File

@ -1,7 +1,7 @@
mod answer;
pub mod question;
use ui::{backend, error, events};
use ui::{backend, events};
pub use answer::{Answer, Answers, ExpandItem, ListItem};
pub use macros::questions;
@ -19,7 +19,7 @@ macro_rules! prompt_module {
pub mod plugin {
pub use crate::{question::Plugin, Answer, Answers};
pub use ui::{self, backend::Backend, events::Events};
pub use ui::{self, backend::Backend, events::KeyEvent};
}
#[derive(Debug, Clone, PartialEq)]
@ -47,14 +47,18 @@ where
self
}
fn prompt_impl<B: backend::Backend>(
pub fn prompt_with<B, E>(
&mut self,
stdout: &mut B,
events: &mut events::Events,
) -> error::Result<Option<&mut Answer>> {
backend: &mut B,
events: &mut E,
) -> Result<Option<&mut Answer>>
where
B: backend::Backend,
E: Iterator<Item = Result<events::KeyEvent>>,
{
while let Some(question) = self.questions.next() {
if let Some((name, answer)) =
question.ask(&self.answers, stdout, events)?
question.ask(&self.answers, backend, events)?
{
return Ok(Some(self.answers.insert(name, answer)));
}
@ -63,45 +67,84 @@ where
Ok(None)
}
pub fn prompt(&mut self) -> error::Result<Option<&mut Answer>> {
pub fn prompt(&mut self) -> Result<Option<&mut Answer>> {
if atty::isnt(atty::Stream::Stdout) {
return Err(error::ErrorKind::NotATty);
return Err(ErrorKind::NotATty);
}
let stdout = std::io::stdout();
let mut stdout = backend::get_backend(stdout.lock())?;
self.prompt_impl(&mut stdout, &mut events::Events::new())
self.prompt_with(&mut stdout, &mut events::Events::new())
}
pub fn prompt_all(mut self) -> error::Result<Answers> {
pub fn prompt_all_with<B, E>(
mut self,
backend: &mut B,
events: &mut E,
) -> Result<Answers>
where
B: backend::Backend,
E: Iterator<Item = Result<events::KeyEvent>>,
{
self.answers.reserve(self.questions.size_hint().0);
if atty::isnt(atty::Stream::Stdout) {
return Err(error::ErrorKind::NotATty);
}
let stdout = std::io::stdout();
let mut stdout = backend::get_backend(stdout.lock())?;
let mut events = events::Events::new();
while self.prompt_impl(&mut stdout, &mut events)?.is_some() {}
while self.prompt_with(backend, events)?.is_some() {}
Ok(self.answers)
}
pub fn prompt_all(self) -> Result<Answers> {
if atty::isnt(atty::Stream::Stdout) {
return Err(ErrorKind::NotATty);
}
let stdout = std::io::stdout();
let mut stdout = backend::get_backend(stdout.lock())?;
let mut events = events::Events::new();
self.prompt_all_with(&mut stdout, &mut events)
}
pub fn into_answers(self) -> Answers {
self.answers
}
}
pub fn prompt<'a, Q>(questions: Q) -> error::Result<Answers>
pub fn prompt<'a, Q>(questions: Q) -> Result<Answers>
where
Q: IntoIterator<Item = Question<'a>>,
{
PromptModule::new(questions).prompt_all()
}
pub fn prompt_one<'a, I: Into<Question<'a>>>(question: I) -> error::Result<Answer> {
pub fn prompt_one<'a, I: Into<Question<'a>>>(question: I) -> Result<Answer> {
let ans = prompt(std::iter::once(question.into()))?;
Ok(ans.into_iter().next().unwrap().1)
}
pub fn prompt_with<'a, Q, B, E>(
questions: Q,
backend: &mut B,
events: &mut E,
) -> Result<Answers>
where
Q: IntoIterator<Item = Question<'a>>,
B: backend::Backend,
E: Iterator<Item = Result<events::KeyEvent>>,
{
PromptModule::new(questions).prompt_all_with(backend, events)
}
pub fn prompt_one_with<'a, Q, B, E>(
question: Q,
backend: &mut B,
events: &mut E,
) -> Result<Answer>
where
Q: Into<Question<'a>>,
B: backend::Backend,
E: Iterator<Item = Result<events::KeyEvent>>,
{
let ans = prompt_with(std::iter::once(question.into()), backend, events)?;
Ok(ans.into_iter().next().unwrap().1)
}

View File

@ -12,6 +12,9 @@ use ui::{
use super::{Choice, Filter, Options, Transform, Validate};
use crate::{Answer, Answers, ListItem};
#[cfg(test)]
mod tests;
#[derive(Debug, Default)]
pub struct Checkbox<'a> {
choices: super::ChoiceList<Text<String>>,
@ -180,7 +183,20 @@ impl widgets::List for Checkbox<'_> {
}
}
impl Checkbox<'_> {
impl<'c> Checkbox<'c> {
fn into_checkbox_prompt<'a>(
self,
message: &'a str,
answers: &'a Answers,
) -> CheckboxPrompt<'a, 'c> {
CheckboxPrompt {
prompt: widgets::Prompt::new(message)
.with_hint("Press <space> to select, <a> to toggle all, <i> to invert selection"),
select: widgets::Select::new(self),
answers,
}
}
pub(crate) fn ask<B: Backend, E: Iterator<Item = error::Result<KeyEvent>>>(
mut self,
message: String,
@ -190,34 +206,18 @@ impl Checkbox<'_> {
) -> error::Result<Answer> {
let transform = self.transform.take();
let ans = ui::Input::new(
CheckboxPrompt {
prompt: widgets::Prompt::new(&*message)
.with_hint("Press <space> to select, <a> to toggle all, <i> to invert selection"),
select: widgets::Select::new(self),
answers,
},
b,
)
.hide_cursor()
.run(events)?;
let ans = ui::Input::new(self.into_checkbox_prompt(&message, answers), b)
.hide_cursor()
.run(events)?;
match transform {
Transform::Sync(transform) => transform(&ans, answers, b)?,
_ => {
widgets::Prompt::write_finished_message(&message, b)?;
b.set_fg(Color::Cyan)?;
print_comma_separated(
ans.iter().map(|item| item.name.lines().next().unwrap()),
b,
)?;
b.set_fg(Color::Reset)?;
b.write_all(b"\n")?;
b.flush()?;
}
}
crate::write_final!(transform, message, &ans, answers, b, {
b.set_fg(Color::Cyan)?;
print_comma_separated(
ans.iter().map(|item| item.name.lines().next().unwrap()),
b,
)?;
b.set_fg(Color::Reset)?;
});
Ok(Answer::ListItems(ans))
}
@ -276,11 +276,7 @@ impl<'a> CheckboxBuilder<'a> {
self.checkbox
.choices
.choices
.extend(choices.into_iter().map(|c| match c.into() {
Choice::Choice(c) => Choice::Choice(Text::new(c)),
Choice::Separator(s) => Choice::Separator(s),
Choice::DefaultSeparator => Choice::DefaultSeparator,
}));
.extend(choices.into_iter().map(|c| c.into().map(Text::new)));
self.checkbox
.selected
.resize(self.checkbox.choices.len(), false);

View File

@ -0,0 +1,178 @@
use rand::prelude::*;
use rand_chacha::ChaCha12Rng;
use ui::{backend::TestBackend, layout::Layout};
use crate::question::{Question, QuestionKind};
use super::*;
const SEED: u64 = 9828123;
const SEP_RATIO: f32 = 0.3;
const DEFAULT_SEP_RATIO: f32 = 0.10;
fn choices_with_default(len: usize) -> impl Iterator<Item = Choice<(String, bool)>> {
let mut rng = ChaCha12Rng::seed_from_u64(SEED);
(0..len).map(move |i| {
let rand: f32 = rng.gen();
if rand < DEFAULT_SEP_RATIO {
Choice::DefaultSeparator
} else if rand < SEP_RATIO {
Choice::Separator(format!("Separator {}", i))
} else {
Choice::Choice((format!("Choice {}", i), rand > 0.7))
}
})
}
fn choices(len: usize) -> impl Iterator<Item = Choice<String>> {
choices_with_default(len).map(|choice| choice.map(|(c, _)| c))
}
fn unwrap_checkbox<'a>(question: impl Into<Question<'a>>) -> Checkbox<'a> {
match question.into().kind {
QuestionKind::Checkbox(c) => c,
_ => unreachable!(),
}
}
macro_rules! test_checkbox {
($mod_name:ident { checkbox = $checkbox:expr; height = $height:expr $(;)? }) => {
test_checkbox!($mod_name {
checkbox = $checkbox;
height = $height;
events = [
KeyEvent::from(KeyCode::Char('a')),
KeyCode::Char('a').into(),
KeyCode::Down.into(),
KeyCode::Char(' ').into(),
KeyCode::Char('i').into(),
];
answers = Answers::default()
});
};
($mod_name:ident { checkbox = $checkbox:expr; height = $height:expr; events = $events:expr $(;)? }) => {
test_checkbox!($mod_name {
checkbox = $checkbox;
height = $height;
events = $events;
answers = Answers::default()
});
};
($mod_name:ident { checkbox = $checkbox:expr; height = $height:expr; answers = $answers:expr $(;)? }) => {
test_checkbox!($mod_name {
checkbox = $checkbox;
height = $height;
events = [
KeyEvent::from(KeyCode::Char('a')),
KeyCode::Char('a').into(),
KeyCode::Down.into(),
KeyCode::Char(' ').into(),
KeyCode::Char('i').into(),
];
answers = $answers
});
};
($mod_name:ident { checkbox = $checkbox:expr; height = $height:expr; events = $events:expr; answers = $answers:expr $(;)? }) => {
mod $mod_name {
use super::*;
#[test]
fn test_height() {
let size = (50, 20).into();
let base_layout = Layout::new(5, size);
let answers = $answers;
let mut checkbox = $checkbox.into_checkbox_prompt("message", &answers);
let events = $events;
for &key in events.iter() {
let mut layout = base_layout;
assert_eq!(checkbox.height(&mut layout), $height);
assert_eq!(
layout,
base_layout.with_offset(0, $height).with_line_offset(0)
);
assert!(checkbox.handle_key(key))
}
let mut layout = base_layout;
assert_eq!(checkbox.height(&mut layout), $height);
assert_eq!(
layout,
base_layout.with_offset(0, $height).with_line_offset(0)
);
}
#[test]
fn test_render() {
let size = (50, 20).into();
let base_layout = Layout::new(5, size);
let answers = $answers;
let mut checkbox = $checkbox.into_checkbox_prompt("message", &answers);
let mut backend = TestBackend::new(size);
let events = $events;
for &key in events.iter() {
let mut layout = base_layout;
backend.reset_with_layout(layout);
assert!(checkbox.render(&mut layout, &mut backend).is_ok());
assert_eq!(
layout,
base_layout.with_offset(0, $height).with_line_offset(0)
);
ui::assert_backend_snapshot!(backend);
assert!(checkbox.handle_key(key))
}
let mut layout = base_layout;
backend.reset_with_layout(layout);
assert!(checkbox.render(&mut layout, &mut backend).is_ok());
assert_eq!(
layout,
base_layout.with_offset(0, $height).with_line_offset(0)
);
ui::assert_backend_snapshot!(backend);
}
}
};
}
test_checkbox!(basic {
checkbox = unwrap_checkbox(
CheckboxBuilder::new("name".into()).choices(choices(10)),
);
height = 12;
});
test_checkbox!(pagination {
checkbox = unwrap_checkbox(
CheckboxBuilder::new("name".into()).choices(choices(20)),
);
height = 17;
});
test_checkbox!(with_default {
checkbox = unwrap_checkbox(
CheckboxBuilder::new("name".into()).choices_with_default(choices_with_default(10)),
);
height = 12;
events = [
KeyEvent::from(KeyCode::Char('i')),
KeyCode::Down.into(),
KeyCode::Char(' ').into(),
KeyCode::Char('a').into(),
KeyCode::Char('a').into(),
]
});

View File

@ -4,7 +4,7 @@ use ui::{style::Color, widgets::List, Widget};
use crate::ExpandItem;
#[derive(Debug)]
#[derive(Debug, Clone)]
pub(crate) struct ChoiceList<T> {
pub(crate) choices: Vec<Choice<T>>,
page_size: usize,
@ -138,7 +138,7 @@ impl<T: Widget> List for ChoiceList<T> {
}
}
#[derive(Debug)]
#[derive(Debug, Clone)]
pub enum Choice<T> {
Choice(T),
Separator(String),
@ -146,11 +146,19 @@ pub enum Choice<T> {
}
impl<T> Choice<T> {
pub(crate) fn is_separator(&self) -> bool {
pub fn map<U, F: FnOnce(T) -> U>(self, f: F) -> Choice<U> {
match self {
Choice::Choice(c) => Choice::Choice(f(c)),
Choice::Separator(s) => Choice::Separator(s),
Choice::DefaultSeparator => Choice::DefaultSeparator,
}
}
pub fn is_separator(&self) -> bool {
matches!(self, Choice::Separator(_) | Choice::DefaultSeparator)
}
pub(crate) fn as_ref(&self) -> Choice<&T> {
pub fn as_ref(&self) -> Choice<&T> {
match self {
Choice::Choice(t) => Choice::Choice(t),
Choice::Separator(s) => Choice::Separator(s.clone()),
@ -158,7 +166,7 @@ impl<T> Choice<T> {
}
}
pub(crate) fn as_mut(&mut self) -> Choice<&mut T> {
pub fn as_mut(&mut self) -> Choice<&mut T> {
match self {
Choice::Choice(t) => Choice::Choice(t),
Choice::Separator(s) => Choice::Separator(s.clone()),
@ -166,7 +174,7 @@ impl<T> Choice<T> {
}
}
pub(crate) fn unwrap_choice(self) -> T {
pub fn unwrap_choice(self) -> T {
match self {
Choice::Choice(c) => c,
_ => panic!("Called unwrap_choice on separator"),

View File

@ -103,17 +103,10 @@ impl Confirm<'_> {
)
.run(events)?;
match transform {
Transform::Sync(transform) => transform(ans, answers, b)?,
_ => {
widgets::Prompt::write_finished_message(&message, b)?;
let ans = if ans { "Yes" } else { "No" };
b.write_styled(&ans.cyan())?;
b.write_all(b"\n")?;
b.flush()?;
}
}
crate::write_final!(transform, message, ans, answers, b, {
let ans = if ans { "Yes" } else { "No" };
b.write_styled(&ans.cyan())?;
});
Ok(Answer::Bool(ans))
}

View File

@ -169,15 +169,14 @@ impl Editor<'_> {
)
.run(events)?;
match transform {
Transform::Sync(transform) => transform(&ans, answers, b)?,
_ => {
widgets::Prompt::write_finished_message(&message, b)?;
b.write_styled(&"Received".dark_grey())?;
b.write_all(b"\n")?;
b.flush()?;
}
}
crate::write_final!(
transform,
message,
&ans,
answers,
b,
b.write_styled(&"Received".dark_grey())?
);
Ok(Answer::String(ans))
}

View File

@ -314,15 +314,14 @@ impl Expand<'_> {
)
.run(events)?;
match transform {
Transform::Sync(transform) => transform(&ans, answers, b)?,
_ => {
widgets::Prompt::write_finished_message(&message, b)?;
b.write_styled(&ans.name.lines().next().unwrap().cyan())?;
b.write_all(b"\n")?;
b.flush()?;
}
}
crate::write_final!(
transform,
message,
&ans,
answers,
b,
b.write_styled(&ans.name.lines().next().unwrap().cyan())?
);
Ok(Answer::ExpandItem(ans))
}
@ -391,28 +390,23 @@ impl<'a> ExpandBuilder<'a> {
..
} = self;
expand
.choices
.choices
.extend(choices.into_iter().map(|c| match c.into() {
Choice::Choice(ExpandItem { name, mut key }) => {
key = key.to_ascii_lowercase();
if key == 'h' {
panic!("Reserved key 'h'");
}
if keys.contains(&key) {
panic!("Duplicate key '{}'", key);
}
keys.insert(key);
Choice::Choice(ExpandItem {
name: Text::new(name),
key,
})
expand.choices.choices.extend(choices.into_iter().map(|c| {
c.into().map(|ExpandItem { name, mut key }| {
key = key.to_ascii_lowercase();
if key == 'h' {
panic!("Reserved key 'h'");
}
Choice::Separator(s) => Choice::Separator(s),
Choice::DefaultSeparator => Choice::DefaultSeparator,
}));
if keys.contains(&key) {
panic!("Duplicate key '{}'", key);
}
keys.insert(key);
ExpandItem {
name: Text::new(name),
key,
}
})
}));
self
}

View File

@ -198,16 +198,14 @@ impl Input<'_> {
)
.run(events)?;
match transform {
Transform::Sync(transform) => transform(&ans, answers, b)?,
_ => {
widgets::Prompt::write_finished_message(&message, b)?;
b.write_styled(&ans.as_str().cyan())?;
b.write_all(b"\n")?;
b.flush()?;
}
}
crate::write_final!(
transform,
message,
&ans,
answers,
b,
b.write_styled(&ans.as_str().cyan())?
);
Ok(Answer::String(ans))
}

View File

@ -28,7 +28,7 @@ pub use choice::Choice;
use choice::{get_sep_str, ChoiceList};
use options::Options;
pub use plugin::Plugin;
use ui::{backend::Backend, error};
use ui::{backend::Backend, error, events::KeyEvent};
use std::fmt;
@ -111,11 +111,11 @@ pub(crate) enum QuestionKind<'a> {
}
impl Question<'_> {
pub(crate) fn ask<B: Backend>(
pub(crate) fn ask<B: Backend, I: Iterator<Item = error::Result<KeyEvent>>>(
mut self,
answers: &Answers,
b: &mut B,
events: &mut ui::events::Events,
events: &mut I,
) -> error::Result<Option<(String, Answer)>> {
if (!self.opts.ask_if_answered && answers.contains_key(&self.opts.name))
|| !self.opts.when.get(answers)
@ -308,3 +308,19 @@ macro_rules! impl_transform_builder {
}
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! write_final {
($transform:expr, $message:expr, $ans:expr, $answers:expr, $backend:expr, $custom:expr) => {{
ui::widgets::Prompt::write_finished_message(&$message, $backend)?;
match $transform {
Transform::Sync(transform) => transform($ans, $answers, $backend)?,
_ => $custom,
}
$backend.write_all(b"\n")?;
$backend.flush()?;
}};
}

View File

@ -33,9 +33,7 @@ impl Int<'_> {
fn write<B: Backend>(i: i64, b: &mut B) -> error::Result<()> {
b.set_fg(Color::Cyan)?;
write!(b, "{}", i)?;
b.set_fg(Color::Reset)?;
b.write_all(b"\n")?;
b.flush().map_err(Into::into)
b.set_fg(Color::Reset)
}
fn delta(i: i64, delta: i64) -> i64 {
@ -59,9 +57,7 @@ impl Float<'_> {
} else {
write!(b, "{}", f)?;
}
b.set_fg(Color::Reset)?;
b.write_all(b"\n")?;
b.flush().map_err(Into::into)
b.set_fg(Color::Reset)
}
fn delta(f: f64, delta: i64) -> f64 {
@ -207,13 +203,14 @@ macro_rules! impl_ask {
)
.run(events)?;
match transform {
Transform::Sync(transform) => transform(ans, answers, b)?,
_ => {
widgets::Prompt::write_finished_message(&message, b)?;
Self::write(ans, b)?
}
}
crate::write_final!(
transform,
message,
ans,
answers,
b,
Self::write(ans, b)?
);
Ok(Answer::$t(ans))
}

View File

@ -99,18 +99,14 @@ impl Password<'_> {
)
.run(events)?;
match transform {
Transform::Sync(transform) => transform(&ans, answers, b)?,
_ => {
b.write_styled(&ui::symbols::TICK.light_green())?;
b.write_all(b" ")?;
b.write_styled(&message.bold())?;
b.write_all(b" ")?;
b.write_styled(&"[hidden]".dark_grey())?;
b.write_all(b"\n")?;
b.flush()?;
}
}
crate::write_final!(
transform,
message,
&ans,
answers,
b,
b.write_styled(&"[hidden]".dark_grey())?
);
Ok(Answer::String(ans))
}

View File

@ -9,7 +9,7 @@ pub trait Plugin: std::fmt::Debug {
message: String,
answers: &Answers,
stdout: &mut dyn Backend,
events: &mut events::Events,
events: &mut dyn Iterator<Item = error::Result<events::KeyEvent>>,
) -> error::Result<Answer>;
}

View File

@ -218,15 +218,14 @@ impl RawSelect<'_> {
)
.run(events)?;
match transform {
Transform::Sync(transform) => transform(&ans, answers, b)?,
_ => {
widgets::Prompt::write_finished_message(&message, b)?;
b.write_styled(&ans.name.lines().next().unwrap().cyan())?;
b.write_all(b"\n")?;
b.flush()?;
}
}
crate::write_final!(
transform,
message,
&ans,
answers,
b,
b.write_styled(&ans.name.lines().next().unwrap().cyan())?
);
Ok(Answer::ListItem(ans))
}
@ -284,14 +283,12 @@ impl<'a> RawSelectBuilder<'a> {
self.list
.choices
.choices
.extend(choices.into_iter().map(|choice| match choice.into() {
Choice::Choice(c) => {
let choice = Choice::Choice((*choice_count, Text::new(c)));
.extend(choices.into_iter().map(|choice| {
choice.into().map(|c| {
let choice = (*choice_count, Text::new(c));
*choice_count += 1;
choice
}
Choice::Separator(s) => Choice::Separator(s),
Choice::DefaultSeparator => Choice::DefaultSeparator,
})
}));
self
}

View File

@ -133,15 +133,14 @@ impl Select<'_> {
.hide_cursor()
.run(events)?;
match transform {
Transform::Sync(transform) => transform(&ans, answers, b)?,
_ => {
widgets::Prompt::write_finished_message(&message, b)?;
b.write_styled(&ans.name.lines().next().unwrap().cyan())?;
b.write_all(b"\n")?;
b.flush()?;
}
}
crate::write_final!(
transform,
message,
&ans,
answers,
b,
b.write_styled(&ans.name.lines().next().unwrap().cyan())?
);
Ok(Answer::ListItem(ans))
}
@ -194,14 +193,11 @@ impl<'a> SelectBuilder<'a> {
T: Into<super::Choice<String>>,
I: IntoIterator<Item = T>,
{
self.list
.choices
.choices
.extend(choices.into_iter().map(|choice| match choice.into() {
super::Choice::Choice(c) => super::Choice::Choice(Text::new(c)),
super::Choice::Separator(s) => super::Choice::Separator(s),
super::Choice::DefaultSeparator => super::Choice::DefaultSeparator,
}));
self.list.choices.choices.extend(
choices
.into_iter()
.map(|choice| choice.into().map(Text::new)),
);
self
}

View File

@ -0,0 +1,27 @@
---
source: tests/helpers/mod.rs
expression: self.backend
---
┌──────────────────────────────────────────────────┐
? checkbox (Press <space> to select, <a> to toggle│
 all, <i> to invert selection) │
✔ Choice 0 │
Separator 1 │
────────────── │
 ✔ Choice 3 │
✔ Choice 4 │
Separator 5 │
✔ Choice 6 │
✔ Choice 7 │
✔ Choice 8 │
✔ Choice 9 │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────┘

View File

@ -0,0 +1,27 @@
---
source: tests/helpers/mod.rs
expression: self.backend
---
┌──────────────────────────────────────────────────┐
? checkbox (Press <space> to select, <a> to toggle│
 all, <i> to invert selection) │
✔ Choice 0 │
Separator 1 │
────────────── │
 ✔ Choice 3 │
✔ Choice 4 │
Separator 5 │
✔ Choice 6 │
✔ Choice 7 │
✔ Choice 8 │
✔ Choice 9 │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────┘

View File

@ -0,0 +1,27 @@
---
source: tests/helpers/mod.rs
expression: self.backend
---
┌──────────────────────────────────────────────────┐
? checkbox (Press <space> to select, <a> to toggle│
 all, <i> to invert selection) │
✔ Choice 0 │
Separator 1 │
────────────── │
✔ Choice 3 │
✔ Choice 4 │
Separator 5 │
✔ Choice 6 │
✔ Choice 7 │
✔ Choice 8 │
 ✔ Choice 9 │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────┘

View File

@ -0,0 +1,27 @@
---
source: tests/helpers/mod.rs
expression: self.backend
---
┌──────────────────────────────────────────────────┐
? checkbox (Press <space> to select, <a> to toggle│
 all, <i> to invert selection) │
✔ Choice 0 │
Separator 1 │
────────────── │
✔ Choice 3 │
✔ Choice 4 │
Separator 5 │
✔ Choice 6 │
✔ Choice 7 │
✔ Choice 8 │
 ✔ Choice 9 │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────┘

View File

@ -0,0 +1,27 @@
---
source: tests/helpers/mod.rs
expression: self.backend
---
┌──────────────────────────────────────────────────┐
✔ checkbox · Choice 0, Choice 4, Choice 6, Choice │
7, Choice 8 │
  │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────┘

View File

@ -0,0 +1,27 @@
---
source: tests/helpers/mod.rs
expression: self.backend
---
┌──────────────────────────────────────────────────┐
? checkbox (Press <space> to select, <a> to toggle│
 all, <i> to invert selection) │
 ✔ Choice 0 │
Separator 1 │
────────────── │
✔ Choice 3 │
✔ Choice 4 │
Separator 5 │
✔ Choice 6 │
✔ Choice 7 │
✔ Choice 8 │
✔ Choice 9 │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────┘

View File

@ -0,0 +1,27 @@
---
source: tests/helpers/mod.rs
expression: self.backend
---
┌──────────────────────────────────────────────────┐
? checkbox (Press <space> to select, <a> to toggle│
 all, <i> to invert selection) │
✔ Choice 0 │
Separator 1 │
────────────── │
 ✔ Choice 3 │
✔ Choice 4 │
Separator 5 │
✔ Choice 6 │
✔ Choice 7 │
✔ Choice 8 │
✔ Choice 9 │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────┘

View File

@ -0,0 +1,27 @@
---
source: tests/helpers/mod.rs
expression: self.backend
---
┌──────────────────────────────────────────────────┐
? checkbox (Press <space> to select, <a> to toggle│
 all, <i> to invert selection) │
✔ Choice 0 │
Separator 1 │
────────────── │
 ✔ Choice 3 │
✔ Choice 4 │
Separator 5 │
✔ Choice 6 │
✔ Choice 7 │
✔ Choice 8 │
✔ Choice 9 │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────┘

View File

@ -0,0 +1,27 @@
---
source: tests/helpers/mod.rs
expression: self.backend
---
┌──────────────────────────────────────────────────┐
? checkbox (Press <space> to select, <a> to toggle│
 all, <i> to invert selection) │
✔ Choice 0 │
Separator 1 │
────────────── │
✔ Choice 3 │
✔ Choice 4 │
Separator 5 │
✔ Choice 6 │
✔ Choice 7 │
✔ Choice 8 │
 ✔ Choice 9 │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────┘

View File

@ -0,0 +1,27 @@
---
source: tests/helpers/mod.rs
expression: self.backend
---
┌──────────────────────────────────────────────────┐
? checkbox (Press <space> to select, <a> to toggle│
 all, <i> to invert selection) │
✔ Choice 0 │
Separator 1 │
────────────── │
✔ Choice 3 │
✔ Choice 4 │
Separator 5 │
✔ Choice 6 │
✔ Choice 7 │
✔ Choice 8 │
 ✔ Choice 9 │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────┘

View File

@ -0,0 +1,27 @@
---
source: tests/helpers/mod.rs
expression: self.backend
---
┌──────────────────────────────────────────────────┐
✔ checkbox · 3: Choice 3, 9: Choice 9 │
  │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────┘

View File

@ -0,0 +1,27 @@
---
source: tests/helpers/mod.rs
expression: self.backend
---
┌──────────────────────────────────────────────────┐
? checkbox (Press <space> to select, <a> to toggle│
 all, <i> to invert selection) │
 ✔ Choice 0 │
Separator 1 │
────────────── │
✔ Choice 3 │
✔ Choice 4 │
Separator 5 │
✔ Choice 6 │
✔ Choice 7 │
✔ Choice 8 │
✔ Choice 9 │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────┘

View File

@ -0,0 +1,27 @@
---
source: tests/helpers/mod.rs
expression: self.backend
---
┌──────────────────────────────────────────────────┐
? checkbox (Press <space> to select, <a> to toggle│
 all, <i> to invert selection) │
✔ Choice 0 │
Separator 1 │
────────────── │
 ✔ Choice 3 │
✔ Choice 4 │
Separator 5 │
✔ Choice 6 │
✔ Choice 7 │
✔ Choice 8 │
✔ Choice 9 │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────┘

View File

@ -0,0 +1,27 @@
---
source: tests/helpers/mod.rs
expression: self.backend
---
┌──────────────────────────────────────────────────┐
? checkbox (Press <space> to select, <a> to toggle│
 all, <i> to invert selection) │
✔ Choice 0 │
Separator 1 │
────────────── │
 ✔ Choice 3 │
✔ Choice 4 │
Separator 5 │
✔ Choice 6 │
✔ Choice 7 │
✔ Choice 8 │
✔ Choice 9 │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────┘

View File

@ -0,0 +1,27 @@
---
source: tests/helpers/mod.rs
expression: self.backend
---
┌──────────────────────────────────────────────────┐
? checkbox (Press <space> to select, <a> to toggle│
 all, <i> to invert selection) │
✔ Choice 0 │
Separator 1 │
────────────── │
 ✔ Choice 3 │
✔ Choice 4 │
Separator 5 │
✔ Choice 6 │
✔ Choice 7 │
✔ Choice 8 │
✔ Choice 9 │
✖ At least 2 items must be checked. 1 items... │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────┘

View File

@ -0,0 +1,27 @@
---
source: tests/helpers/mod.rs
expression: self.backend
---
┌──────────────────────────────────────────────────┐
? checkbox (Press <space> to select, <a> to toggle│
 all, <i> to invert selection) │
✔ Choice 0 │
Separator 1 │
────────────── │
✔ Choice 3 │
✔ Choice 4 │
Separator 5 │
✔ Choice 6 │
✔ Choice 7 │
✔ Choice 8 │
 ✔ Choice 9 │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────┘

View File

@ -0,0 +1,27 @@
---
source: tests/helpers/mod.rs
expression: self.backend
---
┌──────────────────────────────────────────────────┐
? checkbox (Press <space> to select, <a> to toggle│
 all, <i> to invert selection) │
✔ Choice 0 │
Separator 1 │
────────────── │
✔ Choice 3 │
✔ Choice 4 │
Separator 5 │
✔ Choice 6 │
✔ Choice 7 │
✔ Choice 8 │
 ✔ Choice 9 │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────┘

View File

@ -0,0 +1,27 @@
---
source: tests/helpers/mod.rs
expression: self.backend
---
┌──────────────────────────────────────────────────┐
✔ checkbox · Choice 3, Choice 9 │
  │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────┘

View File

@ -0,0 +1,27 @@
---
source: tests/helpers/mod.rs
expression: self.backend
---
┌──────────────────────────────────────────────────┐
? checkbox (Press <space> to select, <a> to toggle│
 all, <i> to invert selection) │
 ✔ Choice 0 │
Separator 1 │
────────────── │
✔ Choice 3 │
✔ Choice 4 │
Separator 5 │
✔ Choice 6 │
✔ Choice 7 │
✔ Choice 8 │
✔ Choice 9 │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────┘

View File

@ -0,0 +1,27 @@
---
source: src/question/checkbox/tests.rs
expression: backend
---
┌──────────────────────────────────────────────────┐
? message (Press <space> to select, <a> to to│
ggle all, <i> to invert selection) │
 ✔ Choice 0 │
Separator 1 │
────────────── │
✔ Choice 3 │
✔ Choice 4 │
Separator 5 │
✔ Choice 6 │
✔ Choice 7 │
✔ Choice 8 │
✔ Choice 9 │
  │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────┘

View File

@ -0,0 +1,27 @@
---
source: src/question/checkbox/tests.rs
expression: backend
---
┌──────────────────────────────────────────────────┐
? message (Press <space> to select, <a> to to│
ggle all, <i> to invert selection) │
 ✔ Choice 0 │
Separator 1 │
────────────── │
✔ Choice 3 │
✔ Choice 4 │
Separator 5 │
✔ Choice 6 │
✔ Choice 7 │
✔ Choice 8 │
✔ Choice 9 │
  │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────┘

View File

@ -0,0 +1,27 @@
---
source: src/question/checkbox/tests.rs
expression: backend
---
┌──────────────────────────────────────────────────┐
? message (Press <space> to select, <a> to to│
ggle all, <i> to invert selection) │
✔ Choice 0 │
Separator 1 │
────────────── │
 ✔ Choice 3 │
✔ Choice 4 │
Separator 5 │
✔ Choice 6 │
✔ Choice 7 │
✔ Choice 8 │
✔ Choice 9 │
  │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────┘

View File

@ -0,0 +1,27 @@
---
source: src/question/checkbox/tests.rs
expression: backend
---
┌──────────────────────────────────────────────────┐
? message (Press <space> to select, <a> to to│
ggle all, <i> to invert selection) │
✔ Choice 0 │
Separator 1 │
────────────── │
 ✔ Choice 3 │
✔ Choice 4 │
Separator 5 │
✔ Choice 6 │
✔ Choice 7 │
✔ Choice 8 │
✔ Choice 9 │
  │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────┘

View File

@ -0,0 +1,27 @@
---
source: src/question/checkbox/tests.rs
expression: backend
---
┌──────────────────────────────────────────────────┐
? message (Press <space> to select, <a> to to│
ggle all, <i> to invert selection) │
✔ Choice 0 │
Separator 1 │
────────────── │
 ✔ Choice 3 │
✔ Choice 4 │
Separator 5 │
✔ Choice 6 │
✔ Choice 7 │
✔ Choice 8 │
✔ Choice 9 │
  │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────┘

View File

@ -0,0 +1,27 @@
---
source: src/question/checkbox/tests.rs
expression: backend
---
┌──────────────────────────────────────────────────┐
? message (Press <space> to select, <a> to to│
ggle all, <i> to invert selection) │
 ✔ Choice 0 │
Separator 1 │
────────────── │
✔ Choice 3 │
✔ Choice 4 │
Separator 5 │
✔ Choice 6 │
✔ Choice 7 │
✔ Choice 8 │
✔ Choice 9 │
  │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────┘

View File

@ -0,0 +1,27 @@
---
source: src/question/checkbox/tests.rs
expression: backend
---
┌──────────────────────────────────────────────────┐
? message (Press <space> to select, <a> to to│
ggle all, <i> to invert selection) │
 ✔ Choice 0 │
Separator 1 │
────────────── │
✔ Choice 3 │
✔ Choice 4 │
Separator 5 │
✔ Choice 6 │
✔ Choice 7 │
✔ Choice 8 │
✔ Choice 9 │
✔ Choice 10 │
✔ Choice 11 │
Separator 12 │
✔ Choice 13 │
(Move up and down to reveal more choices) │
  │
│ │
│ │
└──────────────────────────────────────────────────┘

View File

@ -0,0 +1,27 @@
---
source: src/question/checkbox/tests.rs
expression: backend
---
┌──────────────────────────────────────────────────┐
? message (Press <space> to select, <a> to to│
ggle all, <i> to invert selection) │
 ✔ Choice 0 │
Separator 1 │
────────────── │
✔ Choice 3 │
✔ Choice 4 │
Separator 5 │
✔ Choice 6 │
✔ Choice 7 │
✔ Choice 8 │
✔ Choice 9 │
✔ Choice 10 │
✔ Choice 11 │
Separator 12 │
✔ Choice 13 │
(Move up and down to reveal more choices) │
  │
│ │
│ │
└──────────────────────────────────────────────────┘

View File

@ -0,0 +1,27 @@
---
source: src/question/checkbox/tests.rs
expression: backend
---
┌──────────────────────────────────────────────────┐
? message (Press <space> to select, <a> to to│
ggle all, <i> to invert selection) │
✔ Choice 0 │
Separator 1 │
────────────── │
 ✔ Choice 3 │
✔ Choice 4 │
Separator 5 │
✔ Choice 6 │
✔ Choice 7 │
✔ Choice 8 │
✔ Choice 9 │
✔ Choice 10 │
✔ Choice 11 │
Separator 12 │
✔ Choice 13 │
(Move up and down to reveal more choices) │
  │
│ │
│ │
└──────────────────────────────────────────────────┘

View File

@ -0,0 +1,27 @@
---
source: src/question/checkbox/tests.rs
expression: backend
---
┌──────────────────────────────────────────────────┐
? message (Press <space> to select, <a> to to│
ggle all, <i> to invert selection) │
✔ Choice 0 │
Separator 1 │
────────────── │
 ✔ Choice 3 │
✔ Choice 4 │
Separator 5 │
✔ Choice 6 │
✔ Choice 7 │
✔ Choice 8 │
✔ Choice 9 │
✔ Choice 10 │
✔ Choice 11 │
Separator 12 │
✔ Choice 13 │
(Move up and down to reveal more choices) │
  │
│ │
│ │
└──────────────────────────────────────────────────┘

View File

@ -0,0 +1,27 @@
---
source: src/question/checkbox/tests.rs
expression: backend
---
┌──────────────────────────────────────────────────┐
? message (Press <space> to select, <a> to to│
ggle all, <i> to invert selection) │
✔ Choice 0 │
Separator 1 │
────────────── │
 ✔ Choice 3 │
✔ Choice 4 │
Separator 5 │
✔ Choice 6 │
✔ Choice 7 │
✔ Choice 8 │
✔ Choice 9 │
✔ Choice 10 │
✔ Choice 11 │
Separator 12 │
✔ Choice 13 │
(Move up and down to reveal more choices) │
  │
│ │
│ │
└──────────────────────────────────────────────────┘

View File

@ -0,0 +1,27 @@
---
source: src/question/checkbox/tests.rs
expression: backend
---
┌──────────────────────────────────────────────────┐
? message (Press <space> to select, <a> to to│
ggle all, <i> to invert selection) │
 ✔ Choice 0 │
Separator 1 │
────────────── │
✔ Choice 3 │
✔ Choice 4 │
Separator 5 │
✔ Choice 6 │
✔ Choice 7 │
✔ Choice 8 │
✔ Choice 9 │
✔ Choice 10 │
✔ Choice 11 │
Separator 12 │
✔ Choice 13 │
(Move up and down to reveal more choices) │
  │
│ │
│ │
└──────────────────────────────────────────────────┘

View File

@ -0,0 +1,27 @@
---
source: src/question/checkbox/tests.rs
expression: backend
---
┌──────────────────────────────────────────────────┐
? message (Press <space> to select, <a> to to│
ggle all, <i> to invert selection) │
 ✔ Choice 0 │
Separator 1 │
────────────── │
✔ Choice 3 │
✔ Choice 4 │
Separator 5 │
✔ Choice 6 │
✔ Choice 7 │
✔ Choice 8 │
✔ Choice 9 │
  │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────┘

View File

@ -0,0 +1,27 @@
---
source: src/question/checkbox/tests.rs
expression: backend
---
┌──────────────────────────────────────────────────┐
? message (Press <space> to select, <a> to to│
ggle all, <i> to invert selection) │
✔ Choice 0 │
Separator 1 │
────────────── │
 ✔ Choice 3 │
✔ Choice 4 │
Separator 5 │
✔ Choice 6 │
✔ Choice 7 │
✔ Choice 8 │
✔ Choice 9 │
  │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────┘

View File

@ -0,0 +1,27 @@
---
source: src/question/checkbox/tests.rs
expression: backend
---
┌──────────────────────────────────────────────────┐
? message (Press <space> to select, <a> to to│
ggle all, <i> to invert selection) │
✔ Choice 0 │
Separator 1 │
────────────── │
 ✔ Choice 3 │
✔ Choice 4 │
Separator 5 │
✔ Choice 6 │
✔ Choice 7 │
✔ Choice 8 │
✔ Choice 9 │
  │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────┘

View File

@ -0,0 +1,27 @@
---
source: src/question/checkbox/tests.rs
expression: backend
---
┌──────────────────────────────────────────────────┐
? message (Press <space> to select, <a> to to│
ggle all, <i> to invert selection) │
✔ Choice 0 │
Separator 1 │
────────────── │
 ✔ Choice 3 │
✔ Choice 4 │
Separator 5 │
✔ Choice 6 │
✔ Choice 7 │
✔ Choice 8 │
✔ Choice 9 │
  │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────┘

View File

@ -0,0 +1,27 @@
---
source: src/question/checkbox/tests.rs
expression: backend
---
┌──────────────────────────────────────────────────┐
? message (Press <space> to select, <a> to to│
ggle all, <i> to invert selection) │
✔ Choice 0 │
Separator 1 │
────────────── │
 ✔ Choice 3 │
✔ Choice 4 │
Separator 5 │
✔ Choice 6 │
✔ Choice 7 │
✔ Choice 8 │
✔ Choice 9 │
  │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────┘

View File

@ -0,0 +1,27 @@
---
source: src/question/checkbox/tests.rs
expression: backend
---
┌──────────────────────────────────────────────────┐
? message (Press <space> to select, <a> to to│
ggle all, <i> to invert selection) │
 ✔ Choice 0 │
Separator 1 │
────────────── │
✔ Choice 3 │
✔ Choice 4 │
Separator 5 │
✔ Choice 6 │
✔ Choice 7 │
✔ Choice 8 │
✔ Choice 9 │
  │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────┘

138
tests/checkbox.rs Normal file
View File

@ -0,0 +1,138 @@
use discourse::question::Choice;
use rand::prelude::*;
use rand_chacha::ChaCha12Rng;
use ui::events::{KeyCode, KeyEvent, TestEvents};
mod helpers;
const SEED: u64 = 9828123;
const SEP_RATIO: f32 = 0.3;
const DEFAULT_SEP_RATIO: f32 = 0.10;
fn choices(len: usize) -> impl Iterator<Item = Choice<String>> {
let mut rng = ChaCha12Rng::seed_from_u64(SEED);
(0..len).map(move |i| {
let rand: f32 = rng.gen();
if rand < DEFAULT_SEP_RATIO {
Choice::DefaultSeparator
} else if rand < SEP_RATIO {
Choice::Separator(format!("Separator {}", i))
} else {
Choice::Choice(format!("Choice {}", i))
}
})
}
#[test]
fn test_validate() {
let checkbox = discourse::Question::checkbox("name")
.validate(|checked, _| {
let count = checked.iter().filter(|&&b| b).count();
if count > 1 {
Ok(())
} else {
Err(format!(
"At least 2 items must be checked. {} items were checked",
count
))
}
})
.message("checkbox")
.choices(choices(10));
let size = (50, 20).into();
let mut backend = helpers::SnapshotOnFlushBackend::new(size);
let mut events = TestEvents::new(vec![
KeyEvent::from(KeyCode::Down),
KeyCode::Char(' ').into(),
KeyCode::Enter.into(),
KeyCode::End.into(),
KeyCode::Char(' ').into(),
KeyCode::Enter.into(),
]);
let ans: Vec<_> =
discourse::prompt_one_with(checkbox, &mut backend, &mut events)
.unwrap()
.try_into_list_items()
.unwrap()
.into_iter()
.map(|item| item.index)
.collect();
assert!(events.next().is_none());
assert_eq!(ans, [3, 9]);
}
#[test]
fn test_filter() {
let checkbox = discourse::Question::checkbox("name")
.filter(|mut checked, _| {
checked.iter_mut().for_each(|b| *b = !*b);
checked
})
.message("checkbox")
.choices(choices(10));
let size = (50, 20).into();
let mut backend = helpers::SnapshotOnFlushBackend::new(size);
let mut events = TestEvents::new(vec![
KeyEvent::from(KeyCode::Down),
KeyCode::Char(' ').into(),
KeyCode::End.into(),
KeyCode::Char(' ').into(),
KeyCode::Enter.into(),
]);
let ans: Vec<_> =
discourse::prompt_one_with(checkbox, &mut backend, &mut events)
.unwrap()
.try_into_list_items()
.unwrap()
.into_iter()
.map(|item| item.index)
.collect();
assert!(events.next().is_none());
assert_eq!(ans, [0, 4, 6, 7, 8]);
}
#[test]
fn test_transform() {
let checkbox = discourse::Question::checkbox("name")
.transform(|items, _, b| {
b.set_fg(ui::style::Color::Magenta)?;
for (i, item) in items.iter().enumerate() {
write!(b, "{}: {}", item.index, item.name)?;
if i + 1 != items.len() {
write!(b, ", ")?;
}
}
b.set_fg(ui::style::Color::Reset)
})
.message("checkbox")
.choices(choices(10));
let size = (50, 20).into();
let mut backend = helpers::SnapshotOnFlushBackend::new(size);
let mut events = TestEvents::new(vec![
KeyEvent::from(KeyCode::Down),
KeyCode::Char(' ').into(),
KeyCode::End.into(),
KeyCode::Char(' ').into(),
KeyCode::Enter.into(),
]);
let ans: Vec<_> =
discourse::prompt_one_with(checkbox, &mut backend, &mut events)
.unwrap()
.try_into_list_items()
.unwrap()
.into_iter()
.map(|item| item.index)
.collect();
assert!(events.next().is_none());
assert_eq!(ans, [3, 9]);
}

94
tests/helpers/mod.rs Normal file
View File

@ -0,0 +1,94 @@
use std::io;
use ui::{backend, error, style};
pub struct SnapshotOnFlushBackend {
backend: backend::TestBackend,
}
impl SnapshotOnFlushBackend {
#[allow(dead_code)]
pub fn new(size: backend::Size) -> Self {
Self {
backend: backend::TestBackend::new(size),
}
}
#[allow(dead_code)]
pub fn new_with_layout(size: backend::Size, layout: ui::layout::Layout) -> Self {
Self {
backend: backend::TestBackend::new_with_layout(size, layout),
}
}
}
impl io::Write for SnapshotOnFlushBackend {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.backend.write(buf)
}
fn flush(&mut self) -> io::Result<()> {
ui::assert_backend_snapshot!(self.backend);
Ok(())
}
}
impl backend::Backend for SnapshotOnFlushBackend {
fn enable_raw_mode(&mut self) -> error::Result<()> {
self.backend.enable_raw_mode()
}
fn disable_raw_mode(&mut self) -> error::Result<()> {
self.backend.disable_raw_mode()
}
fn hide_cursor(&mut self) -> error::Result<()> {
self.backend.hide_cursor()
}
fn show_cursor(&mut self) -> error::Result<()> {
self.backend.show_cursor()
}
fn get_cursor_pos(&mut self) -> error::Result<(u16, u16)> {
self.backend.get_cursor_pos()
}
fn move_cursor_to(&mut self, x: u16, y: u16) -> error::Result<()> {
self.backend.move_cursor_to(x, y)
}
fn move_cursor(
&mut self,
direction: backend::MoveDirection,
) -> error::Result<()> {
self.backend.move_cursor(direction)
}
fn scroll(&mut self, dist: i16) -> error::Result<()> {
self.backend.scroll(dist)
}
fn set_attributes(
&mut self,
attributes: style::Attributes,
) -> error::Result<()> {
self.backend.set_attributes(attributes)
}
fn set_fg(&mut self, color: style::Color) -> error::Result<()> {
self.backend.set_fg(color)
}
fn set_bg(&mut self, color: style::Color) -> error::Result<()> {
self.backend.set_bg(color)
}
fn clear(&mut self, clear_type: backend::ClearType) -> error::Result<()> {
self.backend.clear(clear_type)
}
fn size(&self) -> error::Result<backend::Size> {
self.backend.size()
}
}

View File

@ -9,7 +9,7 @@ impl discourse::question::Plugin for TestPlugin {
_message: String,
_answers: &Answers,
_stdout: &mut dyn Backend,
_events: &mut Events,
_events: &mut dyn Iterator<Item = discourse::Result<KeyEvent>>,
) -> discourse::Result<Answer> {
Ok(Answer::Int(0))
}