Skip to content

Commit

Permalink
Merge pull request #125 from krymtkts:feature/refactor
Browse files Browse the repository at this point in the history
Refactor code and enhance unit test coverage
  • Loading branch information
krymtkts authored Jan 27, 2024
2 parents e73a349 + 4337751 commit 095bd65
Show file tree
Hide file tree
Showing 5 changed files with 128 additions and 81 deletions.
109 changes: 51 additions & 58 deletions src/pocof.Test/Pocof.fs
Original file line number Diff line number Diff line change
Expand Up @@ -42,21 +42,6 @@ let propMap = Map.empty

let results = [ "a"; "b"; "c"; "d"; "e" ] |> List.map box

type MockGetKey(keys: ConsoleKeyInfo list list) =
let mutable keys = keys

member __.getKey() =
match keys with
| [] -> failwith "no keys remains. probably test is broken."
| x :: xs ->
keys <- xs
x

member __.check() =
match keys with
| [] -> ()
| _ -> failwith "keys remains. probably test is broken."

module calculateWindowBeginningCursor =
[<Fact>]
let ``should return 0.`` () =
Expand Down Expand Up @@ -104,21 +89,22 @@ module calculateWindowBeginningCursor =
actual |> shouldEqual 0

module loop =

[<Fact>]
let ``should return result when finishing.`` () =
let input = results |> List.map toObj
let state, context = pocof.PocofQuery.prepare state

let m =
MockGetKey [ [ new ConsoleKeyInfo('\000', ConsoleKey.Enter, false, false, false) ] ]
let rui = new MockRawUI(60, 30, [ MockRawUI.consoleKey '\000' ConsoleKey.Enter ])
use buff = new Buff(rui, (fun _ -> Seq.empty))

let args =
{ keymaps = pocof.PocofAction.defaultKeymap
input = input
propMap = propMap
writeScreen = writeScreen
getKey = m.getKey
getConsoleWidth = fun () -> 60
getKey = buff.getKey
getConsoleWidth = buff.getConsoleWidth
getLengthInBufferCells = String.length }

let actual = loop args input state pos context
Expand All @@ -127,45 +113,56 @@ module loop =
actual
|> List.iteri (fun i x -> x = results.[i] |> shouldEqual true)

rui.check ()

[<Fact>]
let ``shouldn't return result when canceling.`` () =
let input = results |> List.map toObj

let state, context =
pocof.PocofQuery.prepare { state with SuppressProperties = true }

let m =
MockGetKey [ [ new ConsoleKeyInfo('\000', ConsoleKey.Escape, false, false, false) ] ]
let rui = new MockRawUI(60, 30, [ MockRawUI.consoleKey '\000' ConsoleKey.Escape ])
use buff = new Buff(rui, (fun _ -> Seq.empty))

let args =
{ keymaps = pocof.PocofAction.defaultKeymap
input = input
propMap = propMap
writeScreen = writeScreen
getKey = m.getKey
getConsoleWidth = fun () -> 60
getKey = buff.getKey
getConsoleWidth = buff.getConsoleWidth
getLengthInBufferCells = String.length }

let actual = loop args input state pos context
actual |> List.length |> shouldEqual 0
rui.check ()

[<Fact>]
let ``should return result when finishing after noop.`` () =
let input = results |> List.map toObj

let state, context = pocof.PocofQuery.prepare { state with Refresh = NotRequired }

let m =
MockGetKey [ [ new ConsoleKeyInfo('\000', ConsoleKey.Escape, true, true, false) ]
[ new ConsoleKeyInfo('\000', ConsoleKey.Enter, false, false, false) ] ]
let rui =
new MockRawUI(
60,
30,
[ new ConsoleKeyInfo('\000', ConsoleKey.Escape, true, true, false)
|> Some
None
MockRawUI.consoleKey '\000' ConsoleKey.Enter ]
)

use buff = new Buff(rui, (fun _ -> Seq.empty))

