Nothing
# test-coverage-splot-polygons-41.R - Comprehensive tests for R/splot-polygons.R
# Tests for polygon vertex generation functions
# Make internal functions available for testing
skip_on_cran()
circle_vertices <- cograph:::circle_vertices
square_vertices <- cograph:::square_vertices
rectangle_vertices <- cograph:::rectangle_vertices
triangle_vertices <- cograph:::triangle_vertices
diamond_vertices <- cograph:::diamond_vertices
pentagon_vertices <- cograph:::pentagon_vertices
hexagon_vertices <- cograph:::hexagon_vertices
star_vertices <- cograph:::star_vertices
heart_vertices <- cograph:::heart_vertices
ellipse_vertices <- cograph:::ellipse_vertices
cross_vertices <- cograph:::cross_vertices
regular_polygon_vertices <- cograph:::regular_polygon_vertices
inset_polygon_vertices <- cograph:::inset_polygon_vertices
get_donut_base_vertices <- cograph:::get_donut_base_vertices
gear_vertices <- cograph:::gear_vertices
cloud_vertices <- cograph:::cloud_vertices
brain_vertices <- cograph:::brain_vertices
get_shape_vertices <- cograph:::get_shape_vertices
# ============================================
# CIRCLE VERTICES
# ============================================
test_that("circle_vertices generates correct structure", {
verts <- circle_vertices(0, 0, 1)
expect_true(is.list(verts))
expect_true("x" %in% names(verts))
expect_true("y" %in% names(verts))
expect_equal(length(verts$x), 50) # default n = 50
expect_equal(length(verts$y), 50)
})
test_that("circle_vertices respects center coordinates", {
verts <- circle_vertices(5, 10, 1)
# Center of mass should be near the specified center
expect_equal(mean(verts$x), 5, tolerance = 0.01)
expect_equal(mean(verts$y), 10, tolerance = 0.01)
})
test_that("circle_vertices respects radius", {
r <- 2.5
verts <- circle_vertices(0, 0, r)
# All points should be at distance r from center
distances <- sqrt(verts$x^2 + verts$y^2)
expect_true(all(abs(distances - r) < 0.01))
})
test_that("circle_vertices respects n parameter", {
for (n in c(10, 25, 100, 200)) {
verts <- circle_vertices(0, 0, 1, n = n)
expect_equal(length(verts$x), n, info = paste("Failed for n =", n))
expect_equal(length(verts$y), n, info = paste("Failed for n =", n))
}
})
test_that("circle_vertices handles small n values", {
# n = 3 creates a triangle-like shape
verts <- circle_vertices(0, 0, 1, n = 3)
expect_equal(length(verts$x), 3)
expect_equal(length(verts$y), 3)
})
test_that("circle_vertices handles negative coordinates", {
verts <- circle_vertices(-5, -3, 1.5)
expect_equal(mean(verts$x), -5, tolerance = 0.01)
expect_equal(mean(verts$y), -3, tolerance = 0.01)
})
# ============================================
# SQUARE VERTICES
# ============================================
test_that("square_vertices generates correct structure", {
verts <- square_vertices(0, 0, 1)
expect_true(is.list(verts))
expect_equal(length(verts$x), 4)
expect_equal(length(verts$y), 4)
})
test_that("square_vertices respects center coordinates", {
verts <- square_vertices(3, 7, 1)
expect_equal(mean(verts$x), 3)
expect_equal(mean(verts$y), 7)
})
test_that("square_vertices respects half-width parameter", {
r <- 2
verts <- square_vertices(0, 0, r)
# All x values should be +/- r
expect_true(all(abs(verts$x) == r))
expect_true(all(abs(verts$y) == r))
})
test_that("square_vertices creates proper corners", {
verts <- square_vertices(0, 0, 1)
# Should have corners at (-1,-1), (1,-1), (1,1), (-1,1)
corners <- data.frame(x = verts$x, y = verts$y)
expect_true(any(corners$x == -1 & corners$y == -1))
expect_true(any(corners$x == 1 & corners$y == -1))
expect_true(any(corners$x == 1 & corners$y == 1))
expect_true(any(corners$x == -1 & corners$y == 1))
})
# ============================================
# RECTANGLE VERTICES
# ============================================
test_that("rectangle_vertices generates correct structure", {
verts <- rectangle_vertices(0, 0, 2, 1)
expect_true(is.list(verts))
expect_equal(length(verts$x), 4)
expect_equal(length(verts$y), 4)
})
test_that("rectangle_vertices respects width and height", {
w <- 3
h <- 1.5
verts <- rectangle_vertices(0, 0, w, h)
# X values should be +/- w
expect_true(all(abs(verts$x) == w))
# Y values should be +/- h
expect_true(all(abs(verts$y) == h))
})
test_that("rectangle_vertices respects center coordinates", {
verts <- rectangle_vertices(5, -2, 2, 1)
expect_equal(mean(verts$x), 5)
expect_equal(mean(verts$y), -2)
})
test_that("rectangle_vertices handles tall rectangle", {
# Height > Width
verts <- rectangle_vertices(0, 0, 1, 3)
# Width extent should be 2, height extent should be 6
expect_equal(diff(range(verts$x)), 2)
expect_equal(diff(range(verts$y)), 6)
})
test_that("rectangle_vertices handles equal w and h (becomes square)", {
verts <- rectangle_vertices(0, 0, 2, 2)
expect_equal(diff(range(verts$x)), diff(range(verts$y)))
})
# ============================================
# TRIANGLE VERTICES
# ============================================
test_that("triangle_vertices generates correct structure", {
verts <- triangle_vertices(0, 0, 1)
expect_true(is.list(verts))
expect_equal(length(verts$x), 3)
expect_equal(length(verts$y), 3)
})
test_that("triangle_vertices has vertex at top", {
verts <- triangle_vertices(0, 0, 1)
# Top vertex should be at (0, 1) - pi/2 angle
max_y_idx <- which.max(verts$y)
expect_equal(verts$x[max_y_idx], 0, tolerance = 0.001)
expect_equal(verts$y[max_y_idx], 1, tolerance = 0.001)
})
test_that("triangle_vertices respects radius", {
r <- 2.5
verts <- triangle_vertices(0, 0, r)
# All vertices should be at distance r from center
distances <- sqrt(verts$x^2 + verts$y^2)
expect_true(all(abs(distances - r) < 0.001))
})
test_that("triangle_vertices respects center coordinates", {
verts <- triangle_vertices(4, -3, 1)
expect_equal(mean(verts$x), 4, tolerance = 0.001)
expect_equal(mean(verts$y), -3, tolerance = 0.001)
})
# ============================================
# DIAMOND VERTICES
# ============================================
test_that("diamond_vertices generates correct structure", {
verts <- diamond_vertices(0, 0, 1)
expect_true(is.list(verts))
expect_equal(length(verts$x), 4)
expect_equal(length(verts$y), 4)
})
test_that("diamond_vertices has vertices on axes", {
r <- 1
verts <- diamond_vertices(0, 0, r)
# Should have vertices at (r,0), (0,r), (-r,0), (0,-r)
corners <- data.frame(x = verts$x, y = verts$y)
expect_true(any(abs(corners$x - r) < 0.001 & abs(corners$y) < 0.001))
expect_true(any(abs(corners$x) < 0.001 & abs(corners$y - r) < 0.001))
expect_true(any(abs(corners$x - (-r)) < 0.001 & abs(corners$y) < 0.001))
expect_true(any(abs(corners$x) < 0.001 & abs(corners$y - (-r)) < 0.001))
})
test_that("diamond_vertices respects center coordinates", {
verts <- diamond_vertices(2, 3, 1)
expect_equal(mean(verts$x), 2, tolerance = 0.001)
expect_equal(mean(verts$y), 3, tolerance = 0.001)
})
# ============================================
# PENTAGON VERTICES
# ============================================
test_that("pentagon_vertices generates correct structure", {
verts <- pentagon_vertices(0, 0, 1)
expect_true(is.list(verts))
expect_equal(length(verts$x), 5)
expect_equal(length(verts$y), 5)
})
test_that("pentagon_vertices has vertex at top", {
verts <- pentagon_vertices(0, 0, 1)
# First vertex should be at top (angle pi/2)
max_y_idx <- which.max(verts$y)
expect_equal(verts$x[max_y_idx], 0, tolerance = 0.001)
expect_equal(verts$y[max_y_idx], 1, tolerance = 0.001)
})
test_that("pentagon_vertices respects radius", {
r <- 3
verts <- pentagon_vertices(0, 0, r)
distances <- sqrt(verts$x^2 + verts$y^2)
expect_true(all(abs(distances - r) < 0.001))
})
# ============================================
# HEXAGON VERTICES
# ============================================
test_that("hexagon_vertices generates correct structure", {
verts <- hexagon_vertices(0, 0, 1)
expect_true(is.list(verts))
expect_equal(length(verts$x), 6)
expect_equal(length(verts$y), 6)
})
test_that("hexagon_vertices has flat sides on top and bottom", {
verts <- hexagon_vertices(0, 0, 1)
# First vertex should be at angle 0 (rightmost point)
expect_true(any(abs(verts$x - 1) < 0.001 & abs(verts$y) < 0.001))
})
test_that("hexagon_vertices respects radius", {
r <- 2.5
verts <- hexagon_vertices(0, 0, r)
distances <- sqrt(verts$x^2 + verts$y^2)
expect_true(all(abs(distances - r) < 0.001))
})
test_that("hexagon_vertices respects center coordinates", {
verts <- hexagon_vertices(-1, 2, 1)
expect_equal(mean(verts$x), -1, tolerance = 0.001)
expect_equal(mean(verts$y), 2, tolerance = 0.001)
})
# ============================================
# STAR VERTICES
# ============================================
test_that("star_vertices generates correct structure with defaults", {
verts <- star_vertices(0, 0, 1)
expect_true(is.list(verts))
# 5 points * 2 = 10 vertices
expect_equal(length(verts$x), 10)
expect_equal(length(verts$y), 10)
})
test_that("star_vertices respects n_points parameter", {
for (n_points in c(3, 4, 5, 6, 8)) {
verts <- star_vertices(0, 0, 1, n_points = n_points)
expect_equal(length(verts$x), n_points * 2,
info = paste("Failed for n_points =", n_points))
}
})
test_that("star_vertices respects inner_ratio parameter", {
r <- 2
inner_ratio <- 0.3
verts <- star_vertices(0, 0, r, n_points = 5, inner_ratio = inner_ratio)
# Outer vertices should be at distance r
# Inner vertices should be at distance r * inner_ratio
distances <- sqrt(verts$x^2 + verts$y^2)
outer_dist <- distances[seq(1, length(distances), 2)]
inner_dist <- distances[seq(2, length(distances), 2)]
expect_true(all(abs(outer_dist - r) < 0.001))
expect_true(all(abs(inner_dist - r * inner_ratio) < 0.001))
})
test_that("star_vertices handles inner_ratio = 0.5", {
verts <- star_vertices(0, 0, 1, inner_ratio = 0.5)
expect_equal(length(verts$x), 10)
})
test_that("star_vertices first vertex is at top", {
verts <- star_vertices(0, 0, 1, n_points = 5)
# First vertex should be at angle pi/2 (top)
expect_equal(verts$x[1], 0, tolerance = 0.001)
expect_equal(verts$y[1], 1, tolerance = 0.001)
})
# ============================================
# HEART VERTICES
# ============================================
test_that("heart_vertices generates correct structure with defaults", {
verts <- heart_vertices(0, 0, 1)
expect_true(is.list(verts))
expect_equal(length(verts$x), 100) # default n = 100
expect_equal(length(verts$y), 100)
})
test_that("heart_vertices respects n parameter", {
for (n in c(50, 100, 200)) {
verts <- heart_vertices(0, 0, 1, n = n)
expect_equal(length(verts$x), n, info = paste("Failed for n =", n))
}
})
test_that("heart_vertices is centered approximately at given coordinates", {
verts <- heart_vertices(3, -2, 1)
# Heart shape is not perfectly centered, but should be close
expect_equal(mean(verts$x), 3, tolerance = 0.1)
# Heart y is offset due to shape, center should be near given y
expect_true(abs(mean(verts$y) - (-2)) < 0.5)
})
test_that("heart_vertices respects scale", {
verts_small <- heart_vertices(0, 0, 0.5)
verts_large <- heart_vertices(0, 0, 2)
# Larger scale should have larger extent
extent_small <- max(abs(c(verts_small$x, verts_small$y)))
extent_large <- max(abs(c(verts_large$x, verts_large$y)))
expect_true(extent_large > extent_small)
})
# ============================================
# ELLIPSE VERTICES
# ============================================
test_that("ellipse_vertices generates correct structure", {
verts <- ellipse_vertices(0, 0, 2, 1)
expect_true(is.list(verts))
expect_equal(length(verts$x), 50) # default n = 50
expect_equal(length(verts$y), 50)
})
test_that("ellipse_vertices respects rx and ry", {
rx <- 3
ry <- 1
verts <- ellipse_vertices(0, 0, rx, ry)
# Check x extent is rx
expect_equal(max(verts$x), rx, tolerance = 0.01)
expect_equal(min(verts$x), -rx, tolerance = 0.01)
# Check y extent is ry
expect_equal(max(verts$y), ry, tolerance = 0.01)
expect_equal(min(verts$y), -ry, tolerance = 0.01)
})
test_that("ellipse_vertices respects n parameter", {
verts <- ellipse_vertices(0, 0, 1, 1, n = 100)
expect_equal(length(verts$x), 100)
})
test_that("ellipse_vertices with equal radii is a circle", {
r <- 1.5
verts <- ellipse_vertices(0, 0, r, r, n = 100)
# All points should be at distance r
distances <- sqrt(verts$x^2 + verts$y^2)
expect_true(all(abs(distances - r) < 0.01))
})
test_that("ellipse_vertices respects center coordinates", {
verts <- ellipse_vertices(5, -3, 2, 1)
expect_equal(mean(verts$x), 5, tolerance = 0.01)
expect_equal(mean(verts$y), -3, tolerance = 0.01)
})
# ============================================
# CROSS VERTICES
# ============================================
test_that("cross_vertices generates correct structure", {
verts <- cross_vertices(0, 0, 1)
expect_true(is.list(verts))
expect_equal(length(verts$x), 12) # 12-point cross
expect_equal(length(verts$y), 12)
})
test_that("cross_vertices respects thickness parameter", {
r <- 1
thickness <- 0.3
verts <- cross_vertices(0, 0, r, thickness = thickness)
# The arm should extend to r
expect_true(max(verts$x) == r)
expect_true(max(verts$y) == r)
expect_true(min(verts$x) == -r)
expect_true(min(verts$y) == -r)
})
test_that("cross_vertices handles different thickness values", {
for (thickness in c(0.1, 0.3, 0.5, 0.8)) {
verts <- cross_vertices(0, 0, 1, thickness = thickness)
expect_equal(length(verts$x), 12,
info = paste("Failed for thickness =", thickness))
}
})
test_that("cross_vertices is symmetric", {
verts <- cross_vertices(0, 0, 1, thickness = 0.3)
# Should be symmetric about both axes
expect_equal(sort(abs(verts$x)), sort(abs(verts$x)))
expect_equal(sort(abs(verts$y)), sort(abs(verts$y)))
})
test_that("cross_vertices respects center coordinates", {
verts <- cross_vertices(2, -1, 1)
expect_equal(mean(verts$x), 2, tolerance = 0.001)
expect_equal(mean(verts$y), -1, tolerance = 0.001)
})
# ============================================
# REGULAR POLYGON VERTICES
# ============================================
test_that("regular_polygon_vertices generates correct number of vertices", {
for (n in c(3, 4, 5, 6, 7, 8, 10, 12)) {
verts <- regular_polygon_vertices(0, 0, 1, n)
expect_equal(length(verts$x), n, info = paste("Failed for n =", n))
expect_equal(length(verts$y), n, info = paste("Failed for n =", n))
}
})
test_that("regular_polygon_vertices default rotation places vertex at top", {
verts <- regular_polygon_vertices(0, 0, 1, 5) # default rotation = pi/2
# First vertex should be at top
expect_equal(verts$x[1], 0, tolerance = 0.001)
expect_equal(verts$y[1], 1, tolerance = 0.001)
})
test_that("regular_polygon_vertices respects rotation parameter", {
r <- 1
verts <- regular_polygon_vertices(0, 0, r, 4, rotation = 0) # Square with vertex on right
# First vertex should be on the right (angle 0)
expect_equal(verts$x[1], r, tolerance = 0.001)
expect_equal(verts$y[1], 0, tolerance = 0.001)
})
test_that("regular_polygon_vertices respects radius", {
r <- 2.5
verts <- regular_polygon_vertices(0, 0, r, 6)
distances <- sqrt(verts$x^2 + verts$y^2)
expect_true(all(abs(distances - r) < 0.001))
})
test_that("regular_polygon_vertices respects center coordinates", {
verts <- regular_polygon_vertices(3, -2, 1, 5)
expect_equal(mean(verts$x), 3, tolerance = 0.001)
expect_equal(mean(verts$y), -2, tolerance = 0.001)
})
test_that("regular_polygon_vertices with n=3 equals triangle_vertices", {
verts_reg <- regular_polygon_vertices(0, 0, 1, 3, rotation = pi/2)
verts_tri <- triangle_vertices(0, 0, 1)
expect_equal(verts_reg$x, verts_tri$x, tolerance = 0.001)
expect_equal(verts_reg$y, verts_tri$y, tolerance = 0.001)
})
# ============================================
# INSET POLYGON VERTICES
# ============================================
test_that("inset_polygon_vertices generates correct structure", {
outer <- list(x = c(-1, 1, 1, -1), y = c(-1, -1, 1, 1))
inner <- inset_polygon_vertices(outer, 0.5)
expect_true(is.list(inner))
expect_equal(length(inner$x), length(outer$x))
expect_equal(length(inner$y), length(outer$y))
})
test_that("inset_polygon_vertices creates smaller polygon", {
outer <- list(x = c(-1, 1, 1, -1), y = c(-1, -1, 1, 1))
inner <- inset_polygon_vertices(outer, 0.5)
# Inner polygon should be smaller
expect_true(max(abs(inner$x)) < max(abs(outer$x)))
expect_true(max(abs(inner$y)) < max(abs(outer$y)))
})
test_that("inset_polygon_vertices with ratio 0 collapses to center", {
outer <- list(x = c(-1, 1, 1, -1), y = c(-1, -1, 1, 1))
inner <- inset_polygon_vertices(outer, 0)
# All points should be at the centroid
expect_equal(inner$x, rep(mean(outer$x), length(outer$x)))
expect_equal(inner$y, rep(mean(outer$y), length(outer$y)))
})
test_that("inset_polygon_vertices with ratio 1 equals original", {
outer <- list(x = c(-1, 1, 1, -1), y = c(-1, -1, 1, 1))
inner <- inset_polygon_vertices(outer, 1)
expect_equal(inner$x, outer$x)
expect_equal(inner$y, outer$y)
})
test_that("inset_polygon_vertices preserves shape", {
# Triangle
outer <- list(x = c(0, 1, 0.5), y = c(0, 0, 1))
inner <- inset_polygon_vertices(outer, 0.5)
# Should still have 3 vertices
expect_equal(length(inner$x), 3)
})
test_that("inset_polygon_vertices handles non-centered polygon", {
outer <- list(x = c(4, 6, 6, 4), y = c(4, 4, 6, 6)) # Square centered at (5,5)
inner <- inset_polygon_vertices(outer, 0.5)
# Inner centroid should match outer centroid
expect_equal(mean(inner$x), mean(outer$x))
expect_equal(mean(inner$y), mean(outer$y))
})
# ============================================
# GET DONUT BASE VERTICES
# ============================================
test_that("get_donut_base_vertices returns vertices for circle", {
verts <- get_donut_base_vertices("circle", 0, 0, 1)
expect_true(is.list(verts))
expect_equal(length(verts$x), 100) # n = 100 for donut circle
})
test_that("get_donut_base_vertices returns vertices for square", {
verts <- get_donut_base_vertices("square", 0, 0, 1)
expect_equal(length(verts$x), 4)
})
test_that("get_donut_base_vertices returns vertices for rectangle", {
verts <- get_donut_base_vertices("rectangle", 0, 0, 1)
expect_equal(length(verts$x), 4)
# Rectangle has r * 0.7 height
expect_equal(max(abs(verts$y)), 0.7, tolerance = 0.001)
})
test_that("get_donut_base_vertices returns vertices for triangle", {
verts <- get_donut_base_vertices("triangle", 0, 0, 1)
expect_equal(length(verts$x), 3)
})
test_that("get_donut_base_vertices returns vertices for diamond", {
verts <- get_donut_base_vertices("diamond", 0, 0, 1)
expect_equal(length(verts$x), 4)
})
test_that("get_donut_base_vertices returns vertices for pentagon", {
verts <- get_donut_base_vertices("pentagon", 0, 0, 1)
expect_equal(length(verts$x), 5)
})
test_that("get_donut_base_vertices returns vertices for hexagon", {
verts <- get_donut_base_vertices("hexagon", 0, 0, 1)
expect_equal(length(verts$x), 6)
})
test_that("get_donut_base_vertices defaults to circle for unknown shape", {
verts <- get_donut_base_vertices("unknown_shape", 0, 0, 1)
# Should fall back to circle with n = 100
expect_equal(length(verts$x), 100)
})
test_that("get_donut_base_vertices respects center and radius", {
verts <- get_donut_base_vertices("hexagon", 5, -3, 2)
expect_equal(mean(verts$x), 5, tolerance = 0.001)
expect_equal(mean(verts$y), -3, tolerance = 0.001)
})
# ============================================
# GEAR VERTICES
# ============================================
test_that("gear_vertices generates correct structure with defaults", {
verts <- gear_vertices(0, 0, 1)
expect_true(is.list(verts))
# 8 teeth * 8 points per tooth = 64 vertices
expect_equal(length(verts$x), 64)
expect_equal(length(verts$y), 64)
})
test_that("gear_vertices respects n_teeth parameter", {
for (n_teeth in c(4, 6, 8, 10, 12)) {
verts <- gear_vertices(0, 0, 1, n_teeth = n_teeth)
expected_pts <- n_teeth * 8
expect_equal(length(verts$x), expected_pts,
info = paste("Failed for n_teeth =", n_teeth))
}
})
test_that("gear_vertices is centered at given coordinates", {
verts <- gear_vertices(3, -2, 1)
expect_equal(mean(verts$x), 3, tolerance = 0.1)
expect_equal(mean(verts$y), -2, tolerance = 0.1)
})
test_that("gear_vertices respects outer radius", {
r <- 2
verts <- gear_vertices(0, 0, r)
# Max distance should be approximately inner_r + tooth_height = 0.65*r + 0.25*r = 0.9*r
distances <- sqrt(verts$x^2 + verts$y^2)
expect_true(max(distances) <= r * 0.91)
expect_true(max(distances) >= r * 0.8)
})
test_that("gear_vertices has varying radii for teeth", {
verts <- gear_vertices(0, 0, 1, n_teeth = 8)
distances <- sqrt(verts$x^2 + verts$y^2)
# Should have both inner and outer radii
expect_true(length(unique(round(distances, 2))) > 1)
})
# ============================================
# CLOUD VERTICES
# ============================================
test_that("cloud_vertices generates correct structure with defaults", {
verts <- cloud_vertices(0, 0, 1)
expect_true(is.list(verts))
expect_equal(length(verts$x), 100) # default n = 100
expect_equal(length(verts$y), 100)
})
test_that("cloud_vertices respects n parameter", {
verts <- cloud_vertices(0, 0, 1, n = 50)
expect_equal(length(verts$x), 50)
})
test_that("cloud_vertices is approximately centered at given coordinates", {
verts <- cloud_vertices(2, -1, 1)
# Cloud has some offset, but should be close
expect_equal(mean(verts$x), 2, tolerance = 0.2)
# y has offset of r * 0.1
expect_equal(mean(verts$y), -1 + 0.1, tolerance = 0.2)
})
test_that("cloud_vertices has bumpy profile", {
verts <- cloud_vertices(0, 0, 1, n = 100)
distances <- sqrt(verts$x^2 + (verts$y - 0.1)^2)
# Cloud should have varying radii due to sin modulation
expect_true(sd(distances) > 0.01)
})
# ============================================
# BRAIN VERTICES
# ============================================
test_that("brain_vertices generates correct structure with defaults", {
verts <- brain_vertices(0, 0, 1)
expect_true(is.list(verts))
expect_equal(length(verts$x), 80) # default n = 80
expect_equal(length(verts$y), 80)
})
test_that("brain_vertices respects n parameter", {
verts <- brain_vertices(0, 0, 1, n = 50)
expect_equal(length(verts$x), 50)
})
test_that("brain_vertices is centered at given coordinates", {
verts <- brain_vertices(3, -2, 1)
expect_equal(mean(verts$x), 3, tolerance = 0.1)
expect_equal(mean(verts$y), -2, tolerance = 0.1)
})
test_that("brain_vertices has wrinkled profile", {
verts <- brain_vertices(0, 0, 1, n = 100)
# Calculate effective radii (accounting for y scaling of 0.85)
distances <- sqrt(verts$x^2 + (verts$y / 0.85)^2)
# Brain should have varying radii due to sin modulation
expect_true(sd(distances) > 0.01)
})
test_that("brain_vertices respects radius scale", {
verts_small <- brain_vertices(0, 0, 0.5)
verts_large <- brain_vertices(0, 0, 2)
extent_small <- max(abs(c(verts_small$x, verts_small$y)))
extent_large <- max(abs(c(verts_large$x, verts_large$y)))
expect_true(extent_large > extent_small)
})
# ============================================
# GET SHAPE VERTICES - Main Dispatch Function
# ============================================
test_that("get_shape_vertices returns vertices for all standard shapes", {
shapes <- c("circle", "square", "rectangle", "triangle", "diamond",
"pentagon", "hexagon", "star", "heart", "ellipse", "cross",
"gear", "cloud", "brain")
for (shape in shapes) {
verts <- get_shape_vertices(shape, 0, 0, 1)
expect_true(is.list(verts), info = paste("Failed for shape:", shape))
expect_true("x" %in% names(verts), info = paste("Missing x for shape:", shape))
expect_true("y" %in% names(verts), info = paste("Missing y for shape:", shape))
expect_true(length(verts$x) > 0, info = paste("Empty x for shape:", shape))
expect_equal(length(verts$x), length(verts$y),
info = paste("x/y length mismatch for shape:", shape))
}
})
test_that("get_shape_vertices defaults to circle for unknown shape", {
verts <- get_shape_vertices("unknown_shape_xyz", 0, 0, 1)
# Should fall back to circle with default n = 50
expect_equal(length(verts$x), 50)
})
test_that("get_shape_vertices handles r2 parameter for rectangle", {
verts <- get_shape_vertices("rectangle", 0, 0, 2, r2 = 1)
# Width should be 2*2=4, height should be 2*1=2
expect_equal(diff(range(verts$x)), 4)
expect_equal(diff(range(verts$y)), 2)
})
test_that("get_shape_vertices handles r2 parameter for ellipse", {
verts <- get_shape_vertices("ellipse", 0, 0, 3, r2 = 1)
# X extent should be 2*3=6, Y extent should be 2*1=2
expect_equal(diff(range(verts$x)), 6, tolerance = 0.1)
expect_equal(diff(range(verts$y)), 2, tolerance = 0.1)
})
test_that("get_shape_vertices uses r for r2 when r2 is NULL", {
verts <- get_shape_vertices("ellipse", 0, 0, 2, r2 = NULL)
# Should become a circle (equal extents)
expect_equal(diff(range(verts$x)), diff(range(verts$y)), tolerance = 0.1)
})
test_that("get_shape_vertices passes ... to star_vertices", {
verts <- get_shape_vertices("star", 0, 0, 1, n_points = 6, inner_ratio = 0.5)
# 6 points * 2 = 12 vertices
expect_equal(length(verts$x), 12)
})
test_that("get_shape_vertices passes ... to cross_vertices", {
verts <- get_shape_vertices("cross", 0, 0, 1, thickness = 0.5)
expect_equal(length(verts$x), 12)
})
test_that("get_shape_vertices passes ... to gear_vertices", {
verts <- get_shape_vertices("gear", 0, 0, 1, n_teeth = 6)
# 6 teeth * 8 points per tooth = 48 vertices
expect_equal(length(verts$x), 48)
})
# ============================================
# GRAPHICAL TESTS - Rendering polygon shapes
# ============================================
test_that("circle_vertices can be rendered with polygon()", {
with_temp_png({
plot(0, 0, xlim = c(-2, 2), ylim = c(-2, 2), type = "n", asp = 1)
verts <- circle_vertices(0, 0, 1)
polygon(verts$x, verts$y, col = "lightblue", border = "navy")
})
expect_true(TRUE)
})
test_that("star_vertices can be rendered with polygon()", {
with_temp_png({
plot(0, 0, xlim = c(-2, 2), ylim = c(-2, 2), type = "n", asp = 1)
verts <- star_vertices(0, 0, 1, n_points = 5)
polygon(verts$x, verts$y, col = "gold", border = "orange")
})
expect_true(TRUE)
})
test_that("heart_vertices can be rendered with polygon()", {
with_temp_png({
plot(0, 0, xlim = c(-2, 2), ylim = c(-2, 2), type = "n", asp = 1)
verts <- heart_vertices(0, 0, 1)
polygon(verts$x, verts$y, col = "red", border = "darkred")
})
expect_true(TRUE)
})
test_that("gear_vertices can be rendered with polygon()", {
with_temp_png({
plot(0, 0, xlim = c(-2, 2), ylim = c(-2, 2), type = "n", asp = 1)
verts <- gear_vertices(0, 0, 1, n_teeth = 8)
polygon(verts$x, verts$y, col = "gray50", border = "black")
})
expect_true(TRUE)
})
test_that("cloud_vertices can be rendered with polygon()", {
with_temp_png({
plot(0, 0, xlim = c(-2, 2), ylim = c(-2, 2), type = "n", asp = 1)
verts <- cloud_vertices(0, 0, 1)
polygon(verts$x, verts$y, col = "white", border = "gray")
})
expect_true(TRUE)
})
test_that("brain_vertices can be rendered with polygon()", {
with_temp_png({
plot(0, 0, xlim = c(-2, 2), ylim = c(-2, 2), type = "n", asp = 1)
verts <- brain_vertices(0, 0, 1)
polygon(verts$x, verts$y, col = "pink", border = "maroon")
})
expect_true(TRUE)
})
test_that("inset_polygon_vertices can create donut ring", {
with_temp_png({
plot(0, 0, xlim = c(-2, 2), ylim = c(-2, 2), type = "n", asp = 1)
outer <- hexagon_vertices(0, 0, 1)
inner <- inset_polygon_vertices(outer, 0.6)
# Draw outer polygon
polygon(outer$x, outer$y, col = "steelblue", border = "navy")
# Draw inner polygon (covers center)
polygon(inner$x, inner$y, col = "white", border = "navy")
})
expect_true(TRUE)
})
test_that("multiple shapes can be rendered together", {
with_temp_png({
plot(0, 0, xlim = c(-6, 6), ylim = c(-4, 4), type = "n", asp = 1)
# Row 1: Basic shapes
shapes <- c("circle", "square", "triangle", "diamond")
xs <- c(-4.5, -1.5, 1.5, 4.5)
for (i in seq_along(shapes)) {
verts <- get_shape_vertices(shapes[i], xs[i], 2, 1)
polygon(verts$x, verts$y, col = rainbow(4)[i], border = "black")
}
# Row 2: Polygon shapes
shapes2 <- c("pentagon", "hexagon", "star", "cross")
for (i in seq_along(shapes2)) {
verts <- get_shape_vertices(shapes2[i], xs[i], -2, 1)
polygon(verts$x, verts$y, col = rainbow(4, start = 0.5)[i], border = "black")
}
})
expect_true(TRUE)
})
# ============================================
# EDGE CASES AND NUMERIC PRECISION
# ============================================
test_that("polygon vertices handle very small radius", {
for (shape in c("circle", "square", "triangle", "hexagon")) {
verts <- get_shape_vertices(shape, 0, 0, 0.001)
expect_true(all(is.finite(verts$x)), info = paste("Non-finite x for shape:", shape))
expect_true(all(is.finite(verts$y)), info = paste("Non-finite y for shape:", shape))
}
})
test_that("polygon vertices handle very large radius", {
for (shape in c("circle", "square", "triangle", "hexagon")) {
verts <- get_shape_vertices(shape, 0, 0, 1000)
expect_true(all(is.finite(verts$x)), info = paste("Non-finite x for shape:", shape))
expect_true(all(is.finite(verts$y)), info = paste("Non-finite y for shape:", shape))
}
})
test_that("polygon vertices handle zero radius", {
verts <- circle_vertices(0, 0, 0, n = 50)
# All points should be at origin
expect_true(all(verts$x == 0))
expect_true(all(verts$y == 0))
})
test_that("polygon vertices handle large coordinates", {
verts <- circle_vertices(1e6, -1e6, 1)
expect_equal(mean(verts$x), 1e6, tolerance = 0.01)
expect_equal(mean(verts$y), -1e6, tolerance = 0.01)
})
test_that("star_vertices handles extreme inner_ratio values", {
# Very small inner ratio
verts <- star_vertices(0, 0, 1, inner_ratio = 0.01)
expect_equal(length(verts$x), 10)
# Inner ratio close to 1
verts <- star_vertices(0, 0, 1, inner_ratio = 0.99)
expect_equal(length(verts$x), 10)
})
test_that("cross_vertices handles extreme thickness values", {
# Very thin cross
verts <- cross_vertices(0, 0, 1, thickness = 0.01)
expect_equal(length(verts$x), 12)
# Very thick cross (arms touch)
verts <- cross_vertices(0, 0, 1, thickness = 1)
expect_equal(length(verts$x), 12)
})
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.