Claude Code tire-kicking: generate some unit tests
This commit is contained in:
parent
c375665a6d
commit
5a30ab0d3f
7 changed files with 1025 additions and 0 deletions
84
CLAUDE.md
Normal file
84
CLAUDE.md
Normal file
|
|
@ -0,0 +1,84 @@
|
||||||
|
# CLAUDE.md
|
||||||
|
|
||||||
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||||
|
|
||||||
|
## Project Overview
|
||||||
|
|
||||||
|
Dynmap is a dynamic web mapping plugin/mod for Minecraft servers. It's a multi-platform project supporting Spigot/PaperMC, Forge, and Fabric across multiple Minecraft versions (1.12.2 - 1.21.x).
|
||||||
|
|
||||||
|
## Build Commands
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Build all platforms (requires JDK 21 as default)
|
||||||
|
./gradlew setup build
|
||||||
|
|
||||||
|
# Build outputs go to /target directory
|
||||||
|
|
||||||
|
# Build specific module (for faster iteration, but NOT for PR submissions)
|
||||||
|
./gradlew :fabric-1.18:build
|
||||||
|
|
||||||
|
# Forge 1.12.2 (requires JDK 8 - set JAVA_HOME accordingly)
|
||||||
|
cd oldgradle
|
||||||
|
./gradlew setup build
|
||||||
|
```
|
||||||
|
|
||||||
|
**JDK Requirements:**
|
||||||
|
- Default: JDK 21
|
||||||
|
- Forge 1.12.2 (oldgradle): JDK 8 strictly required
|
||||||
|
- Runtime targets: JDK 8 (1.16-), JDK 16 (1.17.x), JDK 17 (1.18-1.20.4), JDK 21 (1.20.5+)
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
### Module Structure (71 modules total)
|
||||||
|
|
||||||
|
**Core Shared Modules:**
|
||||||
|
- `DynmapCoreAPI/` - Stable public API for external plugins/mods (markers, mod support, rendering)
|
||||||
|
- `DynmapCore/` - Internal shared implementation (NOT stable - subject to breaking changes)
|
||||||
|
- `dynmap-api/` - Bukkit-specific public API
|
||||||
|
|
||||||
|
**Platform Implementations:**
|
||||||
|
- `spigot/` - Bukkit/PaperMC implementation
|
||||||
|
- `bukkit-helper-*` - Version-specific NMS code (25 versions: 1.13-1.21)
|
||||||
|
- `fabric-*` - Fabric mod implementations (14 versions: 1.14.4-1.21.11)
|
||||||
|
- `forge-*` - Forge mod implementations (14 versions: 1.14.4-1.21.11)
|
||||||
|
|
||||||
|
### Dependency Flow
|
||||||
|
```
|
||||||
|
External Plugins/Mods
|
||||||
|
↓
|
||||||
|
DynmapCoreAPI (stable, published to repo.mikeprimm.com)
|
||||||
|
↓
|
||||||
|
DynmapCore (internal, unstable)
|
||||||
|
↓
|
||||||
|
Platform-specific modules (Spigot, Fabric, Forge)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Key Components in DynmapCore
|
||||||
|
- `MapManager` - Tile/map rendering orchestration
|
||||||
|
- `DynmapCore.java` - Main coordination hub (~3,100 lines)
|
||||||
|
- `storage/` - Storage backends (FileTree, MySQL, PostgreSQL, SQLite, S3)
|
||||||
|
- `hdmap/` - HD map rendering (block models, shaders, textures)
|
||||||
|
- `web/` - Embedded Jetty server with servlets
|
||||||
|
- `markers/` - Marker system implementation
|
||||||
|
|
||||||
|
## Critical Contribution Rules
|
||||||
|
|
||||||
|
**PRs must build and test on ALL platforms including oldgradle. Changes to DynmapCore/DynmapCoreAPI require testing on all platforms.**
|
||||||
|
|
||||||
|
- **Java 8 compatibility required** - Code must compile and run on Java 8
|
||||||
|
- **Java only** - No Kotlin, Scala, or other JVM languages
|
||||||
|
- **No dependency updates** - Library versions are tied to platform compatibility
|
||||||
|
- **No platform-specific code** - Must work on Windows, Linux (x86/ARM), macOS, Docker
|
||||||
|
- **Small PRs only** - One feature per PR, no style/formatting changes
|
||||||
|
- **No mod-specific code** - Use Dynmap APIs instead; external mods should depend on DynmapCoreAPI
|
||||||
|
- **Apache License v2** - All code must be compatible
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
|
||||||
|
No automated tests exist. Verification is done by:
|
||||||
|
1. Building all platforms successfully (`./gradlew setup build` AND `cd oldgradle && ./gradlew setup build`)
|
||||||
|
2. Manual testing on target Minecraft server platforms
|
||||||
|
|
||||||
|
## Storage Backends
|
||||||
|
|
||||||
|
Dynmap supports: FileTree (default), MySQL/MariaDB, PostgreSQL, SQLite, MS SQL Server, AWS S3
|
||||||
|
|
@ -26,6 +26,18 @@ dependencies {
|
||||||
implementation 'io.github.linktosriram.s3lite:util:0.0.2-SNAPSHOT'
|
implementation 'io.github.linktosriram.s3lite:util:0.0.2-SNAPSHOT'
|
||||||
implementation 'jakarta.xml.bind:jakarta.xml.bind-api:3.0.1'
|
implementation 'jakarta.xml.bind:jakarta.xml.bind-api:3.0.1'
|
||||||
implementation 'com.sun.xml.bind:jaxb-impl:3.0.0'
|
implementation 'com.sun.xml.bind:jaxb-impl:3.0.0'
|
||||||
|
// Test dependencies (Java 8 compatible versions)
|
||||||
|
testImplementation 'junit:junit:4.13.2'
|
||||||
|
testImplementation 'org.mockito:mockito-core:4.11.0'
|
||||||
|
testImplementation 'org.assertj:assertj-core:3.24.2'
|
||||||
|
}
|
||||||
|
|
||||||
|
test {
|
||||||
|
useJUnit()
|
||||||
|
testLogging {
|
||||||
|
events "passed", "skipped", "failed"
|
||||||
|
exceptionFormat "full"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
processResources {
|
processResources {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,189 @@
|
||||||
|
package org.dynmap.utils;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import java.io.IOException;
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
public class BufferInputStreamTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testConstructorWithBuffer() {
|
||||||
|
byte[] data = {1, 2, 3, 4, 5};
|
||||||
|
BufferInputStream stream = new BufferInputStream(data);
|
||||||
|
assertEquals(5, stream.length());
|
||||||
|
assertSame(data, stream.buffer());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testConstructorWithBufferAndLength() {
|
||||||
|
byte[] data = {1, 2, 3, 4, 5};
|
||||||
|
BufferInputStream stream = new BufferInputStream(data, 3);
|
||||||
|
assertEquals(3, stream.length());
|
||||||
|
assertSame(data, stream.buffer());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testReadSingleByte() {
|
||||||
|
byte[] data = {10, 20, 30};
|
||||||
|
BufferInputStream stream = new BufferInputStream(data);
|
||||||
|
assertEquals(10, stream.read());
|
||||||
|
assertEquals(20, stream.read());
|
||||||
|
assertEquals(30, stream.read());
|
||||||
|
assertEquals(-1, stream.read()); // EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testReadSingleByteUnsigned() {
|
||||||
|
// Test that bytes are returned as unsigned (0-255)
|
||||||
|
byte[] data = {(byte) 255, (byte) 128};
|
||||||
|
BufferInputStream stream = new BufferInputStream(data);
|
||||||
|
assertEquals(255, stream.read());
|
||||||
|
assertEquals(128, stream.read());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testReadArray() throws IOException {
|
||||||
|
byte[] data = {1, 2, 3, 4, 5};
|
||||||
|
BufferInputStream stream = new BufferInputStream(data);
|
||||||
|
byte[] buffer = new byte[3];
|
||||||
|
int bytesRead = stream.read(buffer, 0, 3);
|
||||||
|
assertEquals(3, bytesRead);
|
||||||
|
assertEquals(1, buffer[0]);
|
||||||
|
assertEquals(2, buffer[1]);
|
||||||
|
assertEquals(3, buffer[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testReadArrayPartial() throws IOException {
|
||||||
|
byte[] data = {1, 2, 3};
|
||||||
|
BufferInputStream stream = new BufferInputStream(data);
|
||||||
|
byte[] buffer = new byte[5];
|
||||||
|
int bytesRead = stream.read(buffer, 0, 5);
|
||||||
|
assertEquals(3, bytesRead);
|
||||||
|
assertEquals(1, buffer[0]);
|
||||||
|
assertEquals(2, buffer[1]);
|
||||||
|
assertEquals(3, buffer[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testReadArrayAtEOF() throws IOException {
|
||||||
|
byte[] data = {1, 2};
|
||||||
|
BufferInputStream stream = new BufferInputStream(data);
|
||||||
|
stream.read();
|
||||||
|
stream.read();
|
||||||
|
byte[] buffer = new byte[5];
|
||||||
|
int bytesRead = stream.read(buffer, 0, 5);
|
||||||
|
assertEquals(-1, bytesRead);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = IOException.class)
|
||||||
|
public void testReadArrayNullBuffer() throws IOException {
|
||||||
|
byte[] data = {1, 2, 3};
|
||||||
|
BufferInputStream stream = new BufferInputStream(data);
|
||||||
|
stream.read(null, 0, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = IOException.class)
|
||||||
|
public void testReadArrayNegativeOffset() throws IOException {
|
||||||
|
byte[] data = {1, 2, 3};
|
||||||
|
BufferInputStream stream = new BufferInputStream(data);
|
||||||
|
byte[] buffer = new byte[5];
|
||||||
|
stream.read(buffer, -1, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAvailable() {
|
||||||
|
byte[] data = {1, 2, 3, 4, 5};
|
||||||
|
BufferInputStream stream = new BufferInputStream(data);
|
||||||
|
assertEquals(5, stream.available());
|
||||||
|
stream.read();
|
||||||
|
assertEquals(4, stream.available());
|
||||||
|
stream.read();
|
||||||
|
stream.read();
|
||||||
|
assertEquals(2, stream.available());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSkip() {
|
||||||
|
byte[] data = {1, 2, 3, 4, 5};
|
||||||
|
BufferInputStream stream = new BufferInputStream(data);
|
||||||
|
long skipped = stream.skip(2);
|
||||||
|
assertEquals(2, skipped);
|
||||||
|
assertEquals(3, stream.read());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSkipPastEnd() {
|
||||||
|
byte[] data = {1, 2, 3};
|
||||||
|
BufferInputStream stream = new BufferInputStream(data);
|
||||||
|
long skipped = stream.skip(10);
|
||||||
|
assertEquals(3, skipped);
|
||||||
|
assertEquals(-1, stream.read());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSkipNegative() {
|
||||||
|
byte[] data = {1, 2, 3};
|
||||||
|
BufferInputStream stream = new BufferInputStream(data);
|
||||||
|
stream.read();
|
||||||
|
long skipped = stream.skip(-5);
|
||||||
|
assertEquals(0, skipped);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMarkSupported() {
|
||||||
|
byte[] data = {1, 2, 3};
|
||||||
|
BufferInputStream stream = new BufferInputStream(data);
|
||||||
|
assertTrue(stream.markSupported());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMarkAndReset() {
|
||||||
|
byte[] data = {1, 2, 3, 4, 5};
|
||||||
|
BufferInputStream stream = new BufferInputStream(data);
|
||||||
|
stream.read();
|
||||||
|
stream.read();
|
||||||
|
stream.mark(0); // Mark at position 2
|
||||||
|
assertEquals(3, stream.read());
|
||||||
|
assertEquals(4, stream.read());
|
||||||
|
stream.reset();
|
||||||
|
assertEquals(3, stream.read()); // Back to position 2
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testResetWithoutMark() {
|
||||||
|
byte[] data = {1, 2, 3};
|
||||||
|
BufferInputStream stream = new BufferInputStream(data);
|
||||||
|
stream.read();
|
||||||
|
stream.read();
|
||||||
|
stream.reset(); // Should reset to 0 (default mark)
|
||||||
|
assertEquals(1, stream.read());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testClose() {
|
||||||
|
byte[] data = {1, 2, 3};
|
||||||
|
BufferInputStream stream = new BufferInputStream(data);
|
||||||
|
stream.close(); // Should not throw
|
||||||
|
// Stream should still be usable after close (no-op)
|
||||||
|
assertEquals(1, stream.read());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEmptyBuffer() {
|
||||||
|
byte[] data = {};
|
||||||
|
BufferInputStream stream = new BufferInputStream(data);
|
||||||
|
assertEquals(0, stream.available());
|
||||||
|
assertEquals(-1, stream.read());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLengthVsBufferLength() {
|
||||||
|
byte[] data = {1, 2, 3, 4, 5};
|
||||||
|
BufferInputStream stream = new BufferInputStream(data, 2);
|
||||||
|
assertEquals(2, stream.available());
|
||||||
|
assertEquals(1, stream.read());
|
||||||
|
assertEquals(2, stream.read());
|
||||||
|
assertEquals(-1, stream.read()); // EOF at specified length
|
||||||
|
}
|
||||||
|
}
|
||||||
249
DynmapCore/src/test/java/org/dynmap/utils/DynIntHashMapTest.java
Normal file
249
DynmapCore/src/test/java/org/dynmap/utils/DynIntHashMapTest.java
Normal file
|
|
@ -0,0 +1,249 @@
|
||||||
|
package org.dynmap.utils;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import java.util.List;
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
public class DynIntHashMapTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDefaultConstructor() {
|
||||||
|
DynIntHashMap map = new DynIntHashMap();
|
||||||
|
assertTrue(map.isEmpty());
|
||||||
|
assertEquals(0, map.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testConstructorWithCapacity() {
|
||||||
|
DynIntHashMap map = new DynIntHashMap(100);
|
||||||
|
assertTrue(map.isEmpty());
|
||||||
|
assertEquals(0, map.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testConstructorWithCapacityAndLoadFactor() {
|
||||||
|
DynIntHashMap map = new DynIntHashMap(100, 0.5f);
|
||||||
|
assertTrue(map.isEmpty());
|
||||||
|
assertEquals(0, map.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = IllegalArgumentException.class)
|
||||||
|
public void testConstructorNegativeCapacity() {
|
||||||
|
new DynIntHashMap(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = IllegalArgumentException.class)
|
||||||
|
public void testConstructorZeroLoadFactor() {
|
||||||
|
new DynIntHashMap(10, 0.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = IllegalArgumentException.class)
|
||||||
|
public void testConstructorNegativeLoadFactor() {
|
||||||
|
new DynIntHashMap(10, -0.5f);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCopyConstructor() {
|
||||||
|
DynIntHashMap original = new DynIntHashMap();
|
||||||
|
original.put(1, "one");
|
||||||
|
original.put(2, "two");
|
||||||
|
|
||||||
|
DynIntHashMap copy = new DynIntHashMap(original);
|
||||||
|
assertEquals(2, copy.size());
|
||||||
|
assertEquals("one", copy.get(1));
|
||||||
|
assertEquals("two", copy.get(2));
|
||||||
|
|
||||||
|
// Verify it's a deep copy
|
||||||
|
original.put(1, "modified");
|
||||||
|
assertEquals("one", copy.get(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPutAndGet() {
|
||||||
|
DynIntHashMap map = new DynIntHashMap();
|
||||||
|
assertNull(map.put(1, "one"));
|
||||||
|
assertEquals("one", map.get(1));
|
||||||
|
assertEquals(1, map.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPutReplace() {
|
||||||
|
DynIntHashMap map = new DynIntHashMap();
|
||||||
|
map.put(1, "one");
|
||||||
|
Object oldValue = map.put(1, "ONE");
|
||||||
|
assertEquals("one", oldValue);
|
||||||
|
assertEquals("ONE", map.get(1));
|
||||||
|
assertEquals(1, map.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPutNullValue() {
|
||||||
|
DynIntHashMap map = new DynIntHashMap();
|
||||||
|
map.put(1, null);
|
||||||
|
assertNull(map.get(1));
|
||||||
|
assertTrue(map.containsKey(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetNonExistent() {
|
||||||
|
DynIntHashMap map = new DynIntHashMap();
|
||||||
|
assertNull(map.get(999));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testContainsKey() {
|
||||||
|
DynIntHashMap map = new DynIntHashMap();
|
||||||
|
map.put(1, "one");
|
||||||
|
assertTrue(map.containsKey(1));
|
||||||
|
assertFalse(map.containsKey(2));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testContainsValue() {
|
||||||
|
DynIntHashMap map = new DynIntHashMap();
|
||||||
|
map.put(1, "one");
|
||||||
|
map.put(2, "two");
|
||||||
|
assertTrue(map.containsValue("one"));
|
||||||
|
assertTrue(map.containsValue("two"));
|
||||||
|
assertFalse(map.containsValue("three"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testContainsValueNull() {
|
||||||
|
DynIntHashMap map = new DynIntHashMap();
|
||||||
|
map.put(1, null);
|
||||||
|
assertTrue(map.containsValue(null));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRemove() {
|
||||||
|
DynIntHashMap map = new DynIntHashMap();
|
||||||
|
map.put(1, "one");
|
||||||
|
map.put(2, "two");
|
||||||
|
|
||||||
|
Object removed = map.remove(1);
|
||||||
|
assertEquals("one", removed);
|
||||||
|
assertEquals(1, map.size());
|
||||||
|
assertFalse(map.containsKey(1));
|
||||||
|
assertTrue(map.containsKey(2));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRemoveNonExistent() {
|
||||||
|
DynIntHashMap map = new DynIntHashMap();
|
||||||
|
map.put(1, "one");
|
||||||
|
|
||||||
|
Object removed = map.remove(999);
|
||||||
|
assertNull(removed);
|
||||||
|
assertEquals(1, map.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testClear() {
|
||||||
|
DynIntHashMap map = new DynIntHashMap();
|
||||||
|
map.put(1, "one");
|
||||||
|
map.put(2, "two");
|
||||||
|
map.put(3, "three");
|
||||||
|
|
||||||
|
map.clear();
|
||||||
|
assertTrue(map.isEmpty());
|
||||||
|
assertEquals(0, map.size());
|
||||||
|
assertNull(map.get(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIsEmpty() {
|
||||||
|
DynIntHashMap map = new DynIntHashMap();
|
||||||
|
assertTrue(map.isEmpty());
|
||||||
|
|
||||||
|
map.put(1, "one");
|
||||||
|
assertFalse(map.isEmpty());
|
||||||
|
|
||||||
|
map.remove(1);
|
||||||
|
assertTrue(map.isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testKeysWithValue() {
|
||||||
|
DynIntHashMap map = new DynIntHashMap();
|
||||||
|
map.put(1, "value");
|
||||||
|
map.put(2, "value");
|
||||||
|
map.put(3, "other");
|
||||||
|
|
||||||
|
List<Integer> keys = map.keysWithValue("value");
|
||||||
|
assertEquals(2, keys.size());
|
||||||
|
assertTrue(keys.contains(1));
|
||||||
|
assertTrue(keys.contains(2));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testKeysWithValueNull() {
|
||||||
|
DynIntHashMap map = new DynIntHashMap();
|
||||||
|
map.put(1, null);
|
||||||
|
map.put(2, null);
|
||||||
|
map.put(3, "value");
|
||||||
|
|
||||||
|
List<Integer> keys = map.keysWithValue(null);
|
||||||
|
assertEquals(2, keys.size());
|
||||||
|
assertTrue(keys.contains(1));
|
||||||
|
assertTrue(keys.contains(2));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testKeysWithValueNoMatch() {
|
||||||
|
DynIntHashMap map = new DynIntHashMap();
|
||||||
|
map.put(1, "one");
|
||||||
|
map.put(2, "two");
|
||||||
|
|
||||||
|
List<Integer> keys = map.keysWithValue("nonexistent");
|
||||||
|
assertTrue(keys.isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRehashing() {
|
||||||
|
// Use small initial capacity to trigger rehash
|
||||||
|
DynIntHashMap map = new DynIntHashMap(2, 0.75f);
|
||||||
|
|
||||||
|
// Add enough entries to trigger rehash
|
||||||
|
for (int i = 0; i < 100; i++) {
|
||||||
|
map.put(i, "value" + i);
|
||||||
|
}
|
||||||
|
|
||||||
|
assertEquals(100, map.size());
|
||||||
|
|
||||||
|
// Verify all entries are still accessible
|
||||||
|
for (int i = 0; i < 100; i++) {
|
||||||
|
assertEquals("value" + i, map.get(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNegativeKey() {
|
||||||
|
DynIntHashMap map = new DynIntHashMap();
|
||||||
|
map.put(-1, "negative");
|
||||||
|
assertEquals("negative", map.get(-1));
|
||||||
|
assertTrue(map.containsKey(-1));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testZeroKey() {
|
||||||
|
DynIntHashMap map = new DynIntHashMap();
|
||||||
|
map.put(0, "zero");
|
||||||
|
assertEquals("zero", map.get(0));
|
||||||
|
assertTrue(map.containsKey(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMaxIntKey() {
|
||||||
|
DynIntHashMap map = new DynIntHashMap();
|
||||||
|
map.put(Integer.MAX_VALUE, "max");
|
||||||
|
assertEquals("max", map.get(Integer.MAX_VALUE));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMinIntKey() {
|
||||||
|
DynIntHashMap map = new DynIntHashMap();
|
||||||
|
map.put(Integer.MIN_VALUE, "min");
|
||||||
|
assertEquals("min", map.get(Integer.MIN_VALUE));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,122 @@
|
||||||
|
package org.dynmap.utils;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
public class IpAddressMatcherTest {
|
||||||
|
|
||||||
|
// IPv4 exact match tests
|
||||||
|
@Test
|
||||||
|
public void testIPv4ExactMatch() {
|
||||||
|
IpAddressMatcher matcher = new IpAddressMatcher("192.168.1.100");
|
||||||
|
assertTrue(matcher.matches("192.168.1.100"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIPv4ExactMatchNoMatch() {
|
||||||
|
IpAddressMatcher matcher = new IpAddressMatcher("192.168.1.100");
|
||||||
|
assertFalse(matcher.matches("192.168.1.101"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIPv4Localhost() {
|
||||||
|
IpAddressMatcher matcher = new IpAddressMatcher("127.0.0.1");
|
||||||
|
assertTrue(matcher.matches("127.0.0.1"));
|
||||||
|
assertFalse(matcher.matches("127.0.0.2"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// IPv4 CIDR tests
|
||||||
|
@Test
|
||||||
|
public void testIPv4Cidr24() {
|
||||||
|
IpAddressMatcher matcher = new IpAddressMatcher("192.168.1.0/24");
|
||||||
|
assertTrue(matcher.matches("192.168.1.0"));
|
||||||
|
assertTrue(matcher.matches("192.168.1.1"));
|
||||||
|
assertTrue(matcher.matches("192.168.1.255"));
|
||||||
|
assertFalse(matcher.matches("192.168.2.1"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIPv4Cidr16() {
|
||||||
|
IpAddressMatcher matcher = new IpAddressMatcher("192.168.0.0/16");
|
||||||
|
assertTrue(matcher.matches("192.168.0.1"));
|
||||||
|
assertTrue(matcher.matches("192.168.255.255"));
|
||||||
|
assertFalse(matcher.matches("192.169.0.1"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIPv4Cidr8() {
|
||||||
|
IpAddressMatcher matcher = new IpAddressMatcher("10.0.0.0/8");
|
||||||
|
assertTrue(matcher.matches("10.0.0.1"));
|
||||||
|
assertTrue(matcher.matches("10.255.255.255"));
|
||||||
|
assertFalse(matcher.matches("11.0.0.1"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIPv4Cidr32() {
|
||||||
|
IpAddressMatcher matcher = new IpAddressMatcher("192.168.1.100/32");
|
||||||
|
assertTrue(matcher.matches("192.168.1.100"));
|
||||||
|
assertFalse(matcher.matches("192.168.1.101"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIPv4CidrZero() {
|
||||||
|
IpAddressMatcher matcher = new IpAddressMatcher("0.0.0.0/0");
|
||||||
|
assertTrue(matcher.matches("192.168.1.1"));
|
||||||
|
assertTrue(matcher.matches("10.0.0.1"));
|
||||||
|
assertTrue(matcher.matches("255.255.255.255"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// IPv6 tests
|
||||||
|
@Test
|
||||||
|
public void testIPv6ExactMatch() {
|
||||||
|
IpAddressMatcher matcher = new IpAddressMatcher("::1");
|
||||||
|
assertTrue(matcher.matches("::1"));
|
||||||
|
assertTrue(matcher.matches("0:0:0:0:0:0:0:1"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIPv6Cidr() {
|
||||||
|
IpAddressMatcher matcher = new IpAddressMatcher("2001:db8::/32");
|
||||||
|
assertTrue(matcher.matches("2001:db8::1"));
|
||||||
|
assertTrue(matcher.matches("2001:db8:ffff:ffff:ffff:ffff:ffff:ffff"));
|
||||||
|
assertFalse(matcher.matches("2001:db9::1"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cross-family rejection tests
|
||||||
|
@Test
|
||||||
|
public void testIPv4DoesNotMatchIPv6() {
|
||||||
|
IpAddressMatcher matcher = new IpAddressMatcher("192.168.1.0/24");
|
||||||
|
assertFalse(matcher.matches("::1"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIPv6DoesNotMatchIPv4() {
|
||||||
|
IpAddressMatcher matcher = new IpAddressMatcher("::1");
|
||||||
|
assertFalse(matcher.matches("127.0.0.1"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Edge cases
|
||||||
|
@Test(expected = IllegalArgumentException.class)
|
||||||
|
public void testInvalidIPAddress() {
|
||||||
|
new IpAddressMatcher("invalid.ip.address");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPrivateNetworkRanges() {
|
||||||
|
// Class A private
|
||||||
|
IpAddressMatcher classA = new IpAddressMatcher("10.0.0.0/8");
|
||||||
|
assertTrue(classA.matches("10.0.0.1"));
|
||||||
|
assertTrue(classA.matches("10.255.255.254"));
|
||||||
|
|
||||||
|
// Class B private
|
||||||
|
IpAddressMatcher classB = new IpAddressMatcher("172.16.0.0/12");
|
||||||
|
assertTrue(classB.matches("172.16.0.1"));
|
||||||
|
assertTrue(classB.matches("172.31.255.254"));
|
||||||
|
assertFalse(classB.matches("172.32.0.1"));
|
||||||
|
|
||||||
|
// Class C private
|
||||||
|
IpAddressMatcher classC = new IpAddressMatcher("192.168.0.0/16");
|
||||||
|
assertTrue(classC.matches("192.168.0.1"));
|
||||||
|
assertTrue(classC.matches("192.168.255.254"));
|
||||||
|
}
|
||||||
|
}
|
||||||
196
DynmapCore/src/test/java/org/dynmap/utils/Matrix3DTest.java
Normal file
196
DynmapCore/src/test/java/org/dynmap/utils/Matrix3DTest.java
Normal file
|
|
@ -0,0 +1,196 @@
|
||||||
|
package org.dynmap.utils;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
public class Matrix3DTest {
|
||||||
|
|
||||||
|
private static final double DELTA = 1e-10;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIdentityConstructor() {
|
||||||
|
Matrix3D m = new Matrix3D();
|
||||||
|
double[] v = {1.0, 2.0, 3.0};
|
||||||
|
m.transform(v);
|
||||||
|
// Identity matrix should not change the vector
|
||||||
|
assertEquals(1.0, v[0], DELTA);
|
||||||
|
assertEquals(2.0, v[1], DELTA);
|
||||||
|
assertEquals(3.0, v[2], DELTA);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testParameterizedConstructor() {
|
||||||
|
// Create a matrix that doubles each component
|
||||||
|
Matrix3D m = new Matrix3D(2, 0, 0, 0, 2, 0, 0, 0, 2);
|
||||||
|
double[] v = {1.0, 2.0, 3.0};
|
||||||
|
m.transform(v);
|
||||||
|
assertEquals(2.0, v[0], DELTA);
|
||||||
|
assertEquals(4.0, v[1], DELTA);
|
||||||
|
assertEquals(6.0, v[2], DELTA);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testTransformArray() {
|
||||||
|
Matrix3D m = new Matrix3D(1, 2, 3, 4, 5, 6, 7, 8, 9);
|
||||||
|
double[] v = {1.0, 1.0, 1.0};
|
||||||
|
m.transform(v);
|
||||||
|
// Row 1: 1*1 + 2*1 + 3*1 = 6
|
||||||
|
// Row 2: 4*1 + 5*1 + 6*1 = 15
|
||||||
|
// Row 3: 7*1 + 8*1 + 9*1 = 24
|
||||||
|
assertEquals(6.0, v[0], DELTA);
|
||||||
|
assertEquals(15.0, v[1], DELTA);
|
||||||
|
assertEquals(24.0, v[2], DELTA);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testTransformVector3D() {
|
||||||
|
Matrix3D m = new Matrix3D(1, 2, 3, 4, 5, 6, 7, 8, 9);
|
||||||
|
Vector3D v = new Vector3D(1.0, 1.0, 1.0);
|
||||||
|
m.transform(v);
|
||||||
|
assertEquals(6.0, v.x, DELTA);
|
||||||
|
assertEquals(15.0, v.y, DELTA);
|
||||||
|
assertEquals(24.0, v.z, DELTA);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testTransformVector3DWithOutput() {
|
||||||
|
Matrix3D m = new Matrix3D(1, 2, 3, 4, 5, 6, 7, 8, 9);
|
||||||
|
Vector3D v = new Vector3D(1.0, 1.0, 1.0);
|
||||||
|
Vector3D out = new Vector3D();
|
||||||
|
m.transform(v, out);
|
||||||
|
// Input should be unchanged
|
||||||
|
assertEquals(1.0, v.x, DELTA);
|
||||||
|
assertEquals(1.0, v.y, DELTA);
|
||||||
|
assertEquals(1.0, v.z, DELTA);
|
||||||
|
// Output should have transformed values
|
||||||
|
assertEquals(6.0, out.x, DELTA);
|
||||||
|
assertEquals(15.0, out.y, DELTA);
|
||||||
|
assertEquals(24.0, out.z, DELTA);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testScale() {
|
||||||
|
Matrix3D m = new Matrix3D();
|
||||||
|
m.scale(2.0, 3.0, 4.0);
|
||||||
|
double[] v = {1.0, 1.0, 1.0};
|
||||||
|
m.transform(v);
|
||||||
|
assertEquals(2.0, v[0], DELTA);
|
||||||
|
assertEquals(3.0, v[1], DELTA);
|
||||||
|
assertEquals(4.0, v[2], DELTA);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRotateXY90Degrees() {
|
||||||
|
Matrix3D m = new Matrix3D();
|
||||||
|
m.rotateXY(90.0);
|
||||||
|
double[] v = {1.0, 0.0, 0.0};
|
||||||
|
m.transform(v);
|
||||||
|
// X axis rotated 90 degrees clockwise around Z should point to Y
|
||||||
|
assertEquals(0.0, v[0], DELTA);
|
||||||
|
assertEquals(-1.0, v[1], DELTA);
|
||||||
|
assertEquals(0.0, v[2], DELTA);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRotateXZ90Degrees() {
|
||||||
|
Matrix3D m = new Matrix3D();
|
||||||
|
m.rotateXZ(90.0);
|
||||||
|
double[] v = {1.0, 0.0, 0.0};
|
||||||
|
m.transform(v);
|
||||||
|
// X axis rotated 90 degrees clockwise around Y should point to +Z
|
||||||
|
assertEquals(0.0, v[0], DELTA);
|
||||||
|
assertEquals(0.0, v[1], DELTA);
|
||||||
|
assertEquals(1.0, v[2], DELTA);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRotateYZ90Degrees() {
|
||||||
|
Matrix3D m = new Matrix3D();
|
||||||
|
m.rotateYZ(90.0);
|
||||||
|
double[] v = {0.0, 1.0, 0.0};
|
||||||
|
m.transform(v);
|
||||||
|
// Y axis rotated 90 degrees clockwise around X should point to Z
|
||||||
|
assertEquals(0.0, v[0], DELTA);
|
||||||
|
assertEquals(0.0, v[1], DELTA);
|
||||||
|
assertEquals(-1.0, v[2], DELTA);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRotate360DegreesReturnsToOriginal() {
|
||||||
|
Matrix3D m = new Matrix3D();
|
||||||
|
m.rotateXY(360.0);
|
||||||
|
double[] v = {1.0, 2.0, 3.0};
|
||||||
|
m.transform(v);
|
||||||
|
assertEquals(1.0, v[0], DELTA);
|
||||||
|
assertEquals(2.0, v[1], DELTA);
|
||||||
|
assertEquals(3.0, v[2], DELTA);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMultiply() {
|
||||||
|
// Create two scaling matrices
|
||||||
|
Matrix3D m1 = new Matrix3D(2, 0, 0, 0, 2, 0, 0, 0, 2);
|
||||||
|
Matrix3D m2 = new Matrix3D(3, 0, 0, 0, 3, 0, 0, 0, 3);
|
||||||
|
m1.multiply(m2);
|
||||||
|
double[] v = {1.0, 1.0, 1.0};
|
||||||
|
m1.transform(v);
|
||||||
|
// Should scale by 6 (2*3)
|
||||||
|
assertEquals(6.0, v[0], DELTA);
|
||||||
|
assertEquals(6.0, v[1], DELTA);
|
||||||
|
assertEquals(6.0, v[2], DELTA);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testShearZ() {
|
||||||
|
Matrix3D m = new Matrix3D();
|
||||||
|
m.shearZ(1.0, 0.0);
|
||||||
|
// With shearZ matrix [1,0,0; 0,1,0; x_fact,y_fact,1] multiplied as mat*this
|
||||||
|
// The result matrix has x_fact in position m31
|
||||||
|
// transform: v1 = m11*x + m12*y + m13*z = x
|
||||||
|
// v2 = m21*x + m22*y + m23*z = y
|
||||||
|
// v3 = m31*x + m32*y + m33*z = x_fact*x + y_fact*y + z
|
||||||
|
double[] v = {1.0, 0.0, 0.0};
|
||||||
|
m.transform(v);
|
||||||
|
// X contributes to Z via shear
|
||||||
|
assertEquals(1.0, v[0], DELTA);
|
||||||
|
assertEquals(0.0, v[1], DELTA);
|
||||||
|
assertEquals(1.0, v[2], DELTA);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testChainedTransformations() {
|
||||||
|
Matrix3D m = new Matrix3D();
|
||||||
|
m.scale(2.0, 2.0, 2.0);
|
||||||
|
m.rotateXY(90.0);
|
||||||
|
double[] v = {1.0, 0.0, 0.0};
|
||||||
|
m.transform(v);
|
||||||
|
// First scale by 2, then rotate - result should be scaled and rotated
|
||||||
|
assertEquals(0.0, v[0], DELTA);
|
||||||
|
assertEquals(-2.0, v[1], DELTA);
|
||||||
|
assertEquals(0.0, v[2], DELTA);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testToString() {
|
||||||
|
Matrix3D m = new Matrix3D();
|
||||||
|
String str = m.toString();
|
||||||
|
assertNotNull(str);
|
||||||
|
assertTrue(str.contains("1.0"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testToJSON() {
|
||||||
|
Matrix3D m = new Matrix3D(1, 2, 3, 4, 5, 6, 7, 8, 9);
|
||||||
|
org.json.simple.JSONArray json = m.toJSON();
|
||||||
|
assertEquals(9, json.size());
|
||||||
|
assertEquals(1.0, json.get(0));
|
||||||
|
assertEquals(2.0, json.get(1));
|
||||||
|
assertEquals(3.0, json.get(2));
|
||||||
|
assertEquals(4.0, json.get(3));
|
||||||
|
assertEquals(5.0, json.get(4));
|
||||||
|
assertEquals(6.0, json.get(5));
|
||||||
|
assertEquals(7.0, json.get(6));
|
||||||
|
assertEquals(8.0, json.get(7));
|
||||||
|
assertEquals(9.0, json.get(8));
|
||||||
|
}
|
||||||
|
}
|
||||||
173
DynmapCore/src/test/java/org/dynmap/utils/Vector3DTest.java
Normal file
173
DynmapCore/src/test/java/org/dynmap/utils/Vector3DTest.java
Normal file
|
|
@ -0,0 +1,173 @@
|
||||||
|
package org.dynmap.utils;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
public class Vector3DTest {
|
||||||
|
|
||||||
|
private static final double DELTA = 1e-10;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDefaultConstructor() {
|
||||||
|
Vector3D v = new Vector3D();
|
||||||
|
assertEquals(0.0, v.x, DELTA);
|
||||||
|
assertEquals(0.0, v.y, DELTA);
|
||||||
|
assertEquals(0.0, v.z, DELTA);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testParameterizedConstructor() {
|
||||||
|
Vector3D v = new Vector3D(1.0, 2.0, 3.0);
|
||||||
|
assertEquals(1.0, v.x, DELTA);
|
||||||
|
assertEquals(2.0, v.y, DELTA);
|
||||||
|
assertEquals(3.0, v.z, DELTA);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCopyConstructor() {
|
||||||
|
Vector3D original = new Vector3D(5.0, 6.0, 7.0);
|
||||||
|
Vector3D copy = new Vector3D(original);
|
||||||
|
assertEquals(original.x, copy.x, DELTA);
|
||||||
|
assertEquals(original.y, copy.y, DELTA);
|
||||||
|
assertEquals(original.z, copy.z, DELTA);
|
||||||
|
// Ensure it's a copy, not a reference
|
||||||
|
original.x = 100.0;
|
||||||
|
assertEquals(5.0, copy.x, DELTA);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSet() {
|
||||||
|
Vector3D v1 = new Vector3D(1.0, 2.0, 3.0);
|
||||||
|
Vector3D v2 = new Vector3D();
|
||||||
|
Vector3D result = v2.set(v1);
|
||||||
|
assertEquals(1.0, v2.x, DELTA);
|
||||||
|
assertEquals(2.0, v2.y, DELTA);
|
||||||
|
assertEquals(3.0, v2.z, DELTA);
|
||||||
|
assertSame(v2, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAdd() {
|
||||||
|
Vector3D v1 = new Vector3D(1.0, 2.0, 3.0);
|
||||||
|
Vector3D v2 = new Vector3D(4.0, 5.0, 6.0);
|
||||||
|
Vector3D result = v1.add(v2);
|
||||||
|
assertEquals(5.0, v1.x, DELTA);
|
||||||
|
assertEquals(7.0, v1.y, DELTA);
|
||||||
|
assertEquals(9.0, v1.z, DELTA);
|
||||||
|
assertSame(v1, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSubtract() {
|
||||||
|
Vector3D v1 = new Vector3D(5.0, 7.0, 9.0);
|
||||||
|
Vector3D v2 = new Vector3D(1.0, 2.0, 3.0);
|
||||||
|
Vector3D result = v1.subtract(v2);
|
||||||
|
assertEquals(4.0, v1.x, DELTA);
|
||||||
|
assertEquals(5.0, v1.y, DELTA);
|
||||||
|
assertEquals(6.0, v1.z, DELTA);
|
||||||
|
assertSame(v1, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testScale() {
|
||||||
|
Vector3D v = new Vector3D(2.0, 3.0, 4.0);
|
||||||
|
Vector3D result = v.scale(2.0);
|
||||||
|
assertEquals(4.0, v.x, DELTA);
|
||||||
|
assertEquals(6.0, v.y, DELTA);
|
||||||
|
assertEquals(8.0, v.z, DELTA);
|
||||||
|
assertSame(v, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testInnerProduct() {
|
||||||
|
Vector3D v1 = new Vector3D(1.0, 2.0, 3.0);
|
||||||
|
Vector3D v2 = new Vector3D(4.0, 5.0, 6.0);
|
||||||
|
double result = v1.innerProduct(v2);
|
||||||
|
// 1*4 + 2*5 + 3*6 = 4 + 10 + 18 = 32
|
||||||
|
assertEquals(32.0, result, DELTA);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCrossProduct() {
|
||||||
|
Vector3D v1 = new Vector3D(1.0, 0.0, 0.0);
|
||||||
|
Vector3D v2 = new Vector3D(0.0, 1.0, 0.0);
|
||||||
|
Vector3D result = v1.crossProduct(v2);
|
||||||
|
// i x j = k
|
||||||
|
assertEquals(0.0, v1.x, DELTA);
|
||||||
|
assertEquals(0.0, v1.y, DELTA);
|
||||||
|
assertEquals(1.0, v1.z, DELTA);
|
||||||
|
assertSame(v1, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCrossProductGeneral() {
|
||||||
|
Vector3D v1 = new Vector3D(2.0, 3.0, 4.0);
|
||||||
|
Vector3D v2 = new Vector3D(5.0, 6.0, 7.0);
|
||||||
|
v1.crossProduct(v2);
|
||||||
|
// (3*7 - 4*6, 4*5 - 2*7, 2*6 - 3*5) = (21-24, 20-14, 12-15) = (-3, 6, -3)
|
||||||
|
assertEquals(-3.0, v1.x, DELTA);
|
||||||
|
assertEquals(6.0, v1.y, DELTA);
|
||||||
|
assertEquals(-3.0, v1.z, DELTA);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLength() {
|
||||||
|
Vector3D v = new Vector3D(3.0, 4.0, 0.0);
|
||||||
|
assertEquals(5.0, v.length(), DELTA);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLengthUnit() {
|
||||||
|
Vector3D v = new Vector3D(1.0, 0.0, 0.0);
|
||||||
|
assertEquals(1.0, v.length(), DELTA);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLengthZero() {
|
||||||
|
Vector3D v = new Vector3D();
|
||||||
|
assertEquals(0.0, v.length(), DELTA);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEquals() {
|
||||||
|
Vector3D v1 = new Vector3D(1.0, 2.0, 3.0);
|
||||||
|
Vector3D v2 = new Vector3D(1.0, 2.0, 3.0);
|
||||||
|
assertTrue(v1.equals(v2));
|
||||||
|
assertTrue(v2.equals(v1));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEqualsNotEqual() {
|
||||||
|
Vector3D v1 = new Vector3D(1.0, 2.0, 3.0);
|
||||||
|
Vector3D v2 = new Vector3D(1.0, 2.0, 4.0);
|
||||||
|
assertFalse(v1.equals(v2));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEqualsNull() {
|
||||||
|
Vector3D v = new Vector3D(1.0, 2.0, 3.0);
|
||||||
|
assertFalse(v.equals(null));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEqualsWrongType() {
|
||||||
|
Vector3D v = new Vector3D(1.0, 2.0, 3.0);
|
||||||
|
assertFalse(v.equals("not a vector"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testHashCodeConsistency() {
|
||||||
|
Vector3D v1 = new Vector3D(1.0, 2.0, 3.0);
|
||||||
|
Vector3D v2 = new Vector3D(1.0, 2.0, 3.0);
|
||||||
|
assertEquals(v1.hashCode(), v2.hashCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testToString() {
|
||||||
|
Vector3D v = new Vector3D(1.0, 2.0, 3.0);
|
||||||
|
String str = v.toString();
|
||||||
|
assertTrue(str.contains("1.0"));
|
||||||
|
assertTrue(str.contains("2.0"));
|
||||||
|
assertTrue(str.contains("3.0"));
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue