Skip to content

Commit

Permalink
2.4.0: limited js support
Browse files Browse the repository at this point in the history
  • Loading branch information
disruptek committed Jan 29, 2021
1 parent 8f296d5 commit d80bf5c
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 35 deletions.
40 changes: 25 additions & 15 deletions balls.nim
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,10 @@ proc numberLines(s: string; first = 1): NimNode =

proc checkpoint*(ss: varargs[string, `$`]) =
## Like `echo`, but outputs to `stderr` with the other test output.
writeLine(stderr, ss.join " ")
when defined(js):
echo ss.join(" ")
else:
writeLine(stderr, ss.join(" "))

proc output(n: NimNode): NimNode =
assert not n.isNil
Expand Down Expand Up @@ -307,12 +310,15 @@ proc success(t: var Test): NimNode =

proc fromFileGetLine(file: string; line: int): string =
## TODO: optimize this expensive fetch
if file.fileExists:
let lines = toSeq lines(file)
result = lines[line - 1]
when defined(js):
result = "(unsupported on js)"
else:
#result = "(not found: $#)" % [ file ]
result = "(file not found)"
if file.fileExists:
let lines = toSeq lines(file)
result = lines[line - 1]
else:
#result = "(not found: $#)" % [ file ]
result = "(file not found)"

proc findWhere(s: string; p: string; into: var string): bool {.used.} =
## find the location of a substring and, if found, produce empty prefix
Expand All @@ -336,12 +342,15 @@ proc renderStack(prefix: string; stack: seq[StackTraceEntry]) =

proc renderTrace(t: Test; n: NimNode = nil): NimNode =
## output the stack trace of a test, and perhaps that of any exception
var renderStack = bindSym"renderStack"
var getStack = newCall(ident"getStackTraceEntries")
if not n.isNil:
getStack.add n # get the exception's stacktrace
result = newIfStmt((newCall(ident"stackTraceAvailable"),
newCall(renderStack, newLit($t.status), getStack)))
when defined(js):
result = newEmptyNode()
else:
var renderStack = bindSym"renderStack"
var getStack = newCall(bindSym"getStackTraceEntries")
if not n.isNil:
getStack.add n # get the exception's stacktrace
result = newIfStmt((newCall(bindSym"stackTraceAvailable"),
newCall(renderStack, newLit($t.status), getStack)))

proc renderSource(t: Test): NimNode =
## strip the first comment, include the remainder
Expand Down Expand Up @@ -690,9 +699,10 @@ macro suite*(name: string; tests: untyped) =
nnkDiscardStmt.newTree:
bindSym"execShellCmd".newCall newLit""

# ensure that we flush stderr on exit
add result:
bindSym"addExitProc".newCall bindSym"flushStderr"
when not defined(js):
# ensure that we flush stderr on exit
add result:
bindSym"addExitProc".newCall bindSym"flushStderr"

for index, n in tests.pairs:
var test: Test
Expand Down
2 changes: 1 addition & 1 deletion balls.nimble
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version = "2.3.1"
version = "2.4.0"
author = "disruptek"
description = "a unittest framework with balls 🔴🟡🟢"
license = "MIT"
Expand Down
34 changes: 27 additions & 7 deletions balls/runner.nim
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,23 @@ type
Compiler* = enum ## backends that we test
c
cpp
js

Optimizer* = enum ## optimization modes that we test
debug
release
danger

MemModel* = enum ## memory managers that we test
refc
markAndSweep
arc
orc
vm

Matrix* = OrderedTable[Profile, StatusKind] ##
## the Matrix collects test results in the order they are obtained

Profile* = object ##
## the Profile defines compilation settings for a single test invocation
cp*: Compiler
Expand Down Expand Up @@ -181,11 +187,14 @@ elif ci:
# remote ci expands the matrix
if ci:
cp.add cpp # add cpp
cp.add js # add js
gc.incl refc # add refc
gc.incl markAndSweep # add markAndSweep
if arc in gc: # add orc if arc is available
if (NimMajor, NimMinor) >= (1, 4): # but 1.2 has infinite loops!
gc.incl orc
if js in cp:
gc.incl vm
else:
# do a danger build locally so we can check time/space; omit release
opt.del release
Expand Down Expand Up @@ -226,7 +235,11 @@ proc options(p: Profile): seq[string] =

