Skip to content

Commit

Permalink
- Issue #91: "Attr.readOnly false" fixed
Browse files Browse the repository at this point in the history
- Removed diagnostic output to console
- Observable.init: Provide the initial value for a sequence so that new subscribers will receive an immediate update of the current value. Probably only useful for IObservables that are not derived from an initial IStore
- IReadOnlyStore.Dispose(f), IStore.Dispose(f) : Call f() when the store is disposed
- Removed dependency on ConstructStyleSheetsPolyfill and included directly
- Fixed some warnings in the App (not part of the nuget pkg)
  • Loading branch information
davedawkins committed Sep 21, 2024
1 parent 47b8319 commit a5b1426
Showing 1 changed file with 127 additions and 18 deletions.
145 changes: 127 additions & 18 deletions tests/package.json
Original file line number Diff line number Diff line change
@@ -1,19 +1,128 @@
{
"private": true,
"scripts": {
"install": "dotnet tool restore",
"bundle": "cd src/Fable.Expect && esbuild queries.js --bundle --outfile=queries.bundle.js --format=esm",
"publish": "dotnet fsi build.fsx publish",
"test": "dotnet fable test --define HEADLESS --run web-test-runner test/*Test.fs.js --node-resolve",
"test:watch": "dotnet fable watch test -o build/test --define HEADLESS --run web-test-runner build/test/*Test.js --node-resolve --watch",
"test-in-browser:build": "dotnet fable test --run webpack --config webpack.config.tests.js",
"test-in-browser": "dotnet fable watch test --run webpack serve --config webpack.config.tests.js "
},
"devDependencies": {
"@web/test-runner": "^0.13.18",
"@web/test-runner-commands": "^0.5.13",
"aria-query": "^5.0.0",
"dom-accessibility-api": "^0.5.7",
"esbuild": "^0.13.4"
}
module BrowserFramework

open System
open Browser.Dom
open Browser.Types
open Fable.Core


let testAppId = "test-app"
let mutable currentEl : HTMLElement = Unchecked.defaultof<_>

type TestCase = {
Name : string
Test : unit -> JS.Promise<unit>
}

type TestSuite = {
Name : string
}

Suites : TestSuite list
Tests : TestCase list
}

let logC (s: string) = Browser.Dom.console.log(s)

let log (category:string) (s : string) =
logC(s)
let logE = document.querySelector("#test-log")
if not(isNull logE) then
let span = document.createElement("span")
span.classList.add([|category|])
let t = document.createTextNode(s + "\n")
span.appendChild(t) |> ignore
logE.appendChild(span) |> ignore

let timeNow() = (float)System.DateTime.Now.Ticks / 10000000.0

let timestamp (t : float) =
sprintf "%0.3f" t

let logS s = log "success" s
let logE s = log "failure" s
let logH s = log "heading" s
let logI s = log "info" s

let private rafu f =
window.requestAnimationFrame (fun _ -> f()) |> ignore

let waitAnimationFrame () : JS.Promise<unit> =
Fable.Core.JS.Constructors.Promise.Create <|
fun accept _ -> rafu accept

let mountTestApp app =
Fable.Core.JS.console.log("mountTestApp")
let el = document.querySelector("#" + testAppId)
el.innerHTML <- ""
(testAppId, app) |> Sutil.Program.mount

let testCase (name:string) (f:unit -> unit) =
{
Name = name;
Test = fun () ->
promise {
f()
}
}

let testCaseP (name:string) (f:unit -> JS.Promise<unit>) =
{
Name = name;
Test = f
}

let testList (name:string) (tests : TestCase list) = { Name = name; Tests = tests; Suites = [] }

type TestContext = {
StartTime : float
NumFail : int
NumPass : int
TestSuites : TestSuite list
TestCases : TestCase list
}

let rec nextTestCase (testCtx : TestContext) =
rafu (fun _ -> nextTestCaseNow testCtx) // Allow browser to update between tests
//nextTestCaseNow testCtx // Allow browser to update between tests

and nextTestCaseNow (testCtx : TestContext) =
match testCtx.TestCases with
| [] ->
nextTestSuite testCtx
| test :: tests ->
test.Test()
|> Promise.map (fun _ ->
logS ($"{timestamp(timeNow() - testCtx.StartTime)}: " + test.Name + ": PASS")
nextTestCase { testCtx with TestCases = tests; NumPass = testCtx.NumPass + 1 }
)
|> Promise.catch (fun x ->
logE ($"{timestamp(timeNow() - testCtx.StartTime)}: " + test.Name + ": FAIL: "+ x.Message)
nextTestCase { testCtx with TestCases = tests; NumFail = testCtx.NumFail + 1 }
)
|> ignore

and nextTestSuite (testCtx : TestContext) =
match testCtx.TestSuites with
| [] ->
logH "Result"
if testCtx.NumFail = 0 then
logS ($"{timestamp(timeNow() - testCtx.StartTime)}: SUCCESS: All tests passed (" + string testCtx.NumPass + ")")
else
logE ($"{timestamp(timeNow() - testCtx.StartTime)}: FAIL: " + string testCtx.NumFail + " failed, " + string testCtx.NumPass + " passed")
| suite :: suites ->
logH (suite.Name)
nextTestCase { testCtx with TestCases = suite.Tests; TestSuites = suites }

let mutable testSuites : TestSuite list = []

let addSuite suite =
testSuites <- testSuites @ [ suite ]

let runTests (tests : TestSuite list) =
logH $"Test Suite"
logI $"{timestamp(0.)}: Starting test"
nextTestSuite { StartTime = timeNow(); NumPass = 0; NumFail = 0; TestSuites = tests; TestCases = [] }

let runAll() =
runTests testSuites

0 comments on commit a5b1426

Please sign in to comment.