diff --git a/test/arc.test.ts b/test/arc.test.ts new file mode 100644 index 0000000..81a9b0e --- /dev/null +++ b/test/arc.test.ts @@ -0,0 +1,161 @@ +import { assert } from 'chai'; +import { Vector3 } from 'three'; +import { MeshLine } from '../src/MeshLine'; +import { Geometry } from '../src/index'; + +describe('Arc', () => { + describe('default config', () => { + it('should set default config', () => { + const arc = new Geometry.Arc(); + + assert.equal(arc.radius, 1); + assert.equal(arc.angle, Math.PI / 2); + assert.isFalse(arc.closed); + assert.isUndefined(arc.fill); + }); + + it('should have default style set', () => { + const arc = new Geometry.Arc(); + const defaults = Geometry.Arrow.defaultStyle(); + + assert.isUndefined(arc.fill); + assert.equal(arc.stroke?.material.color.getHexString(), defaults.strokeColor.getHexString()); + assert.equal(arc.stroke?.material.opacity, defaults.strokeOpacity); + assert.equal(arc.stroke?.material.width, defaults.strokeWidth); + }); + }); + + describe('attributes', () => { + it('should have a radius, angle, and closed attributes', () => { + const arc = new Geometry.Arc(); + assert.containsAllKeys(arc.getAttributes(), ['radius', 'angle', 'closed']); + assert.deepEqual(arc.getAttributes(), { radius: 1, angle: Math.PI / 2, closed: false }); + }); + + it('should correctly return clone attributes', () => { + const arc = new Geometry.Arc(10, 8, { closed: true }); + assert.deepEqual(arc.getCloneAttributes(), [10, 8, true]); + }); + + it('should correctly return attribute data', () => { + const arc = new Geometry.Arc(); + assert.deepEqual(arc.attributeData, [ + { + attribute: 'radius', + type: 'number', + default: 1, + }, + { + attribute: 'angle', + type: 'angle', + default: 45, + }, + { + attribute: 'closed', + type: 'boolean', + default: false, + }, + ]); + }); + }); + + describe('shape', () => { + it('closed arc should start and end with a (0, 0, 0) vector 3', () => { + const closedArc = new Geometry.Arc(10, 8, { closed: true }); + const openArc = new Geometry.Arc(10, 8, { closed: false }); + + assert.equal(closedArc.points.length, openArc.points.length + 2); + assert.deepEqual(closedArc.points.at(0)?.toArray(), [0, 0, 0]); + assert.deepEqual(closedArc.points.at(-1)?.toArray(), [0, 0, 0]); + }); + + it('should set correct curveEndIndices on a closed arc', () => { + const arc = new Geometry.Arc(1, Math.PI / 2, { closed: true }); + assert.deepEqual(arc.curveEndIndices, [ + [0, 1], + [1, 51], + [51, 52], + ]); + }); + + it('should set correct curveEndIndices on an arc', () => { + const arc = new Geometry.Arc(1, Math.PI / 2, { closed: false }); + assert.deepEqual(arc.curveEndIndices, [[0, 50]]); + }); + + it('should have correct points with a 0 angle', () => { + const arc = new Geometry.Arc(1, 0); + assert.deepEqual(arc.points, [new Vector3(1, 0, 0), new Vector3(1, 0, 0)]); + }); + + it('should return the correct dimensions', () => { + const arc = new Geometry.Arc(1, 0); + assert.deepEqual(arc.getDimensions().toArray(), [2, 2]); + }); + + it('should have correct points', () => { + const arc = new Geometry.Arc(1, 1); + + assert.deepEqual(arc.points, [ + new Vector3(1, 0, 0), + new Vector3(0.9998000066665778, 0.01999866669333308, 0), + new Vector3(0.9992001066609779, 0.03998933418663416, 0), + new Vector3(0.9982005399352042, 0.059964006479444595, 0), + new Vector3(0.9968017063026194, 0.0799146939691727, 0), + new Vector3(0.9950041652780257, 0.09983341664682815, 0), + new Vector3(0.9928086358538663, 0.11971220728891938, 0), + new Vector3(0.9902159962126371, 0.1395431146442365, 0), + new Vector3(0.9872272833756269, 0.15931820661424598, 0), + new Vector3(0.9838436927881214, 0.17902957342582418, 0), + new Vector3(0.9800665778412416, 0.1986693307950612, 0), + new Vector3(0.9758974493306055, 0.2182296230808693, 0), + new Vector3(0.9713379748520297, 0.23770262642713455, 0), + new Vector3(0.9663899781345132, 0.25708055189215506, 0), + new Vector3(0.961055438310771, 0.2763556485641137, 0), + new Vector3(0.955336489125606, 0.29552020666133955, 0), + new Vector3(0.9492354180824408, 0.31456656061611776, 0), + new Vector3(0.9427546655283462, 0.3334870921408144, 0), + new Vector3(0.9358968236779348, 0.35227423327509, 0), + new Vector3(0.9286646355765102, 0.37092046941298273, 0), + new Vector3(0.9210609940028851, 0.3894183423086506, 0), + new Vector3(0.9130889403123083, 0.40776045305957026, 0), + new Vector3(0.9047516632199634, 0.4259394650659997, 0), + new Vector3(0.8960524975255252, 0.4439481069655199, 0), + new Vector3(0.8869949227792842, 0.461779175541483, 0), + new Vector3(0.8775825618903726, 0.4794255386042031, 0), + new Vector3(0.8678191796776499, 0.49688013784373686, 0), + new Vector3(0.857708681363824, 0.5141359916531132, 0), + new Vector3(0.8472551110134161, 0.5311861979208835, 0), + new Vector3(0.8364626499151868, 0.5480239367918737, 0), + new Vector3(0.8253356149096782, 0.5646424733950355, 0), + new Vector3(0.8138784566625338, 0.5810351605373052, 0), + new Vector3(0.8020957578842924, 0.5971954413623922, 0), + new Vector3(0.789992231497365, 0.613116851973434, 0), + new Vector3(0.7775727187509278, 0.6287930240184687, 0), + new Vector3(0.7648421872844883, 0.6442176872376912, 0), + new Vector3(0.7518057291408948, 0.6593846719714734, 0), + new Vector3(0.7384685587295876, 0.6742879116281453, 0), + new Vector3(0.7248360107409049, 0.6889214451105515, 0), + new Vector3(0.7109135380122771, 0.7032794192004104, 0), + new Vector3(0.6967067093471652, 0.717356090899523, 0), + new Vector3(0.6822212072876133, 0.7311458297268961, 0), + new Vector3(0.6674628258413078, 0.7446431199708596, 0), + new Vector3(0.6524374681640516, 0.7578425628952772, 0), + new Vector3(0.6371511441985799, 0.7707388788989695, 0), + new Vector3(0.6216099682706641, 0.7833269096274836, 0), + new Vector3(0.6058201566434624, 0.7956016200363664, 0), + new Vector3(0.5897880250310978, 0.8075581004051146, 0), + new Vector3(0.5735199860724562, 0.8191915683009986, 0), + new Vector3(0.5570225467662169, 0.8304973704919708, 0), + new Vector3(0.5403023058681393, 0.8414709848078967, 0), + ]); + }); + }); + + it('should inherit from shape', () => { + const arc = new Geometry.Arc(); + assert.isUndefined(arc.fill); + assert.instanceOf(arc.stroke, MeshLine); + assert.isArray(arc.curveEndIndices); + }); +}); diff --git a/test/arrow.test.ts b/test/arrow.test.ts new file mode 100644 index 0000000..6fcdcae --- /dev/null +++ b/test/arrow.test.ts @@ -0,0 +1,71 @@ +import { assert } from 'chai'; +import { MeshLine } from '../src/MeshLine'; +import { Geometry, THREE } from '../src/index'; + +describe('Arrow', () => { + function getTestPoints(): [start: THREE.Vector3, end: THREE.Vector3] { + return [new THREE.Vector3(-1, -1, 0), new THREE.Vector3(1, 1, 0)]; + } + + describe('default config', () => { + it('should set arrow to true', () => { + const arrowOne = new Geometry.Arrow(...getTestPoints()); + assert.isTrue(arrowOne.arrow); + + // @ts-expect-error invalid config + const arrowTwo = new Geometry.Arrow(...getTestPoints(), { arrow: false }); + assert.isTrue(arrowTwo.arrow); + }); + + it('should have default style set', () => { + const arrow = new Geometry.Arrow(...getTestPoints()); + const defaults = Geometry.Arrow.defaultStyle(); + + assert.equal(arrow.fill?.material.color.getHexString(), defaults.fillColor.getHexString()); + assert.equal(arrow.fill?.material.opacity, defaults.fillOpacity); + assert.isTrue(arrow.fill?.material.transparent); + assert.equal( + arrow.stroke?.material.color.getHexString(), + defaults.strokeColor.getHexString(), + ); + assert.equal(arrow.stroke?.material.opacity, defaults.strokeOpacity); + assert.equal(arrow.stroke?.material.width, defaults.strokeWidth); + }); + }); + + describe('attributes', () => { + it('should have a start and end attribute', () => { + const arrow = new Geometry.Arrow(...getTestPoints()); + assert.containsAllKeys(arrow.getAttributes(), ['start', 'end']); + }); + }); + + describe('shape', () => { + it('should set start and end correctly', () => { + const arrow = new Geometry.Arrow(...getTestPoints()); + + assert.deepEqual(arrow.start.toArray(), [-1, -1, 0]); + assert.deepEqual(arrow.end.toArray(), [1, 1, 0]); + }); + + it.skip('should correctly reshape', () => { + const arrow = new Geometry.Arrow(...getTestPoints()); + + arrow.reshape(new THREE.Vector3(-2, -2, 0), new THREE.Vector3(2, 2, 0), { + fillColor: new THREE.Color('#C458A5'), + }); + + assert.deepEqual(arrow.start.toArray(), [-2, -2, 0]); + assert.deepEqual(arrow.end.toArray(), [2, 2, 0]); + assert.equal(arrow.fill?.material.color.getHexString(), 'c458a5'); + }); + }); + + it('should inherit from shape', () => { + const arrow = new Geometry.Arrow(...getTestPoints()); + assert.instanceOf(arrow.fill, THREE.Mesh); + assert.instanceOf(arrow.stroke, MeshLine); + assert.isArray(arrow.curveEndIndices); + assert.isBoolean(arrow.arrow); + }); +}); diff --git a/test/circle.test.ts b/test/circle.test.ts new file mode 100644 index 0000000..8924378 --- /dev/null +++ b/test/circle.test.ts @@ -0,0 +1,141 @@ +import { assert } from 'chai'; +import { Vector3 } from 'three'; +import { MeshLine } from '../src/MeshLine'; +import { Geometry, THREE } from '../src/index'; + +describe('Circle', () => { + describe('default config', () => { + it('should set defaults', () => { + const circle = new Geometry.Circle(); + + assert.equal(circle.radius, 1); + assert.equal(circle.angle, Math.PI * 2); + assert.isFalse(circle.closed); + }); + + it('should have default style set', () => { + const circle = new Geometry.Circle(); + const defaults = Geometry.Arrow.defaultStyle(); + + assert.equal(circle.fill?.material.color.getHexString(), defaults.fillColor.getHexString()); + assert.equal(circle.fill?.material.opacity, defaults.fillOpacity); + assert.isTrue(circle.fill?.material.transparent); + assert.equal( + circle.stroke?.material.color.getHexString(), + defaults.strokeColor.getHexString(), + ); + assert.equal(circle.stroke?.material.opacity, defaults.strokeOpacity); + assert.equal(circle.stroke?.material.width, defaults.strokeWidth); + }); + }); + + describe('attributes', () => { + it('should have a radius, angle, and closed attributes', () => { + const circle = new Geometry.Circle(10); + assert.containsAllKeys(circle.getAttributes(), ['radius', 'angle', 'closed']); + assert.deepEqual(circle.getAttributes(), { radius: 10, angle: Math.PI * 2, closed: false }); + }); + + it('should correctly return clone attributes', () => { + const circle = new Geometry.Circle(10); + assert.deepEqual(circle.getCloneAttributes(), [10]); + }); + + it('should correctly return attribute data', () => { + const circle = new Geometry.Circle(); + assert.deepEqual(circle.attributeData, [ + { + attribute: 'radius', + type: 'number', + default: 1, + }, + ]); + }); + }); + + describe('shape', () => { + it('should set correct curveEndIndices on an circle', () => { + const circle = new Geometry.Circle(1); + assert.deepEqual(circle.curveEndIndices, [[0, 50]]); + }); + + it('should return the correct dimensions', () => { + const circle = new Geometry.Circle(1); + assert.deepEqual(circle.getDimensions().toArray(), [2, 2]); + }); + + it('should have correct points', () => { + const circle = new Geometry.Circle(1); + + assert.deepEqual(circle.points, [ + new Vector3(1, 0, 0), + new Vector3(0.9921147013144779, 0.12533323356430426, 0), + new Vector3(0.9685831611286311, 0.2486898871648548, 0), + new Vector3(0.9297764858882513, 0.368124552684678, 0), + new Vector3(0.8763066800438636, 0.4817536741017153, 0), + new Vector3(0.8090169943749475, 0.5877852522924731, 0), + new Vector3(0.7289686274214116, 0.6845471059286886, 0), + new Vector3(0.6374239897486899, 0.7705132427757891, 0), + new Vector3(0.5358267949789968, 0.844327925502015, 0), + new Vector3(0.4257792915650728, 0.9048270524660195, 0), + new Vector3(0.3090169943749477, 0.9510565162951535, 0), + new Vector3(0.18738131458572493, 0.9822872507286886, 0), + new Vector3(0.06279051952931375, 0.9980267284282716, 0), + new Vector3(-0.06279051952931296, 0.9980267284282716, 0), + new Vector3(-0.18738131458572418, 0.9822872507286887, 0), + new Vector3(-0.30901699437494695, 0.9510565162951538, 0), + new Vector3(-0.4257792915650723, 0.9048270524660197, 0), + new Vector3(-0.5358267949789964, 0.8443279255020152, 0), + new Vector3(-0.6374239897486897, 0.7705132427757893, 0), + new Vector3(-0.7289686274214117, 0.6845471059286885, 0), + new Vector3(-0.8090169943749477, 0.5877852522924728, 0), + new Vector3(-0.8763066800438638, 0.4817536741017148, 0), + new Vector3(-0.9297764858882517, 0.3681245526846773, 0), + new Vector3(-0.9685831611286313, 0.24868988716485396, 0), + new Vector3(-0.992114701314478, 0.1253332335643032, 0), + new Vector3(-1, -1.2098029496354525e-15, 0), + new Vector3(-0.9921147013144777, -0.12533323356430562, 0), + new Vector3(-0.9685831611286307, -0.2486898871648563, 0), + new Vector3(-0.9297764858882508, -0.3681245526846796, 0), + new Vector3(-0.8763066800438627, -0.48175367410171693, 0), + new Vector3(-0.8090169943749462, -0.5877852522924748, 0), + new Vector3(-0.72896862742141, -0.6845471059286903, 0), + new Vector3(-0.6374239897486882, -0.7705132427757905, 0), + new Vector3(-0.5358267949789948, -0.8443279255020163, 0), + new Vector3(-0.42577929156507055, -0.9048270524660205, 0), + new Vector3(-0.30901699437494506, -0.9510565162951543, 0), + new Vector3(-0.18738131458572202, -0.9822872507286892, 0), + new Vector3(-0.06279051952931054, -0.9980267284282718, 0), + new Vector3(0.06279051952931639, -0.9980267284282713, 0), + new Vector3(0.18738131458572777, -0.982287250728688, 0), + new Vector3(0.3090169943749506, -0.9510565162951525, 0), + new Vector3(0.4257792915650758, -0.904827052466018, 0), + new Vector3(0.5358267949789998, -0.8443279255020131, 0), + new Vector3(0.6374239897486927, -0.7705132427757867, 0), + new Vector3(0.7289686274214142, -0.6845471059286857, 0), + new Vector3(0.8090169943749499, -0.5877852522924697, 0), + new Vector3(0.8763066800438657, -0.48175367410171144, 0), + new Vector3(0.9297764858882531, -0.3681245526846737, 0), + new Vector3(0.9685831611286323, -0.2486898871648502, 0), + new Vector3(0.9921147013144784, -0.12533323356429937, 0), + new Vector3(1, 5.084141158371281e-15, 0), + ]); + }); + }); + + describe('inheritance', () => { + it('from shape', () => { + const circle = new Geometry.Circle(); + assert.instanceOf(circle.fill, THREE.Mesh); + assert.instanceOf(circle.stroke, MeshLine); + assert.isArray(circle.curveEndIndices); + }); + + it('from arc', () => { + const circle = new Geometry.Circle(); + assert.equal(circle.radius, 1); + assert.equal(circle.angle, Math.PI * 2); + assert.deepEqual(circle.curveEndIndices, [[0, 50]]); + }); + }); +}); diff --git a/test/line.test.ts b/test/line.test.ts new file mode 100644 index 0000000..12b63fa --- /dev/null +++ b/test/line.test.ts @@ -0,0 +1,33 @@ +import { assert } from 'chai'; +import { MeshLine } from '../src/MeshLine'; +import { Geometry, THREE } from '../src/index'; + +describe('Line', () => { + const line = new Geometry.Line(new THREE.Vector3(0, 0, 0), new THREE.Vector3(1, 1, 1)); + + describe('attributes', () => { + it('should have a start and end attribute', () => { + const attributes = line.getAttributes(); + assert.containsAllKeys(attributes, ['start', 'end']); + }); + + it('should have the correct start attribute', () => { + const start = line.start; + const startDifference = new THREE.Vector3(0, 0, 0).sub(start).length(); + assert.isAtMost(startDifference, 0.001); + }); + + it('should have the corrent end attribute', () => { + const end = line.end; + const endDifference = new THREE.Vector3(1, 1, 1).sub(end).length(); + assert.isAtMost(endDifference, 0.001); + }); + }); + + it('should inherit from shape', () => { + assert.instanceOf(line.fill, THREE.Mesh); + assert.instanceOf(line.stroke, MeshLine); + assert.isArray(line.curveEndIndices); + assert.isBoolean(line.arrow); + }); +}); diff --git a/test/point.test.ts b/test/point.test.ts new file mode 100644 index 0000000..01537e3 --- /dev/null +++ b/test/point.test.ts @@ -0,0 +1,147 @@ +import { assert } from 'chai'; +import { Vector3 } from 'three'; +import { MeshLine } from '../src/MeshLine'; +import { Geometry, THREE } from '../src/index'; + +describe('Point', () => { + describe('default config', () => { + it('should set defaults', () => { + const point = new Geometry.Point(); + + assert.equal(point.radius, 0.08); + assert.equal(point.angle, Math.PI * 2); + assert.deepEqual(point.position, new Vector3(0, 0, 0)); + assert.isFalse(point.closed); + }); + + it.skip('should have default style set', () => { + const point = new Geometry.Point(); + const defaults = Geometry.Arrow.defaultStyle(); + + assert.equal(point.fill?.material.color.getHexString(), defaults.fillColor.getHexString()); + assert.equal(point.fill?.material.opacity, defaults.fillOpacity); + assert.isTrue(point.fill?.material.transparent); + assert.equal( + point.stroke?.material.color.getHexString(), + defaults.strokeColor.getHexString(), + ); + assert.equal(point.stroke?.material.opacity, defaults.strokeOpacity); + assert.equal(point.stroke?.material.width, defaults.strokeWidth); + }); + }); + + describe('attributes', () => { + it('should have a radius, angle, and closed attributes', () => { + const point = new Geometry.Point(undefined, { radius: 10 }); + assert.containsAllKeys(point.getAttributes(), ['radius', 'angle', 'closed']); + assert.deepEqual(point.getAttributes(), { radius: 10, angle: Math.PI * 2, closed: false }); + }); + + it('should correctly return clone attributes', () => { + const point = new Geometry.Point(undefined, { radius: 10 }); + assert.deepEqual(point.getCloneAttributes(), [10]); + }); + + it('should correctly return attribute data', () => { + const point = new Geometry.Point(); + assert.deepEqual(point.attributeData, [ + { + attribute: 'radius', + type: 'number', + default: 1, + }, + ]); + }); + }); + + describe('shape', () => { + it('should set correct curveEndIndices on an point', () => { + const point = new Geometry.Point(); + assert.deepEqual(point.curveEndIndices, [[0, 50]]); + }); + + it('should return the correct dimensions', () => { + const point = new Geometry.Point(); + assert.deepEqual(point.getDimensions().toArray(), [0.16, 0.16]); + }); + + it('should have correct points', () => { + const point = new Geometry.Point(); + + assert.deepEqual(point.points, [ + new Vector3(0.08, 0, 0), + new Vector3(0.07936917610515823, 0.010026658685144341, 0), + new Vector3(0.07748665289029048, 0.019895190973188384, 0), + new Vector3(0.07438211887106011, 0.02944996421477424, 0), + new Vector3(0.07010453440350908, 0.03854029392813723, 0), + new Vector3(0.06472135954999579, 0.04702282018339785, 0), + new Vector3(0.05831749019371293, 0.054763768474295094, 0), + new Vector3(0.05099391917989519, 0.06164105942206313, 0), + new Vector3(0.04286614359831974, 0.0675462340401612, 0), + new Vector3(0.03406234332520583, 0.07238616419728156, 0), + new Vector3(0.024721359549995815, 0.07608452130361229, 0), + new Vector3(0.014990505166857996, 0.07858298005829509, 0), + new Vector3(0.0050232415623451, 0.07984213827426173, 0), + new Vector3(-0.005023241562345036, 0.07984213827426173, 0), + new Vector3(-0.014990505166857935, 0.0785829800582951, 0), + new Vector3(-0.024721359549995756, 0.0760845213036123, 0), + new Vector3(-0.03406234332520579, 0.07238616419728158, 0), + new Vector3(-0.042866143598319716, 0.06754623404016122, 0), + new Vector3(-0.05099391917989518, 0.06164105942206314, 0), + new Vector3(-0.058317490193712934, 0.05476376847429508, 0), + new Vector3(-0.06472135954999582, 0.047022820183397825, 0), + new Vector3(-0.07010453440350911, 0.03854029392813719, 0), + new Vector3(-0.07438211887106014, 0.029449964214774187, 0), + new Vector3(-0.07748665289029051, 0.019895190973188318, 0), + new Vector3(-0.07936917610515824, 0.010026658685144256, 0), + new Vector3(-0.08, -9.678423597083621e-17, 0), + new Vector3(-0.07936917610515822, -0.010026658685144449, 0), + new Vector3(-0.07748665289029046, -0.019895190973188506, 0), + new Vector3(-0.07438211887106007, -0.029449964214774367, 0), + new Vector3(-0.07010453440350901, -0.038540293928137355, 0), + new Vector3(-0.0647213595499957, -0.047022820183397984, 0), + new Vector3(-0.0583174901937128, -0.054763768474295225, 0), + new Vector3(-0.050993919179895056, -0.06164105942206324, 0), + new Vector3(-0.042866143598319584, -0.0675462340401613, 0), + new Vector3(-0.03406234332520564, -0.07238616419728164, 0), + new Vector3(-0.024721359549995606, -0.07608452130361235, 0), + new Vector3(-0.014990505166857761, -0.07858298005829513, 0), + new Vector3(-0.005023241562344844, -0.07984213827426175, 0), + new Vector3(0.005023241562345311, -0.0798421382742617, 0), + new Vector3(0.014990505166858221, -0.07858298005829505, 0), + new Vector3(0.02472135954999605, -0.07608452130361221, 0), + new Vector3(0.034062343325206065, -0.07238616419728144, 0), + new Vector3(0.04286614359831998, -0.06754623404016105, 0), + new Vector3(0.050993919179895424, -0.06164105942206294, 0), + new Vector3(0.058317490193713135, -0.05476376847429486, 0), + new Vector3(0.064721359549996, -0.047022820183397575, 0), + new Vector3(0.07010453440350926, -0.03854029392813692, 0), + new Vector3(0.07438211887106025, -0.029449964214773895, 0), + new Vector3(0.07748665289029058, -0.019895190973188016, 0), + new Vector3(0.07936917610515827, -0.01002665868514395, 0), + new Vector3(0.08, 4.067312926697025e-16, 0), + ]); + }); + }); + + describe('inheritance', () => { + it('from shape', () => { + const point = new Geometry.Point(); + assert.instanceOf(point.fill, THREE.Mesh); + assert.instanceOf(point.stroke, MeshLine); + assert.isArray(point.curveEndIndices); + }); + + it('from arc', () => { + const point = new Geometry.Point(); + assert.equal(point.radius, 0.08); + assert.equal(point.angle, Math.PI * 2); + assert.deepEqual(point.curveEndIndices, [[0, 50]]); + }); + + it('from circle', () => { + const point = new Geometry.Point(); + assert.instanceOf(point, Geometry.Circle); + }); + }); +}); diff --git a/test/polygon.test.ts b/test/polygon.test.ts new file mode 100644 index 0000000..be519bc --- /dev/null +++ b/test/polygon.test.ts @@ -0,0 +1,79 @@ +import { assert } from 'chai'; +import { MeshLine } from '../src/MeshLine'; +import { Geometry, THREE } from '../src/index'; + +describe('Polygon', () => { + function getTestPoints() { + return [ + new THREE.Vector3(-2, -1, 0), + new THREE.Vector3(-1, 1, 0), + new THREE.Vector3(1, 1, 0), + new THREE.Vector3(2, -1, 0), + new THREE.Vector3(-2, -1, 0), + ]; + } + + describe('default config', () => { + it('should set curveEndIndices', () => { + const polygon = new Geometry.Polygon(getTestPoints()); + assert.deepEqual(polygon.curveEndIndices, [ + [0, 1], + [1, 2], + [2, 3], + [3, 4], + ]); + }); + + it('should have default style set', () => { + const polygon = new Geometry.Polygon(getTestPoints()); + const defaults = Geometry.Arrow.defaultStyle(); + + assert.equal(polygon.fill?.material.color.getHexString(), defaults.fillColor.getHexString()); + assert.equal(polygon.fill?.material.opacity, defaults.fillOpacity); + assert.isTrue(polygon.fill?.material.transparent); + assert.equal( + polygon.stroke?.material.color.getHexString(), + defaults.strokeColor.getHexString(), + ); + assert.equal(polygon.stroke?.material.opacity, defaults.strokeOpacity); + assert.equal(polygon.stroke?.material.width, defaults.strokeWidth); + }); + }); + + describe('attributes', () => { + it('should have a points attribute', () => { + const points = getTestPoints(); + const polygon = new Geometry.Polygon(points); + assert.containsAllKeys(polygon.getAttributes(), ['points']); + assert.deepEqual(polygon.getAttributes().points, points); + }); + }); + + describe('shape', () => { + it('should set points correctly', () => { + const points = getTestPoints(); + const polygon = new Geometry.Polygon(points); + + assert.deepEqual(polygon.points, points); + }); + + it.skip('should correctly reshape', () => { + const polygon = new Geometry.Polygon(getTestPoints()); + + const newPoints = [new THREE.Vector3(-2, -2, 0), new THREE.Vector3(2, 2, 0)]; + polygon.reshape(newPoints, { + strokeColor: new THREE.Color('#C458A5'), + }); + + assert.deepEqual(polygon.points, newPoints); + assert.equal(polygon.stroke?.material.color.getHexString(), 'c458a5'); + }); + }); + + it('should inherit from shape', () => { + const polygon = new Geometry.Polygon(getTestPoints()); + assert.instanceOf(polygon.fill, THREE.Mesh); + assert.instanceOf(polygon.stroke, MeshLine); + assert.isArray(polygon.curveEndIndices); + }); +}); diff --git a/test/polyline.test.ts b/test/polyline.test.ts new file mode 100644 index 0000000..225e3cb --- /dev/null +++ b/test/polyline.test.ts @@ -0,0 +1,66 @@ +import { assert } from 'chai'; +import { MeshLine } from '../src/MeshLine'; +import { Geometry, THREE } from '../src/index'; + +describe('Polyline', () => { + function getTestPoints() { + return [new THREE.Vector3(-1, -1, 0), new THREE.Vector3(1, 1, 0)]; + } + + describe('default config', () => { + it('should set curveEndIndices', () => { + const polyline = new Geometry.Polyline(getTestPoints()); + assert.deepEqual(polyline.curveEndIndices, [[0, 1]]); + }); + + it('should have default style set', () => { + const polyline = new Geometry.Polyline(getTestPoints()); + const defaults = Geometry.Arrow.defaultStyle(); + + assert.isUndefined(polyline.fill); + assert.equal( + polyline.stroke?.material.color.getHexString(), + defaults.strokeColor.getHexString(), + ); + assert.equal(polyline.stroke?.material.opacity, defaults.strokeOpacity); + assert.equal(polyline.stroke?.material.width, defaults.strokeWidth); + }); + }); + + describe('attributes', () => { + it('should have points attribute', () => { + const points = getTestPoints(); + const polyline = new Geometry.Polyline(points); + assert.containsAllKeys(polyline.getAttributes(), ['points']); + assert.deepEqual(polyline.getAttributes().points, points); + }); + }); + + describe('shape', () => { + it('should set points correctly', () => { + const points = getTestPoints(); + const polyline = new Geometry.Polyline(points); + + assert.deepEqual(polyline.points, points); + }); + + it.skip('should correctly reshape', () => { + const polyline = new Geometry.Polyline(getTestPoints()); + + const newPoints = [new THREE.Vector3(-2, -2, 0), new THREE.Vector3(2, 2, 0)]; + polyline.reshape(newPoints, { + strokeColor: new THREE.Color('#C458A5'), + }); + + assert.deepEqual(polyline.points, newPoints); + assert.equal(polyline.stroke?.material.color.getHexString(), 'c458a5'); + }); + }); + + it('should inherit from shape', () => { + const polyline = new Geometry.Polyline(getTestPoints()); + assert.isUndefined(polyline.fill); + assert.instanceOf(polyline.stroke, MeshLine); + assert.isArray(polyline.curveEndIndices); + }); +}); diff --git a/test/rectange.test.ts b/test/rectange.test.ts new file mode 100644 index 0000000..fe44779 --- /dev/null +++ b/test/rectange.test.ts @@ -0,0 +1,103 @@ +import { assert } from 'chai'; +import { MeshLine } from '../src/MeshLine'; +import { Geometry, THREE } from '../src/index'; + +describe('Rectangle', () => { + describe('default config', () => { + it('should set default width and height', () => { + const rectangle = new Geometry.Rectangle(); + + assert.deepEqual(rectangle.points, [ + new THREE.Vector3(-2, 1, 0), + new THREE.Vector3(2, 1, 0), + new THREE.Vector3(2, -1, 0), + new THREE.Vector3(-2, -1, 0), + new THREE.Vector3(-2, 1, 0), + ]); + + assert.equal(rectangle.width, 4); + assert.equal(rectangle.height, 2); + }); + + it('should have default style set', () => { + const rectangle = new Geometry.Rectangle(); + const defaults = Geometry.Arrow.defaultStyle(); + + assert.equal( + rectangle.fill?.material.color.getHexString(), + defaults.fillColor.getHexString(), + ); + assert.equal(rectangle.fill?.material.opacity, defaults.fillOpacity); + assert.isTrue(rectangle.fill?.material.transparent); + assert.equal( + rectangle.stroke?.material.color.getHexString(), + defaults.strokeColor.getHexString(), + ); + assert.equal(rectangle.stroke?.material.opacity, defaults.strokeOpacity); + assert.equal(rectangle.stroke?.material.width, defaults.strokeWidth); + }); + }); + + describe('attributes', () => { + it('should have a width and height attribute', () => { + const rectangle = new Geometry.Rectangle(10, 8); + assert.containsAllKeys(rectangle.getAttributes(), ['width', 'height']); + assert.deepEqual(rectangle.getAttributes(), { width: 10, height: 8 }); + }); + + it('should correctly return clone attributes', () => { + const rectangle = new Geometry.Rectangle(10, 8); + assert.deepEqual(rectangle.getCloneAttributes(), [10, 8]); + }); + + it('should correctly return attribute data', () => { + const rectangle = new Geometry.Rectangle(10, 8); + assert.deepEqual(rectangle.attributeData, [ + { + attribute: 'width', + type: 'number', + default: 4, + }, + { + attribute: 'height', + type: 'number', + default: 2, + }, + ]); + }); + }); + + describe('shape', () => { + it('should correctly use width and height', () => { + const rectangle = new Geometry.Rectangle(10, 8); + + assert.deepEqual(rectangle.points, [ + new THREE.Vector3(-5, 4, 0), + new THREE.Vector3(5, 4, 0), + new THREE.Vector3(5, -4, 0), + new THREE.Vector3(-5, -4, 0), + new THREE.Vector3(-5, 4, 0), + ]); + + assert.equal(rectangle.width, 10); + assert.equal(rectangle.height, 8); + }); + }); + + it('should correctly return curve end indices', () => { + const rectangle = new Geometry.Rectangle(10, 8); + assert.deepEqual(rectangle.getCurveEndIndices(), [ + [0, 1], + [1, 2], + [2, 3], + [3, 4], + ]); + }); + + it('should inherit from shape', () => { + const rectangle = new Geometry.Rectangle(); + assert.instanceOf(rectangle.fill, THREE.Mesh); + assert.instanceOf(rectangle.stroke, MeshLine); + assert.isArray(rectangle.curveEndIndices); + }); +}); diff --git a/test/test.ts b/test/shape.test.ts similarity index 77% rename from test/test.ts rename to test/shape.test.ts index d4a0e9d..2066d9c 100644 --- a/test/test.ts +++ b/test/shape.test.ts @@ -2,36 +2,6 @@ import { assert } from 'chai'; import { MeshLine } from '../src/MeshLine'; import { Geometry, THREE } from '../src/index'; -describe('Line', () => { - const line = new Geometry.Line(new THREE.Vector3(0, 0, 0), new THREE.Vector3(1, 1, 1)); - - describe('attributes', () => { - it('should have a start and end attribute', () => { - const attributes = line.getAttributes(); - assert.containsAllKeys(attributes, ['start', 'end']); - }); - - it('should have the correct start attribute', () => { - const start = line.start; - const startDifference = new THREE.Vector3(0, 0, 0).sub(start).length(); - assert.isAtMost(startDifference, 0.001); - }); - - it('should have the corrent end attribute', () => { - const end = line.end; - const endDifference = new THREE.Vector3(1, 1, 1).sub(end).length(); - assert.isAtMost(endDifference, 0.001); - }); - }); - - it('should inherit from shape', () => { - assert.instanceOf(line.fill, THREE.Mesh); - assert.instanceOf(line.stroke, MeshLine); - assert.isArray(line.curveEndIndices); - assert.isBoolean(line.arrow); - }); -}); - describe('Shape', () => { class TestShape extends Geometry.Shape { getAttributes() { diff --git a/test/square.test.ts b/test/square.test.ts new file mode 100644 index 0000000..5dc4c0c --- /dev/null +++ b/test/square.test.ts @@ -0,0 +1,121 @@ +import { assert } from 'chai'; +import { MeshLine } from '../src/MeshLine'; +import { Geometry, THREE } from '../src/index'; + +describe('Square', () => { + describe('default config', () => { + it('should set default side length', () => { + const square = new Geometry.Square(); + + assert.deepEqual(square.points, [ + new THREE.Vector3(-1, 1, 0), + new THREE.Vector3(1, 1, 0), + new THREE.Vector3(1, -1, 0), + new THREE.Vector3(-1, -1, 0), + new THREE.Vector3(-1, 1, 0), + ]); + + assert.equal(square.width, 2); + assert.equal(square.height, 2); + assert.equal(square.sideLength, 2); + }); + + it('should have default style set', () => { + const square = new Geometry.Square(); + const defaults = Geometry.Arrow.defaultStyle(); + + assert.equal(square.fill?.material.color.getHexString(), defaults.fillColor.getHexString()); + assert.equal(square.fill?.material.opacity, defaults.fillOpacity); + assert.isTrue(square.fill?.material.transparent); + assert.equal( + square.stroke?.material.color.getHexString(), + defaults.strokeColor.getHexString(), + ); + assert.equal(square.stroke?.material.opacity, defaults.strokeOpacity); + assert.equal(square.stroke?.material.width, defaults.strokeWidth); + }); + }); + + describe('attributes', () => { + it('should have a width and height attribute', () => { + const square = new Geometry.Square(10); + assert.containsAllKeys(square.getAttributes(), ['width', 'height']); + assert.deepEqual(square.getAttributes(), { width: 10, height: 10 }); + }); + + it('should correctly return clone attributes', () => { + const square = new Geometry.Square(10); + assert.deepEqual(square.getCloneAttributes(), [10]); + }); + + it('should correctly return attribute data', () => { + const square = new Geometry.Square(10); + assert.deepEqual(square.attributeData, [ + { + attribute: 'sideLength', + type: 'number', + default: 2, + }, + ]); + }); + }); + + describe('shape', () => { + it('should correctly use width and height', () => { + const square = new Geometry.Square(10); + + assert.deepEqual(square.points, [ + new THREE.Vector3(-5, 5, 0), + new THREE.Vector3(5, 5, 0), + new THREE.Vector3(5, -5, 0), + new THREE.Vector3(-5, -5, 0), + new THREE.Vector3(-5, 5, 0), + ]); + + assert.equal(square.width, 10); + assert.equal(square.height, 10); + assert.equal(square.sideLength, 10); + }); + + it('should correctly reshape', () => { + const square = new Geometry.Square(6); + + assert.deepEqual(square.points, [ + new THREE.Vector3(-3, 3, 0), + new THREE.Vector3(3, 3, 0), + new THREE.Vector3(3, -3, 0), + new THREE.Vector3(-3, -3, 0), + new THREE.Vector3(-3, 3, 0), + ]); + + assert.equal(square.width, 6); + assert.equal(square.height, 6); + assert.equal(square.sideLength, 6); + }); + }); + + it('should correctly return curve end indices', () => { + const square = new Geometry.Square(10); + assert.deepEqual(square.getCurveEndIndices(), [ + [0, 1], + [1, 2], + [2, 3], + [3, 4], + ]); + }); + + describe('inheritance', () => { + it('from shape', () => { + const square = new Geometry.Square(); + assert.instanceOf(square.fill, THREE.Mesh); + assert.instanceOf(square.stroke, MeshLine); + assert.isArray(square.curveEndIndices); + }); + + it('from rectange', () => { + const square = new Geometry.Square(); + assert.equal(square.width, 2); + assert.equal(square.height, 2); + }); + }); +});