240 lines
5.1 KiB
Go
240 lines
5.1 KiB
Go
// LeetCode 3025 Go 單元測試
|
||
package main
|
||
|
||
import (
|
||
"math/rand"
|
||
"testing"
|
||
"fmt"
|
||
)
|
||
|
||
func TestCase1_ExampleFromProblem(t *testing.T) {
|
||
// Arrange
|
||
points := [][]int{
|
||
{6, 2},
|
||
{4, 4},
|
||
{2, 6},
|
||
}
|
||
expected := 2
|
||
|
||
// Act
|
||
result := numberOfPairs(points)
|
||
|
||
// Assert
|
||
if result != expected {
|
||
t.Errorf("TestCase1 failed. Expected: %v, Got: %v", expected, result)
|
||
}
|
||
}
|
||
|
||
func TestCase2_TwoPoints(t *testing.T) {
|
||
// Arrange
|
||
points := [][]int{
|
||
{1, 3},
|
||
{2, 1},
|
||
}
|
||
expected := 1
|
||
|
||
// Act
|
||
result := numberOfPairs(points)
|
||
|
||
// Assert
|
||
if result != expected {
|
||
t.Errorf("TestCase2 failed. Expected: %v, Got: %v", expected, result)
|
||
}
|
||
}
|
||
|
||
func TestCase3_NoValidPairs(t *testing.T) {
|
||
// Arrange - 沒有有效點對的情況
|
||
points := [][]int{
|
||
{1, 1},
|
||
{2, 2},
|
||
{3, 3},
|
||
}
|
||
expected := 0
|
||
|
||
// Act
|
||
result := numberOfPairs(points)
|
||
|
||
// Assert
|
||
if result != expected {
|
||
t.Errorf("TestCase3 failed. Expected: %v, Got: %v", expected, result)
|
||
}
|
||
}
|
||
|
||
func TestCase4_SameXCoordinate(t *testing.T) {
|
||
// Arrange - x 座標相同的情況
|
||
points := [][]int{
|
||
{3, 5}, // A
|
||
{3, 2}, // B
|
||
{3, 1}, // C
|
||
}
|
||
// 詳細分析:
|
||
// (A, B): (3,5) -> (3,2) ✓ 矩形是線段,無其他點
|
||
// (A, C): (3,5) -> (3,1) ✗ 點B在矩形內
|
||
// (B, C): (3,2) -> (3,1) ✓ 矩形是線段,無其他點
|
||
expected := 2
|
||
|
||
// Act
|
||
result := numberOfPairs(points)
|
||
|
||
// Assert
|
||
if result != expected {
|
||
t.Errorf("TestCase4 failed. Expected: %v, Got: %v", expected, result)
|
||
}
|
||
}
|
||
|
||
func TestCase5_SameYCoordinate(t *testing.T) {
|
||
// Arrange - y 座標相同的情況
|
||
points := [][]int{
|
||
{1, 4}, // A
|
||
{3, 4}, // B
|
||
{5, 4}, // C
|
||
}
|
||
// 詳細分析:
|
||
// (A, B): (1,4) -> (3,4) ✓ 矩形是線段,無其他點
|
||
// (A, C): (1,4) -> (5,4) ✗ 點B在矩形內
|
||
// (B, C): (3,4) -> (5,4) ✓ 矩形是線段,無其他點
|
||
expected := 2
|
||
|
||
// Act
|
||
result := numberOfPairs(points)
|
||
|
||
// Assert
|
||
if result != expected {
|
||
t.Errorf("TestCase5 failed. Expected: %v, Got: %v", expected, result)
|
||
}
|
||
}
|
||
|
||
func TestCase6_PointsInsideRectangle(t *testing.T) {
|
||
// Arrange - 矩形內有其他點的情況
|
||
points := [][]int{
|
||
{0, 4}, // A
|
||
{4, 0}, // B
|
||
{2, 2}, // C
|
||
}
|
||
// 詳細分析:
|
||
// (A, B): (0,4) -> (4,0) ✗ 點C在矩形內
|
||
// (A, C): (0,4) -> (2,2) ✓ 點B不在矩形內
|
||
// (C, B): (2,2) -> (4,0) ✓ 點A不在矩形內
|
||
expected := 2
|
||
|
||
// Act
|
||
result := numberOfPairs(points)
|
||
|
||
// Assert
|
||
if result != expected {
|
||
t.Errorf("TestCase6 failed. Expected: %v, Got: %v", expected, result)
|
||
}
|
||
}
|
||
|
||
func TestCase7_PointsOnBorder(t *testing.T) {
|
||
// Arrange - 點在矩形邊界上的情況
|
||
points := [][]int{
|
||
{0, 3}, // A
|
||
{3, 0}, // B
|
||
{0, 0}, // C
|
||
}
|
||
// 詳細分析:
|
||
// (A, B): (0,3) -> (3,0) ✗ 點C在矩形邊界上
|
||
// (A, C): (0,3) -> (0,0) ✓ 矩形是線段,點B不在其中
|
||
// (C, B): (0,0) -> (3,0) ✓ 矩形是線段,點A不在其中
|
||
expected := 2
|
||
|
||
// Act
|
||
result := numberOfPairs(points)
|
||
|
||
// Assert
|
||
if result != expected {
|
||
t.Errorf("TestCase7 failed. Expected: %v, Got: %v", expected, result)
|
||
}
|
||
}
|
||
|
||
func TestEdgeCases_MinimumPoints(t *testing.T) {
|
||
// Arrange - 最少點數情況 (題目限制 n >= 2)
|
||
points := [][]int{
|
||
{0, 1},
|
||
{1, 0},
|
||
}
|
||
expected := 1 // (0,1) 在 (1,0) 的左上方
|
||
|
||
// Act
|
||
result := numberOfPairs(points)
|
||
|
||
// Assert
|
||
if result != expected {
|
||
t.Errorf("TestEdgeCases_MinimumPoints failed. Expected: %v, Got: %v", expected, result)
|
||
}
|
||
}
|
||
|
||
func TestEdgeCases_MaxCoordinateValues(t *testing.T) {
|
||
// Arrange - 最大座標值情況 (題目限制 0 <= coordinates <= 50)
|
||
points := [][]int{
|
||
{0, 50}, // A
|
||
{50, 0}, // B
|
||
{25, 25}, // C
|
||
}
|
||
expected := 2 // (A,C) 和 (C,B) 有效
|
||
|
||
// Act
|
||
result := numberOfPairs(points)
|
||
|
||
// Assert
|
||
if result != expected {
|
||
t.Errorf("TestEdgeCases_MaxCoordinateValues failed. Expected: %v, Got: %v", expected, result)
|
||
}
|
||
}
|
||
|
||
func TestEdgeCases_EmptyArray(t *testing.T) {
|
||
// Arrange - 空陣列情況
|
||
points := [][]int{}
|
||
expected := 0
|
||
|
||
// Act
|
||
result := numberOfPairs(points)
|
||
|
||
// Assert
|
||
if result != expected {
|
||
t.Errorf("TestEdgeCases_EmptyArray failed. Expected: %v, Got: %v", expected, result)
|
||
}
|
||
}
|
||
|
||
func TestEdgeCases_MaxPoints_RandomPattern(t *testing.T) {
|
||
// Arrange - 50個不同的點,隨機模式
|
||
points := make([][]int, 0, 50)
|
||
usedPoints := make(map[string]bool)
|
||
|
||
// 使用固定種子確保測試可重現
|
||
rand.Seed(42)
|
||
|
||
for len(points) < 50 {
|
||
x := rand.Intn(51) // 0-50
|
||
y := rand.Intn(51) // 0-50
|
||
pointKey := fmt.Sprintf("%d,%d", x, y)
|
||
|
||
if !usedPoints[pointKey] {
|
||
usedPoints[pointKey] = true
|
||
points = append(points, []int{x, y})
|
||
}
|
||
}
|
||
|
||
// Act
|
||
result := numberOfPairs(points)
|
||
|
||
// Assert
|
||
if result < 0 {
|
||
t.Errorf("TestEdgeCases_MaxPoints_RandomPattern failed. Result should be non-negative, got: %v", result)
|
||
}
|
||
if result > 50*49 {
|
||
t.Errorf("TestEdgeCases_MaxPoints_RandomPattern failed. Result should not exceed 50*49, got: %v", result)
|
||
}
|
||
|
||
// 額外驗證:確保所有點都是不同的
|
||
distinctPoints := make(map[string]bool)
|
||
for _, point := range points {
|
||
key := fmt.Sprintf("%d,%d", point[0], point[1])
|
||
distinctPoints[key] = true
|
||
}
|
||
if len(distinctPoints) != 50 {
|
||
t.Errorf("TestEdgeCases_MaxPoints_RandomPattern failed. Expected 50 distinct points, got: %v", len(distinctPoints))
|
||
}
|
||
}
|