Skip to content

Commit

Permalink
chore: update moc 0.13.4 (#672)
Browse files Browse the repository at this point in the history
  • Loading branch information
crusso authored Nov 29, 2024
2 parents ec1a9c6 + b3e58c7 commit 2916a8e
Show file tree
Hide file tree
Showing 7 changed files with 108 additions and 85 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ on:
# Remember to update me in package-set.yml as well
env:
vessel_version: "v0.7.0"
moc_version: "0.13.3"
moc_version: "0.13.4"

jobs:
tests:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/package-set.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ on:

env:
vessel_version: "v0.7.0"
moc_version: "0.13.3"
moc_version: "0.13.4"

jobs:
verify:
Expand Down
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
## 0.13.4

* Breaking change (minor): `Float.format(#hex)` is no longer supported.
This is because newer versions of Motoko (such as with enhanced orthogonal persistence)
rely on the Rust-native formatter that does not offer this functionality.
It is expected that this formatter is very rarely used in practice.

* Formatter change (minor): The text formatting of `NaN`, positive or negative,
will be `NaN` in newer Motoko versions, while it was `nan` or `-nan` in older versions.

## 0.13.3

* Add modules `OrderedMap` and `OrderedSet` to replace `RBTree` (thanks to Serokell) (#662).
Expand Down
4 changes: 2 additions & 2 deletions mops.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "base"
version = "0.13.3"
version = "0.13.4"
description = "The Motoko base library"
repository = "https://github.com/dfinity/motoko-base"
keywords = [ "base" ]
Expand All @@ -10,5 +10,5 @@ license = "Apache-2.0"
matchers = "https://github.com/kritzcreek/motoko-matchers#v1.3.0@3dac8a071b69e4e651b25a7d9683fe831eb7cffd"

[toolchain]
moc = "0.13.3"
moc = "0.13.4"
wasmtime = "17.0.0"
13 changes: 7 additions & 6 deletions src/Float.mo
Original file line number Diff line number Diff line change
Expand Up @@ -402,25 +402,26 @@ module {
/// * `#fix prec` as fixed-point format with `prec` digits
/// * `#exp prec` as exponential format with `prec` digits
/// * `#gen prec` as generic format with `prec` digits
/// * `#hex prec` as hexadecimal format with `prec` digits
/// * `#exact` as exact format that can be decoded without loss.
///
/// `-0.0` is formatted with negative sign bit.
/// Positive infinity is formatted as `inf`.
/// Negative infinity is formatted as `-inf`.
/// `NaN` is formatted as `NaN` or `-NaN` depending on its sign bit.
/// Positive infinity is formatted as "inf".
/// Negative infinity is formatted as "-inf".
///
/// Note: The numerical precision and the text format can vary between
/// Motoko versions and runtime configuration. Moreover, `NaN` can be printed
/// differently, i.e. "NaN" or "nan", potentially omitting the `NaN` sign.
///
/// Example:
/// ```motoko
/// import Float "mo:base/Float";
///
/// Float.format(#exp 3, 123.0) // => "1.230e+02"
/// ```
public func format(fmt : { #fix : Nat8; #exp : Nat8; #gen : Nat8; #hex : Nat8; #exact }, x : Float) : Text = switch fmt {
public func format(fmt : { #fix : Nat8; #exp : Nat8; #gen : Nat8; #exact }, x : Float) : Text = switch fmt {
case (#fix(prec)) { Prim.floatToFormattedText(x, prec, 0) };
case (#exp(prec)) { Prim.floatToFormattedText(x, prec, 1) };
case (#gen(prec)) { Prim.floatToFormattedText(x, prec, 2) };
case (#hex(prec)) { Prim.floatToFormattedText(x, prec, 3) };
case (#exact) { Prim.floatToFormattedText(x, 17, 2) }
};

Expand Down
134 changes: 66 additions & 68 deletions test/Float.test.mo
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import Debug "../src/Debug";
import Float "../src/Float";
import Text "../src/Text";

import Suite "mo:matchers/Suite";
import T "mo:matchers/Testable";
Expand Down Expand Up @@ -44,11 +45,11 @@ let positiveNaN = Float.copySign(0.0 / 0.0, 1.0);
let negativeNaN = Float.copySign(0.0 / 0.0, -1.0);

func isPositiveNaN(number : Float) : Bool {
debug_show (number) == "nan"
Float.isNaN(number) and Float.copySign(1.0, number) == 1.0
};

func isNegativeNaN(number : Float) : Bool {
debug_show (number) == "-nan"
Float.isNaN(number) and Float.copySign(1.0, number) == -1.0
};

let positiveZero = 0.0;
Expand Down Expand Up @@ -87,7 +88,7 @@ let smallEpsilon = 1e-6;

class NaNMatcher() : M.Matcher<Float> {
public func describeMismatch(number : Float, _description : M.Description) {
Debug.print(debug_show (number) # " should be 'nan' or '-nan'")
Debug.print(debug_show (number) # " should be 'NaN' or '-NaN'")
};

public func matches(number : Float) : Bool {
Expand All @@ -97,7 +98,7 @@ class NaNMatcher() : M.Matcher<Float> {

class PositiveNaNMatcher() : M.Matcher<Float> {
public func describeMismatch(number : Float, _description : M.Description) {
Debug.print(debug_show (number) # " should be 'nan' (positive)")
Debug.print(debug_show (number) # " should be 'NaN' (positive)")
};

public func matches(number : Float) : Bool {
Expand All @@ -107,14 +108,49 @@ class PositiveNaNMatcher() : M.Matcher<Float> {

class NegativeNaNMatcher() : M.Matcher<Float> {
public func describeMismatch(number : Float, _description : M.Description) {
Debug.print(debug_show (number) # " should be '-nan' (negative)")
Debug.print(debug_show (number) # " should be '-NaN' (negative)")
};

public func matches(number : Float) : Bool {
isNegativeNaN(number)
}
};

// The Rust float formatter prints `NaN`.
// The Musl float formatter prints `nan`.
class PositiveNaNTextMatcher() : M.Matcher<Text> {
public func describeMismatch(text : Text, _description : M.Description) {
Debug.print("'" # text # "' should be 'NaN' or 'nan', depending on the Motoko version and runtime configuration")
};

public func matches(text : Text) : Bool {
text == "NaN" or text == "nan"
}
};

// The Rust float formatter ignores the sign of NaN and emits `NaN`.
// The Musl float formatter prints `-nan`.
class NegativeNaNTextMatcher() : M.Matcher<Text> {
public func describeMismatch(text : Text, _description : M.Description) {
Debug.print("'" # text # "' should be 'NaN' or '-nan', depending on the Motoko version and runtime configuration")
};

public func matches(text : Text) : Bool {
text == "NaN" or text == "-nan"
}
};

// Account for different numerical errors becoming visible in float formatting.
class TextPrefixMatcher(prefix : Text) : M.Matcher<Text> {
public func describeMismatch(text : Text, _description : M.Description) {
Debug.print("'" # text # "' does not start with '" # prefix # "'")
};

public func matches(text : Text) : Bool {
Text.startsWith(text, #text prefix)
}
};

// Some tests are adopted from Motoko compiler test `float-ops.mo`.

/* --------------------------------------- */
Expand Down Expand Up @@ -1341,7 +1377,7 @@ run(
test(
"one",
Float.exp(1.0),
M.equals(FloatTestable(Float.e, noEpsilon))
M.equals(FloatTestable(Float.e, smallEpsilon))
),
test(
"positive infinity",
Expand Down Expand Up @@ -1431,22 +1467,22 @@ run(
test(
"exact positive",
Float.format(#exact, 20.12345678901),
M.equals(T.text("20.12345678901"))
TextPrefixMatcher("20.1234567890")
),
test(
"exact negative",
Float.format(#exact, -20.12345678901),
M.equals(T.text("-20.12345678901"))
TextPrefixMatcher("-20.1234567890")
),
test(
"exact positive zero",
Float.format(#exact, positiveZero),
M.equals(T.text("0"))
M.anyOf([M.equals(T.text("0")), M.equals(T.text("0.00000000000000000"))])
),
test(
"exact negative zero",
Float.format(#exact, negativeZero),
M.equals(T.text("-0"))
M.anyOf([M.equals(T.text("-0")), M.equals(T.text("-0.00000000000000000"))])
),
test(
"exact positive infinity",
Expand All @@ -1461,12 +1497,12 @@ run(
test(
"exact positive NaN",
Float.format(#exact, positiveNaN),
M.equals(T.text("nan"))
PositiveNaNTextMatcher()
),
test(
"exact negative NaN",
Float.format(#exact, negativeNaN),
M.equals(T.text("-nan"))
NegativeNaNTextMatcher()
),
test(
"fix positive",
Expand Down Expand Up @@ -1501,32 +1537,32 @@ run(
test(
"fix positive NaN",
Float.format(#fix 6, positiveNaN),
M.equals(T.text("nan"))
PositiveNaNTextMatcher()
),
test(
"fix negative NaN",
Float.format(#fix 6, negativeNaN),
M.equals(T.text("-nan"))
NegativeNaNTextMatcher()
),
test(
"exp positive",
Float.format(#exp 9, 20.12345678901),
M.equals(T.text("2.012345679e+01"))
M.anyOf([M.equals(T.text("2.012345679e1")), M.equals(T.text("2.012345679e+01"))])
),
test(
"exp negative",
Float.format(#exp 9, -20.12345678901),
M.equals(T.text("-2.012345679e+01"))
M.anyOf([M.equals(T.text("-2.012345679e1")), M.equals(T.text("-2.012345679e+01"))])
),
test(
"exp positive zero",
Float.format(#exp 9, positiveZero),
M.equals(T.text("0.000000000e+00"))
M.anyOf([M.equals(T.text("0.000000000e0")), M.equals(T.text("0.000000000e+00"))])
),
test(
"exp negative zero",
Float.format(#exp 9, negativeZero),
M.equals(T.text("-0.000000000e+00"))
M.anyOf([M.equals(T.text("-0.000000000e0")), M.equals(T.text("-0.000000000e+00"))])
),
test(
"exp positive infinity",
Expand All @@ -1541,32 +1577,32 @@ run(
test(
"exp positive NaN",
Float.format(#exp 9, positiveNaN),
M.equals(T.text("nan"))
PositiveNaNTextMatcher()
),
test(
"exp negative NaN",
Float.format(#exp 9, negativeNaN),
M.equals(T.text("-nan"))
NegativeNaNTextMatcher()
),
test(
"gen positive",
Float.format(#gen 12, 20.12345678901),
M.equals(T.text("20.123456789"))
TextPrefixMatcher("20.123456789")
),
test(
"gen negative",
Float.format(#gen 12, -20.12345678901),
M.equals(T.text("-20.123456789"))
TextPrefixMatcher("-20.123456789")
),
test(
"gen positive zero",
Float.format(#gen 12, positiveZero),
M.equals(T.text("0"))
M.anyOf([M.equals(T.text("0")), M.equals(T.text("0.000000000000"))])
),
test(
"gen negative zero",
Float.format(#gen 12, negativeZero),
M.equals(T.text("-0"))
M.anyOf([M.equals(T.text("-0")), M.equals(T.text("-0.000000000000"))])
),
test(
"gen positive infinity",
Expand All @@ -1581,53 +1617,15 @@ run(
test(
"gen positive NaN",
Float.format(#gen 12, positiveNaN),
M.equals(T.text("nan"))
PositiveNaNTextMatcher()
),
test(
"gen negative NaN",
Float.format(#gen 12, negativeNaN),
M.equals(T.text("-nan"))
),
test(
"hex positive",
Float.format(#hex 10, 20.12345678901),
M.equals(T.text("0x1.41f9add374p+4"))
NegativeNaNTextMatcher()
),
test(
"hex negative",
Float.format(#hex 10, -20.12345678901),
M.equals(T.text("-0x1.41f9add374p+4"))
),
test(
"hex positive zero",
Float.format(#hex 10, positiveZero),
M.equals(T.text("0x0.0000000000p+0"))
),
test(
"hex negative zero",
Float.format(#hex 10, negativeZero),
M.equals(T.text("-0x0.0000000000p+0"))
),
test(
"hex positive infinity",
Float.format(#hex 10, positiveInfinity),
M.equals(T.text("inf"))
),
test(
"hex negative infinity",
Float.format(#hex 10, negativeInfinity),
M.equals(T.text("-inf"))
),
test(
"hex positive NaN",
Float.format(#hex 10, positiveNaN),
M.equals(T.text("nan"))
),
test(
"hex negative NaN",
Float.format(#hex 10, negativeNaN),
M.equals(T.text("-nan"))
)
// hex float formatting was only supported with Musl
// and is no longer supported with Rust-implemented formatter.
]
)
);
Expand Down Expand Up @@ -1671,12 +1669,12 @@ run(
test(
"positive NaN",
Float.toText(positiveNaN),
M.equals(T.text("nan"))
PositiveNaNTextMatcher()
),
test(
"negative NaN",
Float.toText(negativeNaN),
M.equals(T.text("-nan"))
NegativeNaNTextMatcher()
)
]
)
Expand Down
Loading

0 comments on commit 2916a8e

Please sign in to comment.