1package main23import "testing"45func TestWorldTileRange(t *testing.T) {6 tests := []struct {7 zoom int8 wantMin int9 wantMax int10 }{11 {zoom: 8, wantMin: 127, wantMax: 127},12 {zoom: 10, wantMin: 508, wantMax: 511},13 {zoom: 13, wantMin: 4064, wantMax: 4095},14 {zoom: 14, wantMin: 8128, wantMax: 8191},15 }16 for _, test := range tests {17 minimum, maximum := worldTileRange(test.zoom)18 if minimum != test.wantMin || maximum != test.wantMax {19 t.Errorf("worldTileRange(%d) = (%d, %d), want (%d, %d)",20 test.zoom, minimum, maximum, test.wantMin, test.wantMax)21 }22 }23}2425func TestExpectedBoundsUsesConfiguredLayerBounds(t *testing.T) {26 set := rawTileSet{Bounds: map[string]rawTileSetBound{27 "13": {28 X: rawRange{Min: 4064, Max: 4078},29 Y: rawRange{Min: 4064, Max: 4075},30 },31 }}32 got := expectedBounds(set, 13)33 if got.X.Min != 4064 || got.X.Max != 4078 || got.Y.Min != 4064 || got.Y.Max != 4075 {34 t.Fatalf("expectedBounds() = %#v", got)35 }36}3738// The two windows the archive holds. A layer that declares nothing is cut from39// the shared square at zoom 13, and lands on the base and world grid the viewer40// assumed before any of this was measured; GTA 5 declares its own, five levels41// shallower and anchored at the origin.42func TestFrameForMeasuresEachWindow(t *testing.T) {43 tests := []struct {44 name string45 set rawTileSet46 wantBase int47 wantGrid gridSpec48 }{49 {50 name: "the shared window",51 set: rawTileSet{MaxZoom: 15},52 wantBase: 8,53 wantGrid: gridSpec{SourceZoom: 13, FirstTile: 4064},54 },55 {56 name: "a window of its own",57 set: rawTileSet{MaxZoom: 7, Bounds: map[string]rawTileSetBound{58 "7": {X: rawRange{Min: 0, Max: 42}, Y: rawRange{Min: 0, Max: 42}},59 }},60 wantBase: 1,61 wantGrid: gridSpec{SourceZoom: 6, FirstTile: 0},62 },63 }64 for _, test := range tests {65 t.Run(test.name, func(t *testing.T) {66 frame, ok := frameFor(test.set)67 if !ok {68 t.Fatal("frameFor() found no window")69 }70 if frame.BaseZoom != test.wantBase {71 t.Errorf("BaseZoom = %d, want %d", frame.BaseZoom, test.wantBase)72 }73 if got := frame.grid(); got != test.wantGrid {74 t.Errorf("grid() = %#v, want %#v", got, test.wantGrid)75 }76 })77 }78}7980// A window that is one tile on one axis and two on the other would place pins81// against an origin it does not have.82func TestFrameForRejectsAnUnsquareWindow(t *testing.T) {83 set := rawTileSet{MaxZoom: 4, Bounds: map[string]rawTileSetBound{84 "4": {X: rawRange{Min: 0, Max: 3}, Y: rawRange{Min: 8, Max: 11}},85 }}86 if _, ok := frameFor(set); ok {87 t.Fatal("frameFor() accepted a window whose axes rest on different tiles")88 }89}9091func TestTileSetPath(t *testing.T) {92 const rawURL = "https://tiles.mapgenie.io/games/skyrim/skyrim/default-v1/13/4076/4064.jpg"93 if got, want := tileSetPath(rawURL, 13), "skyrim/skyrim/default-v1"; got != want {94 t.Fatalf("tileSetPath() = %q, want %q", got, want)95 }96}9798func TestPixelArtUsesNearestNeighbor(t *testing.T) {99 if !isPixelArt("pokemon-red-blue-yellow") {100 t.Fatal("Pokémon maps must be classified as pixel art")101 }102 if isPixelArt("fallout-new-vegas") {103 t.Fatal("photographic maps must retain smooth interpolation")104 }105}