use super::super::checked; #[test] fn handler_ranges_check_unused_templates_inference_and_forwarding() { let apply = "apply(route: handler(value: Int >= 1) (answer: Int >= 2)) (answer: Int >= 2) { answer = route(1) }\n"; checked(apply).unwrap(); checked(&(apply.to_owned() + "twice(value: Int) (answer: Int) { answer = 2 }\nmake() (answer: Int >= 2) { answer = apply(twice) }")).unwrap(); assert_eq!(checked(&(apply.to_owned() + "identity(value: Int) (answer: Int) { answer = value }\nmake() (answer: Int) { answer = apply(identity) }")).unwrap_err().code, "C011"); assert_eq!( checked( "bad(route: handler(value: Int >= 1) (answer: Int)) (answer: Int) { answer = route(0) }" ) .unwrap_err() .code, "C011" ); checked(&(apply.to_owned() + "forward(route: handler(value: Int) (answer: Int >= 3)) (answer: Int >= 2) { answer = apply(route) }")).unwrap(); for contract in [ "handler(value: Int >= 2) (answer: Int >= 3)", "handler(value: Int) (answer: Int >= 1)", ] { assert_eq!( checked(&format!( "{apply}forward(route: {contract}) (answer: Int) {{ answer = apply(route) }}" )) .unwrap_err() .code, "C011" ); } } #[test] fn prototype_cache_keeps_distinct_range_contracts() { let prefix = "first(route: handler(value: Int) (answer: Int >= 2)) (answer: Int >= 2) { answer = route(1) }\n"; assert_eq!(checked(&(prefix.to_owned() + "second(route: handler(value: Int) (answer: Int >= 1)) (answer: Int >= 2) { answer = route(1) }")).unwrap_err().code, "C011"); assert_eq!(checked("first(route: handler(value: Int >= 1) (answer: Int)) (answer: Int) { answer = route(1) }\nsecond(route: handler(value: Int >= 2) (answer: Int)) (answer: Int) { answer = route(1) }").unwrap_err().code, "C011"); } #[test] fn collection_handlers_check_items_context_and_repeated_state() { checked("valid(route: handler(value: Int >= 1) (answer: Int >= 2)) (answer: List) { answer = each(route, [1, 2]) }").unwrap(); for body in [ "bad(route: handler(value: Int >= 1) (answer: Int), values: List) (answer: List) { answer = each(route, values) }", "bad(route: handler(value: Int >= 1) (answer: Int)) (answer: List) { answer = each(route, [0, 1]) }", "bad(route: handler(value: Int, state: Int >= 1) (answer: Int)) (answer: Int) { answer = reduce(route, [1, 2], 1) }", "bad(route: handler(value: Int, context: Int >= 1) (answer: Int)) (answer: List) { answer = each(route, [1], 0) }", ] { assert_eq!(checked(body).unwrap_err().code, "C011", "{body}"); } checked("valid(route: handler(value: Int, state: Int >= 1) (answer: Int >= 1)) (answer: Int >= 1) { answer = reduce(route, [1, 2], 1) }").unwrap(); checked("valid(route: handler(value: Int >= 0 and <= 255) (answer: Int), values: Bytes) (answer: List) { answer = each(route, values) }").unwrap(); } #[test] fn failing_collection_inputs_do_not_produce_invalid_values() { let prefix = "type Problem { error Failed }\nabortOperation() (answer: Int) { fail(Problem.Failed) }\n"; checked(&(prefix.to_owned() + "apply(route: handler(value: Int, context: Int >= 1) (answer: Int)) (answer: List) { answer = each(route, [1], abortOperation()) }")).unwrap(); checked("type Problem { error Failed }\nabortOperation(value: Int, state: Int) (answer: Int) { fail(Problem.Failed) }\napply(route: handler(value: Int, state: Int >= 1) (answer: Int >= 1)) (answer: Int >= 1) { answer = reduce(route, [1], 1) }\nentry() (answer: Int >= 1) { answer = apply(abortOperation) }").unwrap(); }