Alpha: allow no commas in tez litterals

This commit is contained in:
Benjamin Canou 2017-12-14 18:40:30 +01:00
parent 319585dd80
commit ac93872b2c
3 changed files with 40 additions and 11 deletions

View File

@ -6,9 +6,11 @@ For the next reset
- Do not allow revealing the same endorsement twice. - Do not allow revealing the same endorsement twice.
- Tez values now have 6 decimals instead of two. The syntax used by - Tez values now have 6 decimals instead of two. The syntax used by
the client and Michelson requires comma separators every three the client and Michelson use comma separators every three
digits, before and after the dot. For instance, 3 million tez and 10 digits, before and after the dot. For instance, 3 million tez and 10
µtez is written `3,000,000.000,01`. µtez is written `3,000,000.000,01`. The syntax in JSON is the raw
amount in µtez, either as a number without decimals or as a decimal
string, for the same example we would get `"3000000000010"`.
[Node] [Node]

View File

@ -107,8 +107,20 @@ module Make (T: QTY) : S = struct
Some (Int64.of_string (remove_commas left ^ pad_to_six (remove_commas right))) Some (Int64.of_string (remove_commas left ^ pad_to_six (remove_commas right)))
with _ -> None in with _ -> None in
match String.split_on_char '.' s with match String.split_on_char '.' s with
| [ left ; right ] when (integers left && decimals right) -> parse left right | [ left ; right ] ->
| [ left ] when integers left -> parse left "" if String.contains s ',' then
if integers left && decimals right then
parse left right
else
None
else if Compare.Int.(String.length right > 0)
&& Compare.Int.(String.length right <= 6) then
parse left right
else None
| [ left ] ->
if not (String.contains s ',') || integers left then
parse left ""
else None
| _ -> None | _ -> None
let pp ppf amount = let pp ppf amount =

View File

@ -34,14 +34,16 @@ let known_ok_tez_litterals =
999_999_999_999_999_999L, "999,999,999,999.999,999" ] 999_999_999_999_999_999L, "999,999,999,999.999,999" ]
let known_bad_tez_litterals = let known_bad_tez_litterals =
[ "10000" ; [ "10000." ;
"100,." ;
"100," ;
"1,0000" ; "1,0000" ;
"0.0000,1" ; "0.0000,1" ;
"0.00,1" ; "0.00,1" ;
"0,1" ; "0,1" ;
"0.0001" ;
"HAHA" ; "HAHA" ;
"0.000,000,1" ; "0.000,000,1" ;
"0.0000000" ;
"9,999,999,999,999.999,999"] "9,999,999,999,999.999,999"]
let test_known_tez_litterals () = let test_known_tez_litterals () =
@ -49,9 +51,12 @@ let test_known_tez_litterals () =
(fun (v, s) -> (fun (v, s) ->
let vv = Tez_repr.of_mutez v in let vv = Tez_repr.of_mutez v in
let vs = Tez_repr.of_string s in let vs = Tez_repr.of_string s in
let vs' = Tez_repr.of_string (String.concat "" (String.split_on_char ',' s)) in
let vv = match vv with None -> Assert.fail_msg "could not unopt %Ld" v | Some vv -> vv in let vv = match vv with None -> Assert.fail_msg "could not unopt %Ld" v | Some vv -> vv in
let vs = match vs with None -> Assert.fail_msg "could not unopt %s" s | Some vs -> vs in let vs = match vs with None -> Assert.fail_msg "could not unopt %s" s | Some vs -> vs in
let vs' = match vs' with None -> Assert.fail_msg "could not unopt %s" s | Some vs' -> vs' in
Assert.equal ~prn:Tez_repr.to_string vv vs ; Assert.equal ~prn:Tez_repr.to_string vv vs ;
Assert.equal ~prn:Tez_repr.to_string vv vs' ;
Assert.equal ~prn:(fun s -> s) (Tez_repr.to_string vv) s) Assert.equal ~prn:(fun s -> s) (Tez_repr.to_string vv) s)
known_ok_tez_litterals ; known_ok_tez_litterals ;
List.iter List.iter
@ -68,12 +73,22 @@ let test_random_tez_litterals () =
let vv = match vv with None -> Assert.fail_msg "could not unopt %Ld" v | Some vv -> vv in let vv = match vv with None -> Assert.fail_msg "could not unopt %Ld" v | Some vv -> vv in
let s = Tez_repr.to_string vv in let s = Tez_repr.to_string vv in
let vs = Tez_repr.of_string s in let vs = Tez_repr.of_string s in
let s' = String.concat "" (String.split_on_char ',' s) in
let vs' = Tez_repr.of_string s' in
Assert.is_some ~msg:("Could not parse " ^ s ^ " back") vs ; Assert.is_some ~msg:("Could not parse " ^ s ^ " back") vs ;
match vs with Assert.is_some ~msg:("Could not parse " ^ s ^ " back") vs' ;
begin match vs with
| None -> assert false | None -> assert false
| Some vs -> | Some vs ->
let rev = Tez_repr.to_int64 vs in let rev = Tez_repr.to_int64 vs in
Assert.equal ~prn:Int64.to_string ~msg:(Tez_repr.to_string vv) v rev Assert.equal ~prn:Int64.to_string ~msg:(Tez_repr.to_string vv) v rev
end ;
begin match vs' with
| None -> assert false
| Some vs' ->
let rev = Tez_repr.to_int64 vs' in
Assert.equal ~prn:Int64.to_string ~msg:(Tez_repr.to_string vv) v rev
end
done ; done ;
return () return ()