proc perform*(p: var Profile): StatusKind =
## Run a single Profile `p` and return its StatusKind.
const pattern = "nim $1 --gc:$2 $3"
let pattern =
if p.gc == vm:
"nim $1 $3"
else:
"nim $1 --gc:$2 $3"
# we also use it to determine which hints to include
let hs = hints(p, ci)

Expand All @@ -239,12 +252,19 @@ proc perform*(p: var Profile): StatusKind =
# add the hints into the invocation ahead of the filename
run.add hs & " " & p.fn

# run it and return the result
let code = attempt run
if code == 0:
result = Pass
# certain profiles don't even get attempted
if p.gc == vm and p.cp != js:
result = Skip
elif p.cp == js and p.gc != vm:
result = Skip
else:
result = Fail
# run it and return the result
let code = attempt run
case code
of 0:
result = Pass
else:
result = Fail

proc contains*(matrix: Matrix; p: Profile): bool =
## A test result of `None` or `Skip` effectively does not count as being
Expand Down Expand Up @@ -282,7 +302,7 @@ proc perform*(matrix: var Matrix; profiles: seq[Profile]) =
discard execCmd "nim --version"
# don't quit when run locally; just keep chugging away
if ci and ballsFailFast:
if p.cp != cpp and p.gc notin {arc, orc}:
if p.cp notin {cpp, js} and p.gc notin {arc, orc}:
# before we fail the ci, run a debug test for shits and grins
var n = p
n.opt = debug
Expand Down
15 changes: 8 additions & 7 deletions balls/spec.nim
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,13 @@ when ballsDry:
type
StatusKind* = enum ## possible test results
None = " " ## (undefined)
Info = "i" ## may prefix information
Pass = "🗸" ## total success
Skip = "?" ## test was skipped
Part = "/" ## partial success
Fail = "𐄂" ## assertion failure
Info = "" ## may prefix information
Pass = "" ## total success
Skip = "" ## test was skipped
Part = "" ## partial success
Fail = "" ## assertion failure
Died = "" ## unexpected exception
Oops = "؟" ## compiles() failed
Oops = "" ## compiles() failed

else:
const
Expand Down Expand Up @@ -116,4 +116,5 @@ proc dollar*(n: NimNode): NimNode =

proc flushStderr*() {.noconv, used.} =
## Convenience for flushing stderr during process exit.
flushFile stderr
when not defined(js):
flushFile stderr
23 changes: 18 additions & 5 deletions balls/style.nim
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import std/macros
import std/terminal
import std/colors

import balls/spec
Expand All @@ -13,14 +12,25 @@ proc `&`*(a: string; b: Styling): Styling = b & a

{.push hint[ConvFromXtoItselfNotNeeded]: off.}

when defined(js):
template ansiStyleCode(x: untyped): string = ""
template ansiForegroundColorCode(x: untyped; bool = true): string = ""
template ansiBackgroundColorCode(x: untyped; bool = true): string = ""
const
ansiResetCode = ""
else:
import std/terminal

const
resetStyle* = Styling ansiResetCode
resultsStyle* = Styling ansiStyleCode(styleItalic) &
Styling ansiForegroundColorCode(fgWhite, true)
informStyle* = Styling ansiForegroundColorCode(fgBlue, true)
commentStyle* = Styling ansiStyleCode(styleItalic) &
Styling ansiForegroundColorCode(fgWhite, true)
lineNumStyle* = Styling ansiStyleCode(styleItalic) &
Styling ansiForegroundColorCode(fgBlack, true)
partialStyle* = Styling ansiForegroundColorCode(fgYellow, true)
successStyle* = Styling ansiForegroundColorCode(fgGreen)
oopsStyle* = Styling ansiStyleCode(styleBright) &
Styling ansiStyleCode(styleReverse) &
Expand All @@ -43,10 +53,10 @@ const
Styling ansiForegroundColorCode(fgCyan, true)
statusStyles*: array[StatusKind, Styling] = [
None: resetStyle,
Info: commentStyle,
Info: informStyle,
Pass: successStyle,
Skip: skippedStyle,
Part: resetStyle,
Skip: commentStyle,
Part: partialStyle,
Fail: failureStyle,
Died: exceptionStyle,
Oops: oopsStyle
Expand All @@ -69,7 +79,10 @@ proc useColor*(): bool =
true
else:
# at runtime, try to emit style if possible
onCI or stderr.isAtty
when defined(js):
onCI
else:
onCI or stderr.isAtty

proc `$`*(style: Styling): string =
if useColor():
Expand Down

0 comments on commit d80bf5c

Please sign in to comment.