-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Issue #91: "Attr.readOnly false" fixed
- 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
1 parent
47b8319
commit a5b1426
Showing
1 changed file
with
127 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |