Shared domain types of the Moon-Lander framework
///|
import {
"moonrockz/moon-lander-core" @lander_core,
}///|
test "parse an application name and match a failure by its rule" {
let name = @lander_core.AppName::parse("my-tool")
assert_eq(name.to_string(), "my-tool")
let rule = try {
ignore(@lander_core.AppName::parse("my tool"))
None
} catch {
InvalidAppName(rule~, ..) => Some(rule)
}
assert_true(rule is Some(CharNotAllowed(' ')))
}| Rule | Case | Example that breaks it |
|---|---|---|
| Not empty | Empty | "" |
| Starts with an ASCII letter | FirstNotAsciiLetter | 9tool, -tool |
| Only ASCII letters, digits, - and _ | CharNotAllowed(char) | my tool, my.tool, café |
///|
/// A function that takes a timeout as milliseconds, such as
/// `@async.with_timeout`.
fn wait_up_to(millis : Int) -> String {
"waits up to \{millis} ms"
}
///|
test "parse a time limit and give it to a timeout" {
let limit = @lander_core.TimeLimit::parse("2m30s")
assert_eq(wait_up_to(limit.to_millis()), "waits up to 150000 ms")
assert_eq(limit.to_string(), "2m30s")
assert_eq(limit, @lander_core.TimeLimit::seconds(150))
}| Unit | Short | Long |
|---|---|---|
| Millisecond | ms | millisecond, milliseconds |
| Second | s | second, seconds |
| Minute | m | minute, minutes |
| Hour | h | hour, hours |
| Rule | Case | Example that breaks it |
|---|---|---|
| Not empty | Empty | "" |
| At most one space, only inside or between parts; no other whitespace | UnexpectedSpace | 10s, 10 s, 10\ts |
| Each part starts with a number | NotANumber | -1s, .5s |
| Each number has a unit | MissingUnit | 5000 |
| A known unit, in lower case | UnknownUnit(unit) | 30d, 10 Seconds, 10µs |
| Largest unit first | UnitsOutOfOrder | 30s 1m |
| Each unit one time | RepeatedUnit | 1m 1m |
| Each part a whole number of milliseconds | NotWholeMilliseconds | 0.5ms, 1.0005s |
| Greater than zero | NotPositive | 0s |
| Not more than the largest limit | AboveLargest | 597h |
///|
test "derive a prefix and parse an absolute working directory" {
let name = @lander_core.AppName::parse("my-tool")
assert_eq(@lander_core.EnvPrefix::from_app_name(name).to_string(), "MY_TOOL")
assert_eq(@lander_core.EnvPrefix::parse("MT").to_string(), "MT")
let directory = @lander_core.AbsolutePath::parse("/work/repo")
assert_eq(directory.to_string(), "/work/repo")
assert_eq(@lander_core.AbsolutePath::root().to_string(), "/")
}pub suberror AbsolutePathError {
InvalidAbsolutePath(text~ : String, rule~ : AbsolutePathRule)
} derive(Debug)pub suberror EnvPrefixError {
InvalidEnvPrefix(text~ : String, rule~ : EnvPrefixRule)
} derive(Debug)pub suberror TimeLimitError {
InvalidTimeLimit(input~ : String, rule~ : TimeLimitRule)
} derive(Debug)impl Show for AbsolutePath