let args =
{ keymaps = pocof.PocofAction.defaultKeymap
input = input
propMap = propMap
writeScreen = writeScreen
getKey = m.getKey
getConsoleWidth = fun () -> 60
getKey = buff.getKey
getConsoleWidth = buff.getConsoleWidth
getLengthInBufferCells = String.length }

let actual = loop args input state pos context
Expand All @@ -174,34 +171,40 @@ module loop =
actual
|> List.iteri (fun i x -> x = results.[i] |> shouldEqual true)

m.check ()
rui.check ()

[<Fact>]
let ``should return result when finishing with filter.`` () =
let input = results |> List.map toObj

let state, context = pocof.PocofQuery.prepare state

let m =
MockGetKey [ [ new ConsoleKeyInfo('a', ConsoleKey.A, false, false, false)
new ConsoleKeyInfo(' ', ConsoleKey.Spacebar, false, false, false)
new ConsoleKeyInfo('d', ConsoleKey.D, false, false, false) ]
[ new ConsoleKeyInfo('\000', ConsoleKey.Enter, false, false, false) ] ]
let rui =
new MockRawUI(
60,
30,
[ MockRawUI.consoleKey 'a' ConsoleKey.A
MockRawUI.consoleKey ' ' ConsoleKey.Spacebar
MockRawUI.consoleKey 'd' ConsoleKey.D
None
MockRawUI.consoleKey '\000' ConsoleKey.Enter ]
)

use buff = new Buff(rui, (fun _ -> Seq.empty))

let args =
{ keymaps = pocof.PocofAction.defaultKeymap
input = input
propMap = propMap
writeScreen = writeScreen
getKey = m.getKey
getConsoleWidth = fun () -> 60
getKey = buff.getKey
getConsoleWidth = buff.getConsoleWidth
getLengthInBufferCells = String.length }

let actual = loop args input state pos context
actual |> List.length |> shouldEqual 2
actual.[0] = results.[0] |> shouldEqual true
actual.[1] = results.[3] |> shouldEqual true
m.check ()
rui.check ()

[<Fact>]
let ``should update QueryState.WindowWidth based on ConsoleWidth.`` () =
Expand All @@ -210,19 +213,23 @@ module loop =
let state, context =
pocof.PocofQuery.prepare { state with SuppressProperties = true }

let m =
MockGetKey [ [ new ConsoleKeyInfo('a', ConsoleKey.A, false, false, false) ]
[ new ConsoleKeyInfo('\000', ConsoleKey.Enter, false, false, false) ] ]
let rui =
new MockRawUI(
60,
30,
[ MockRawUI.consoleKey 'a' ConsoleKey.A
None
MockRawUI.consoleKey '\000' ConsoleKey.Enter ]
)

let rui = new MockRawUI(60, 30)
use buff = new Buff(rui, (fun _ -> Seq.empty))

let args =
{ keymaps = pocof.PocofAction.defaultKeymap
input = input
propMap = propMap
writeScreen = buff.writeTopDown
getKey = m.getKey
getKey = buff.getKey
getConsoleWidth =
fun () ->
rui.width <- 80
Expand All @@ -238,23 +245,9 @@ module loop =
:: (generateLine 80 (rui.height - 1))

rui.screen |> shouldEqual expected
rui.check ()

module interact =
type MockGetKey(keys: ConsoleKeyInfo list list) =
let mutable keys = keys

member __.getKey() =
match keys with
| [] -> failwith "no keys remains. probably test is broken."
| x :: xs ->
keys <- xs
x

member __.check() =
match keys with
| [] -> ()
| _ -> failwith "keys remains. probably test is broken."

[<Fact>]
let ``should return result with NonInteractive mode.`` () =
let config: InternalConfig =
Expand Down
51 changes: 47 additions & 4 deletions src/pocof.Test/PocofUI.fs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ module PocofUI
open Xunit
open FsUnitTyped
open System
open pocof.LanguageExtension
open pocof.PocofData
open pocof.PocofQuery
open pocof.PocofScreen
Expand All @@ -19,9 +18,11 @@ type MockRawUI =
val mutable x: int
val mutable y: int
val mutable screen: string list

val mutable keys: ConsoleKeyInfo option list
static xx = 50
static yy = 30


new() =
// NOTE: accessing Console.TreatControlCAsInput will raise System.IO.IOException when running on GitHub Actions windows runner.
{ caAsInput = true
Expand All @@ -30,6 +31,7 @@ type MockRawUI =
width = MockRawUI.xx
height = MockRawUI.yy
screen = generateLine MockRawUI.xx MockRawUI.yy
keys = [MockRawUI.consoleKey '\000' ConsoleKey.Enter]
}
new(x:int, y:int) =
// NOTE: accessing Console.TreatControlCAsInput will raise System.IO.IOException when running on GitHub Actions windows runner.
Expand All @@ -39,8 +41,20 @@ type MockRawUI =
width = x
height = y
screen = generateLine x y
keys = [MockRawUI.consoleKey '\000' ConsoleKey.Enter]
}

