mirror of
https://github.com/nushell/nushell.git
synced 2024-11-22 08:23:24 +01:00
stdlib: Implement common assert commands (#8515)
Implement common assert commands with tests. Fixes #8419. --------- Co-authored-by: Mate Farkas <Mate.Farkas@oneidentity.com>
This commit is contained in:
parent
ecc153cbef
commit
7d963776a0
@ -1,18 +1,11 @@
|
|||||||
# std.nu, `used` to load all standard library components
|
# std.nu, `used` to load all standard library components
|
||||||
|
|
||||||
# ---------------- builtin std functions --------------------
|
# Universal assert command
|
||||||
|
#
|
||||||
def _assertion-error [start, end, label, message?: string] {
|
# If the condition is not true, it generates an error.
|
||||||
error make {
|
#
|
||||||
msg: ($message | default "Assertion failed."),
|
# # Example
|
||||||
label: {
|
#
|
||||||
text: $label,
|
|
||||||
start: $start,
|
|
||||||
end: $end
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# ```nushell
|
# ```nushell
|
||||||
# >_ assert (3 == 3)
|
# >_ assert (3 == 3)
|
||||||
# >_ assert (42 == 3)
|
# >_ assert (42 == 3)
|
||||||
@ -26,51 +19,183 @@ def _assertion-error [start, end, label, message?: string] {
|
|||||||
# 13 │
|
# 13 │
|
||||||
# ╰────
|
# ╰────
|
||||||
# ```
|
# ```
|
||||||
export def assert [cond: bool, message?: string] {
|
|
||||||
if $cond { return }
|
|
||||||
let span = (metadata $cond).span
|
|
||||||
_assertion-error $span.start $span.end "It is not true." $message
|
|
||||||
}
|
|
||||||
|
|
||||||
# ```nushell
|
|
||||||
# ❯ assert eq 3 3
|
|
||||||
# ❯ assert eq 3 1
|
|
||||||
# Error:
|
|
||||||
# × Assertion failed.
|
|
||||||
# ╭─[entry #14:1:1]
|
|
||||||
# 1 │ assert eq 3 1
|
|
||||||
# · ─┬─
|
|
||||||
# · ╰── They are not equal: 3 != 1
|
|
||||||
# ╰────
|
|
||||||
#
|
|
||||||
#
|
#
|
||||||
|
# The --error-label flag can be used if you want to create a custom assert command:
|
||||||
# ```
|
# ```
|
||||||
export def "assert eq" [left: any, right: any, message?: string] {
|
# def "assert even" [number: int] {
|
||||||
let left_start = (metadata $left).span.start
|
# assert ($number mod 2 == 0) --error-label {
|
||||||
let right_end = (metadata $right).span.end
|
# start: (metadata $number).span.start,
|
||||||
|
# end: (metadata $number).span.end,
|
||||||
if ($left != $right) {
|
# text: $"($number) is not an even number",
|
||||||
_assertion-error $left_start $right_end $"They are not equal: ($left) != ($right)" $message
|
# }
|
||||||
|
# }
|
||||||
|
# ```
|
||||||
|
export def assert [
|
||||||
|
condition: bool, # Condition, which should be true
|
||||||
|
message?: string, # Optional error message
|
||||||
|
--error-label: record # Label for `error make` if you want to create a custom assert
|
||||||
|
] {
|
||||||
|
if $condition { return }
|
||||||
|
let span = (metadata $condition).span
|
||||||
|
error make {
|
||||||
|
msg: ($message | default "Assertion failed."),
|
||||||
|
label: ($error_label | default {
|
||||||
|
text: "It is not true.",
|
||||||
|
start: (metadata $condition).span.start,
|
||||||
|
end: (metadata $condition).span.end
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# ```nushell
|
# Assert that executing the code generates an error
|
||||||
# ❯ assert ne 1 3
|
#
|
||||||
# ❯ assert ne 42 42
|
# For more documentation see the assert command
|
||||||
# Error:
|
#
|
||||||
# × Assertion failed.
|
# # Examples
|
||||||
# ╭─[entry #23:1:1]
|
#
|
||||||
# 1 │ assert ne 42 42
|
# > assert error {|| missing_command} # passes
|
||||||
# · ──┬──
|
# > assert error {|| 12} # fails
|
||||||
# · ╰── They both are 42
|
export def "assert error" [
|
||||||
# ╰────
|
code: closure,
|
||||||
# ```
|
message?: string
|
||||||
export def "assert ne" [left: any, right: any, message?: string] {
|
] {
|
||||||
let left_start = (metadata $left).span.start
|
let error_raised = (try { do $code; false } catch { true })
|
||||||
let right_end = (metadata $right).span.end
|
assert ($error_raised) $message --error-label {
|
||||||
|
start: (metadata $code).span.start
|
||||||
|
end: (metadata $code).span.end
|
||||||
|
text: $"There were no error during code execution: (view source $code)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ($left == $right) {
|
# Assert $left == $right
|
||||||
_assertion-error $left_start $right_end $"They both are ($left)" $message
|
#
|
||||||
|
# For more documentation see the assert command
|
||||||
|
#
|
||||||
|
# # Examples
|
||||||
|
#
|
||||||
|
# > assert equal 1 1 # passes
|
||||||
|
# > assert equal (0.1 + 0.2) 0.3
|
||||||
|
# > assert equal 1 2 # fails
|
||||||
|
export def "assert equal" [left: any, right: any, message?: string] {
|
||||||
|
assert ($left == $right) $message --error-label {
|
||||||
|
start: (metadata $left).span.start
|
||||||
|
end: (metadata $right).span.end
|
||||||
|
text: $"They are not equal. Left = ($left). Right = ($right)."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Assert $left != $right
|
||||||
|
#
|
||||||
|
# For more documentation see the assert command
|
||||||
|
#
|
||||||
|
# # Examples
|
||||||
|
#
|
||||||
|
# > assert not equal 1 2 # passes
|
||||||
|
# > assert not equal 1 "apple" # passes
|
||||||
|
# > assert not equal 7 7 # fails
|
||||||
|
export def "assert not equal" [left: any, right: any, message?: string] {
|
||||||
|
assert ($left != $right) $message --error-label {
|
||||||
|
start: (metadata $left).span.start
|
||||||
|
end: (metadata $right).span.end
|
||||||
|
text: $"They both are ($left)."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Assert $left <= $right
|
||||||
|
#
|
||||||
|
# For more documentation see the assert command
|
||||||
|
#
|
||||||
|
# # Examples
|
||||||
|
#
|
||||||
|
# > assert less or equal 1 2 # passes
|
||||||
|
# > assert less or equal 1 1 # passes
|
||||||
|
# > assert less or equal 1 0 # fails
|
||||||
|
export def "assert less or equal" [left: any, right: any, message?: string] {
|
||||||
|
assert ($left <= $right) $message --error-label {
|
||||||
|
start: (metadata $left).span.start
|
||||||
|
end: (metadata $right).span.end
|
||||||
|
text: $"Left: ($left), Right: ($right)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Assert $left < $right
|
||||||
|
#
|
||||||
|
# For more documentation see the assert command
|
||||||
|
#
|
||||||
|
# # Examples
|
||||||
|
#
|
||||||
|
# > assert less 1 2 # passes
|
||||||
|
# > assert less 1 1 # fails
|
||||||
|
export def "assert less" [left: any, right: any, message?: string] {
|
||||||
|
assert ($left < $right) $message --error-label {
|
||||||
|
start: (metadata $left).span.start
|
||||||
|
end: (metadata $right).span.end
|
||||||
|
text: $"Left: ($left), Right: ($right)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Assert $left > $right
|
||||||
|
#
|
||||||
|
# For more documentation see the assert command
|
||||||
|
#
|
||||||
|
# # Examples
|
||||||
|
#
|
||||||
|
# > assert greater 2 1 # passes
|
||||||
|
# > assert greater 2 2 # fails
|
||||||
|
export def "assert greater" [left: any, right: any, message?: string] {
|
||||||
|
assert ($left > $right) $message --error-label {
|
||||||
|
start: (metadata $left).span.start
|
||||||
|
end: (metadata $right).span.end
|
||||||
|
text: $"Left: ($left), Right: ($right)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Assert $left >= $right
|
||||||
|
#
|
||||||
|
# For more documentation see the assert command
|
||||||
|
#
|
||||||
|
# # Examples
|
||||||
|
#
|
||||||
|
# > assert greater or equal 2 1 # passes
|
||||||
|
# > assert greater or equal 2 2 # passes
|
||||||
|
# > assert greater or equal 1 2 # fails
|
||||||
|
export def "assert greater or equal" [left: any, right: any, message?: string] {
|
||||||
|
assert ($left >= $right) $message --error-label {
|
||||||
|
start: (metadata $left).span.start
|
||||||
|
end: (metadata $right).span.end
|
||||||
|
text: $"Left: ($left), Right: ($right)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Assert length of $left is $right
|
||||||
|
#
|
||||||
|
# For more documentation see the assert command
|
||||||
|
#
|
||||||
|
# # Examples
|
||||||
|
#
|
||||||
|
# > assert length [0, 0] 2 # passes
|
||||||
|
# > assert length [0] 3 # fails
|
||||||
|
export def "assert length" [left: list, right: int, message?: string] {
|
||||||
|
assert (($left | length) == $right) $message --error-label {
|
||||||
|
start: (metadata $left).span.start
|
||||||
|
end: (metadata $right).span.end
|
||||||
|
text: $"Length of ($left) is ($left | length), not ($right)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Assert that ($left | str contains $right)
|
||||||
|
#
|
||||||
|
# For more documentation see the assert command
|
||||||
|
#
|
||||||
|
# # Examples
|
||||||
|
#
|
||||||
|
# > assert str contains "arst" "rs" # passes
|
||||||
|
# > assert str contains "arst" "k" # fails
|
||||||
|
export def "assert str contains" [left: string, right: string, message?: string] {
|
||||||
|
assert ($left | str contains $right) $message --error-label {
|
||||||
|
start: (metadata $left).span.start
|
||||||
|
end: (metadata $right).span.end
|
||||||
|
text: $"'($left)' does not contain '($right)'."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -125,7 +250,7 @@ export def match [
|
|||||||
# std path add "bar" "baz"
|
# std path add "bar" "baz"
|
||||||
# std path add "fooo" --append
|
# std path add "fooo" --append
|
||||||
#
|
#
|
||||||
# assert eq $env.PATH ["bar" "baz" "foo" "fooo"]
|
# assert equal $env.PATH ["bar" "baz" "foo" "fooo"]
|
||||||
#
|
#
|
||||||
# print (std path add "returned" --ret)
|
# print (std path add "returned" --ret)
|
||||||
# }
|
# }
|
||||||
|
64
crates/nu-utils/standard_library/test_asserts.nu
Normal file
64
crates/nu-utils/standard_library/test_asserts.nu
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
use std.nu *
|
||||||
|
|
||||||
|
export def test_assert [] {
|
||||||
|
assert true
|
||||||
|
assert (1 + 2 == 3)
|
||||||
|
assert error { assert false }
|
||||||
|
assert error { assert (1 + 2 == 4) }
|
||||||
|
}
|
||||||
|
|
||||||
|
export def test_assert_equal [] {
|
||||||
|
assert equal (1 + 2) 3
|
||||||
|
assert equal (0.1 + 0.2 | into string | into decimal) 0.3 # 0.30000000000000004 == 0.3
|
||||||
|
assert error { assert equal 1 "foo" }
|
||||||
|
assert error { assert equal (1 + 2) 4) }
|
||||||
|
}
|
||||||
|
|
||||||
|
export def test_assert_not_equal [] {
|
||||||
|
assert not equal (1 + 2) 4
|
||||||
|
assert not equal 1 "foo"
|
||||||
|
assert not equal (1 + 2) 3)
|
||||||
|
assert error { assert not equal 1 1 }
|
||||||
|
}
|
||||||
|
|
||||||
|
export def test_assert_error [] {
|
||||||
|
let failing_code = {|| missing_code_to_run}
|
||||||
|
assert error $failing_code
|
||||||
|
|
||||||
|
let good_code = {|| }
|
||||||
|
let assert_error_raised = (try { do assert $good_code; false } catch { true })
|
||||||
|
assert $assert_error_raised "The assert error should raise an error if there is no error in the executed code."
|
||||||
|
}
|
||||||
|
|
||||||
|
export def test_assert_less [] {
|
||||||
|
assert less 1 2
|
||||||
|
assert error { assert less 1 1 }
|
||||||
|
}
|
||||||
|
|
||||||
|
export def test_assert_less_or_equal [] {
|
||||||
|
assert less or equal 1 2
|
||||||
|
assert less or equal 1 1
|
||||||
|
assert error { assert less or equal 1 0 }
|
||||||
|
}
|
||||||
|
|
||||||
|
export def test_assert_greater [] {
|
||||||
|
assert greater 2 1
|
||||||
|
assert error { assert greater 2 2 }
|
||||||
|
}
|
||||||
|
|
||||||
|
export def test_assert_greater_or_equal [] {
|
||||||
|
assert greater or equal 1 1
|
||||||
|
assert greater or equal 2 1
|
||||||
|
assert error { assert greater or equal 0 1 }
|
||||||
|
}
|
||||||
|
|
||||||
|
export def test_assert_length [] {
|
||||||
|
assert length [0, 0, 0] 3
|
||||||
|
assert error { assert length [0, 0] 3 }
|
||||||
|
}
|
||||||
|
|
||||||
|
# export def test_assert_§ [] {
|
||||||
|
# assert §
|
||||||
|
# assert error { assert § }
|
||||||
|
# }
|
||||||
|
|
@ -1,4 +1,5 @@
|
|||||||
use std.nu assert
|
use std.nu "assert length"
|
||||||
|
use std.nu "assert equal"
|
||||||
|
|
||||||
def clean [path: path] {
|
def clean [path: path] {
|
||||||
cd $path
|
cd $path
|
||||||
@ -21,31 +22,31 @@ export def test_dirs_command [] {
|
|||||||
use std.nu "dirs drop"
|
use std.nu "dirs drop"
|
||||||
use std.nu "dirs show"
|
use std.nu "dirs show"
|
||||||
|
|
||||||
assert (1 == ($env.DIRS_LIST | length)) "list is just pwd after initialization"
|
assert length $env.DIRS_LIST 1 "list is just pwd after initialization"
|
||||||
assert ($base_path == $env.DIRS_LIST.0) "list is just pwd after initialization"
|
assert equal $base_path $env.DIRS_LIST.0 "list is just pwd after initialization"
|
||||||
|
|
||||||
dirs next
|
dirs next
|
||||||
assert ($base_path == $env.DIRS_LIST.0) "next wraps at end of list"
|
assert equal $base_path $env.DIRS_LIST.0 "next wraps at end of list"
|
||||||
|
|
||||||
dirs prev
|
dirs prev
|
||||||
assert ($base_path == $env.DIRS_LIST.0) "prev wraps at top of list"
|
assert equal $base_path $env.DIRS_LIST.0 "prev wraps at top of list"
|
||||||
|
|
||||||
dirs add $path_b $path_a
|
dirs add $path_b $path_a
|
||||||
assert ($path_b == $env.PWD) "add changes PWD to first added dir"
|
assert equal $path_b $env.PWD "add changes PWD to first added dir"
|
||||||
assert (3 == ($env.DIRS_LIST | length)) "add in fact adds to list"
|
assert length $env.DIRS_LIST 3 "add in fact adds to list"
|
||||||
assert ($path_a == $env.DIRS_LIST.2) "add in fact adds to list"
|
assert equal $path_a $env.DIRS_LIST.2 "add in fact adds to list"
|
||||||
|
|
||||||
dirs next 2
|
dirs next 2
|
||||||
assert ($base_path == $env.PWD) "next wraps at end of list"
|
assert equal $base_path $env.PWD "next wraps at end of list"
|
||||||
|
|
||||||
dirs prev 1
|
dirs prev 1
|
||||||
assert ($path_a == $env.PWD) "prev wraps at start of list"
|
assert equal $path_a $env.PWD "prev wraps at start of list"
|
||||||
|
|
||||||
dirs drop
|
dirs drop
|
||||||
assert (2 == ($env.DIRS_LIST | length)) "drop removes from list"
|
assert length $env.DIRS_LIST 2 "drop removes from list"
|
||||||
assert ($base_path == $env.PWD) "drop changes PWD to next in list (after dropped element)"
|
assert equal $base_path $env.PWD "drop changes PWD to next in list (after dropped element)"
|
||||||
|
|
||||||
assert ((dirs show) == [[active path]; [true $base_path] [false $path_b]]) "show table contains expected information"
|
assert equal (dirs show) [[active path]; [true $base_path] [false $path_b]] "show table contains expected information"
|
||||||
} catch { |error|
|
} catch { |error|
|
||||||
clean $base_path
|
clean $base_path
|
||||||
|
|
||||||
|
@ -8,13 +8,13 @@ def run [system_level, message_level] {
|
|||||||
}
|
}
|
||||||
def "assert no message" [system_level, message_level] {
|
def "assert no message" [system_level, message_level] {
|
||||||
let output = (run $system_level $message_level)
|
let output = (run $system_level $message_level)
|
||||||
assert eq $output ""
|
assert equal "" $output
|
||||||
}
|
}
|
||||||
|
|
||||||
def "assert message" [system_level, message_level, message_level_str] {
|
def "assert message" [system_level, message_level, message_level_str] {
|
||||||
let output = (run $system_level $message_level)
|
let output = (run $system_level $message_level)
|
||||||
assert ($output | str contains $message_level_str)
|
assert str contains $output $message_level_str
|
||||||
assert ($output | str contains "test message")
|
assert str contains $output "test message"
|
||||||
}
|
}
|
||||||
|
|
||||||
export def test_critical [] {
|
export def test_critical [] {
|
||||||
|
@ -1,28 +1,5 @@
|
|||||||
use std.nu
|
use std.nu
|
||||||
|
|
||||||
export def test_assert [] {
|
|
||||||
def test_failing [code: closure] {
|
|
||||||
let code_did_run = (try { do $code; true } catch { false })
|
|
||||||
|
|
||||||
if $code_did_run {
|
|
||||||
error make {msg: (view source $code)}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std assert true
|
|
||||||
std assert (1 + 2 == 3)
|
|
||||||
test_failing { std assert false }
|
|
||||||
test_failing { std assert (1 + 2 == 4) }
|
|
||||||
|
|
||||||
std assert eq (1 + 2) 3
|
|
||||||
test_failing { std assert eq 1 "foo" }
|
|
||||||
test_failing { std assert eq (1 + 2) 4) }
|
|
||||||
|
|
||||||
std assert ne (1 + 2) 4
|
|
||||||
std assert ne 1 "foo"
|
|
||||||
std assert ne (1 + 2) 3)
|
|
||||||
}
|
|
||||||
|
|
||||||
export def test_match [] {
|
export def test_match [] {
|
||||||
use std.nu assert
|
use std.nu assert
|
||||||
|
|
||||||
@ -41,24 +18,24 @@ export def test_match [] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export def test_path_add [] {
|
export def test_path_add [] {
|
||||||
use std.nu "assert eq"
|
use std.nu "assert equal"
|
||||||
|
|
||||||
with-env [PATH []] {
|
with-env [PATH []] {
|
||||||
assert eq $env.PATH []
|
assert equal $env.PATH []
|
||||||
|
|
||||||
std path add "/foo/"
|
std path add "/foo/"
|
||||||
assert eq $env.PATH ["/foo/"]
|
assert equal $env.PATH ["/foo/"]
|
||||||
|
|
||||||
std path add "/bar/" "/baz/"
|
std path add "/bar/" "/baz/"
|
||||||
assert eq $env.PATH ["/bar/", "/baz/", "/foo/"]
|
assert equal $env.PATH ["/bar/", "/baz/", "/foo/"]
|
||||||
|
|
||||||
let-env PATH = []
|
let-env PATH = []
|
||||||
|
|
||||||
std path add "foo"
|
std path add "foo"
|
||||||
std path add "bar" "baz" --append
|
std path add "bar" "baz" --append
|
||||||
assert eq $env.PATH ["foo", "bar", "baz"]
|
assert equal $env.PATH ["foo", "bar", "baz"]
|
||||||
|
|
||||||
assert eq (std path add "fooooo" --ret) ["fooooo", "foo", "bar", "baz"]
|
assert equal (std path add "fooooo" --ret) ["fooooo", "foo", "bar", "baz"]
|
||||||
assert eq $env.PATH ["fooooo", "foo", "bar", "baz"]
|
assert equal $env.PATH ["fooooo", "foo", "bar", "baz"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user