Initial commit
This commit is contained in:
commit
a6272848f9
379 changed files with 74829 additions and 0 deletions
BIN
build/dev/javascript/gleeunit/_gleam_artefacts/gleeunit.cache
Normal file
BIN
build/dev/javascript/gleeunit/_gleam_artefacts/gleeunit.cache
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
1
build/dev/javascript/gleeunit/gleam.mjs
Normal file
1
build/dev/javascript/gleeunit/gleam.mjs
Normal file
|
|
@ -0,0 +1 @@
|
|||
export * from "../prelude.mjs";
|
||||
89
build/dev/javascript/gleeunit/gleeunit.erl
Normal file
89
build/dev/javascript/gleeunit/gleeunit.erl
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
-module(gleeunit).
|
||||
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
|
||||
-define(FILEPATH, "src/gleeunit.gleam").
|
||||
-export([main/0]).
|
||||
-export_type([atom_/0, encoding/0, report_module_name/0, gleeunit_progress_option/0, eunit_option/0]).
|
||||
|
||||
-if(?OTP_RELEASE >= 27).
|
||||
-define(MODULEDOC(Str), -moduledoc(Str)).
|
||||
-define(DOC(Str), -doc(Str)).
|
||||
-else.
|
||||
-define(MODULEDOC(Str), -compile([])).
|
||||
-define(DOC(Str), -compile([])).
|
||||
-endif.
|
||||
|
||||
-type atom_() :: any().
|
||||
|
||||
-type encoding() :: utf8.
|
||||
|
||||
-type report_module_name() :: gleeunit_progress.
|
||||
|
||||
-type gleeunit_progress_option() :: {colored, boolean()}.
|
||||
|
||||
-type eunit_option() :: verbose |
|
||||
no_tty |
|
||||
{report, {report_module_name(), list(gleeunit_progress_option())}} |
|
||||
{scale_timeouts, integer()}.
|
||||
|
||||
-file("src/gleeunit.gleam", 42).
|
||||
-spec gleam_to_erlang_module_name(binary()) -> binary().
|
||||
gleam_to_erlang_module_name(Path) ->
|
||||
case gleam_stdlib:string_ends_with(Path, <<".gleam"/utf8>>) of
|
||||
true ->
|
||||
_pipe = Path,
|
||||
_pipe@1 = gleam@string:replace(
|
||||
_pipe,
|
||||
<<".gleam"/utf8>>,
|
||||
<<""/utf8>>
|
||||
),
|
||||
gleam@string:replace(_pipe@1, <<"/"/utf8>>, <<"@"/utf8>>);
|
||||
|
||||
false ->
|
||||
_pipe@2 = Path,
|
||||
_pipe@3 = gleam@string:split(_pipe@2, <<"/"/utf8>>),
|
||||
_pipe@4 = gleam@list:last(_pipe@3),
|
||||
_pipe@5 = gleam@result:unwrap(_pipe@4, Path),
|
||||
gleam@string:replace(_pipe@5, <<".erl"/utf8>>, <<""/utf8>>)
|
||||
end.
|
||||
|
||||
-file("src/gleeunit.gleam", 18).
|
||||
-spec do_main() -> nil.
|
||||
do_main() ->
|
||||
Options = [verbose,
|
||||
no_tty,
|
||||
{report, {gleeunit_progress, [{colored, true}]}},
|
||||
{scale_timeouts, 10}],
|
||||
Result = begin
|
||||
_pipe = gleeunit_ffi:find_files(
|
||||
<<"**/*.{erl,gleam}"/utf8>>,
|
||||
<<"test"/utf8>>
|
||||
),
|
||||
_pipe@1 = gleam@list:map(_pipe, fun gleam_to_erlang_module_name/1),
|
||||
_pipe@2 = gleam@list:map(
|
||||
_pipe@1,
|
||||
fun(_capture) -> erlang:binary_to_atom(_capture, utf8) end
|
||||
),
|
||||
gleeunit_ffi:run_eunit(_pipe@2, Options)
|
||||
end,
|
||||
Code = case Result of
|
||||
{ok, _} ->
|
||||
0;
|
||||
|
||||
{error, _} ->
|
||||
1
|
||||
end,
|
||||
erlang:halt(Code).
|
||||
|
||||
-file("src/gleeunit.gleam", 13).
|
||||
?DOC(
|
||||
" Find and run all test functions for the current project using Erlang's EUnit\n"
|
||||
" test framework, or a custom JavaScript test runner.\n"
|
||||
"\n"
|
||||
" Any Erlang or Gleam function in the `test` directory with a name ending in\n"
|
||||
" `_test` is considered a test function and will be run.\n"
|
||||
"\n"
|
||||
" A test that panics is considered a failure.\n"
|
||||
).
|
||||
-spec main() -> nil.
|
||||
main() ->
|
||||
do_main().
|
||||
62
build/dev/javascript/gleeunit/gleeunit.mjs
Normal file
62
build/dev/javascript/gleeunit/gleeunit.mjs
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
import * as $list from "../gleam_stdlib/gleam/list.mjs";
|
||||
import * as $result from "../gleam_stdlib/gleam/result.mjs";
|
||||
import * as $string from "../gleam_stdlib/gleam/string.mjs";
|
||||
import { CustomType as $CustomType } from "./gleam.mjs";
|
||||
import { main as do_main } from "./gleeunit_ffi.mjs";
|
||||
|
||||
class Utf8 extends $CustomType {}
|
||||
|
||||
class GleeunitProgress extends $CustomType {}
|
||||
|
||||
class Colored extends $CustomType {
|
||||
constructor($0) {
|
||||
super();
|
||||
this[0] = $0;
|
||||
}
|
||||
}
|
||||
|
||||
class Verbose extends $CustomType {}
|
||||
|
||||
class NoTty extends $CustomType {}
|
||||
|
||||
class Report extends $CustomType {
|
||||
constructor($0) {
|
||||
super();
|
||||
this[0] = $0;
|
||||
}
|
||||
}
|
||||
|
||||
class ScaleTimeouts extends $CustomType {
|
||||
constructor($0) {
|
||||
super();
|
||||
this[0] = $0;
|
||||
}
|
||||
}
|
||||
|
||||
function gleam_to_erlang_module_name(path) {
|
||||
let $ = $string.ends_with(path, ".gleam");
|
||||
if ($) {
|
||||
let _pipe = path;
|
||||
let _pipe$1 = $string.replace(_pipe, ".gleam", "");
|
||||
return $string.replace(_pipe$1, "/", "@");
|
||||
} else {
|
||||
let _pipe = path;
|
||||
let _pipe$1 = $string.split(_pipe, "/");
|
||||
let _pipe$2 = $list.last(_pipe$1);
|
||||
let _pipe$3 = $result.unwrap(_pipe$2, path);
|
||||
return $string.replace(_pipe$3, ".erl", "");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find and run all test functions for the current project using Erlang's EUnit
|
||||
* test framework, or a custom JavaScript test runner.
|
||||
*
|
||||
* Any Erlang or Gleam function in the `test` directory with a name ending in
|
||||
* `_test` is considered a test function and will be run.
|
||||
*
|
||||
* A test that panics is considered a failure.
|
||||
*/
|
||||
export function main() {
|
||||
return do_main();
|
||||
}
|
||||
180
build/dev/javascript/gleeunit/gleeunit/internal/gleam_panic.mjs
Normal file
180
build/dev/javascript/gleeunit/gleeunit/internal/gleam_panic.mjs
Normal file
|
|
@ -0,0 +1,180 @@
|
|||
import * as $dynamic from "../../../gleam_stdlib/gleam/dynamic.mjs";
|
||||
import { CustomType as $CustomType } from "../../gleam.mjs";
|
||||
import { from_dynamic } from "./gleeunit_gleam_panic_ffi.mjs";
|
||||
|
||||
export { from_dynamic };
|
||||
|
||||
export class GleamPanic extends $CustomType {
|
||||
constructor(message, file, module, function$, line, kind) {
|
||||
super();
|
||||
this.message = message;
|
||||
this.file = file;
|
||||
this.module = module;
|
||||
this.function = function$;
|
||||
this.line = line;
|
||||
this.kind = kind;
|
||||
}
|
||||
}
|
||||
export const GleamPanic$GleamPanic = (message, file, module, function$, line, kind) =>
|
||||
new GleamPanic(message, file, module, function$, line, kind);
|
||||
export const GleamPanic$isGleamPanic = (value) => value instanceof GleamPanic;
|
||||
export const GleamPanic$GleamPanic$message = (value) => value.message;
|
||||
export const GleamPanic$GleamPanic$0 = (value) => value.message;
|
||||
export const GleamPanic$GleamPanic$file = (value) => value.file;
|
||||
export const GleamPanic$GleamPanic$1 = (value) => value.file;
|
||||
export const GleamPanic$GleamPanic$module = (value) => value.module;
|
||||
export const GleamPanic$GleamPanic$2 = (value) => value.module;
|
||||
export const GleamPanic$GleamPanic$function = (value) => value.function;
|
||||
export const GleamPanic$GleamPanic$3 = (value) => value.function;
|
||||
export const GleamPanic$GleamPanic$line = (value) => value.line;
|
||||
export const GleamPanic$GleamPanic$4 = (value) => value.line;
|
||||
export const GleamPanic$GleamPanic$kind = (value) => value.kind;
|
||||
export const GleamPanic$GleamPanic$5 = (value) => value.kind;
|
||||
|
||||
export class Todo extends $CustomType {}
|
||||
export const PanicKind$Todo = () => new Todo();
|
||||
export const PanicKind$isTodo = (value) => value instanceof Todo;
|
||||
|
||||
export class Panic extends $CustomType {}
|
||||
export const PanicKind$Panic = () => new Panic();
|
||||
export const PanicKind$isPanic = (value) => value instanceof Panic;
|
||||
|
||||
export class LetAssert extends $CustomType {
|
||||
constructor(start, end, pattern_start, pattern_end, value) {
|
||||
super();
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
this.pattern_start = pattern_start;
|
||||
this.pattern_end = pattern_end;
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
export const PanicKind$LetAssert = (start, end, pattern_start, pattern_end, value) =>
|
||||
new LetAssert(start, end, pattern_start, pattern_end, value);
|
||||
export const PanicKind$isLetAssert = (value) => value instanceof LetAssert;
|
||||
export const PanicKind$LetAssert$start = (value) => value.start;
|
||||
export const PanicKind$LetAssert$0 = (value) => value.start;
|
||||
export const PanicKind$LetAssert$end = (value) => value.end;
|
||||
export const PanicKind$LetAssert$1 = (value) => value.end;
|
||||
export const PanicKind$LetAssert$pattern_start = (value) => value.pattern_start;
|
||||
export const PanicKind$LetAssert$2 = (value) => value.pattern_start;
|
||||
export const PanicKind$LetAssert$pattern_end = (value) => value.pattern_end;
|
||||
export const PanicKind$LetAssert$3 = (value) => value.pattern_end;
|
||||
export const PanicKind$LetAssert$value = (value) => value.value;
|
||||
export const PanicKind$LetAssert$4 = (value) => value.value;
|
||||
|
||||
export class Assert extends $CustomType {
|
||||
constructor(start, end, expression_start, kind) {
|
||||
super();
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
this.expression_start = expression_start;
|
||||
this.kind = kind;
|
||||
}
|
||||
}
|
||||
export const PanicKind$Assert = (start, end, expression_start, kind) =>
|
||||
new Assert(start, end, expression_start, kind);
|
||||
export const PanicKind$isAssert = (value) => value instanceof Assert;
|
||||
export const PanicKind$Assert$start = (value) => value.start;
|
||||
export const PanicKind$Assert$0 = (value) => value.start;
|
||||
export const PanicKind$Assert$end = (value) => value.end;
|
||||
export const PanicKind$Assert$1 = (value) => value.end;
|
||||
export const PanicKind$Assert$expression_start = (value) =>
|
||||
value.expression_start;
|
||||
export const PanicKind$Assert$2 = (value) => value.expression_start;
|
||||
export const PanicKind$Assert$kind = (value) => value.kind;
|
||||
export const PanicKind$Assert$3 = (value) => value.kind;
|
||||
|
||||
export class BinaryOperator extends $CustomType {
|
||||
constructor(operator, left, right) {
|
||||
super();
|
||||
this.operator = operator;
|
||||
this.left = left;
|
||||
this.right = right;
|
||||
}
|
||||
}
|
||||
export const AssertKind$BinaryOperator = (operator, left, right) =>
|
||||
new BinaryOperator(operator, left, right);
|
||||
export const AssertKind$isBinaryOperator = (value) =>
|
||||
value instanceof BinaryOperator;
|
||||
export const AssertKind$BinaryOperator$operator = (value) => value.operator;
|
||||
export const AssertKind$BinaryOperator$0 = (value) => value.operator;
|
||||
export const AssertKind$BinaryOperator$left = (value) => value.left;
|
||||
export const AssertKind$BinaryOperator$1 = (value) => value.left;
|
||||
export const AssertKind$BinaryOperator$right = (value) => value.right;
|
||||
export const AssertKind$BinaryOperator$2 = (value) => value.right;
|
||||
|
||||
export class FunctionCall extends $CustomType {
|
||||
constructor(arguments$) {
|
||||
super();
|
||||
this.arguments = arguments$;
|
||||
}
|
||||
}
|
||||
export const AssertKind$FunctionCall = (arguments$) =>
|
||||
new FunctionCall(arguments$);
|
||||
export const AssertKind$isFunctionCall = (value) =>
|
||||
value instanceof FunctionCall;
|
||||
export const AssertKind$FunctionCall$arguments = (value) => value.arguments;
|
||||
export const AssertKind$FunctionCall$0 = (value) => value.arguments;
|
||||
|
||||
export class OtherExpression extends $CustomType {
|
||||
constructor(expression) {
|
||||
super();
|
||||
this.expression = expression;
|
||||
}
|
||||
}
|
||||
export const AssertKind$OtherExpression = (expression) =>
|
||||
new OtherExpression(expression);
|
||||
export const AssertKind$isOtherExpression = (value) =>
|
||||
value instanceof OtherExpression;
|
||||
export const AssertKind$OtherExpression$expression = (value) =>
|
||||
value.expression;
|
||||
export const AssertKind$OtherExpression$0 = (value) => value.expression;
|
||||
|
||||
export class AssertedExpression extends $CustomType {
|
||||
constructor(start, end, kind) {
|
||||
super();
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
this.kind = kind;
|
||||
}
|
||||
}
|
||||
export const AssertedExpression$AssertedExpression = (start, end, kind) =>
|
||||
new AssertedExpression(start, end, kind);
|
||||
export const AssertedExpression$isAssertedExpression = (value) =>
|
||||
value instanceof AssertedExpression;
|
||||
export const AssertedExpression$AssertedExpression$start = (value) =>
|
||||
value.start;
|
||||
export const AssertedExpression$AssertedExpression$0 = (value) => value.start;
|
||||
export const AssertedExpression$AssertedExpression$end = (value) => value.end;
|
||||
export const AssertedExpression$AssertedExpression$1 = (value) => value.end;
|
||||
export const AssertedExpression$AssertedExpression$kind = (value) => value.kind;
|
||||
export const AssertedExpression$AssertedExpression$2 = (value) => value.kind;
|
||||
|
||||
export class Literal extends $CustomType {
|
||||
constructor(value) {
|
||||
super();
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
export const ExpressionKind$Literal = (value) => new Literal(value);
|
||||
export const ExpressionKind$isLiteral = (value) => value instanceof Literal;
|
||||
export const ExpressionKind$Literal$value = (value) => value.value;
|
||||
export const ExpressionKind$Literal$0 = (value) => value.value;
|
||||
|
||||
export class Expression extends $CustomType {
|
||||
constructor(value) {
|
||||
super();
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
export const ExpressionKind$Expression = (value) => new Expression(value);
|
||||
export const ExpressionKind$isExpression = (value) =>
|
||||
value instanceof Expression;
|
||||
export const ExpressionKind$Expression$value = (value) => value.value;
|
||||
export const ExpressionKind$Expression$0 = (value) => value.value;
|
||||
|
||||
export class Unevaluated extends $CustomType {}
|
||||
export const ExpressionKind$Unevaluated = () => new Unevaluated();
|
||||
export const ExpressionKind$isUnevaluated = (value) =>
|
||||
value instanceof Unevaluated;
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
-module(gleeunit_gleam_panic_ffi).
|
||||
-export([from_dynamic/1]).
|
||||
|
||||
from_dynamic(#{
|
||||
gleam_error := assert,
|
||||
start := Start,
|
||||
'end' := End,
|
||||
expression_start := EStart
|
||||
} = E) ->
|
||||
wrap(E, {assert, Start, End, EStart, assert_kind(E)});
|
||||
from_dynamic(#{
|
||||
gleam_error := let_assert,
|
||||
start := Start,
|
||||
'end' := End,
|
||||
pattern_start := PStart,
|
||||
pattern_end := PEnd,
|
||||
value := Value
|
||||
} = E) ->
|
||||
wrap(E, {let_assert, Start, End, PStart, PEnd, Value});
|
||||
from_dynamic(#{gleam_error := panic} = E) ->
|
||||
wrap(E, panic);
|
||||
from_dynamic(#{gleam_error := todo} = E) ->
|
||||
wrap(E, todo);
|
||||
from_dynamic(_) ->
|
||||
{error, nil}.
|
||||
|
||||
assert_kind(#{kind := binary_operator, left := L, right := R, operator := O}) ->
|
||||
{binary_operator, atom_to_binary(O), expression(L), expression(R)};
|
||||
assert_kind(#{kind := function_call, arguments := Arguments}) ->
|
||||
{function_call, lists:map(fun expression/1, Arguments)};
|
||||
assert_kind(#{kind := expression, expression := Expression}) ->
|
||||
{other_expression, expression(Expression)}.
|
||||
|
||||
expression(#{start := S, 'end' := E, kind := literal, value := Value}) ->
|
||||
{asserted_expression, S, E, {literal, Value}};
|
||||
expression(#{start := S, 'end' := E, kind := expression, value := Value}) ->
|
||||
{asserted_expression, S, E, {expression, Value}};
|
||||
expression(#{start := S, 'end' := E, kind := unevaluated}) ->
|
||||
{asserted_expression, S, E, unevaluated}.
|
||||
|
||||
wrap(#{
|
||||
gleam_error := _,
|
||||
file := File,
|
||||
message := Message,
|
||||
module := Module,
|
||||
function := Function,
|
||||
line := Line
|
||||
}, Kind) ->
|
||||
{ok, {gleam_panic, Message, File, Module, Function, Line, Kind}}.
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
import { Result$Ok, Result$Error, List$Empty, List$NonEmpty } from "../../gleam.mjs";
|
||||
import {
|
||||
GleamPanic$GleamPanic,
|
||||
PanicKind$Todo,
|
||||
PanicKind$Panic,
|
||||
PanicKind$LetAssert,
|
||||
PanicKind$Assert,
|
||||
AssertKind$BinaryOperator,
|
||||
AssertKind$FunctionCall,
|
||||
AssertKind$OtherExpression,
|
||||
AssertedExpression$AssertedExpression,
|
||||
ExpressionKind$Literal,
|
||||
ExpressionKind$Expression,
|
||||
ExpressionKind$Unevaluated,
|
||||
} from "./gleam_panic.mjs";
|
||||
|
||||
export function from_dynamic(error) {
|
||||
if (!(error instanceof globalThis.Error) || !error.gleam_error) {
|
||||
return Result$Error(undefined);
|
||||
}
|
||||
|
||||
if (error.gleam_error === "todo") {
|
||||
return wrap(error, PanicKind$Todo());
|
||||
}
|
||||
|
||||
if (error.gleam_error === "panic") {
|
||||
return wrap(error, PanicKind$Panic());
|
||||
}
|
||||
|
||||
if (error.gleam_error === "let_assert") {
|
||||
let kind = PanicKind$LetAssert(
|
||||
error.start,
|
||||
error.end,
|
||||
error.pattern_start,
|
||||
error.pattern_end,
|
||||
error.value,
|
||||
);
|
||||
return wrap(error, kind);
|
||||
}
|
||||
|
||||
if (error.gleam_error === "assert") {
|
||||
let kind = PanicKind$Assert(
|
||||
error.start,
|
||||
error.end,
|
||||
error.expression_start,
|
||||
assert_kind(error),
|
||||
);
|
||||
return wrap(error, kind);
|
||||
}
|
||||
|
||||
return Result$Error(undefined);
|
||||
}
|
||||
|
||||
function assert_kind(error) {
|
||||
if (error.kind == "binary_operator") {
|
||||
return AssertKind$BinaryOperator(
|
||||
error.operator,
|
||||
expression(error.left),
|
||||
expression(error.right),
|
||||
);
|
||||
}
|
||||
|
||||
if (error.kind == "function_call") {
|
||||
let list = List$Empty();
|
||||
let i = error.arguments.length;
|
||||
while (i--) {
|
||||
list = List$NonEmpty(expression(error.arguments[i]), list);
|
||||
}
|
||||
return AssertKind$FunctionCall(list);
|
||||
}
|
||||
|
||||
return AssertKind$OtherExpression(expression(error.expression));
|
||||
}
|
||||
|
||||
function expression(data) {
|
||||
const expression = AssertedExpression$AssertedExpression(data.start, data.end, undefined);
|
||||
if (data.kind == "literal") {
|
||||
expression.kind = ExpressionKind$Literal(data.value);
|
||||
} else if (data.kind == "expression") {
|
||||
expression.kind = ExpressionKind$Expression(data.value);
|
||||
} else {
|
||||
expression.kind = ExpressionKind$Unevaluated();
|
||||
}
|
||||
return expression;
|
||||
}
|
||||
|
||||
function wrap(e, kind) {
|
||||
return Result$Ok(
|
||||
GleamPanic$GleamPanic(e.message, e.file, e.module, e.function, e.line, kind),
|
||||
);
|
||||
}
|
||||
256
build/dev/javascript/gleeunit/gleeunit/internal/reporting.mjs
Normal file
256
build/dev/javascript/gleeunit/gleeunit/internal/reporting.mjs
Normal file
|
|
@ -0,0 +1,256 @@
|
|||
import * as $bit_array from "../../../gleam_stdlib/gleam/bit_array.mjs";
|
||||
import * as $dynamic from "../../../gleam_stdlib/gleam/dynamic.mjs";
|
||||
import * as $int from "../../../gleam_stdlib/gleam/int.mjs";
|
||||
import * as $io from "../../../gleam_stdlib/gleam/io.mjs";
|
||||
import * as $list from "../../../gleam_stdlib/gleam/list.mjs";
|
||||
import * as $option from "../../../gleam_stdlib/gleam/option.mjs";
|
||||
import * as $result from "../../../gleam_stdlib/gleam/result.mjs";
|
||||
import * as $string from "../../../gleam_stdlib/gleam/string.mjs";
|
||||
import { Ok, Error, toList, CustomType as $CustomType } from "../../gleam.mjs";
|
||||
import * as $gleam_panic from "../../gleeunit/internal/gleam_panic.mjs";
|
||||
import { read_file as read_file_text } from "../../gleeunit_ffi.mjs";
|
||||
|
||||
export class State extends $CustomType {
|
||||
constructor(passed, failed, skipped) {
|
||||
super();
|
||||
this.passed = passed;
|
||||
this.failed = failed;
|
||||
this.skipped = skipped;
|
||||
}
|
||||
}
|
||||
export const State$State = (passed, failed, skipped) =>
|
||||
new State(passed, failed, skipped);
|
||||
export const State$isState = (value) => value instanceof State;
|
||||
export const State$State$passed = (value) => value.passed;
|
||||
export const State$State$0 = (value) => value.passed;
|
||||
export const State$State$failed = (value) => value.failed;
|
||||
export const State$State$1 = (value) => value.failed;
|
||||
export const State$State$skipped = (value) => value.skipped;
|
||||
export const State$State$2 = (value) => value.skipped;
|
||||
|
||||
export function new_state() {
|
||||
return new State(0, 0, 0);
|
||||
}
|
||||
|
||||
function bold(text) {
|
||||
return ("\u{001b}[1m" + text) + "\u{001b}[22m";
|
||||
}
|
||||
|
||||
function cyan(text) {
|
||||
return ("\u{001b}[36m" + text) + "\u{001b}[39m";
|
||||
}
|
||||
|
||||
function code_snippet(src, start, end) {
|
||||
let _pipe = $result.try$(
|
||||
$option.to_result(src, undefined),
|
||||
(src) => {
|
||||
return $result.try$(
|
||||
$bit_array.slice(src, start, end - start),
|
||||
(snippet) => {
|
||||
return $result.try$(
|
||||
$bit_array.to_string(snippet),
|
||||
(snippet) => {
|
||||
let snippet$1 = ((cyan(" code") + ": ") + snippet) + "\n";
|
||||
return new Ok(snippet$1);
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
return $result.unwrap(_pipe, "");
|
||||
}
|
||||
|
||||
function yellow(text) {
|
||||
return ("\u{001b}[33m" + text) + "\u{001b}[39m";
|
||||
}
|
||||
|
||||
export function test_skipped(state, module, function$) {
|
||||
$io.print(((("\n" + module) + ".") + function$) + yellow(" skipped"));
|
||||
return new State(state.passed, state.failed, state.skipped + 1);
|
||||
}
|
||||
|
||||
function green(text) {
|
||||
return ("\u{001b}[32m" + text) + "\u{001b}[39m";
|
||||
}
|
||||
|
||||
export function test_passed(state) {
|
||||
$io.print(green("."));
|
||||
return new State(state.passed + 1, state.failed, state.skipped);
|
||||
}
|
||||
|
||||
function red(text) {
|
||||
return ("\u{001b}[31m" + text) + "\u{001b}[39m";
|
||||
}
|
||||
|
||||
export function finished(state) {
|
||||
let $ = state.failed;
|
||||
if ($ === 0) {
|
||||
let $1 = state.skipped;
|
||||
if ($1 === 0) {
|
||||
let $2 = state.passed;
|
||||
if ($2 === 0) {
|
||||
$io.println("\nNo tests found!");
|
||||
return 1;
|
||||
} else {
|
||||
let message = ("\n" + $int.to_string(state.passed)) + " passed, no failures";
|
||||
$io.println(green(message));
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
let message = ((("\n" + $int.to_string(state.passed)) + " passed, 0 failures, ") + $int.to_string(
|
||||
state.skipped,
|
||||
)) + " skipped";
|
||||
$io.println(yellow(message));
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
let $1 = state.skipped;
|
||||
if ($1 === 0) {
|
||||
let message = ((("\n" + $int.to_string(state.passed)) + " passed, ") + $int.to_string(
|
||||
state.failed,
|
||||
)) + " failures";
|
||||
$io.println(red(message));
|
||||
return 1;
|
||||
} else {
|
||||
let message = ((((("\n" + $int.to_string(state.passed)) + " passed, ") + $int.to_string(
|
||||
state.failed,
|
||||
)) + " failures, ") + $int.to_string(state.skipped)) + " skipped";
|
||||
$io.println(red(message));
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function eunit_missing() {
|
||||
let message = bold(red("Error")) + ": EUnit libraries not found.\n\nYour Erlang installation seems to be incomplete. If you installed Erlang using\na package manager ensure that you have installed the full Erlang\ndistribution instead of a stripped-down version.\n";
|
||||
$io.print_error(message);
|
||||
return new Error(undefined);
|
||||
}
|
||||
|
||||
function grey(text) {
|
||||
return ("\u{001b}[90m" + text) + "\u{001b}[39m";
|
||||
}
|
||||
|
||||
function format_unknown(module, function$, error) {
|
||||
return $string.concat(
|
||||
toList([
|
||||
grey((module + ".") + function$) + "\n",
|
||||
"An unexpected error occurred:\n",
|
||||
"\n",
|
||||
(" " + $string.inspect(error)) + "\n",
|
||||
]),
|
||||
);
|
||||
}
|
||||
|
||||
function inspect_value(value) {
|
||||
let $ = value.kind;
|
||||
if ($ instanceof $gleam_panic.Literal) {
|
||||
return grey("literal");
|
||||
} else if ($ instanceof $gleam_panic.Expression) {
|
||||
let value$1 = $.value;
|
||||
return $string.inspect(value$1);
|
||||
} else {
|
||||
return grey("unevaluated");
|
||||
}
|
||||
}
|
||||
|
||||
function assert_value(name, value) {
|
||||
return ((cyan(name) + ": ") + inspect_value(value)) + "\n";
|
||||
}
|
||||
|
||||
function assert_info(kind) {
|
||||
if (kind instanceof $gleam_panic.BinaryOperator) {
|
||||
let left = kind.left;
|
||||
let right = kind.right;
|
||||
return $string.concat(
|
||||
toList([assert_value(" left", left), assert_value("right", right)]),
|
||||
);
|
||||
} else if (kind instanceof $gleam_panic.FunctionCall) {
|
||||
let arguments$ = kind.arguments;
|
||||
let _pipe = arguments$;
|
||||
let _pipe$1 = $list.index_map(
|
||||
_pipe,
|
||||
(e, i) => {
|
||||
let number = $string.pad_start($int.to_string(i), 5, " ");
|
||||
return assert_value(number, e);
|
||||
},
|
||||
);
|
||||
return $string.concat(_pipe$1);
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
function format_gleam_error(error, module, function$, src) {
|
||||
let location = grey((error.file + ":") + $int.to_string(error.line));
|
||||
let $ = error.kind;
|
||||
if ($ instanceof $gleam_panic.Todo) {
|
||||
return $string.concat(
|
||||
toList([
|
||||
((bold(yellow("todo")) + " ") + location) + "\n",
|
||||
((((cyan(" test") + ": ") + module) + ".") + function$) + "\n",
|
||||
((cyan(" info") + ": ") + error.message) + "\n",
|
||||
]),
|
||||
);
|
||||
} else if ($ instanceof $gleam_panic.Panic) {
|
||||
return $string.concat(
|
||||
toList([
|
||||
((bold(red("panic")) + " ") + location) + "\n",
|
||||
((((cyan(" test") + ": ") + module) + ".") + function$) + "\n",
|
||||
((cyan(" info") + ": ") + error.message) + "\n",
|
||||
]),
|
||||
);
|
||||
} else if ($ instanceof $gleam_panic.LetAssert) {
|
||||
let start = $.start;
|
||||
let end = $.end;
|
||||
let value = $.value;
|
||||
return $string.concat(
|
||||
toList([
|
||||
((bold(red("let assert")) + " ") + location) + "\n",
|
||||
((((cyan(" test") + ": ") + module) + ".") + function$) + "\n",
|
||||
code_snippet(src, start, end),
|
||||
((cyan("value") + ": ") + $string.inspect(value)) + "\n",
|
||||
((cyan(" info") + ": ") + error.message) + "\n",
|
||||
]),
|
||||
);
|
||||
} else {
|
||||
let start = $.start;
|
||||
let end = $.end;
|
||||
let kind = $.kind;
|
||||
return $string.concat(
|
||||
toList([
|
||||
((bold(red("assert")) + " ") + location) + "\n",
|
||||
((((cyan(" test") + ": ") + module) + ".") + function$) + "\n",
|
||||
code_snippet(src, start, end),
|
||||
assert_info(kind),
|
||||
((cyan(" info") + ": ") + error.message) + "\n",
|
||||
]),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function read_file(path) {
|
||||
let $ = read_file_text(path);
|
||||
if ($ instanceof Ok) {
|
||||
let text = $[0];
|
||||
return new Ok($bit_array.from_string(text));
|
||||
} else {
|
||||
return $;
|
||||
}
|
||||
}
|
||||
|
||||
export function test_failed(state, module, function$, error) {
|
||||
let _block;
|
||||
let $ = $gleam_panic.from_dynamic(error);
|
||||
if ($ instanceof Ok) {
|
||||
let error$1 = $[0];
|
||||
let src = $option.from_result(read_file(error$1.file));
|
||||
_block = format_gleam_error(error$1, module, function$, src);
|
||||
} else {
|
||||
_block = format_unknown(module, function$, error);
|
||||
}
|
||||
let message = _block;
|
||||
$io.print("\n" + message);
|
||||
return new State(state.passed, state.failed + 1, state.skipped);
|
||||
}
|
||||
135
build/dev/javascript/gleeunit/gleeunit/should.mjs
Normal file
135
build/dev/javascript/gleeunit/gleeunit/should.mjs
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
import * as $option from "../../gleam_stdlib/gleam/option.mjs";
|
||||
import { None, Some } from "../../gleam_stdlib/gleam/option.mjs";
|
||||
import * as $string from "../../gleam_stdlib/gleam/string.mjs";
|
||||
import { Ok, Error, toList, makeError, isEqual } from "../gleam.mjs";
|
||||
|
||||
const FILEPATH = "src/gleeunit/should.gleam";
|
||||
|
||||
export function equal(a, b) {
|
||||
let $ = isEqual(a, b);
|
||||
if ($) {
|
||||
return undefined;
|
||||
} else {
|
||||
throw makeError(
|
||||
"panic",
|
||||
FILEPATH,
|
||||
"gleeunit/should",
|
||||
10,
|
||||
"equal",
|
||||
$string.concat(
|
||||
toList([
|
||||
"\n",
|
||||
$string.inspect(a),
|
||||
"\nshould equal\n",
|
||||
$string.inspect(b),
|
||||
]),
|
||||
),
|
||||
{}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export function not_equal(a, b) {
|
||||
let $ = !isEqual(a, b);
|
||||
if ($) {
|
||||
return undefined;
|
||||
} else {
|
||||
throw makeError(
|
||||
"panic",
|
||||
FILEPATH,
|
||||
"gleeunit/should",
|
||||
23,
|
||||
"not_equal",
|
||||
$string.concat(
|
||||
toList([
|
||||
"\n",
|
||||
$string.inspect(a),
|
||||
"\nshould not equal\n",
|
||||
$string.inspect(b),
|
||||
]),
|
||||
),
|
||||
{}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export function be_ok(a) {
|
||||
if (a instanceof Ok) {
|
||||
let value = a[0];
|
||||
return value;
|
||||
} else {
|
||||
throw makeError(
|
||||
"panic",
|
||||
FILEPATH,
|
||||
"gleeunit/should",
|
||||
35,
|
||||
"be_ok",
|
||||
$string.concat(toList(["\n", $string.inspect(a), "\nshould be ok"])),
|
||||
{}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export function be_error(a) {
|
||||
if (a instanceof Error) {
|
||||
let error = a[0];
|
||||
return error;
|
||||
} else {
|
||||
throw makeError(
|
||||
"panic",
|
||||
FILEPATH,
|
||||
"gleeunit/should",
|
||||
42,
|
||||
"be_error",
|
||||
$string.concat(toList(["\n", $string.inspect(a), "\nshould be error"])),
|
||||
{}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export function be_some(a) {
|
||||
if (a instanceof Some) {
|
||||
let value = a[0];
|
||||
return value;
|
||||
} else {
|
||||
throw makeError(
|
||||
"panic",
|
||||
FILEPATH,
|
||||
"gleeunit/should",
|
||||
49,
|
||||
"be_some",
|
||||
$string.concat(toList(["\n", $string.inspect(a), "\nshould be some"])),
|
||||
{}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export function be_none(a) {
|
||||
if (a instanceof None) {
|
||||
return undefined;
|
||||
} else {
|
||||
throw makeError(
|
||||
"panic",
|
||||
FILEPATH,
|
||||
"gleeunit/should",
|
||||
56,
|
||||
"be_none",
|
||||
$string.concat(toList(["\n", $string.inspect(a), "\nshould be none"])),
|
||||
{}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export function be_true(actual) {
|
||||
let _pipe = actual;
|
||||
return equal(_pipe, true);
|
||||
}
|
||||
|
||||
export function be_false(actual) {
|
||||
let _pipe = actual;
|
||||
return equal(_pipe, false);
|
||||
}
|
||||
|
||||
export function fail() {
|
||||
return be_true(false);
|
||||
}
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
-module(gleeunit@internal@gleam_panic).
|
||||
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
|
||||
-define(FILEPATH, "src/gleeunit/internal/gleam_panic.gleam").
|
||||
-export([from_dynamic/1]).
|
||||
-export_type([gleam_panic/0, panic_kind/0, assert_kind/0, asserted_expression/0, expression_kind/0]).
|
||||
|
||||
-if(?OTP_RELEASE >= 27).
|
||||
-define(MODULEDOC(Str), -moduledoc(Str)).
|
||||
-define(DOC(Str), -doc(Str)).
|
||||
-else.
|
||||
-define(MODULEDOC(Str), -compile([])).
|
||||
-define(DOC(Str), -compile([])).
|
||||
-endif.
|
||||
|
||||
?MODULEDOC(false).
|
||||
|
||||
-type gleam_panic() :: {gleam_panic,
|
||||
binary(),
|
||||
binary(),
|
||||
binary(),
|
||||
binary(),
|
||||
integer(),
|
||||
panic_kind()}.
|
||||
|
||||
-type panic_kind() :: todo |
|
||||
panic |
|
||||
{let_assert,
|
||||
integer(),
|
||||
integer(),
|
||||
integer(),
|
||||
integer(),
|
||||
gleam@dynamic:dynamic_()} |
|
||||
{assert, integer(), integer(), integer(), assert_kind()}.
|
||||
|
||||
-type assert_kind() :: {binary_operator,
|
||||
binary(),
|
||||
asserted_expression(),
|
||||
asserted_expression()} |
|
||||
{function_call, list(asserted_expression())} |
|
||||
{other_expression, asserted_expression()}.
|
||||
|
||||
-type asserted_expression() :: {asserted_expression,
|
||||
integer(),
|
||||
integer(),
|
||||
expression_kind()}.
|
||||
|
||||
-type expression_kind() :: {literal, gleam@dynamic:dynamic_()} |
|
||||
{expression, gleam@dynamic:dynamic_()} |
|
||||
unevaluated.
|
||||
|
||||
-file("src/gleeunit/internal/gleam_panic.gleam", 49).
|
||||
?DOC(false).
|
||||
-spec from_dynamic(gleam@dynamic:dynamic_()) -> {ok, gleam_panic()} |
|
||||
{error, nil}.
|
||||
from_dynamic(Data) ->
|
||||
gleeunit_gleam_panic_ffi:from_dynamic(Data).
|
||||
343
build/dev/javascript/gleeunit/gleeunit@internal@reporting.erl
Normal file
343
build/dev/javascript/gleeunit/gleeunit@internal@reporting.erl
Normal file
|
|
@ -0,0 +1,343 @@
|
|||
-module(gleeunit@internal@reporting).
|
||||
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
|
||||
-define(FILEPATH, "src/gleeunit/internal/reporting.gleam").
|
||||
-export([new_state/0, test_skipped/3, test_passed/1, finished/1, eunit_missing/0, test_failed/4]).
|
||||
-export_type([state/0]).
|
||||
|
||||
-if(?OTP_RELEASE >= 27).
|
||||
-define(MODULEDOC(Str), -moduledoc(Str)).
|
||||
-define(DOC(Str), -doc(Str)).
|
||||
-else.
|
||||
-define(MODULEDOC(Str), -compile([])).
|
||||
-define(DOC(Str), -compile([])).
|
||||
-endif.
|
||||
|
||||
?MODULEDOC(false).
|
||||
|
||||
-type state() :: {state, integer(), integer(), integer()}.
|
||||
|
||||
-file("src/gleeunit/internal/reporting.gleam", 15).
|
||||
?DOC(false).
|
||||
-spec new_state() -> state().
|
||||
new_state() ->
|
||||
{state, 0, 0, 0}.
|
||||
|
||||
-file("src/gleeunit/internal/reporting.gleam", 207).
|
||||
?DOC(false).
|
||||
-spec bold(binary()) -> binary().
|
||||
bold(Text) ->
|
||||
<<<<"\x{001b}[1m"/utf8, Text/binary>>/binary, "\x{001b}[22m"/utf8>>.
|
||||
|
||||
-file("src/gleeunit/internal/reporting.gleam", 211).
|
||||
?DOC(false).
|
||||
-spec cyan(binary()) -> binary().
|
||||
cyan(Text) ->
|
||||
<<<<"\x{001b}[36m"/utf8, Text/binary>>/binary, "\x{001b}[39m"/utf8>>.
|
||||
|
||||
-file("src/gleeunit/internal/reporting.gleam", 191).
|
||||
?DOC(false).
|
||||
-spec code_snippet(gleam@option:option(bitstring()), integer(), integer()) -> binary().
|
||||
code_snippet(Src, Start, End) ->
|
||||
_pipe = begin
|
||||
gleam@result:'try'(
|
||||
gleam@option:to_result(Src, nil),
|
||||
fun(Src@1) ->
|
||||
gleam@result:'try'(
|
||||
gleam_stdlib:bit_array_slice(Src@1, Start, End - Start),
|
||||
fun(Snippet) ->
|
||||
gleam@result:'try'(
|
||||
gleam@bit_array:to_string(Snippet),
|
||||
fun(Snippet@1) ->
|
||||
Snippet@2 = <<<<<<(cyan(<<" code"/utf8>>))/binary,
|
||||
": "/utf8>>/binary,
|
||||
Snippet@1/binary>>/binary,
|
||||
"\n"/utf8>>,
|
||||
{ok, Snippet@2}
|
||||
end
|
||||
)
|
||||
end
|
||||
)
|
||||
end
|
||||
)
|
||||
end,
|
||||
gleam@result:unwrap(_pipe, <<""/utf8>>).
|
||||
|
||||
-file("src/gleeunit/internal/reporting.gleam", 215).
|
||||
?DOC(false).
|
||||
-spec yellow(binary()) -> binary().
|
||||
yellow(Text) ->
|
||||
<<<<"\x{001b}[33m"/utf8, Text/binary>>/binary, "\x{001b}[39m"/utf8>>.
|
||||
|
||||
-file("src/gleeunit/internal/reporting.gleam", 202).
|
||||
?DOC(false).
|
||||
-spec test_skipped(state(), binary(), binary()) -> state().
|
||||
test_skipped(State, Module, Function) ->
|
||||
gleam_stdlib:print(
|
||||
<<<<<<<<"\n"/utf8, Module/binary>>/binary, "."/utf8>>/binary,
|
||||
Function/binary>>/binary,
|
||||
(yellow(<<" skipped"/utf8>>))/binary>>
|
||||
),
|
||||
{state,
|
||||
erlang:element(2, State),
|
||||
erlang:element(3, State),
|
||||
erlang:element(4, State) + 1}.
|
||||
|
||||
-file("src/gleeunit/internal/reporting.gleam", 219).
|
||||
?DOC(false).
|
||||
-spec green(binary()) -> binary().
|
||||
green(Text) ->
|
||||
<<<<"\x{001b}[32m"/utf8, Text/binary>>/binary, "\x{001b}[39m"/utf8>>.
|
||||
|
||||
-file("src/gleeunit/internal/reporting.gleam", 66).
|
||||
?DOC(false).
|
||||
-spec test_passed(state()) -> state().
|
||||
test_passed(State) ->
|
||||
gleam_stdlib:print(green(<<"."/utf8>>)),
|
||||
{state,
|
||||
erlang:element(2, State) + 1,
|
||||
erlang:element(3, State),
|
||||
erlang:element(4, State)}.
|
||||
|
||||
-file("src/gleeunit/internal/reporting.gleam", 223).
|
||||
?DOC(false).
|
||||
-spec red(binary()) -> binary().
|
||||
red(Text) ->
|
||||
<<<<"\x{001b}[31m"/utf8, Text/binary>>/binary, "\x{001b}[39m"/utf8>>.
|
||||
|
||||
-file("src/gleeunit/internal/reporting.gleam", 19).
|
||||
?DOC(false).
|
||||
-spec finished(state()) -> integer().
|
||||
finished(State) ->
|
||||
case State of
|
||||
{state, 0, 0, 0} ->
|
||||
gleam_stdlib:println(<<"\nNo tests found!"/utf8>>),
|
||||
1;
|
||||
|
||||
{state, _, 0, 0} ->
|
||||
Message = <<<<"\n"/utf8,
|
||||
(erlang:integer_to_binary(erlang:element(2, State)))/binary>>/binary,
|
||||
" passed, no failures"/utf8>>,
|
||||
gleam_stdlib:println(green(Message)),
|
||||
0;
|
||||
|
||||
{state, _, _, 0} ->
|
||||
Message@1 = <<<<<<<<"\n"/utf8,
|
||||
(erlang:integer_to_binary(erlang:element(2, State)))/binary>>/binary,
|
||||
" passed, "/utf8>>/binary,
|
||||
(erlang:integer_to_binary(erlang:element(3, State)))/binary>>/binary,
|
||||
" failures"/utf8>>,
|
||||
gleam_stdlib:println(red(Message@1)),
|
||||
1;
|
||||
|
||||
{state, _, 0, _} ->
|
||||
Message@2 = <<<<<<<<"\n"/utf8,
|
||||
(erlang:integer_to_binary(erlang:element(2, State)))/binary>>/binary,
|
||||
" passed, 0 failures, "/utf8>>/binary,
|
||||
(erlang:integer_to_binary(erlang:element(4, State)))/binary>>/binary,
|
||||
" skipped"/utf8>>,
|
||||
gleam_stdlib:println(yellow(Message@2)),
|
||||
1;
|
||||
|
||||
{state, _, _, _} ->
|
||||
Message@3 = <<<<<<<<<<<<"\n"/utf8,
|
||||
(erlang:integer_to_binary(
|
||||
erlang:element(2, State)
|
||||
))/binary>>/binary,
|
||||
" passed, "/utf8>>/binary,
|
||||
(erlang:integer_to_binary(erlang:element(3, State)))/binary>>/binary,
|
||||
" failures, "/utf8>>/binary,
|
||||
(erlang:integer_to_binary(erlang:element(4, State)))/binary>>/binary,
|
||||
" skipped"/utf8>>,
|
||||
gleam_stdlib:println(red(Message@3)),
|
||||
1
|
||||
end.
|
||||
|
||||
-file("src/gleeunit/internal/reporting.gleam", 89).
|
||||
?DOC(false).
|
||||
-spec eunit_missing() -> {ok, any()} | {error, nil}.
|
||||
eunit_missing() ->
|
||||
Message = <<(bold(red(<<"Error"/utf8>>)))/binary,
|
||||
": EUnit libraries not found.
|
||||
|
||||
Your Erlang installation seems to be incomplete. If you installed Erlang using
|
||||
a package manager ensure that you have installed the full Erlang
|
||||
distribution instead of a stripped-down version.
|
||||
"/utf8>>,
|
||||
gleam_stdlib:print_error(Message),
|
||||
{error, nil}.
|
||||
|
||||
-file("src/gleeunit/internal/reporting.gleam", 227).
|
||||
?DOC(false).
|
||||
-spec grey(binary()) -> binary().
|
||||
grey(Text) ->
|
||||
<<<<"\x{001b}[90m"/utf8, Text/binary>>/binary, "\x{001b}[39m"/utf8>>.
|
||||
|
||||
-file("src/gleeunit/internal/reporting.gleam", 100).
|
||||
?DOC(false).
|
||||
-spec format_unknown(binary(), binary(), gleam@dynamic:dynamic_()) -> binary().
|
||||
format_unknown(Module, Function, Error) ->
|
||||
erlang:list_to_binary(
|
||||
[<<(grey(<<<<Module/binary, "."/utf8>>/binary, Function/binary>>))/binary,
|
||||
"\n"/utf8>>,
|
||||
<<"An unexpected error occurred:\n"/utf8>>,
|
||||
<<"\n"/utf8>>,
|
||||
<<<<" "/utf8, (gleam@string:inspect(Error))/binary>>/binary,
|
||||
"\n"/utf8>>]
|
||||
).
|
||||
|
||||
-file("src/gleeunit/internal/reporting.gleam", 183).
|
||||
?DOC(false).
|
||||
-spec inspect_value(gleeunit@internal@gleam_panic:asserted_expression()) -> binary().
|
||||
inspect_value(Value) ->
|
||||
case erlang:element(4, Value) of
|
||||
unevaluated ->
|
||||
grey(<<"unevaluated"/utf8>>);
|
||||
|
||||
{literal, _} ->
|
||||
grey(<<"literal"/utf8>>);
|
||||
|
||||
{expression, Value@1} ->
|
||||
gleam@string:inspect(Value@1)
|
||||
end.
|
||||
|
||||
-file("src/gleeunit/internal/reporting.gleam", 179).
|
||||
?DOC(false).
|
||||
-spec assert_value(
|
||||
binary(),
|
||||
gleeunit@internal@gleam_panic:asserted_expression()
|
||||
) -> binary().
|
||||
assert_value(Name, Value) ->
|
||||
<<<<<<(cyan(Name))/binary, ": "/utf8>>/binary,
|
||||
(inspect_value(Value))/binary>>/binary,
|
||||
"\n"/utf8>>.
|
||||
|
||||
-file("src/gleeunit/internal/reporting.gleam", 160).
|
||||
?DOC(false).
|
||||
-spec assert_info(gleeunit@internal@gleam_panic:assert_kind()) -> binary().
|
||||
assert_info(Kind) ->
|
||||
case Kind of
|
||||
{binary_operator, _, Left, Right} ->
|
||||
erlang:list_to_binary(
|
||||
[assert_value(<<" left"/utf8>>, Left),
|
||||
assert_value(<<"right"/utf8>>, Right)]
|
||||
);
|
||||
|
||||
{function_call, Arguments} ->
|
||||
_pipe = Arguments,
|
||||
_pipe@1 = gleam@list:index_map(
|
||||
_pipe,
|
||||
fun(E, I) ->
|
||||
Number = gleam@string:pad_start(
|
||||
erlang:integer_to_binary(I),
|
||||
5,
|
||||
<<" "/utf8>>
|
||||
),
|
||||
assert_value(Number, E)
|
||||
end
|
||||
),
|
||||
erlang:list_to_binary(_pipe@1);
|
||||
|
||||
{other_expression, _} ->
|
||||
<<""/utf8>>
|
||||
end.
|
||||
|
||||
-file("src/gleeunit/internal/reporting.gleam", 113).
|
||||
?DOC(false).
|
||||
-spec format_gleam_error(
|
||||
gleeunit@internal@gleam_panic:gleam_panic(),
|
||||
binary(),
|
||||
binary(),
|
||||
gleam@option:option(bitstring())
|
||||
) -> binary().
|
||||
format_gleam_error(Error, Module, Function, Src) ->
|
||||
Location = grey(
|
||||
<<<<(erlang:element(3, Error))/binary, ":"/utf8>>/binary,
|
||||
(erlang:integer_to_binary(erlang:element(6, Error)))/binary>>
|
||||
),
|
||||
case erlang:element(7, Error) of
|
||||
panic ->
|
||||
erlang:list_to_binary(
|
||||
[<<<<<<(bold(red(<<"panic"/utf8>>)))/binary, " "/utf8>>/binary,
|
||||
Location/binary>>/binary,
|
||||
"\n"/utf8>>,
|
||||
<<<<<<<<<<(cyan(<<" test"/utf8>>))/binary, ": "/utf8>>/binary,
|
||||
Module/binary>>/binary,
|
||||
"."/utf8>>/binary,
|
||||
Function/binary>>/binary,
|
||||
"\n"/utf8>>,
|
||||
<<<<<<(cyan(<<" info"/utf8>>))/binary, ": "/utf8>>/binary,
|
||||
(erlang:element(2, Error))/binary>>/binary,
|
||||
"\n"/utf8>>]
|
||||
);
|
||||
|
||||
todo ->
|
||||
erlang:list_to_binary(
|
||||
[<<<<<<(bold(yellow(<<"todo"/utf8>>)))/binary, " "/utf8>>/binary,
|
||||
Location/binary>>/binary,
|
||||
"\n"/utf8>>,
|
||||
<<<<<<<<<<(cyan(<<" test"/utf8>>))/binary, ": "/utf8>>/binary,
|
||||
Module/binary>>/binary,
|
||||
"."/utf8>>/binary,
|
||||
Function/binary>>/binary,
|
||||
"\n"/utf8>>,
|
||||
<<<<<<(cyan(<<" info"/utf8>>))/binary, ": "/utf8>>/binary,
|
||||
(erlang:element(2, Error))/binary>>/binary,
|
||||
"\n"/utf8>>]
|
||||
);
|
||||
|
||||
{assert, Start, End, _, Kind} ->
|
||||
erlang:list_to_binary(
|
||||
[<<<<<<(bold(red(<<"assert"/utf8>>)))/binary, " "/utf8>>/binary,
|
||||
Location/binary>>/binary,
|
||||
"\n"/utf8>>,
|
||||
<<<<<<<<<<(cyan(<<" test"/utf8>>))/binary, ": "/utf8>>/binary,
|
||||
Module/binary>>/binary,
|
||||
"."/utf8>>/binary,
|
||||
Function/binary>>/binary,
|
||||
"\n"/utf8>>,
|
||||
code_snippet(Src, Start, End),
|
||||
assert_info(Kind),
|
||||
<<<<<<(cyan(<<" info"/utf8>>))/binary, ": "/utf8>>/binary,
|
||||
(erlang:element(2, Error))/binary>>/binary,
|
||||
"\n"/utf8>>]
|
||||
);
|
||||
|
||||
{let_assert, Start@1, End@1, _, _, Value} ->
|
||||
erlang:list_to_binary(
|
||||
[<<<<<<(bold(red(<<"let assert"/utf8>>)))/binary, " "/utf8>>/binary,
|
||||
Location/binary>>/binary,
|
||||
"\n"/utf8>>,
|
||||
<<<<<<<<<<(cyan(<<" test"/utf8>>))/binary, ": "/utf8>>/binary,
|
||||
Module/binary>>/binary,
|
||||
"."/utf8>>/binary,
|
||||
Function/binary>>/binary,
|
||||
"\n"/utf8>>,
|
||||
code_snippet(Src, Start@1, End@1),
|
||||
<<<<<<(cyan(<<"value"/utf8>>))/binary, ": "/utf8>>/binary,
|
||||
(gleam@string:inspect(Value))/binary>>/binary,
|
||||
"\n"/utf8>>,
|
||||
<<<<<<(cyan(<<" info"/utf8>>))/binary, ": "/utf8>>/binary,
|
||||
(erlang:element(2, Error))/binary>>/binary,
|
||||
"\n"/utf8>>]
|
||||
)
|
||||
end.
|
||||
|
||||
-file("src/gleeunit/internal/reporting.gleam", 71).
|
||||
?DOC(false).
|
||||
-spec test_failed(state(), binary(), binary(), gleam@dynamic:dynamic_()) -> state().
|
||||
test_failed(State, Module, Function, Error) ->
|
||||
Message = case gleeunit_gleam_panic_ffi:from_dynamic(Error) of
|
||||
{ok, Error@1} ->
|
||||
Src = gleam@option:from_result(
|
||||
file:read_file(erlang:element(3, Error@1))
|
||||
),
|
||||
format_gleam_error(Error@1, Module, Function, Src);
|
||||
|
||||
{error, _} ->
|
||||
format_unknown(Module, Function, Error)
|
||||
end,
|
||||
gleam_stdlib:print(<<"\n"/utf8, Message/binary>>),
|
||||
{state,
|
||||
erlang:element(2, State),
|
||||
erlang:element(3, State) + 1,
|
||||
erlang:element(4, State)}.
|
||||
153
build/dev/javascript/gleeunit/gleeunit@should.erl
Normal file
153
build/dev/javascript/gleeunit/gleeunit@should.erl
Normal file
|
|
@ -0,0 +1,153 @@
|
|||
-module(gleeunit@should).
|
||||
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
|
||||
-define(FILEPATH, "src/gleeunit/should.gleam").
|
||||
-export([equal/2, not_equal/2, be_ok/1, be_error/1, be_some/1, be_none/1, be_true/1, be_false/1, fail/0]).
|
||||
|
||||
-if(?OTP_RELEASE >= 27).
|
||||
-define(MODULEDOC(Str), -moduledoc(Str)).
|
||||
-define(DOC(Str), -doc(Str)).
|
||||
-else.
|
||||
-define(MODULEDOC(Str), -compile([])).
|
||||
-define(DOC(Str), -compile([])).
|
||||
-endif.
|
||||
|
||||
?MODULEDOC(" Use the `assert` keyword instead of this module.\n").
|
||||
|
||||
-file("src/gleeunit/should.gleam", 6).
|
||||
-spec equal(DOF, DOF) -> nil.
|
||||
equal(A, B) ->
|
||||
case A =:= B of
|
||||
true ->
|
||||
nil;
|
||||
|
||||
_ ->
|
||||
erlang:error(#{gleam_error => panic,
|
||||
message => erlang:list_to_binary(
|
||||
[<<"\n"/utf8>>,
|
||||
gleam@string:inspect(A),
|
||||
<<"\nshould equal\n"/utf8>>,
|
||||
gleam@string:inspect(B)]
|
||||
),
|
||||
file => <<?FILEPATH/utf8>>,
|
||||
module => <<"gleeunit/should"/utf8>>,
|
||||
function => <<"equal"/utf8>>,
|
||||
line => 10})
|
||||
end.
|
||||
|
||||
-file("src/gleeunit/should.gleam", 19).
|
||||
-spec not_equal(DOG, DOG) -> nil.
|
||||
not_equal(A, B) ->
|
||||
case A /= B of
|
||||
true ->
|
||||
nil;
|
||||
|
||||
_ ->
|
||||
erlang:error(#{gleam_error => panic,
|
||||
message => erlang:list_to_binary(
|
||||
[<<"\n"/utf8>>,
|
||||
gleam@string:inspect(A),
|
||||
<<"\nshould not equal\n"/utf8>>,
|
||||
gleam@string:inspect(B)]
|
||||
),
|
||||
file => <<?FILEPATH/utf8>>,
|
||||
module => <<"gleeunit/should"/utf8>>,
|
||||
function => <<"not_equal"/utf8>>,
|
||||
line => 23})
|
||||
end.
|
||||
|
||||
-file("src/gleeunit/should.gleam", 32).
|
||||
-spec be_ok({ok, DOH} | {error, any()}) -> DOH.
|
||||
be_ok(A) ->
|
||||
case A of
|
||||
{ok, Value} ->
|
||||
Value;
|
||||
|
||||
_ ->
|
||||
erlang:error(#{gleam_error => panic,
|
||||
message => erlang:list_to_binary(
|
||||
[<<"\n"/utf8>>,
|
||||
gleam@string:inspect(A),
|
||||
<<"\nshould be ok"/utf8>>]
|
||||
),
|
||||
file => <<?FILEPATH/utf8>>,
|
||||
module => <<"gleeunit/should"/utf8>>,
|
||||
function => <<"be_ok"/utf8>>,
|
||||
line => 35})
|
||||
end.
|
||||
|
||||
-file("src/gleeunit/should.gleam", 39).
|
||||
-spec be_error({ok, any()} | {error, DOM}) -> DOM.
|
||||
be_error(A) ->
|
||||
case A of
|
||||
{error, Error} ->
|
||||
Error;
|
||||
|
||||
_ ->
|
||||
erlang:error(#{gleam_error => panic,
|
||||
message => erlang:list_to_binary(
|
||||
[<<"\n"/utf8>>,
|
||||
gleam@string:inspect(A),
|
||||
<<"\nshould be error"/utf8>>]
|
||||
),
|
||||
file => <<?FILEPATH/utf8>>,
|
||||
module => <<"gleeunit/should"/utf8>>,
|
||||
function => <<"be_error"/utf8>>,
|
||||
line => 42})
|
||||
end.
|
||||
|
||||
-file("src/gleeunit/should.gleam", 46).
|
||||
-spec be_some(gleam@option:option(DOP)) -> DOP.
|
||||
be_some(A) ->
|
||||
case A of
|
||||
{some, Value} ->
|
||||
Value;
|
||||
|
||||
_ ->
|
||||
erlang:error(#{gleam_error => panic,
|
||||
message => erlang:list_to_binary(
|
||||
[<<"\n"/utf8>>,
|
||||
gleam@string:inspect(A),
|
||||
<<"\nshould be some"/utf8>>]
|
||||
),
|
||||
file => <<?FILEPATH/utf8>>,
|
||||
module => <<"gleeunit/should"/utf8>>,
|
||||
function => <<"be_some"/utf8>>,
|
||||
line => 49})
|
||||
end.
|
||||
|
||||
-file("src/gleeunit/should.gleam", 53).
|
||||
-spec be_none(gleam@option:option(any())) -> nil.
|
||||
be_none(A) ->
|
||||
case A of
|
||||
none ->
|
||||
nil;
|
||||
|
||||
_ ->
|
||||
erlang:error(#{gleam_error => panic,
|
||||
message => erlang:list_to_binary(
|
||||
[<<"\n"/utf8>>,
|
||||
gleam@string:inspect(A),
|
||||
<<"\nshould be none"/utf8>>]
|
||||
),
|
||||
file => <<?FILEPATH/utf8>>,
|
||||
module => <<"gleeunit/should"/utf8>>,
|
||||
function => <<"be_none"/utf8>>,
|
||||
line => 56})
|
||||
end.
|
||||
|
||||
-file("src/gleeunit/should.gleam", 60).
|
||||
-spec be_true(boolean()) -> nil.
|
||||
be_true(Actual) ->
|
||||
_pipe = Actual,
|
||||
equal(_pipe, true).
|
||||
|
||||
-file("src/gleeunit/should.gleam", 65).
|
||||
-spec be_false(boolean()) -> nil.
|
||||
be_false(Actual) ->
|
||||
_pipe = Actual,
|
||||
equal(_pipe, false).
|
||||
|
||||
-file("src/gleeunit/should.gleam", 70).
|
||||
-spec fail() -> nil.
|
||||
fail() ->
|
||||
be_true(false).
|
||||
21
build/dev/javascript/gleeunit/gleeunit_ffi.erl
Normal file
21
build/dev/javascript/gleeunit/gleeunit_ffi.erl
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
-module(gleeunit_ffi).
|
||||
|
||||
-export([find_files/2, run_eunit/2]).
|
||||
|
||||
find_files(Pattern, In) ->
|
||||
Results = filelib:wildcard(binary_to_list(Pattern), binary_to_list(In)),
|
||||
lists:map(fun list_to_binary/1, Results).
|
||||
|
||||
run_eunit(Tests, Options) ->
|
||||
case code:which(eunit) of
|
||||
non_existing ->
|
||||
gleeunit@internal@reporting:eunit_missing();
|
||||
|
||||
_ ->
|
||||
case eunit:test(Tests, Options) of
|
||||
ok -> {ok, nil};
|
||||
error -> {error, nil};
|
||||
{error, Term} -> {error, Term}
|
||||
end
|
||||
end.
|
||||
|
||||
100
build/dev/javascript/gleeunit/gleeunit_ffi.mjs
Normal file
100
build/dev/javascript/gleeunit/gleeunit_ffi.mjs
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
import { readFileSync } from "node:fs";
|
||||
import { Result$Ok, Result$Error } from "./gleam.mjs";
|
||||
import * as reporting from "./gleeunit/internal/reporting.mjs";
|
||||
|
||||
export function read_file(path) {
|
||||
try {
|
||||
return Result$Ok(readFileSync(path));
|
||||
} catch {
|
||||
return Result$Error(undefined);
|
||||
}
|
||||
}
|
||||
|
||||
async function* gleamFiles(directory) {
|
||||
for (let entry of await read_dir(directory)) {
|
||||
let path = join_path(directory, entry);
|
||||
if (path.endsWith(".gleam")) {
|
||||
yield path;
|
||||
} else {
|
||||
try {
|
||||
yield* gleamFiles(path);
|
||||
} catch (error) {
|
||||
// Could not read directory, assume it's a file
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function readRootPackageName() {
|
||||
let toml = await async_read_file("gleam.toml", "utf-8");
|
||||
for (let line of toml.split("\n")) {
|
||||
let matches = line.match(/\s*name\s*=\s*"([a-z][a-z0-9_]*)"/); // Match regexp in compiler-cli/src/new.rs in validate_name()
|
||||
if (matches) return matches[1];
|
||||
}
|
||||
throw new Error("Could not determine package name from gleam.toml");
|
||||
}
|
||||
|
||||
export async function main() {
|
||||
let state = reporting.new_state();
|
||||
|
||||
let packageName = await readRootPackageName();
|
||||
let dist = `../${packageName}/`;
|
||||
|
||||
for await (let path of await gleamFiles("test")) {
|
||||
let js_path = path.slice("test/".length).replace(".gleam", ".mjs");
|
||||
let module = await import(join_path(dist, js_path));
|
||||
for (let fnName of Object.keys(module)) {
|
||||
if (!fnName.endsWith("_test")) continue;
|
||||
try {
|
||||
await module[fnName]();
|
||||
state = reporting.test_passed(state);
|
||||
} catch (error) {
|
||||
let moduleName = js_path.slice(0, -4);
|
||||
state = reporting.test_failed(state, moduleName, fnName, error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const status = reporting.finished(state);
|
||||
exit(status);
|
||||
}
|
||||
|
||||
export function crash(message) {
|
||||
throw new Error(message);
|
||||
}
|
||||
|
||||
function exit(code) {
|
||||
if (globalThis.Deno) {
|
||||
Deno.exit(code);
|
||||
} else {
|
||||
process.exit(code);
|
||||
}
|
||||
}
|
||||
|
||||
async function read_dir(path) {
|
||||
if (globalThis.Deno) {
|
||||
let items = [];
|
||||
for await (let item of Deno.readDir(path, { withFileTypes: true })) {
|
||||
items.push(item.name);
|
||||
}
|
||||
return items;
|
||||
} else {
|
||||
let { readdir } = await import("node:fs/promises");
|
||||
return readdir(path);
|
||||
}
|
||||
}
|
||||
|
||||
function join_path(a, b) {
|
||||
if (a.endsWith("/")) return a + b;
|
||||
return a + "/" + b;
|
||||
}
|
||||
|
||||
async function async_read_file(path) {
|
||||
if (globalThis.Deno) {
|
||||
return Deno.readTextFile(path);
|
||||
} else {
|
||||
let { readFile } = await import("node:fs/promises");
|
||||
let contents = await readFile(path);
|
||||
return contents.toString();
|
||||
}
|
||||
}
|
||||
72
build/dev/javascript/gleeunit/gleeunit_progress.erl
Normal file
72
build/dev/javascript/gleeunit/gleeunit_progress.erl
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
%% A formatter adapted from Sean Cribb's https://github.com/seancribbs/eunit_formatters
|
||||
|
||||
-module(gleeunit_progress).
|
||||
-define(NOTEST, true).
|
||||
|
||||
%% eunit_listener callbacks
|
||||
-export([
|
||||
init/1, handle_begin/3, handle_end/3, handle_cancel/3, terminate/2,
|
||||
start/0, start/1
|
||||
]).
|
||||
|
||||
-define(reporting, gleeunit@internal@reporting).
|
||||
|
||||
start() ->
|
||||
start([]).
|
||||
|
||||
start(Options) ->
|
||||
eunit_listener:start(?MODULE, Options).
|
||||
|
||||
init(_Options) ->
|
||||
?reporting:new_state().
|
||||
|
||||
handle_begin(_test_or_group, _data, State) ->
|
||||
State.
|
||||
|
||||
handle_end(group, _data, State) ->
|
||||
State;
|
||||
handle_end(test, Data, State) ->
|
||||
{AtomModule, AtomFunction, _Arity} = proplists:get_value(source, Data),
|
||||
Module = erlang:atom_to_binary(AtomModule),
|
||||
Function = erlang:atom_to_binary(AtomFunction),
|
||||
|
||||
% EUnit swallows stdout, so print it to make debugging easier.
|
||||
case proplists:get_value(output, Data) of
|
||||
undefined -> ok;
|
||||
<<>> -> ok;
|
||||
Out -> gleam@io:print(Out)
|
||||
end,
|
||||
|
||||
case proplists:get_value(status, Data) of
|
||||
ok ->
|
||||
?reporting:test_passed(State);
|
||||
{skipped, _Reason} ->
|
||||
?reporting:test_skipped(State, Module, Function);
|
||||
{error, {_, Exception, _Stack}} ->
|
||||
?reporting:test_failed(State, Module, Function, Exception)
|
||||
end.
|
||||
|
||||
|
||||
handle_cancel(_test_or_group, Data, State) ->
|
||||
?reporting:test_failed(State, <<"gleeunit">>, <<"main">>, Data).
|
||||
|
||||
terminate({ok, _Data}, State) ->
|
||||
?reporting:finished(State),
|
||||
ok;
|
||||
terminate({error, Reason}, State) ->
|
||||
?reporting:finished(State),
|
||||
io:fwrite("
|
||||
Eunit failed:
|
||||
|
||||
~80p
|
||||
|
||||
This is probably a bug in gleeunit. Please report it.
|
||||
", [Reason]),
|
||||
sync_end(error).
|
||||
|
||||
sync_end(Result) ->
|
||||
receive
|
||||
{stop, Reference, ReplyTo} ->
|
||||
ReplyTo ! {result, Reference, Result},
|
||||
ok
|
||||
end.
|
||||
Loading…
Add table
Add a link
Reference in a new issue