new(x:int, y:int, keys: ConsoleKeyInfo option list) =
// NOTE: accessing Console.TreatControlCAsInput will raise System.IO.IOException when running on GitHub Actions windows runner.
{ caAsInput = true
x = x
y = y
width = x
height = y
screen = generateLine x y
keys = keys
}

interface IRawUI with
member __.SetCursorPosition (x: int) (y: int) =
__.x <- x
Expand All @@ -52,8 +66,10 @@ type MockRawUI =
code >= 0xFF00 && code <= 0xFF60

s |> Seq.cast<char> |> Seq.map (fun c -> if isFullWidth c then 2 else 1) |> Seq.sum

member __.GetWindowWidth() = __.width
member __.GetWindowHeight() = __.height

member __.Write x y s =
__.screen <- __.screen |>List.mapi (fun i ss ->
match i with
Expand All @@ -64,12 +80,39 @@ type MockRawUI =
match l <= __.width with
| true -> ss + String.replicate (__.width - l) " "
| _ -> ss)
member __.ReadKey(_) = new ConsoleKeyInfo('\000', ConsoleKey.Enter, false, false, false)
member __.KeyAvailable() = false

member __.ReadKey(_) =
match __.keys with
| [] -> failwith "key sequence is empty. check your test key sequence."
| k::ks ->
match k with
| None -> failwith "key is none. check your test key sequence."
| Some k ->
__.keys <- ks
k

member __.KeyAvailable() =
match __.keys with
| [] -> false
| k::ks ->
match k with
| None ->
__.keys <- ks
false
| Some _ -> true

interface IDisposable with
member __.Dispose() = ()

static member consoleKey keyChar key =
new ConsoleKeyInfo(keyChar, key, false, false, false)
|> Some

member __.check() =
match __.keys with
| [] -> ()
| _ -> failwith "keys remains. probably test is broken."

module ``Buff writeScreen`` =
open System.Collections
open System.Management.Automation
Expand Down
5 changes: 2 additions & 3 deletions src/pocof/Main.fs
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ module Pocof =
(state: InternalState)
(pos: Position)
(rui: unit -> PocofScreen.IRawUI)
(invoke: obj list -> seq<string>)
(invoke: obj list -> string seq)
(input: Entry list)
=

Expand Down Expand Up @@ -160,8 +160,7 @@ module Pocof =

let buildInput acc (input: PSObject array) =
input
|> List.ofArray
|> List.fold
|> Seq.fold
(fun acc o ->
match o.BaseObject with
| :? IDictionary as dct ->
Expand Down
2 changes: 1 addition & 1 deletion src/pocof/Query.fs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ module PocofQuery =
with
| _ -> None

type TesterType<'a> = ('a -> bool) -> list<'a> -> bool
type TesterType<'a> = ('a -> bool) -> 'a list -> bool

type QueryContext =
{ Queries: Query list
Expand Down
Loading

0 comments on commit 095bd65

Please sign in to comment.