Тестовые данные в контексте Turf.js строятся вокруг стандарта
GeoJSON, где любая геометрия представляется в виде объектов
Feature, FeatureCollection и базовых геометрий
(Point, LineString, Polygon).
Структура данных определяет корректность работы большинства
геопространственных функций.
Минимальные формы:
const point = {
type: "Feature",
geometry: {
type: "Point",
coordinates: [30.5, 50.45]
},
properties: {}
};
Коллекция объектов:
const collection = {
type: "FeatureCollection",
features: [point]
};
Корректность тестирования зависит не только от синтаксиса, но и от разнообразия геометрий: одиночные объекты, массивы, вложенные структуры, пустые коллекции, граничные случаи.
Точечные данные используются для тестирования расстояний, кластеризации, поиска ближайших объектов и пространственных фильтров.
Базовое создание через @turf/helpers:
import { point, featureCollection } from "@turf/helpers";
const p1 = point([30, 50], { id: 1 });
const p2 = point([31, 51], { id: 2 });
const points = featureCollection([p1, p2]);
Генерация массива точек вручную:
const points = {
type: "FeatureCollection",
features: Array.from({ length: 100 }).map((_, i) => ({
type: "Feature",
geometry: {
type: "Point",
coordinates: [
30 + Math.random(),
50 + Math.random()
]
},
properties: {
index: i
}
}))
};
Ключевой аспект тестовых точек — контроль диапазонов координат. Часто используется ограничивающий прямоугольник (bbox):
const bbox = [29, 49, 32, 52];
Для создания более реалистичных данных применяется
randomPoint:
import { randomPoint } from "@turf/random";
const points = randomPoint(200, {
bbox: [29, 49, 32, 52]
});
Такая генерация позволяет проверять:
При необходимости можно усиливать концентрацию точек в отдельных зонах, создавая искусственные кластеры.
Линии используются для тестирования маршрутизации, измерения длины, пересечений и анализа геометрии.
Простейшая линия:
import { lineString } from "@turf/helpers";
const line = lineString([
[30, 50],
[31, 51],
[32, 50.5]
]);
Генерация ломаной:
const line = {
type: "Feature",
geometry: {
type: "LineString",
coordinates: Array.from({ length: 50 }).map((_, i) => [
30 + i * 0.1,
50 + Math.sin(i * 0.2)
])
},
properties: {}
};
Для тестов важно варьировать:
Полигональные данные применяются для операций площади, пересечений, включения точек и анализа зон.
Базовый полигон:
import { polygon } from "@turf/helpers";
const poly = polygon([[
[30, 50],
[31, 50],
[31, 51],
[30, 51],
[30, 50]
]]);
Генерация прямоугольных тестовых областей:
function createGridPolygon(x, y, size) {
return polygon([[
[x, y],
[x + size, y],
[x + size, y + size],
[x, y + size],
[x, y]
]]);
}
Полигоны для тестирования часто включают:
Пример полигона с отверстием:
const polyWithHole = polygon([
[
[30, 50],
[32, 50],
[32, 52],
[30, 52],
[30, 50]
],
[
[30.5, 50.5],
[31.5, 50.5],
[31.5, 51.5],
[30.5, 51.5],
[30.5, 50.5]
]
]);
Bounding box является основным инструментом ограничения тестовых сценариев.
const bbox = [29, 49, 32, 52];
С его помощью строятся:
Генерация равномерной сетки точек:
function createGridPoints(bbox, step) {
const [minX, minY, maxX, maxY] = bbox;
const points = [];
for (let x = minX; x <= maxX; x += step) {
for (let y = minY; y <= maxY; y += step) {
points.push({
type: "Feature",
geometry: {
type: "Point",
coordinates: [x, y]
},
properties: {}
});
}
}
return {
type: "FeatureCollection",
features: points
};
}
Случайные данные ухудшают воспроизводимость тестов, поэтому часто применяются фиксированные генераторы псевдослучайных чисел.
Простейший линейный конгруэнтный генератор:
function createRNG(seed) {
let state = seed;
return function () {
state = (state * 1664525 + 1013904223) % 4294967296;
return state / 4294967296;
};
}
const rand = createRNG(42);
Использование:
const points = Array.from({ length: 50 }).map(() => ({
type: "Feature",
geometry: {
type: "Point",
coordinates: [
30 + rand(),
50 + rand()
]
},
properties: {}
}));
Геометрические пересечения являются одной из наиболее чувствительных зон для тестирования.
Создание пересекающихся линий:
const lineA = lineString([[30, 50], [32, 52]]);
const lineB = lineString([[30, 52], [32, 50]]);
Создание перекрывающихся полигонов:
const polyA = polygon([[
[30, 50],
[32, 50],
[32, 52],
[30, 52],
[30, 50]
]]);
const polyB = polygon([[
[31, 51],
[33, 51],
[33, 53],
[31, 53],
[31, 51]
]]);
Такие структуры используются для проверки:
Для тестирования операций буферизации применяются окружности:
import { circle } from "@turf/turf";
const center = [30, 50];
const c = circle(center, 5, {
steps: 64,
units: "kilometers"
});
Окружности используются для проверки:
Регулярные сетки применяются для тестирования индексации и разбиения пространства.
function createTileGrid(bbox, rows, cols) {
const [minX, minY, maxX, maxY] = bbox;
const dx = (maxX - minX) / cols;
const dy = (maxY - minY) / rows;
const features = [];
for (let i = 0; i < rows; i++) {
for (let j = 0; j < cols; j++) {
const x = minX + j * dx;
const y = minY + i * dy;
features.push({
type: "Feature",
geometry: {
type: "Polygon",
coordinates: [[
[x, y],
[x + dx, y],
[x + dx, y + dy],
[x, y + dy],
[x, y]
]]
},
properties: { row: i, col: j }
});
}
}
return {
type: "FeatureCollection",
features
};
}
Сложные тестовые наборы формируются из смешанных коллекций:
const mixed = {
type: "FeatureCollection",
features: [
point([30, 50]),
lineString([[30, 50], [31, 51]]),
polygon([[
[30, 50],
[31, 50],
[31, 51],
[30, 51],
[30, 50]
]])
]
};
Такие наборы позволяют проверять устойчивость алгоритмов к неоднородным входным данным.
Тестовые данные должны включать некорректные и пограничные структуры:
FeatureCollectionnull координатыПример вырожденной линии:
const degenerateLine = lineString([
[30, 50],
[30, 50]
]);
Такие случаи выявляют слабые места геометрических алгоритмов и обработчиков ошибок.