-
Notifications
You must be signed in to change notification settings - Fork 0
/
code-contract.test.ts
122 lines (108 loc) · 2.71 KB
/
code-contract.test.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
/**
* @file Unit tests for code contract utility
*/
import {
assertEquals,
assertThrows,
} from "https://deno.land/std/testing/asserts.ts";
import {
codeContract,
disableContract,
enableContract,
} from "./code-contract.ts";
//
// Variables
//
let sideEffectTarget = true;
//
// Functions
//
const func = (lhs: number, rhs: number) => (lhs + rhs);
//
// Test cases
//
Deno.test({
name: "It should success the function call if the contract is kept",
fn: () => {
// arrange
enableContract();
sideEffectTarget = false;
const contracted = codeContract(func, {
pre: (lhs: number, rhs: number) => 0 < lhs && 0 < rhs,
post: (result: number) => (result === 30),
});
// act & assert
assertEquals(contracted(10, 20), 30);
},
});
Deno.test({
name: "It should fail the function call if the pre condition is invalid",
fn: () => {
assertThrows(
() => {
// arrange
enableContract();
sideEffectTarget = false;
const contracted = codeContract(func, {
pre: (lhs: number, rhs: number) => 0 < lhs && 0 < rhs,
});
// act & assert
assertEquals(contracted(20, -10), 10);
},
);
},
});
Deno.test({
name: "It should fail the function call if the post condition is invalid",
fn: () => {
assertThrows(
() => {
// arrange
enableContract();
sideEffectTarget = false;
const contracted = codeContract(func, {
post: (result: number) => (result === 30),
});
// act & assert
assertEquals(contracted(20, 20), 40);
},
);
},
});
Deno.test({
name:
"It should fail the function call if the invariant condition is invalid",
fn: () => {
assertThrows(
() => {
// arrange
enableContract();
sideEffectTarget = false;
const funcWithSideEffect = (
lhs: number,
rhs: number,
) => (sideEffectTarget = true, lhs + rhs);
const contracted = codeContract(funcWithSideEffect, {
invariant: () => (sideEffectTarget === false),
});
// act & assert
assertEquals(contracted(20, 20), 40);
},
);
},
});
Deno.test({
name: "It should omit contract check if contract check is disabled",
fn: () => {
// arrange
disableContract();
sideEffectTarget = false;
const contracted = codeContract(func, {
pre: (lhs: number, rhs: number) => 0 < lhs && 0 < rhs,
post: (result: number) => (result === 30),
});
// act & assert
assertEquals(contracted(-10, -20), -30);
enableContract();
},
});