Skip to content

Commit 5f1f946

Browse files
committed
Add Dafny runtime tests to CI
1 parent 0fa3a55 commit 5f1f946

9 files changed

Lines changed: 123 additions & 8 deletions

‎.github/workflows/ci.yaml‎

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,19 +23,24 @@ jobs:
2323
wget -q https://github.com/dafny-lang/dafny/releases/download/v4.11.0/dafny-4.11.0-x64-ubuntu-22.04.zip
2424
unzip -qq dafny-4.11.0-x64-ubuntu-22.04.zip
2525
echo "dafny=$PWD/dafny/dafny" >> $GITHUB_ENV
26-
- name: test
26+
- name: verify and test
2727
env:
2828
DAFNY: "${{ env.dafny }}"
2929
TEST_DIR: "${{ matrix.test_dir }}"
3030
run: |
31-
for b in $(ls $TEST_DIR/*.dfy)
31+
set -euo pipefail
32+
shopt -s nullglob
33+
for b in "$TEST_DIR"/*.dfy
3234
do
33-
echo $b
35+
echo "$b"
3436
if [[ "$b" == *"[wip]"* ]]
3537
then
36-
echo "Ignore working in progress proof: "$b
38+
echo "Ignore working in progress proof: $b"
39+
elif grep -q '{:test}' "$b"
40+
then
41+
"$DAFNY" test --verification-time-limit 30 "$b"
3742
else
38-
$DAFNY verify "$b"
43+
"$DAFNY" verify --verification-time-limit 30 "$b"
3944
fi
4045
echo "================================================"
4146
done

‎.gitignore‎

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,12 @@ bin/
33
leetcode/*.txt
44
lib/**/Work*
55
*.dll
6-
*.json
6+
*.json
7+
8+
# Generated by `dafny test` when using the default C# target.
9+
*.cs
10+
*.csproj
11+
*.exe
12+
*.pdb
13+
obj/
14+
**/obj/

‎leetcode/0001-two-sum.dfy‎

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,17 @@ method TwoSum(nums: array<int>, target: int) returns (r: (int, int))
4040
i := i + 1;
4141
}
4242
return (-1, -1);
43-
}
43+
}
44+
45+
method {:test} TestTwoSum()
46+
{
47+
var nums := new int[4];
48+
nums[0], nums[1], nums[2], nums[3] := 2, 7, 11, 15;
49+
var r := TwoSum(nums, 9);
50+
expect r == (0, 1), "[2,7,11,15], target 9 should return (0,1)";
51+
52+
var none := new int[3];
53+
none[0], none[1], none[2] := 1, 2, 4;
54+
var missing := TwoSum(none, 8);
55+
expect missing == (-1, -1), "no-solution case should return (-1,-1)";
56+
}

‎leetcode/0004-median-two-sorted-arrays.dfy‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -464,3 +464,15 @@ lemma ExampleEven()
464464
assert Merge([1, 2], [3, 4]) == [1, 2, 3, 4];
465465
MergeLen([1, 2], [3, 4]);
466466
}
467+
468+
method {:test} TestFindMedianSortedArraysX2()
469+
{
470+
var odd := FindMedianSortedArraysX2([1, 3], [2]);
471+
expect odd == 4, "median of [1,3] and [2] should be 2.0";
472+
473+
var even := FindMedianSortedArraysX2([1, 2], [3, 4]);
474+
expect even == 5, "median of [1,2] and [3,4] should be 2.5";
475+
476+
var swapped := FindMedianSortedArraysX2([3, 4], [1, 2]);
477+
expect swapped == 5, "median should be independent of argument order";
478+
}

‎leetcode/0146-lru-cache.dfy‎

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -396,3 +396,27 @@ class LRUCache {
396396
}
397397
}
398398
}
399+
400+
method {:test} TestLRUCache()
401+
{
402+
var cache := new LRUCache(2);
403+
cache.Put(1, 1);
404+
cache.Put(2, 2);
405+
406+
var one := cache.Get(1);
407+
expect one == 1, "Get(1) should return 1";
408+
409+
cache.Put(3, 3);
410+
var evictedTwo := cache.Get(2);
411+
expect evictedTwo == -1, "Put(3,3) should evict key 2";
412+
413+
cache.Put(4, 4);
414+
var evictedOne := cache.Get(1);
415+
expect evictedOne == -1, "Put(4,4) should evict key 1";
416+
417+
var three := cache.Get(3);
418+
expect three == 3, "Get(3) should return 3";
419+
420+
var four := cache.Get(4);
421+
expect four == 4, "Get(4) should return 4";
422+
}

‎leetcode/0155-min-stack.dfy‎

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,4 +155,24 @@ class MinStack {
155155
// {
156156
// return Last(mins);
157157
// }
158-
// }
158+
// }
159+
160+
method {:test} TestMinStack()
161+
{
162+
var stack := new MinStack();
163+
stack.Push(-2);
164+
stack.Push(0);
165+
stack.Push(-3);
166+
167+
var min1 := stack.GetMin();
168+
expect min1 == -3, "minimum should be -3";
169+
170+
var popped := stack.Pop();
171+
expect popped == -3, "pop should remove -3";
172+
173+
var top := stack.Top();
174+
expect top == 0, "top should be 0";
175+
176+
var min2 := stack.GetMin();
177+
expect min2 == -2, "minimum should be -2 after popping -3";
178+
}

‎leetcode/0312-burst-balloons.dfy‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,3 +352,18 @@ lemma BruteVsBestTwo()
352352
{
353353
BestEqualsBruteMaxPair(3, 1);
354354
}
355+
356+
method {:test} TestBurstBalloons()
357+
{
358+
var empty := BurstBalloons([]);
359+
expect empty == 0, "empty input should score 0";
360+
361+
var single := BurstBalloons([5]);
362+
expect single == 5, "single balloon [5] should score 5";
363+
364+
var pair := BurstBalloons([3, 1]);
365+
expect pair == 6, "[3,1] should score 6";
366+
367+
var leet := BurstBalloons([3, 1, 5, 8]);
368+
expect leet == 167, "[3,1,5,8] should score 167";
369+
}

‎leetcode/0407-trapping-rain-water-ii-correct.dfy‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -526,3 +526,12 @@ ExampleBowl()
526526
Vol(EscGrid(H, 5, 1), H) == 4
527527
{
528528
}
529+
530+
method {:test} TestTrappingRainWaterByEscapeLevels()
531+
{
532+
var bowl := TrappingRainWater([[5, 5, 5], [5, 1, 5], [5, 5, 5]]);
533+
expect bowl == 4, "3x3 bowl should trap 4";
534+
535+
var flat := TrappingRainWater([[1, 1], [1, 1]]);
536+
expect flat == 0, "boundary-only grid should trap 0";
537+
}

‎leetcode/0407-trapping-rain-water-ii.dfy‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,3 +178,12 @@ method HeapFloodTrappingRainWater(heightMap: seq<seq<int>>) returns (water: int)
178178
water == Vol(L, heightMap);
179179
}
180180
}
181+
182+
method {:test} TestHeapFloodBoundaryOnly()
183+
{
184+
var oneRow := HeapFloodTrappingRainWater([[1, 4, 2]]);
185+
expect oneRow == 0, "single-row grid should trap 0";
186+
187+
var twoRows := HeapFloodTrappingRainWater([[3, 1, 3], [3, 3, 3]]);
188+
expect twoRows == 0, "two-row grid should trap 0";
189+
}

0 commit comments

Comments
 (0)