Add dlint rule to suggest === (#10485)

* Add dlint rule to suggest ===

This rule doesn’t quite work in all cases since you can have types
that have Eq instances but not Show instances. However, I think the
benefits of people learning about this are much larger than the
downsides here of getting a hint that doesn’t apply in edge cases.

changelog_begin
changelog_end

* fix all the tests, why are there so many :(

changelog_begin
changelog_end
This commit is contained in:
Moritz Kiefer 2021-08-05 11:44:57 +02:00 committed by GitHub
parent 185f888b44
commit 348c6de92c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
43 changed files with 264 additions and 205 deletions

View File

@ -612,6 +612,11 @@
- warn: {lhs: null x , rhs: "False", side: isTuple x, name: Using null on tuple}
- warn: {lhs: length x, rhs: "1" , side: isTuple x, name: Using length on tuple}
# ASSERTIONS
- warn: {lhs: "assert (x == y)", rhs: "x === y", name: Use === for better error messages}
- warn: {lhs: "assert (x /= y)", rhs: "x =/= y", name: Use === for better error messages}
- group:
name: generalise
enabled: false

View File

@ -1,10 +1,12 @@
-- Copyright (c) 2020, Digital Asset (Switzerland) GmbH and/or its affiliates.
-- All rights reserved.
-- @INFO range=9:22-9:39; Use catOptionals
-- @INFO range=11:22-11:39; Use catOptionals
module ActionFail where
import DA.Assert
catOptionalsComp : [Optional a] -> [a]
catOptionalsComp l = [x | Some x <- l]
@ -14,7 +16,5 @@ catOptionalsMonad l = do
return x
main = scenario do
alice <- getParty "alice"
submit alice do
assert $ catOptionalsComp [None,Some 1,Some 2] == [1,2]
assert $ catOptionalsMonad [None,Some 1,Some 2] == [1,2]
catOptionalsComp [None,Some 1,Some 2] === [1,2]
catOptionalsMonad [None,Some 1,Some 2] === [1,2]

View File

@ -5,8 +5,10 @@
module AliasNonLocal where
import DA.Assert
data Coin = BTC | Other Text
deriving (Eq)
deriving (Eq, Show)
btc = BTC
@ -17,5 +19,5 @@ main = scenario do
let btc2 = BTC
let other1 = other
let other2 = Other
assert (btc1 == btc2)
assert (other1 "ETH" == other2 "ETH")
btc1 === btc2
other1 "ETH" === other2 "ETH"

View File

@ -0,0 +1,9 @@
-- Copyright (c) 2020, Digital Asset (Switzerland) GmbH and/or its affiliates.
-- All rights reserved.
-- @INFO range=9:3-9:18; Use ===
module Assert where
test = scenario do
assert (1 == 1)

View File

@ -3,6 +3,8 @@
module Choice_no_params_template where
import DA.Assert
template Bond
with
issuer : Party
@ -30,7 +32,7 @@ template Bond
with otherCid : ContractId Bond
do
otherBond <- fetch otherCid
assert $ this == otherBond with amount
this === otherBond with amount
archive otherCid
create $ Bond with amount = amount + otherBond.amount, ..

View File

@ -7,6 +7,8 @@
module DataTypes where
import DA.Assert
data Rec = Rec with x: Int
newtype RecNT = RecNT with x: Int
@ -38,17 +40,17 @@ eval = \case
main = scenario do
assert $ (Rec with x = 5).x == 5
(Rec with x = 5).x === 5
assert $ (RecNT with x = 7).x == 7
(RecNT with x = 7).x === 7
assert $ case Unit of {Unit -> True}
assert $ untag (MkTag 3) == 3
untag (MkTag 3) === 3
assert $ untagNT (MkTagNT 11) == 11
untagNT (MkTagNT 11) === 11
assert $ eval Zero == 0
assert $ eval (Num1 13) == 13
assert $ eval (Num2 with x = 17) == 17
assert $ eval (Plus with x = 19; y = 23) == 42
eval Zero === 0
eval (Num1 13) === 13
eval (Num2 with x = 17) === 17
eval (Plus with x = 19; y = 23) === 42

View File

@ -3,8 +3,10 @@
module DiscloseViaChoiceObserver where
import DA.Assert
-- @SINCE-LF 1.11
-- @WARN range=37:15-37:67; Use of divulged contracts is deprecated
-- @WARN range=39:15-39:67; Use of divulged contracts is deprecated
-- This example demonstrates the canonical use of choice-observers to achieve disclosure.
@ -35,5 +37,5 @@ test = scenario do
submit alice do exercise id DiscloseTo with receiver = bob
-- (4) Now Bob can see the secret
secret <- submit bob do exercise id Reveal with receiver = bob
assert (secret == "s3cr3t")
secret === "s3cr3t"
pure ()

View File

@ -4,6 +4,8 @@
module EqContractId where
import DA.Assert
template Foo with
p: Party
where
@ -13,5 +15,5 @@ main = scenario do
alice <- getParty "Alice"
cid1 <- submit alice do create Foo{p = alice}
cid2 <- submit alice do create Foo{p = alice}
assert $ cid1 == cid1
assert $ cid1 /= cid2
cid1 === cid1
cid1 =/= cid2

View File

@ -4,16 +4,17 @@
{-# LANGUAGE ExistentialQuantification #-}
-- @WARN Modules compiled with the ExistentialQuantification language extension might not work properly with data-dependencies.
-- @ ERROR range=15:1-15:7; Pattern match with existential type.
-- @ ERROR range=17:1-17:7; Pattern match with existential type.
module Existential where
import DA.Assert
data Foo = forall a . Foo (a, a -> Int)
runFoo : Foo -> Int
runFoo (Foo (a, b)) = b a
main = scenario do
alice <- getParty "alice"
submit alice $ assert (runFoo (Foo (12, (+1))) == 13)
runFoo (Foo (12, (+1))) === 13

View File

@ -4,11 +4,13 @@
{-# LANGUAGE ExistentialQuantification #-}
-- @WARN Modules compiled with the ExistentialQuantification language extension might not work properly with data-dependencies.
-- @ ERROR range=17:1-17:7; Pattern match with existential type.
-- @ ERROR range=19:1-19:7; Pattern match with existential type.
module ExistentialSum where
import DA.Assert
data Foo
= Bar
| forall a. Baz a
@ -18,5 +20,4 @@ runFoo Bar = 0
runFoo (Baz _) = 1
main = scenario do
alice <- getParty "alice"
submit alice $ assert (runFoo (Baz "quux") == 1)
runFoo (Baz "quux") === 1

View File

@ -4,11 +4,12 @@
module Fib where
import DA.Assert
fib : Int -> Int
fib 0 = 0
fib 1 = 1
fib n = fib (n-1) + fib (n-2)
main = scenario do
alice <- getParty "alice"
submit alice $ assert (fib 10 == 55)
fib 10 === 55

View File

@ -5,6 +5,8 @@
module IntBoundsDynamic where
import DA.Assert
maxInt : Int
maxInt = 9223372036854775807
@ -13,6 +15,6 @@ minInt = -9223372036854775808
test = scenario do
p <- getParty "p"
assert $ negate maxInt - 1 == minInt
negate maxInt - 1 === minInt
submitMustFail p $ pure $ maxInt+1
submitMustFail p $ pure $ minInt-1

View File

@ -4,6 +4,8 @@
module Iou12 where
import DA.Assert
template Iou
with
issuer : Party
@ -56,7 +58,7 @@ template Iou
-- Merge two IOUs by aggregating their amounts.
otherIou <- fetch otherCid
-- Check the two IOU's are compatible
assert $ this == otherIou with amount
this === otherIou with amount
-- Retire the old Iou by transferring to the
-- issuer and archiving
transferCid <-
@ -109,7 +111,7 @@ main = scenario do
-- Assert things are as they should be
submit alice do
aliceIou <- fetch rest
assert $ aliceIou == Iou with
aliceIou === Iou with
issuer = bank
owner = alice
currency = "USD"
@ -119,7 +121,7 @@ main = scenario do
submit bob do
bobIou <- fetch iouTotalCid
assert $ bobIou == Iou with
bobIou === Iou with
issuer = bank
owner = bob
currency = "USD"

View File

@ -16,7 +16,7 @@ import DA.Assert
import DA.Optional
data Foo = Foo with x : Int; y : Text
deriving Eq
deriving (Eq, Show)
testSort6 = scenario do
let l = [ Foo 42 "a"
@ -24,14 +24,14 @@ testSort6 = scenario do
, Foo 15 "c"
, Foo 5 "b" ]
let m = sortOn (\t -> (Down t.y, Down t.x)) l
assert $ head m == Foo 15 "c"
assert $ last m == Foo 42 "a"
head m === Foo 15 "c"
last m === Foo 42 "a"
-- Utility called on by 'testSort4' and 'testSort5'
check45 n m = do
assert $ n == [1, 1, 1, 2, 3]
n === [1, 1, 1, 2, 3]
let o = map (\(_, f) -> f ()) m
assert $ o == ["A", "B", "C", "D", "E"]
o === ["A", "B", "C", "D", "E"]
testSort5 = scenario do
let l = [ (2, const "D"), (1, const "A"), (1, const "B"), (3, const "E"), (1, const "C") ]
@ -48,38 +48,38 @@ testSort4 = scenario do
testSort3 = scenario do
let l = [ "C", "A", "E", "D", "B" ]
let m = sort l
assert $ m == ["A", "B", "C", "D", "E"]
m === ["A", "B", "C", "D", "E"]
testSort2 = scenario do
let l = [ 4, 5, 6, 3, 9, 2, 1, 8, 7 ]
let m = sortBy (\x y -> compare y x) l
assert $ m == reverse [1, 2, 3, 4, 5, 6, 7, 8, 9]
m === reverse [1, 2, 3, 4, 5, 6, 7, 8, 9]
testSort1 = scenario do
let l = [ 4, 5, 6, 3, 9, 2, 1, 8, 7 ]
let m = sort l
assert $ m == [1, 2, 3, 4, 5, 6, 7, 8, 9]
m === [1, 2, 3, 4, 5, 6, 7, 8, 9]
testSortEmpty = scenario do
let l = [] : [Int]
let m = sort l
assert $ m == l
m === l
testSortIsStable = scenario do
let l = [(1, 3), (1,2), (1,1), (1,1), (1,4)]
let m = sortBy (compare `on` fst) l
assert $ m == l
m === l
where on cmp f x y = cmp (f x) (f y)
testGroupOn = scenario do
let l = [(1, 3), (1,2), (1,1), (1,1), (1,4)]
let m = groupOn ( (== 1) . snd ) l
assert $ m == [[(1, 3), (1,2)], [(1,1), (1,1)], [(1,4)]]
m === [[(1, 3), (1,2)], [(1,1), (1,1)], [(1,4)]]
testDedup = scenario do
let l = [4,7,2,1,3,5,7,2,4,2,3,4,7,2,4,2,3,4,4,5,7,7,2]
let m = dedup l
assert $ m == [4,7,2,1,3,5]
m === [4,7,2,1,3,5]
testUnique = scenario do
unique [1, 3, 4] === True
@ -88,7 +88,7 @@ testUnique = scenario do
unique [1, 3, 1, 4] === False
data Employee = Employee with employeeNo : Int; surname : Text; forename : Text
deriving (Eq)
deriving (Eq, Show)
testUniqueOn = scenario do
uniqueOn (.employeeNo) [ Employee 1 "Monday" "Jo", Employee 1 "Tuesday" "Bo" ] === False
@ -96,8 +96,8 @@ testUniqueOn = scenario do
uniqueOn (.employeeNo) ([] : [Employee]) === True
testDedupOn = scenario do
assert $ dedupOn (.employeeNo) [ Employee 1 "Monday" "Jo", Employee 1 "Tuesday" "Bo" ] == [ Employee 1 "Monday" "Jo" ]
assert $ dedupOn (.employeeNo) [ Employee 1 "Monday" "Jo", Employee 2 "Monday" "Jo", Employee 3 "Tuesday" "Bo" ] == [ Employee 1 "Monday" "Jo", Employee 2 "Monday" "Jo", Employee 3 "Tuesday" "Bo" ]
dedupOn (.employeeNo) [ Employee 1 "Monday" "Jo", Employee 1 "Tuesday" "Bo" ] === [ Employee 1 "Monday" "Jo" ]
dedupOn (.employeeNo) [ Employee 1 "Monday" "Jo", Employee 2 "Monday" "Jo", Employee 3 "Tuesday" "Bo" ] === [ Employee 1 "Monday" "Jo", Employee 2 "Monday" "Jo", Employee 3 "Tuesday" "Bo" ]
assert $ null $ dedupOn (.employeeNo) ([] : [Employee])
testUniqueBy = scenario do
@ -109,7 +109,7 @@ testUniqueBy = scenario do
testDedupSort = scenario do
let l = [4,7,2,1,3,5,7,2,4,2,3,4,7,2,4,2,3,4,4,5,7,7,2]
let m = dedupSort l
assert $ m == [1,2,3,4,5,7]
m === [1,2,3,4,5,7]
testDedupBy = scenario do
[2, 1, 3] === dedupBy compare [2, 1, 3, 2, 1]
@ -327,29 +327,29 @@ testNth = scenario do
testElemIndex = scenario do
let x = [5, 4, 6, 7, 9, 4]
assert $ elemIndex 7 x == Some 3
assert $ elemIndex 5 x == Some 0
assert $ elemIndex 4 x == Some 1
elemIndex 7 x === Some 3
elemIndex 5 x === Some 0
elemIndex 4 x === Some 1
assert $ isNone $ elemIndex 10 x
testFindIndex = scenario do
let x = [5, 4, 6, 7, 9, 4]
assert $ findIndex (>6) x == Some 3
assert $ findIndex (>0) x == Some 0
assert $ findIndex (<5) x == Some 1
findIndex (>6) x === Some 3
findIndex (>0) x === Some 0
findIndex (<5) x === Some 1
assert $ isNone $ findIndex (>10) x
testSum = scenario do
assert $ sum [1, 2, 3] == 6
assert $ sum [] == 0
assert $ sum [] == (0.0 : Decimal)
assert $ sum [40.0, 2.0] == (42.0 : Decimal)
sum [1, 2, 3] === 6
sum [] === 0
sum [] === (0.0 : Decimal)
sum [40.0, 2.0] === (42.0 : Decimal)
testProduct = scenario do
assert $ product [1, 2, 3] == 6
assert $ product [] == 1
assert $ product [] == (1.0 : Decimal)
assert $ product [21.0, 2.0] == (42.0 : Decimal)
product [1, 2, 3] === 6
product [] === 1
product [] === (1.0 : Decimal)
product [21.0, 2.0] === (42.0 : Decimal)
testDelete = scenario do
delete "a" ["b","a","n","a","n","a"] === ["b","n","a","n","a"]

View File

@ -4,5 +4,7 @@
module ListComprehension where
import DA.Assert
test = scenario do
assert $ [n | n <- [1..10], n % 2 == 0] == [2*n | n <- [1..5]]
[n | n <- [1..10], n % 2 == 0] === [2*n | n <- [1..5]]

View File

@ -4,9 +4,9 @@
module ListEq where
import DA.Assert
main = scenario do
alice <- getParty "alice"
submit alice do
assert $ [1] == [1]
assert $ [1.0] /= ([2.0] : [Decimal])
assert $ [""] /= []
[1] === [1]
[1.0] =/= ([2.0] : [Decimal])
[""] =/= []

View File

@ -1,18 +1,19 @@
-- Copyright (c) 2020, Digital Asset (Switzerland) GmbH and/or its affiliates.
-- All rights reserved.
-- @WARN range=14:12-14:17; Maybe
-- @WARN range=17:12-17:17; maybe
-- @WARN range=17:29-17:36; Nothing
-- @WARN range=18:12-18:20; fromSome
-- @WARN range=18:22-18:26; Just
-- @WARN range=15:12-15:17; Maybe
-- @WARN range=18:3-18:8; maybe
-- @WARN range=18:20-18:27; Nothing
-- @WARN range=19:3-19:11; fromSome
-- @WARN range=19:13-19:17; Just
module MaybeCompat where
import DA.Assert
import DA.Maybe
import DA.Maybe.Total () -- we want to make sure there are not warnings in this module
type Foo = Maybe Int
main = scenario do
assert $ maybe 0 identity Nothing == 0
assert $ fromJust (Just 1) == 1
maybe 0 identity Nothing === 0
fromJust (Just 1) === 1

View File

@ -4,12 +4,13 @@
module MonoidTest where
import DA.Assert
import DA.Monoid
testSum = scenario do
assert $ Sum (1 : Int) <> Sum 2 == Sum (1 + 2)
assert $ mempty == Sum (aunit : Int)
Sum (1 : Int) <> Sum 2 === Sum (1 + 2)
mempty === Sum (aunit : Int)
testProduct = scenario do
assert $ Product (2 : Int) <> Product 3 == Product (2 * 3)
assert $ mempty == Product (munit : Int)
Product (2 : Int) <> Product 3 === Product (2 * 3)
mempty === Product (munit : Int)

View File

@ -3,6 +3,8 @@
module MoreChoiceObserverDivulgence where
import DA.Assert
-- @SINCE-LF 1.11
-- This example is a small modification of `DiscloseViaChoiceObserver`, but now the divulgence is achieved using a separate `Divulger` template, with a `Divulge` choice, which does a `fetch` on the given `id`, in the view of a choice-observer.
@ -30,7 +32,7 @@ template Divulger with
_ <- fetch id
pure ()
-- @WARN range=47:15-47:67; Use of divulged contracts is deprecated
-- @WARN range=49:15-49:67; Use of divulged contracts is deprecated
test : Scenario ()
test = scenario do
alice <- getParty "Alice"
@ -45,5 +47,5 @@ test = scenario do
exercise divulger Divulge with divulgee = bob; id
-- (4) Now Bob can see the secret
secret <- submit bob do exercise id Reveal with receiver = bob
assert (secret == "s3cr3t")
secret === "s3cr3t"
pure ()

View File

@ -3,8 +3,10 @@
module Nat where
import DA.Assert
data Nat = Z | S Nat
deriving (Eq,Ord)
deriving (Eq,Ord,Show)
add : Nat -> Nat -> Nat
@ -12,5 +14,4 @@ add Z x = x
add (S x) y = add x (S y)
main = scenario do
alice <- getParty "alice"
submit alice $ assert $ add (S (S Z)) (S Z) == S (S (S Z))
add (S (S Z)) (S Z) === S (S (S Z))

View File

@ -4,6 +4,8 @@
module Newtype where
import DA.Assert
newtype Nat = Nat{unNat : Int}
mkNat : Int -> Nat
@ -30,7 +32,7 @@ unNat3 : Nat -> Int
unNat3 n = unNat n
main = scenario do
assert $ unNat zero0 == 0
assert $ unNat1 one1 == 1
assert $ unNat2 (mkNat 2) == 2
assert $ unNat3 (unsafeMkNat 3) == 3
unNat zero0 === 0
unNat1 one1 === 1
unNat2 (mkNat 2) === 2
unNat3 (unsafeMkNat 3) === 3

View File

@ -4,10 +4,12 @@
module NewtypeDerive where
import DA.Assert
newtype New a = New a deriving (Eq, Ord, Show, Functor)
main = scenario do
assert $ New "x" == New "x"
New "x" === New "x"
assert $ New 1 < New 2
assert $ show (New 1) == "New 1"
assert $ fmap (+1) (New 1) == New 2
show (New 1) === "New 1"
fmap (+1) (New 1) === New 2

View File

@ -8,6 +8,8 @@
module NewtypeHigherKinded where
import DA.Assert
newtype App f a = App (f a)
newtype Wrap a = Wrap a
@ -19,4 +21,4 @@ unwrap : Functor f => App f (Wrap a) -> f a
unwrap (App xs) = fmap (\(Wrap x) -> x) xs
main = scenario do
assert (unwrap (wrap [1]) == [1])
unwrap (wrap [1]) === [1]

View File

@ -4,6 +4,7 @@
module NewtypeNested where
import DA.Assert
import Newtype
newtype Nat' = Nat' Nat
@ -15,4 +16,4 @@ unNat' : Nat' -> Nat
unNat' (Nat' n) = n
main = scenario do
assert $ unNat (unNat' (mkNat' (mkNat 1))) == 1
unNat (unNat' (mkNat' (mkNat 1))) === 1

View File

@ -4,6 +4,8 @@
module NewtypePolymorphic where
import DA.Assert
newtype T a = T a
mkT : a -> T a
@ -13,4 +15,4 @@ unT : T a -> a
unT (T x) = x
main = scenario do
assert (unT (mkT 1) == 1)
unT (mkT 1) === 1

View File

@ -9,6 +9,7 @@
module NumericLit where
import DA.Assert
import DA.Numeric (pi)
pi0 : Numeric 0
@ -27,8 +28,8 @@ pi37 : Numeric 37
pi37 = 3.14159_26535_89793_23846_26433_83279_50288_41
piTest = scenario $ do
assert $ pi == pi0
assert $ pi == pi5
assert $ pi == pi10
assert $ pi == pi15
assert $ pi == pi37
pi === pi0
pi === pi5
pi === pi10
pi === pi15
pi === pi37

View File

@ -6,6 +6,8 @@
module PatternSynonyms where
import DA.Assert
type Box = Optional
pattern Empty : Box a
@ -23,5 +25,5 @@ mapOptional f = \case
main = scenario do
let f : Int -> Text = show
assert $ mapOptional f Empty == Empty
assert $ mapOptional f (Filled 1) == Filled "1"
mapOptional f Empty === Empty
mapOptional f (Filled 1) === Filled "1"

View File

@ -3,8 +3,10 @@
module Phantom where
import DA.Assert
data Phantom a = Phantom {}
deriving Eq
deriving (Eq, Show)
phantom : Phantom (Party -> Party)
phantom = Phantom {}
@ -12,7 +14,5 @@ showOptional : (a -> Text) -> Optional a -> Text
showOptional f x = optional "None" f x
main = scenario do
alice <- getParty "alice"
submit alice do
assert $ phantom == Phantom {}
assert $ showOptional show (None : Optional Int) == "None"
phantom === Phantom {}
showOptional show (None : Optional Int) === "None"

View File

@ -1,7 +1,7 @@
-- Copyright (c) 2020, Digital Asset (Switzerland) GmbH and/or its affiliates.
-- All rights reserved.
-- @INFO range=54:27-54:43; Use uncurry
-- @INFO range=54:19-54:35; Use uncurry
-- @INFO range=68:9-68:19; Redundant identity
-- @INFO range=69:13-69:27; Redundant identity
-- @INFO range=70:23-70:61; Redundant identity
@ -17,8 +17,8 @@
-- @INFO range=120:13-120:38; Use &&
-- @INFO range=122:13-122:37; Use &&
-- @INFO range=123:12-123:28; Use &&
-- @INFO range=159:12-159:36; Use isNone
-- @INFO range=159:21-159:35; Use $>
-- @INFO range=159:13-159:27; Use $>
-- @INFO range=165:10-165:56; Evaluate
-- @INFO range=166:10-166:59; Evaluate
-- @INFO range=179:17-179:36; Use ++
@ -48,17 +48,17 @@ import DA.Date
testDollar = scenario do
let x1 = (+) 3 $ (*) 2 10
assert $ 23 == 23
23 === 23
testCurry = scenario do
assert $ 23 == curry (\(x, y) -> x + y) 20 3
23 === curry (\(x, y) -> x + y) 20 3
testUncurry = scenario do
assert $ 23 == uncurry (+) (20, 3)
23 === uncurry (+) (20, 3)
testPow = scenario do
assert $ 256 == 2^8
assert $ 2^2^2^2 == 65536
256 === 2^8
2^2^2^2 === 65536
testRemainder = scenario do
1 === 6 % 5
@ -156,7 +156,7 @@ testOptional = scenario do
None === fmap (+1) (fail "")
None === do None; pure 1
assert $ None == (None *> pure 1)
None === (None *> pure 1)
5 === optional 5 T.length None
5 === optional 5 T.length (Some "12345")
@ -326,27 +326,27 @@ testFixedpoint = scenario do
89 === fixedpoint (\f x -> if x < 2 then 1 else f (x-1) + f (x-2)) 10
testIntToDecimal = scenario do
assert $ intToDecimal 1 == 1.0
assert $ intToDecimal (-7) == (-7.0)
assert $ intToDecimal 0 == 0.0
intToDecimal 1 === 1.0
intToDecimal (-7) === (-7.0)
intToDecimal 0 === 0.0
testTruncate = scenario do
assert $ truncate (14.9 : Decimal) == 14
assert $ truncate (15.0 : Decimal) == 15
assert $ truncate ((-9.3) : Decimal) == (-9)
assert $ truncate (0.0 : Decimal) == 0
truncate (14.9 : Decimal) === 14
truncate (15.0 : Decimal) === 15
truncate ((-9.3) : Decimal) === (-9)
truncate (0.0 : Decimal) === 0
testCeiling = scenario do
assert $ ceiling (14.9 : Decimal) == 15
assert $ ceiling (15.0 : Decimal) == 15
assert $ ceiling ((-9.3) : Decimal) == (-9)
assert $ ceiling (0.0 : Decimal) == 0
ceiling (14.9 : Decimal) === 15
ceiling (15.0 : Decimal) === 15
ceiling ((-9.3) : Decimal) === (-9)
ceiling (0.0 : Decimal) === 0
testFloor = scenario do
assert $ floor (14.9 : Decimal) == 14
assert $ floor (15.0 : Decimal) == 15
assert $ floor ((-9.3) : Decimal) == (-10)
assert $ floor (0.0 : Decimal) == 0
floor (14.9 : Decimal) === 14
floor (15.0 : Decimal) === 15
floor ((-9.3) : Decimal) === (-10)
floor (0.0 : Decimal) === 0
testRound = scenario do
roundCommercial 0 10.5 === (11.0 : Decimal)
@ -361,13 +361,13 @@ testRound = scenario do
testNth = scenario do
let l = [1, 5, 10]
let v = l !! 1
assert $ v == 5
v === 5
testDiv = scenario do
assert $ 10.0 / 2.0 == (5.0 : Decimal)
assert $ 13.2 / 5.0 == (2.64 : Decimal)
10.0 / 2.0 === (5.0 : Decimal)
13.2 / 5.0 === (2.64 : Decimal)
assert $ 0.5 == recip (2.0 : Decimal)
0.5 === recip (2.0 : Decimal)
1.0 / 3.0 === (0.3333333333 : Decimal)
1.0 / 3.0 * 3.0 === (0.9999999999 : Decimal)
@ -379,9 +379,9 @@ testDiv = scenario do
5 / (-3) === -1
testDayOfWeek = scenario do
assert $ dayOfWeek (date 1900 Jan 01) == Monday
assert $ dayOfWeek (date 2018 Jan 17) == Wednesday
assert $ dayOfWeek (date 2020 Feb 29) == Saturday
dayOfWeek (date 1900 Jan 01) === Monday
dayOfWeek (date 2018 Jan 17) === Wednesday
dayOfWeek (date 2020 Feb 29) === Saturday
testDateOverflow = scenario do
pure $ date 2100 Feb 29

View File

@ -7,9 +7,10 @@
module Rank2 where
import DA.Assert
applyBoth : (forall c . [c] -> [c]) -> ([a], [b]) -> ([a], [b])
applyBoth f (a,b) = (f a, f b)
main = scenario do
alice <- getParty "alice"
submit alice $ assert $ applyBoth reverse ([1,2,3],["a","b"]) == ([3,2,1],["b","a"])
applyBoth reverse ([1,2,3],["a","b"]) === ([3,2,1],["b","a"])

View File

@ -4,32 +4,34 @@
module RecordsMore where
import DA.Assert
-- Tests for 'HasField' record preprocessor rewrites.
data A = A with x: Int deriving Eq
data B = B with y: A; z: A deriving Eq
data C = C {a : Int, b : Int} deriving Eq
data A = A with x: Int deriving (Eq, Show)
data B = B with y: A; z: A deriving (Eq, Show)
data C = C {a : Int, b : Int} deriving (Eq, Show)
main = scenario do
f <- return $ \ x y z -> x {a = y, b = z}
assert $ f C{a = 1, b = 2} 3 4 == C{a = 3, b = 4}
f C{a = 1, b = 2} 3 4 === C{a = 3, b = 4}
f <- return $ \ x y z -> x {a = y + z}
assert $ f C{a = 1, b = 2} 1 2 == C{a = 3, b = 2}
f C{a = 1, b = 2} 1 2 === C{a = 3, b = 2}
f <- return $ \ x a -> B a with x a with x
assert $ f 1 A{x = 12} == B (A 1) (A 1)
f 1 A{x = 12} === B (A 1) (A 1)
f <- return $ \ a -> a {x = a.x + 1}
assert $ (f A{x = 1}).x == 2
(f A{x = 1}).x === 2
f <- return $ \b -> b {y = b.y, z = b.z{x = 4}}
assert $ (f B{y = A{x = 1}, z = A{x = 2}}).z.x == 4
assert $ let res = f B{y = A{x = 1}, z = A{x = 2}} in res.z.x == 4
(f B{y = A{x = 1}, z = A{x = 2}}).z.x === 4
let res = f B{y = A{x = 1}, z = A{x = 2}} in res.z.x === 4
f <- return $ \b -> b {y = b.y, z = b.z{x = (\ x -> x * x) b.z.x}}
assert $ (f B{y = A{x = 1}, z = A{x = 2}}).z.x == 4
(f B{y = A{x = 1}, z = A{x = 2}}).z.x === 4
f <- return $ \b -> b {y = b.y{x = b.y.x + 1}, z = b.z{x = (\ x -> x * x) b.z{x = b.z.x}.x}}
assert $ (f B{y = A{x = 1}, z = A{x = 2}}).y.x == 2
assert $ (f B{y = A{x = 1}, z = A{x = 2}}).z.x == 4
(f B{y = A{x = 1}, z = A{x = 2}}).y.x === 2
(f B{y = A{x = 1}, z = A{x = 2}}).z.x === 4
f <- return $ \ l -> map (.x) l
assert $ f [A 1, A 2, A 3] == [1, 2, 3]
f [A 1, A 2, A 3] === [1, 2, 3]
f <- return $ \ l -> map (.y.x) l
assert $ f [B (A 1) (A 2), B (A 2) (A 3), B (A 3) (A 4)] == [1, 2, 3]
f [B (A 1) (A 2), B (A 2) (A 3), B (A 3) (A 4)] === [1, 2, 3]

View File

@ -4,6 +4,8 @@
module Self where
import DA.Assert
template Self with
p: Party
where
@ -12,7 +14,7 @@ template Self with
controller p can
Same : ()
with other: ContractId Self
do assert (self == other)
do self === other
main = scenario do
alice <- getParty "Alice"

View File

@ -4,6 +4,8 @@
module Self2 where
import DA.Assert
template Self2
with
p : Party
@ -33,5 +35,4 @@ main = scenario do
r <- submit alice do
cid <- create $ Self2 alice
exercise cid Foo
assert $ r == "ok"
r === "ok"

View File

@ -4,8 +4,9 @@
module SemigroupTest where
import DA.Assert
import DA.Semigroup
test = scenario do
assert $ Min (23 : Int) <> Min 42 == Min 23
assert $ Max (23 : Int) <> Max 42 == Max 42
Min (23 : Int) <> Min 42 === Min 23
Max (23 : Int) <> Max 42 === Max 42

View File

@ -1,8 +1,7 @@
-- @SINCE-LF 1.2
module Sha256 where
import DA.Assert
import DA.Text as T
test = scenario do
assert (T.sha256 "foo" == "2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae")
T.sha256 "foo" === "2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae"

View File

@ -9,8 +9,10 @@
module SugarUnit where
import DA.Assert
data Foo a = Foo a
deriving (Eq)
deriving (Eq, Show)
joinFoo ffx =
-- The desugaring of this nested pattern produces a `GHC.Tuple.Unit`.
@ -18,4 +20,4 @@ joinFoo ffx =
in Foo x
test = scenario do
assert $ joinFoo (Foo (Foo 1)) == Foo 1
joinFoo (Foo (Foo 1)) === Foo 1

View File

@ -4,19 +4,21 @@
module SumProducts where
import DA.Assert
data SumOfProducts
= Sum1 {field1 : Int, field2 : Text}
| Sum2
| Sum3 {field1 : Int, field3 : Optional Text, field4 : Bool}
| Sum4 Int
deriving (Eq,Ord)
deriving (Eq,Ord, Show)
main = scenario do
let sum1 = Sum1 3 "test"
let sum3 = Sum3 3 None True
let sum4 = Sum4 5
let sum4s = map Sum4 [1, 2]
assert $ sum1 /= Sum2
sum1 =/= Sum2
assert $ sum1 < Sum2
assert $ sum3 < sum4
assert $ sum1.field1 == sum3.field1
sum1.field1 === sum3.field1

View File

@ -26,11 +26,11 @@ testLength = scenario do
3 === T.length "abc"
testTrim = scenario do
assert $ trim " digital asset " == "digital asset"
trim " digital asset " === "digital asset"
testReplace = scenario do
assert $ replace "el" "_" "Hello Bella" == "H_lo B_la"
assert $ replace "el" "e" "Hello" == "Helo"
replace "el" "_" "Hello Bella" === "H_lo B_la"
replace "el" "e" "Hello" === "Helo"
testLines = scenario do
[] === lines ""
@ -51,20 +51,20 @@ testUnwords = scenario do
unwords ["one", "two"] === "one two"
testLinesBy = scenario do
assert $ linesBy (== "a") "aabbaca" == ["","","bb","c"]
assert $ linesBy (== "a") "aabbacaa" == ["","","bb","c",""]
linesBy (== "a") "aabbaca" === ["","","bb","c"]
linesBy (== "a") "aabbacaa" === ["","","bb","c",""]
assert $ null $ linesBy (== "a") ""
assert $ linesBy (== "a") "a" == [""]
assert $ linesBy (== ":") "::xyz:abc::123::" == ["","","xyz","abc","","123",""]
assert $ linesBy (== ",") "my,list,here" == ["my","list","here"]
linesBy (== "a") "a" === [""]
linesBy (== ":") "::xyz:abc::123::" === ["","","xyz","abc","","123",""]
linesBy (== ",") "my,list,here" === ["my","list","here"]
testWordsBy = scenario do
assert $ wordsBy (== "a") "aabbaca" == ["bb","c"]
assert $ wordsBy (== "a") "aabbacaa" == ["bb","c"]
wordsBy (== "a") "aabbaca" === ["bb","c"]
wordsBy (== "a") "aabbacaa" === ["bb","c"]
assert $ null $ wordsBy (== "a") ""
assert $ null $ wordsBy (== "a") "a"
assert $ wordsBy (== ":") "::xyz:abc::123::" == ["xyz","abc","123"]
assert $ wordsBy (== ",") "my,list,here" == ["my","list","here"]
wordsBy (== ":") "::xyz:abc::123::" === ["xyz","abc","123"]
wordsBy (== ",") "my,list,here" === ["my","list","here"]
testIntercalate = scenario do
"1, 2, 3" === intercalate ", " ["1", "2", "3"]
@ -73,22 +73,22 @@ testIntercalate = scenario do
"" === intercalate ", " []
testDropPrefix = scenario do
assert $ dropPrefix "Mr. " "Mr. Men" == "Men"
assert $ dropPrefix "Mr. " "Dr. Men" == "Dr. Men"
dropPrefix "Mr. " "Mr. Men" === "Men"
dropPrefix "Mr. " "Dr. Men" === "Dr. Men"
testDropSuffix = scenario do
assert $ dropSuffix "!" "Hello World!" == "Hello World"
assert $ dropSuffix "!" "Hello World!!" == "Hello World!"
assert $ dropSuffix "!" "Hello World." == "Hello World."
dropSuffix "!" "Hello World!" === "Hello World"
dropSuffix "!" "Hello World!!" === "Hello World!"
dropSuffix "!" "Hello World." === "Hello World."
testStripSuffix = scenario do
assert $ stripSuffix "bar" "foobar" == Some "foo"
assert $ stripSuffix "" "baz" == Some "baz"
stripSuffix "bar" "foobar" === Some "foo"
stripSuffix "" "baz" === Some "baz"
assert $ isNone $ stripSuffix "foo" "quux"
testStripPrefix = scenario do
assert $ stripPrefix "foo" "foobar" == Some "bar"
assert $ stripPrefix "" "baz" == Some "baz"
stripPrefix "foo" "foobar" === Some "bar"
stripPrefix "" "baz" === Some "baz"
assert $ isNone $ stripPrefix "foo" "quux"
testIsPrefixOf = scenario do

View File

@ -3,6 +3,7 @@
module TextEq where -- test of DEL-3881
import DA.Assert
stringEdit x = case x of
"USD" -> "JPY"
@ -10,7 +11,6 @@ stringEdit x = case x of
x -> x
main = scenario do
alice <- getParty "alice"
submit alice $ assert $ stringEdit "USD" == "JPY"
submit alice $ assert $ stringEdit "JPY" == "USD"
submit alice $ assert $ stringEdit "DAML" == "DAML"
stringEdit "USD" === "JPY"
stringEdit "JPY" === "USD"
stringEdit "DAML" === "DAML"

View File

@ -45,11 +45,11 @@ testNull = scenario do
testEq = scenario do
(TM.empty : TextMap Int) === (TM.empty : TextMap Int)
assert (TM.empty /= TM.fromList [("1", 1)])
TM.empty =/= TM.fromList [("1", 1)]
TM.fromList [("1", 1), ("2", 2), ("3", 3)] === TM.fromList [("1", 1), ("2", 2), ("3", 3)]
assert (TM.fromList [("1", 1), ("2", 2), ("3", 3)] /= TM.fromList [("1", 2), ("2", 2)])
assert (TM.fromList [("1", 1), ("2", 2), ("3", 3)] /= TM.fromList [("1", 2), ("2", 2), ("3", 4)])
assert (TM.fromList [("1", 1), ("2", 2), ("3", 3)] /= TM.fromList [("1", 2), ("2", 2), ("4", 3)])
TM.fromList [("1", 1), ("2", 2), ("3", 3)] =/= TM.fromList [("1", 2), ("2", 2)]
TM.fromList [("1", 1), ("2", 2), ("3", 3)] =/= TM.fromList [("1", 2), ("2", 2), ("3", 4)]
TM.fromList [("1", 1), ("2", 2), ("3", 3)] =/= TM.fromList [("1", 2), ("2", 2), ("4", 3)]
testInsert = scenario do
[("1", True), ("2", False), ("3", True), ("4", False), ("5", False)]

View File

@ -2,8 +2,9 @@
-- All rights reserved.
module Trace where
import DA.Assert
main = scenario do
debug "using traceA in a scenario"
alice <- traceId <$> getParty "Alice"
submit alice $ assert $ traceId 1 == trace "custom trace message" 1
traceId 1 === trace "custom trace message" 1

View File

@ -43,7 +43,7 @@ testThd3 = scenario do
True === thd3 (1, "A", True)
testCurry3 = scenario do
assert $ 123 == curry3 (\(x, y, z) -> x + y + z) 20 3 100
123 === curry3 (\(x, y, z) -> x + y + z) 20 3 100
testUncurry3 = scenario do
assert $ 123 == uncurry3 (\x y z -> x + y + z) (20, 3, 100)
123 === uncurry3 (\x y z -> x + y + z) (20, 3, 100)

View File

@ -1,7 +1,5 @@
-- Copyright (c) 2020, Digital Asset (Switzerland) GmbH and/or its affiliates.
-- All rights reserved.
-- @INFO Use negate
-- @INFO Use negate
-- Test that foo does not overflow
@ -12,11 +10,11 @@
module UseInteger where
import DA.Assert
foo = 1
bar = 9223372036854775807 -- maxBound :: Int64 (*)
main = scenario do
alice <- getParty "alice"
submit alice do
assertMsg "Was not one" (foo == 1)
assert $ 0 - foo - bar == 0 - 2^62 - 2^62 -- minBound :: Int64
foo === 1
0 - foo - bar === 0 - 2^62 - 2^62 -- minBound :: Int64