Skip to content

Commit

Permalink
Improve summary
Browse files Browse the repository at this point in the history
  • Loading branch information
maxdeviant committed Apr 21, 2024
1 parent a85c8c2 commit 8d5ef7c
Show file tree
Hide file tree
Showing 4 changed files with 129 additions and 61 deletions.
10 changes: 9 additions & 1 deletion src/startest/cli.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,15 @@ pub fn run(config: Config) {
filter -> Some(filter)
})

let ctx = Context(config, clock: clock.new(), logger: Logger)
let clock = clock.new()

let ctx =
Context(
config,
clock: clock,
logger: Logger,
started_at: clock.now(clock),
)

runner.run_tests(ctx)
})
Expand Down
3 changes: 2 additions & 1 deletion src/startest/context.gleam
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import bigben/clock.{type Clock}
import birl.{type Time}
import startest/config.{type Config}
import startest/logger.{type Logger}

/// The Startest context.
pub type Context {
Context(config: Config, clock: Clock, logger: Logger)
Context(config: Config, clock: Clock, logger: Logger, started_at: Time)
}
72 changes: 15 additions & 57 deletions src/startest/internal/runner/core.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import bigben/clock
import birl
import birl/duration
import gleam/int
import gleam/list
import gleam/option.{None, Some}
Expand All @@ -19,17 +18,9 @@ import startest/test_case.{
import startest/test_failure
import startest/test_tree

pub fn run_tests(tests: List(TestFile), ctx: Context) {
let started_at = clock.now(ctx.clock)

let total_collect_duration =
tests
|> list.fold(duration.micro_seconds(0), fn(acc, test_file) {
duration.add(acc, test_file.collect_duration)
})

pub fn run_tests(test_files: List(TestFile), ctx: Context) {
let tests =
tests
test_files
|> list.flat_map(fn(test_file) {
test_file.tests
|> list.flat_map(test_tree.all_tests)
Expand Down Expand Up @@ -69,6 +60,8 @@ pub fn run_tests(tests: List(TestFile), ctx: Context) {
clock.now(ctx.clock)
|> birl.difference(execution_started_at)

let reporting_started_at = clock.now(ctx.clock)

let reporter_ctx = ReporterContext(logger: ctx.logger)
ctx.config.reporters
|> list.each(fn(reporter) {
Expand All @@ -80,6 +73,10 @@ pub fn run_tests(tests: List(TestFile), ctx: Context) {
reporter.finished(reporter_ctx)
})

let reporting_duration =
clock.now(ctx.clock)
|> birl.difference(reporting_started_at)

let failed_tests =
executed_tests
|> list.filter_map(fn(executed_test) {
Expand All @@ -88,29 +85,13 @@ pub fn run_tests(tests: List(TestFile), ctx: Context) {
Passed | Skipped -> Error(Nil)
}
})
reporter.report_summary(ctx, failed_tests)

let total_duration =
clock.now(ctx.clock)
|> birl.difference(started_at)

logger.log(
ctx.logger,
"Collected "
<> int.to_string(test_count)
<> " tests in "
<> duration_to_string(total_collect_duration),
)
logger.log(
ctx.logger,
"Ran "
<> int.to_string(test_count)
<> " tests in "
<> duration_to_string(total_duration),
)
logger.log(
ctx.logger,
"Execution time: " <> duration_to_string(execution_duration),
reporter.report_summary(
ctx,
test_files,
executed_tests,
failed_tests,
execution_duration,
reporting_duration,
)

let exit_code = case list.is_empty(failed_tests) {
Expand All @@ -132,26 +113,3 @@ fn run_test(test_case: Test) -> TestOutcome {
}
}
}

fn duration_to_string(duration: duration.Duration) -> String {
let parts = duration.decompose(duration)

case parts {
[#(microseconds, duration.MicroSecond)] ->
int.to_string(microseconds) <> "碌s"
[#(milliseconds, duration.MilliSecond), #(_, duration.MicroSecond)] ->
int.to_string(milliseconds) <> "ms"
[
#(seconds, duration.Second),
#(_, duration.MilliSecond),
#(_, duration.MicroSecond),
] -> int.to_string(seconds) <> "s"
[
#(minutes, duration.Minute),
#(_, duration.Second),
#(_, duration.MilliSecond),
#(_, duration.MicroSecond),
] -> int.to_string(minutes) <> "m"
_ -> "too long"
}
}
105 changes: 103 additions & 2 deletions src/startest/reporter.gleam
Original file line number Diff line number Diff line change
@@ -1,13 +1,28 @@
import bigben/clock
import birl
import birl/duration.{type Duration}
import gleam/int
import gleam/list
import gleam/option.{None, Some}
import gleam/string
import gleam_community/ansi
import startest/context.{type Context}
import startest/locator.{type TestFile}
import startest/logger
import startest/test_case.{type Test}
import startest/test_case.{type ExecutedTest, type Test}
import startest/test_failure.{type TestFailure}

pub fn report_summary(ctx: Context, failed_tests: List(#(Test, TestFailure))) {
pub fn report_summary(
ctx: Context,
test_files: List(TestFile),
tests: List(ExecutedTest),
failed_tests: List(#(Test, TestFailure)),
execution_duration: Duration,
reporting_duration: Duration,
) {
let total_test_count = list.length(tests)
let failed_test_count = list.length(failed_tests)
let passed_test_count = total_test_count - failed_test_count
let has_any_failures = failed_test_count > 0

case has_any_failures {
Expand Down Expand Up @@ -37,4 +52,90 @@ pub fn report_summary(ctx: Context, failed_tests: List(#(Test, TestFailure))) {
}
False -> Nil
}

let total_duration =
clock.now(ctx.clock)
|> birl.difference(ctx.started_at)

let passed_tests = case passed_test_count {
0 -> None
_ -> Some(ansi.bright_green(int.to_string(passed_test_count) <> " passed"))
}
let failed_tests = case failed_test_count {
0 -> None
_ -> Some(ansi.bright_red(int.to_string(failed_test_count) <> " failed"))
}
let total_tests = ansi.gray("(" <> int.to_string(total_test_count) <> ")")

let failed_or_passed_tests = case passed_tests, failed_tests {
Some(passed_tests), Some(failed_tests) ->
failed_tests <> " | " <> passed_tests
Some(tests), None | None, Some(tests) -> tests
None, None -> ""
}

let total_collect_duration =
test_files
|> list.fold(duration.micro_seconds(0), fn(acc, test_file) {
duration.add(acc, test_file.collect_duration)
})

let label = fn(text) { ansi.dim(ansi.white(text)) }

logger.log(
ctx.logger,
label("Test Files: ") <> int.to_string(list.length(test_files)),
)
logger.log(
ctx.logger,
label(" Tests: ") <> failed_or_passed_tests <> " " <> total_tests,
)
logger.log(
ctx.logger,
label("Started at: ")
<> {
// TODO: Show in local time.
ctx.started_at
|> birl.to_naive_time_string
|> string.slice(0, string.length("HH:MM:SS"))
},
)
logger.log(
ctx.logger,
label(" Duration: ")
<> duration_to_string(total_duration)
<> " "
<> label(
"(collect "
<> duration_to_string(total_collect_duration)
<> ", tests "
<> duration_to_string(execution_duration)
<> ", reporters "
<> duration_to_string(reporting_duration)
<> ")",
),
)
}

fn duration_to_string(duration: duration.Duration) -> String {
let parts = duration.decompose(duration)

case parts {
[#(microseconds, duration.MicroSecond)] ->
int.to_string(microseconds) <> "碌s"
[#(milliseconds, duration.MilliSecond), #(_, duration.MicroSecond)] ->
int.to_string(milliseconds) <> "ms"
[
#(seconds, duration.Second),
#(_, duration.MilliSecond),
#(_, duration.MicroSecond),
] -> int.to_string(seconds) <> "s"
[
#(minutes, duration.Minute),
#(_, duration.Second),
#(_, duration.MilliSecond),
#(_, duration.MicroSecond),
] -> int.to_string(minutes) <> "m"
_ -> "too long"
}
}

0 comments on commit 8d5ef7c

Please sign in to comment.