diff --git a/src/Process/3dTilesProcessing.js b/src/Process/3dTilesProcessing.js index 44b2352db0..3bce32d607 100644 --- a/src/Process/3dTilesProcessing.js +++ b/src/Process/3dTilesProcessing.js @@ -272,7 +272,6 @@ export function process3dTilesNode(cullingTest = $3dTilesCulling, subdivisionTes return undefined; } - // do proper culling const isVisible = cullingTest ? (!cullingTest(layer, context.camera, node, node.matrixWorld)) : true; node.visible = isVisible; diff --git a/test/data/unitTest/dem/dem3_3_8.bil b/test/data/unitTest/dem/dem3_3_8.bil new file mode 100644 index 0000000000..eb48b5606e Binary files /dev/null and b/test/data/unitTest/dem/dem3_3_8.bil differ diff --git a/test/unit/3dtileslayerprocess.js b/test/unit/3dtileslayerprocess.js index 339c8c3ac0..56f61fdff5 100644 --- a/test/unit/3dtileslayerprocess.js +++ b/test/unit/3dtileslayerprocess.js @@ -1,36 +1,68 @@ import assert from 'assert'; +import fs from 'fs'; import C3DTilesLayer from 'Layer/C3DTilesLayer'; import C3DTilesSource from 'Source/C3DTilesSource'; import View from 'Core/View'; import GlobeView from 'Core/Prefab/GlobeView'; import { HttpsProxyAgent } from 'https-proxy-agent'; import Coordinates from 'Core/Geographic/Coordinates'; +import sinon from 'sinon'; +import Fetcher from 'Provider/Fetcher'; import Renderer from './bootstrap'; +import tilesetDiscretLOD from '../data/unitTest/3dTiles/tilesetDiscretLOD.json'; + +const urlDragonLow = 'https://raw.githubusercontent.com/CesiumGS/3d-tiles-samples/master/1.0/TilesetWithDiscreteLOD/dragon_low.b3dm'; +const urlDragonMedium = 'https://raw.githubusercontent.com/CesiumGS/3d-tiles-samples/master/1.0/TilesetWithDiscreteLOD/dragon_medium.b3dm'; + +const dragonLow = fs.readFileSync('./test/data/unitTest/3dTiles/dragon_low.b3dm'); +const dragonMedium = fs.readFileSync('./test/data/unitTest/3dTiles/dragon_medium.b3dm'); + +const resources = new Map([ + [urlDragonLow, dragonLow.buffer], + [urlDragonMedium, dragonMedium.buffer], +]); + describe('3Dtiles layer', function () { - const url3dTilesDiscretLOD = 'test/data/unitTest/3dTiles/tilesetDiscretLOD.json'; + let stubFetcherArrayBuf; + let context; + let viewer; + let threedTilesLayer; + + before(function () { + const stubFetcherJson = sinon.stub(Fetcher, 'json') + .callsFake(() => Promise.resolve(JSON.parse(tilesetDiscretLOD))); + + stubFetcherArrayBuf = sinon.stub(Fetcher, 'arrayBuffer') + .callsFake(url => Promise.resolve(resources.get(url))); - const renderer = new Renderer(); - const p = { coord: new Coordinates('EPSG:4326', -75.6114, 40.03428, 0), heading: 180, range: 4000, tilt: 22 }; - const viewer = new GlobeView(renderer.domElement, p, { renderer, noControls: true }); + const renderer = new Renderer(); + const p = { coord: new Coordinates('EPSG:4326', -75.6114, 40.03428, 0), heading: 180, range: 4000, tilt: 22 }; + viewer = new GlobeView(renderer.domElement, p, { renderer, noControls: true }); - const source = new C3DTilesSource({ - // url: 'https://raw.githubusercontent.com/CesiumGS/3d-tiles-samples/master/1.0/TilesetWithDiscreteLOD/tileset.json', - url: url3dTilesDiscretLOD, - networkOptions: process.env.HTTPS_PROXY ? { agent: new HttpsProxyAgent(process.env.HTTPS_PROXY) } : {}, + const source = new C3DTilesSource({ + url: 'https://raw.githubusercontent.com/CesiumGS/3d-tiles-samples/master/1.0/TilesetWithDiscreteLOD/tileset.json', + networkOptions: process.env.HTTPS_PROXY ? { agent: new HttpsProxyAgent(process.env.HTTPS_PROXY) } : {}, + }); + threedTilesLayer = new C3DTilesLayer('3d-tiles-discrete-lod', { + source, + sseThreshold: 0.05, + }, viewer); + + context = { + camera: viewer.camera, + engine: viewer.mainLoop.gfxEngine, + scheduler: viewer.mainLoop.scheduler, + geometryLayer: threedTilesLayer, + view: viewer, + }; + + stubFetcherJson.restore(); + }); + + after(() => { + stubFetcherArrayBuf.restore(); }); - const threedTilesLayer = new C3DTilesLayer('3d-tiles-discrete-lod', { - source, - sseThreshold: 0.05, - }, viewer); - - const context = { - camera: viewer.camera, - engine: viewer.mainLoop.gfxEngine, - scheduler: viewer.mainLoop.scheduler, - geometryLayer: threedTilesLayer, - view: viewer, - }; it('Add 3dtiles layer', function (done) { View.prototype.addLayer.call(viewer, threedTilesLayer) @@ -39,10 +71,12 @@ describe('3Dtiles layer', function () { done(); }).catch(done); }); + it('preUpdate 3dtiles layer', function () { const elements = threedTilesLayer.preUpdate(context, new Set([threedTilesLayer])); assert.equal(elements.length, 1); }); + it('update 3dtiles layer', function () { const node = threedTilesLayer.root; viewer.camera3D.updateMatrixWorld(); diff --git a/test/unit/3dtileslayerprocessbatchtable.js b/test/unit/3dtileslayerprocessbatchtable.js index a1f981a95f..e29a0fec2e 100644 --- a/test/unit/3dtileslayerprocessbatchtable.js +++ b/test/unit/3dtileslayerprocessbatchtable.js @@ -1,4 +1,5 @@ import assert from 'assert'; +import fs from 'fs'; import C3DTilesLayer from 'Layer/C3DTilesLayer'; import C3DTBatchTableHierarchyExtension from 'Core/3DTiles/C3DTBatchTableHierarchyExtension'; import C3DTilesSource from 'Source/C3DTilesSource'; @@ -8,37 +9,58 @@ import View from 'Core/View'; import GlobeView from 'Core/Prefab/GlobeView'; import { HttpsProxyAgent } from 'https-proxy-agent'; import Coordinates from 'Core/Geographic/Coordinates'; +import Fetcher from 'Provider/Fetcher'; +import sinon from 'sinon'; import Renderer from './bootstrap'; +import tilesetBatchTable from '../data/unitTest/3dTiles/tilesetBatchTable.json'; + +const tileBatchTable = fs.readFileSync('./test/data/unitTest/3dTiles/tile.b3dm'); + describe('3Dtiles batch table', function () { - const url3dTilesBatchTable = 'test/data/unitTest/3dTiles/tilesetBatchTable.json'; - - const renderer = new Renderer(); - - const p = { - coord: new Coordinates('EPSG:4326', -75.61349, 40.044259), - range: 200, - tilt: 10, - heading: -145, - }; - const viewer = new GlobeView(renderer.domElement, p, { renderer, noControls: true }); - - // Map the extension name to its manager - const extensions = new C3DTExtensions(); - extensions.registerExtension('3DTILES_batch_table_hierarchy', - { [C3DTilesTypes.batchtable]: + let stubFetcherArrayBuf; + let stubFetcherJson; + let viewer; + let threedTilesLayerBTHierarchy; + + before(function () { + stubFetcherJson = sinon.stub(Fetcher, 'json') + .callsFake(() => Promise.resolve(JSON.parse(tilesetBatchTable))); + + stubFetcherArrayBuf = sinon.stub(Fetcher, 'arrayBuffer') + .callsFake(() => Promise.resolve(tileBatchTable.buffer)); + + const renderer = new Renderer(); + + const p = { + coord: new Coordinates('EPSG:4326', -75.61349, 40.044259), + range: 200, + tilt: 10, + heading: -145, + }; + viewer = new GlobeView(renderer.domElement, p, { renderer, noControls: true }); + + // Map the extension name to its manager + const extensions = new C3DTExtensions(); + extensions.registerExtension('3DTILES_batch_table_hierarchy', + { [C3DTilesTypes.batchtable]: C3DTBatchTableHierarchyExtension }); - const source = new C3DTilesSource({ - // url: 'https://raw.githubusercontent.com/AnalyticalGraphicsInc/cesium/master/Apps/SampleData/Cesium3DTiles/Hierarchy/BatchTableHierarchy/tileset.json', - url: url3dTilesBatchTable, - networkOptions: process.env.HTTPS_PROXY ? { agent: new HttpsProxyAgent(process.env.HTTPS_PROXY) } : {}, + const source = new C3DTilesSource({ + url: 'https://raw.githubusercontent.com/AnalyticalGraphicsInc/cesium/master/Apps/SampleData/Cesium3DTiles/Hierarchy/BatchTableHierarchy/tileset.json', + networkOptions: process.env.HTTPS_PROXY ? { agent: new HttpsProxyAgent(process.env.HTTPS_PROXY) } : {}, + }); + threedTilesLayerBTHierarchy = new C3DTilesLayer('3d-tiles-bt-hierarchy', { + name: 'BTHierarchy', + source, + registeredExtensions: extensions, + }, viewer); + }); + + after(() => { + stubFetcherJson.restore(); + stubFetcherArrayBuf.restore(); }); - const threedTilesLayerBTHierarchy = new C3DTilesLayer('3d-tiles-bt-hierarchy', { - name: 'BTHierarchy', - source, - registeredExtensions: extensions, - }, viewer); it('Add 3dtiles layer with batch table', function (done) { View.prototype.addLayer.call(viewer, threedTilesLayerBTHierarchy) diff --git a/test/unit/3dtileslayerstyle.js b/test/unit/3dtileslayerstyle.js index fb4fda7493..395377c4a2 100644 --- a/test/unit/3dtileslayerstyle.js +++ b/test/unit/3dtileslayerstyle.js @@ -7,55 +7,68 @@ import PlanarView from 'Core/Prefab/PlanarView'; import C3DTBatchTable from 'Core/3DTiles/C3DTBatchTable'; import C3DTilesSource from 'Source/C3DTilesSource'; import C3DTilesLayer from 'Layer/C3DTilesLayer'; +import sinon from 'sinon'; +import Fetcher from 'Provider/Fetcher'; import Renderer from './bootstrap'; -describe('3DTilesLayer Style', () => { - // Define crs - proj4.defs('EPSG:3946', '+proj=lcc +lat_1=45.25 +lat_2=46.75 +lat_0=46 +lon_0=3 +x_0=1700000 +y_0=5200000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs'); +import tileset from '../data/unitTest/3dTiles/tileset.json'; - // Define geographic extent: CRS, min/max X, min/max Y - const extent = new Extent('EPSG:3946', - 1840816.94334, 1843692.32501, - 5175036.4587, 5177412.82698); +// Create a 'fake' tile content for this test purpose +function createTileContent(tileId) { + const geometry = new THREE.SphereGeometry(15, 32, 16); + const material = new THREE.MeshBasicMaterial({ color: 0xffff00 }); - const renderer = new Renderer(); + // Add _BATCHID geometry attributes + const array = []; + let currentBatchId = Math.round(Math.random() * 50); + for (let index = 0; index < geometry.attributes.position.count; index++) { + array.push(currentBatchId); - const view = new PlanarView(renderer.domElement, extent, { renderer, noControls: true }); + // Change randomly batch id + if (Math.random() > 0.5) { + currentBatchId = Math.round(Math.random() * 50); + } + } + geometry.setAttribute('_BATCHID', new THREE.BufferAttribute(Int32Array.from(array), 1)); - // Create a 'fake' tile content for this test purpose - const createTileContent = (tileId) => { - const geometry = new THREE.SphereGeometry(15, 32, 16); - const material = new THREE.MeshBasicMaterial({ color: 0xffff00 }); + const result = new THREE.Mesh(geometry, material); + result.batchTable = new C3DTBatchTable(); + result.tileId = tileId; - // Add _BATCHID geometry attributes - const array = []; - let currentBatchId = Math.round(Math.random() * 50); - for (let index = 0; index < geometry.attributes.position.count; index++) { - array.push(currentBatchId); + return result; +} - // Change randomly batch id - if (Math.random() > 0.5) { - currentBatchId = Math.round(Math.random() * 50); - } - } - geometry.setAttribute('_BATCHID', new THREE.BufferAttribute(Int32Array.from(array), 1)); +describe('3DTilesLayer Style', () => { + let view; + let $3dTilesLayer; + let source; + let stubFetcherJson; - const result = new THREE.Mesh(geometry, material); + before(function () { + stubFetcherJson = sinon.stub(Fetcher, 'json') + .callsFake(() => Promise.resolve(JSON.parse(tileset))); - result.batchTable = new C3DTBatchTable(); - result.tileId = tileId; + // Define crs + proj4.defs('EPSG:3946', '+proj=lcc +lat_1=45.25 +lat_2=46.75 +lat_0=46 +lon_0=3 +x_0=1700000 +y_0=5200000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs'); - return result; - }; + // Define geographic extent: CRS, min/max X, min/max Y + const extent = new Extent('EPSG:3946', + 1840816.94334, 1843692.32501, + 5175036.4587, 5177412.82698); - let $3dTilesLayer; - let source; + const renderer = new Renderer(); - const url = 'test/data/unitTest/3dTiles/tileset.json'; + view = new PlanarView(renderer.domElement, extent, { renderer, noControls: true }); + }); + + after(function () { + stubFetcherJson.restore(); + }); it('should instance C3DTilesLayer', function (done) { source = new C3DTilesSource({ - url, + url: 'https://raw.githubusercontent.com/iTowns/iTowns2-sample-data/master/' + + '3DTiles/lyon1_with_surface_type_2018/tileset.json', networkOptions: process.env.HTTPS_PROXY ? { agent: new HttpsProxyAgent(process.env.HTTPS_PROXY) } : {}, }); diff --git a/test/unit/demutils.js b/test/unit/demutils.js index d4c9153e48..15d82c162d 100644 --- a/test/unit/demutils.js +++ b/test/unit/demutils.js @@ -1,6 +1,8 @@ import * as THREE from 'three'; +import fs from 'fs'; import ElevationLayer from 'Layer/ElevationLayer'; import WMTSSource from 'Source/WMTSSource'; +import { supportedFetchers } from 'Source/Source'; import { HttpsProxyAgent } from 'https-proxy-agent'; import assert from 'assert'; import GlobeView from 'Core/Prefab/GlobeView'; @@ -12,39 +14,65 @@ import OBB from 'Renderer/OBB'; import LayerUpdateState from 'Layer/LayerUpdateState'; import DEMUtils from 'Utils/DEMUtils'; import { RasterElevationTile } from 'Renderer/RasterTile'; +import sinon from 'sinon'; import Renderer from './bootstrap'; +const dem338 = fs.readFileSync('./test/data/unitTest/dem/dem3_3_8.bil'); + describe('DemUtils', function () { const renderer = new Renderer(); const placement = { coord: new Coordinates('EPSG:4326', 1.5, 43), zoom: 10 }; const viewer = new GlobeView(renderer.domElement, placement, { renderer }); - const source = new WMTSSource({ - format: 'image/x-bil;bits=32', - crs: 'EPSG:4326', - url: 'https://wxs.ign.fr/altimetrie/geoportail/wmts', - name: 'ELEVATION.ELEVATIONGRIDCOVERAGE.SRTM3', - tileMatrixSet: 'WGS84G', - networkOptions: process.env.HTTPS_PROXY ? { agent: new HttpsProxyAgent(process.env.HTTPS_PROXY) } : { - // referrerPolicy: 'origin-when-cross-origin', - crossOrigin: 'anonymous', - // referrer: 'http://localhost:8080/examples/view_3d_map.html', - }, - }); - source.url = 'https://github.com/iTowns/iTowns2-sample-data/blob/master/dem3_3_8.bil?raw=true'; - const elevationlayer = new ElevationLayer('worldelevation', { source }); + let elevationlayer; + let context; + let stubSuppFetcher; + + before(function () { + stubSuppFetcher = sinon.stub(supportedFetchers, 'get') + .callsFake((format) => { + if (format === 'image/x-bil;bits=32') { + const floatArray = new Float32Array(dem338.buffer); + const texture = new THREE.DataTexture(floatArray, 256, 256, THREE.RedFormat, THREE.FloatType); + texture.internalFormat = 'R32F'; + texture.needsUpdate = true; + return () => Promise.resolve(texture); + } else { + throw new Error(`format (${format}) non supported`); + } + }); + + const source = new WMTSSource({ + format: 'image/x-bil;bits=32', + crs: 'EPSG:4326', + url: 'https://wxs.ign.fr/altimetrie/geoportail/wmts', + name: 'ELEVATION.ELEVATIONGRIDCOVERAGE.SRTM3', + tileMatrixSet: 'WGS84G', + networkOptions: process.env.HTTPS_PROXY ? { agent: new HttpsProxyAgent(process.env.HTTPS_PROXY) } : { + // referrerPolicy: 'origin-when-cross-origin', + crossOrigin: 'anonymous', + // referrer: 'http://localhost:8080/examples/view_3d_map.html', + }, + }); + source.url = 'https://github.com/iTowns/iTowns2-sample-data/blob/master/dem3_3_8.bil?raw=true'; + elevationlayer = new ElevationLayer('worldelevation', { source }); - const context = { - camera: viewer.camera, - engine: viewer.mainLoop.gfxEngine, - scheduler: { - execute: (command) => { - const provider = viewer.mainLoop.scheduler.getProtocolProvider(command.layer.protocol); - return provider.executeCommand(command); + context = { + camera: viewer.camera, + engine: viewer.mainLoop.gfxEngine, + scheduler: { + execute: (command) => { + const provider = viewer.mainLoop.scheduler.getProtocolProvider(command.layer.protocol); + return provider.executeCommand(command); + }, }, - }, - view: viewer, - }; + view: viewer, + }; + }); + + after(() => { + stubSuppFetcher.restore(); + }); it('add elevation layer', (done) => { viewer.addLayer(elevationlayer) diff --git a/test/unit/entwine.js b/test/unit/entwine.js index d45d81cbcf..14ae2318c0 100644 --- a/test/unit/entwine.js +++ b/test/unit/entwine.js @@ -6,13 +6,42 @@ import Coordinates from 'Core/Geographic/Coordinates'; import EntwinePointTileSource from 'Source/EntwinePointTileSource'; import EntwinePointTileLayer from 'Layer/EntwinePointTileLayer'; import EntwinePointTileNode from 'Core/EntwinePointTileNode'; +import sinon from 'sinon'; +import Fetcher from 'Provider/Fetcher'; import Renderer from './bootstrap'; +import ept from '../data/unitTest/entwine/ept.json'; +import eptHierarchy from '../data/unitTest/entwine/ept-hierarchy/0-0-0-0.json'; + +const urlEpt = 'https://raw.githubusercontent.com/iTowns/iTowns2-sample-data/master/pointclouds/entwine/ept.json'; +const urlEptHierarchy = 'https://raw.githubusercontent.com/iTowns/iTowns2-sample-data/master/pointclouds/entwine/ept-hierarchy/0-0-0-0.json'; + +const resources = { + [urlEpt]: ept, + [urlEptHierarchy]: eptHierarchy, +}; + describe('Entwine Point Tile', function () { - const source = new EntwinePointTileSource({ - // url: 'https://raw.githubusercontent.com/iTowns/iTowns2-sample-data/master/pointclouds/entwine', - url: 'test/data/unitTest/entwine', - networkOptions: process.env.HTTPS_PROXY ? { agent: new HttpsProxyAgent(process.env.HTTPS_PROXY) } : {}, + let source; + let stubFetcherJson; + let stubFetcherArrayBuf; + + before(function () { + stubFetcherJson = sinon.stub(Fetcher, 'json') + .callsFake(url => Promise.resolve(JSON.parse(resources[url]))); + stubFetcherArrayBuf = sinon.stub(Fetcher, 'arrayBuffer') + .callsFake(() => Promise.resolve({})); + // currently no test on data fetched... + + source = new EntwinePointTileSource({ + url: 'https://raw.githubusercontent.com/iTowns/iTowns2-sample-data/master/pointclouds/entwine', + networkOptions: process.env.HTTPS_PROXY ? { agent: new HttpsProxyAgent(process.env.HTTPS_PROXY) } : {}, + }); + }); + + after(function () { + stubFetcherJson.restore(); + stubFetcherArrayBuf.restore(); }); it('loads the EPT structure', (done) => { @@ -80,25 +109,28 @@ describe('Entwine Point Tile', function () { }); describe('Node', function () { - const layer = { source: { url: 'http://server.geo', extension: 'laz' } }; - const root = new EntwinePointTileNode(0, 0, 0, 0, layer, 4000); - root.bbox.setFromArray([1000, 1000, 1000, 0, 0, 0]); - - root.add(new EntwinePointTileNode(1, 0, 0, 0, layer, 3000)); - root.add(new EntwinePointTileNode(1, 0, 0, 1, layer, 3000)); - root.add(new EntwinePointTileNode(1, 0, 1, 1, layer, 3000)); - - root.children[0].add(new EntwinePointTileNode(2, 0, 0, 0, layer, 2000)); - root.children[0].add(new EntwinePointTileNode(2, 0, 1, 0, layer, 2000)); - root.children[1].add(new EntwinePointTileNode(2, 0, 1, 3, layer, 2000)); - root.children[2].add(new EntwinePointTileNode(2, 0, 2, 2, layer, 2000)); - root.children[2].add(new EntwinePointTileNode(2, 0, 3, 3, layer, 2000)); - - root.children[0].children[0].add(new EntwinePointTileNode(3, 0, 0, 0, layer, 1000)); - root.children[0].children[0].add(new EntwinePointTileNode(3, 0, 1, 0, layer, 1000)); - root.children[1].children[0].add(new EntwinePointTileNode(3, 0, 2, 7, layer, 1000)); - root.children[2].children[0].add(new EntwinePointTileNode(3, 0, 5, 4, layer, 1000)); - root.children[2].children[1].add(new EntwinePointTileNode(3, 1, 6, 7, layer)); + let root; + before(function () { + const layer = { source: { url: 'http://server.geo', extension: 'laz' } }; + root = new EntwinePointTileNode(0, 0, 0, 0, layer, 4000); + root.bbox.setFromArray([1000, 1000, 1000, 0, 0, 0]); + + root.add(new EntwinePointTileNode(1, 0, 0, 0, layer, 3000)); + root.add(new EntwinePointTileNode(1, 0, 0, 1, layer, 3000)); + root.add(new EntwinePointTileNode(1, 0, 1, 1, layer, 3000)); + + root.children[0].add(new EntwinePointTileNode(2, 0, 0, 0, layer, 2000)); + root.children[0].add(new EntwinePointTileNode(2, 0, 1, 0, layer, 2000)); + root.children[1].add(new EntwinePointTileNode(2, 0, 1, 3, layer, 2000)); + root.children[2].add(new EntwinePointTileNode(2, 0, 2, 2, layer, 2000)); + root.children[2].add(new EntwinePointTileNode(2, 0, 3, 3, layer, 2000)); + + root.children[0].children[0].add(new EntwinePointTileNode(3, 0, 0, 0, layer, 1000)); + root.children[0].children[0].add(new EntwinePointTileNode(3, 0, 1, 0, layer, 1000)); + root.children[1].children[0].add(new EntwinePointTileNode(3, 0, 2, 7, layer, 1000)); + root.children[2].children[0].add(new EntwinePointTileNode(3, 0, 5, 4, layer, 1000)); + root.children[2].children[1].add(new EntwinePointTileNode(3, 1, 6, 7, layer)); + }); it('finds the common ancestor of two nodes', () => { let ancestor = root.children[2].children[1].children[0].findCommonAncestor(root.children[2].children[0].children[0]); diff --git a/test/unit/featuregeometrylayer.js b/test/unit/featuregeometrylayer.js index 539f514c50..f343603064 100644 --- a/test/unit/featuregeometrylayer.js +++ b/test/unit/featuregeometrylayer.js @@ -1,68 +1,90 @@ import * as THREE from 'three'; import assert from 'assert'; +import fs from 'fs'; import GlobeView from 'Core/Prefab/GlobeView'; import FeatureGeometryLayer from 'Layer/FeatureGeometryLayer'; import FileSource from 'Source/FileSource'; +import { supportedFetchers } from 'Source/Source'; import { HttpsProxyAgent } from 'https-proxy-agent'; import Extent from 'Core/Geographic/Extent'; import Coordinates from 'Core/Geographic/Coordinates'; import OBB from 'Renderer/OBB'; import TileMesh from 'Core/TileMesh'; -import Style from 'Core/Style'; +import sinon from 'sinon'; import Renderer from './bootstrap'; -describe('Layer with Feature process', function () { - const urlFilesource = 'test/data/unitTest/filesource/departement-09-ariege.geojson'; +const fileSource = fs.readFileSync('./test/data/unitTest/filesource/departement-09-ariege.geojson'); +describe('Layer with Feature process', function () { const renderer = new Renderer(); const placement = { coord: new Coordinates('EPSG:4326', 1.5, 43), range: 300000 }; const viewer = new GlobeView(renderer.domElement, placement, { renderer }); - const source = new FileSource({ - // url: 'https://raw.githubusercontent.com/gregoiredavid/france-geojson/master/departements/09-ariege/departement-09-ariege.geojson', - url: urlFilesource, - crs: 'EPSG:4326', - format: 'application/json', - networkOptions: process.env.HTTPS_PROXY ? { agent: new HttpsProxyAgent(process.env.HTTPS_PROXY) } : {}, - }); + let ariege; + let ariegeNoProj4; + let tile; + let context; + let stubSuppFetcher; + + before(function () { + stubSuppFetcher = sinon.stub(supportedFetchers, 'get') + .callsFake((format) => { + if (format === 'application/json') { + return () => Promise.resolve(JSON.parse(fileSource)); + } else { + throw new Error(`format (${format}) non supported`); + } + }); - const ariege = new FeatureGeometryLayer('ariege', { - source, - accurate: true, - style: new Style({ - fill: { - extrusion_height: 5000, - color: new THREE.Color(0xffcc00), + const source = new FileSource({ + url: 'https://raw.githubusercontent.com/gregoiredavid/france-geojson/master/departements/09-ariege/departement-09-ariege.geojson', + crs: 'EPSG:4326', + format: 'application/json', + networkOptions: process.env.HTTPS_PROXY ? { agent: new HttpsProxyAgent(process.env.HTTPS_PROXY) } : {}, + }); + + ariege = new FeatureGeometryLayer('ariege', { + source, + accurate: true, + style: { + fill: { + extrusion_height: 5000, + color: new THREE.Color(0xffcc00), + }, }, - }), - zoom: { min: 7 }, - }); + zoom: { min: 7 }, + }); - const ariegeNoProj4 = new FeatureGeometryLayer('ariegeNoProj4', { - source, - accurate: false, - style: new Style({ - fill: { - extrusion_height: 5000, - color: new THREE.Color(0xffcc00), + ariegeNoProj4 = new FeatureGeometryLayer('ariegeNoProj4', { + source, + accurate: false, + style: { + fill: { + extrusion_height: 5000, + color: new THREE.Color(0xffcc00), + }, }, - }), - zoom: { min: 7 }, + zoom: { min: 7 }, + }); + + context = { + camera: viewer.camera, + engine: viewer.mainLoop.gfxEngine, + scheduler: viewer.mainLoop.scheduler, + geometryLayer: ariege, + view: viewer, + }; + + const extent = new Extent('EPSG:4326', 1.40625, 2.8125, 42.1875, 43.59375); + const geom = new THREE.BufferGeometry(); + geom.OBB = new OBB(new THREE.Vector3(), new THREE.Vector3(1, 1, 1)); + tile = new TileMesh(geom, new THREE.Material(), viewer.tileLayer, extent, 7); + tile.parent = {}; }); - const context = { - camera: viewer.camera, - engine: viewer.mainLoop.gfxEngine, - scheduler: viewer.mainLoop.scheduler, - geometryLayer: ariege, - view: viewer, - }; - - const extent = new Extent('EPSG:4326', 1.40625, 2.8125, 42.1875, 43.59375); - const geom = new THREE.BufferGeometry(); - geom.OBB = new OBB(new THREE.Vector3(), new THREE.Vector3(1, 1, 1)); - const tile = new TileMesh(geom, new THREE.Material(), viewer.tileLayer, extent, 7); - tile.parent = {}; + after(function () { + stubSuppFetcher.restore(); + }); it('add layer', function (done) { viewer.addLayer(ariege) diff --git a/test/unit/geoidlayer.js b/test/unit/geoidlayer.js index e90a8fe403..840024b5cf 100644 --- a/test/unit/geoidlayer.js +++ b/test/unit/geoidlayer.js @@ -1,44 +1,70 @@ import * as THREE from 'three'; import assert from 'assert'; +import fs from 'fs'; import GeoidLayer from 'Layer/GeoidLayer'; import FileSource from 'Source/FileSource'; +import { supportedFetchers } from 'Source/Source'; import Coordinates from 'Core/Geographic/Coordinates'; import GlobeView from 'Core/Prefab/GlobeView'; import { HttpsProxyAgent } from 'https-proxy-agent'; import Extent from 'Core/Geographic/Extent'; import OBB from 'Renderer/OBB'; import TileMesh from 'Core/TileMesh'; +import sinon from 'sinon'; import Renderer from './bootstrap'; +const urlGTXFile = './test/data/unitTest/filesource/RAF20_float.gtx'; +const gtxFile = fs.readFileSync(urlGTXFile); + describe('GlobeView', function () { const renderer = new Renderer(); const placement = { coord: new Coordinates('EPSG:4326', 4.631512, 43.675626), range: 3919 }; const view = new GlobeView(renderer.domElement, placement, { renderer }); - // const url = 'https://raw.githubusercontent.com/iTowns/iTowns2-sample-data/master/altitude-conversion-grids/RAF20_float.gtx'; - const urlGTXFile = 'test/data/unitTest/filesource/RAF20_float.gtx'; - - const geoidSource = new FileSource({ - url: urlGTXFile, - crs: 'EPSG:4326', - format: 'application/gtx', - networkOptions: process.env.HTTPS_PROXY ? { agent: new HttpsProxyAgent(process.env.HTTPS_PROXY) } : {}, - }); - // Specify the type geoid height data are encoded with. See GTXParser documentation at - // http://www.itowns-project.org/itowns/docs/#api/Parser/GTXParser for more. - geoidSource.dataType = 'float'; - // Create a Layer to support geoid height data and add it to the view. - const geoidLayer = new GeoidLayer('geoid', { - source: geoidSource, - }); + let geoidLayer; + let context; + let tile; + let stubSuppFetcher; + + before(function () { + stubSuppFetcher = sinon.stub(supportedFetchers, 'get') + .callsFake((format) => { + if (format === 'application/gtx') { + return () => Promise.resolve(gtxFile.buffer); + } else { + throw new Error(`format (${format}) non supported`); + } + }); + + const url = 'https://raw.githubusercontent.com/iTowns/iTowns2-sample-data/master/altitude-conversion-grids/RAF20_float.gtx'; - const context = {}; + const geoidSource = new FileSource({ + url, + crs: 'EPSG:4326', + format: 'application/gtx', + networkOptions: process.env.HTTPS_PROXY ? { agent: new HttpsProxyAgent(process.env.HTTPS_PROXY) } : {}, + }); + // Specify the type geoid height data are encoded with. See GTXParser documentation at + // http://www.itowns-project.org/itowns/docs/#api/Parser/GTXParser for more. + geoidSource.dataType = 'float'; - const extent = new Extent('EPSG:4326', 4.1, 4.3, 48.1, 48.3); - const geom = new THREE.BufferGeometry(); - geom.OBB = new OBB(new THREE.Vector3(), new THREE.Vector3(1, 1, 1)); - const tile = new TileMesh(geom, new THREE.Material(), view.tileLayer, extent, 9); - tile.parent = {}; + // Create a Layer to support geoid height data and add it to the view. + geoidLayer = new GeoidLayer('geoid', { + source: geoidSource, + }); + + context = {}; + + const extent = new Extent('EPSG:4326', 4.1, 4.3, 48.1, 48.3); + const geom = new THREE.BufferGeometry(); + geom.OBB = new OBB(new THREE.Vector3(), new THREE.Vector3(1, 1, 1)); + tile = new TileMesh(geom, new THREE.Material(), view.tileLayer, extent, 9); + tile.parent = {}; + }); + + after(function () { + stubSuppFetcher.restore(); + }); it('add geoid layer', function (done) { view.addLayer(geoidLayer) diff --git a/test/unit/gtx.js b/test/unit/gtxparser.js similarity index 83% rename from test/unit/gtx.js rename to test/unit/gtxparser.js index 09f21fa9ee..9d851ef0df 100644 --- a/test/unit/gtx.js +++ b/test/unit/gtxparser.js @@ -1,21 +1,12 @@ import assert from 'assert'; -import { HttpsProxyAgent } from 'https-proxy-agent'; +import fs from 'fs'; import GTXParser from 'Parser/GTXParser'; -import Fetcher from 'Provider/Fetcher'; +const urlGTXFile = './test/data/unitTest/filesource/RAF20_float.gtx'; +const gtxFile = fs.readFileSync(urlGTXFile); describe('GTXParser', function () { - let buffer; - const url = 'test/data/unitTest/filesource'; - const GTXFile = 'RAF20_float.gtx'; - - before(async () => { - const networkOptions = process.env.HTTPS_PROXY ? { agent: new HttpsProxyAgent(process.env.HTTPS_PROXY) } : {}; - buffer = await Fetcher.arrayBuffer( - `${url}/${GTXFile}`, - networkOptions, - ); - }); + const buffer = gtxFile.buffer; it('should throw error if dataType parameter is wrongly specified', async function () { assert.throws( diff --git a/test/unit/lasparser.js b/test/unit/lasparser.js index 84b582fca7..ce86ba8967 100644 --- a/test/unit/lasparser.js +++ b/test/unit/lasparser.js @@ -1,20 +1,15 @@ import assert from 'assert'; -import { HttpsProxyAgent } from 'https-proxy-agent'; +import fs from 'fs'; import LASParser from 'Parser/LASParser'; -import Fetcher from 'Provider/Fetcher'; import { compareWithEpsilon } from './utils'; -describe('LASParser', function () { - let lasData; - let lazData; - // const baseurl = 'https://raw.githubusercontent.com/iTowns/iTowns2-sample-data/master/pointclouds/'; - const baseurl = 'test/data/unitTest/pointclouds/'; +const urlData = './test/data/unitTest/pointclouds/'; +const lasFile = fs.readFileSync(`${urlData}/data_test.las`); +const lazFile = fs.readFileSync(`${urlData}/data_test.laz`); - before(async () => { - const networkOptions = process.env.HTTPS_PROXY ? { agent: new HttpsProxyAgent(process.env.HTTPS_PROXY) } : {}; - lazData = await Fetcher.arrayBuffer(`${baseurl}data_test.laz`, networkOptions); - lasData = await Fetcher.arrayBuffer(`${baseurl}data_test.las`, networkOptions); - }); +describe('LASParser', function () { + const lasData = lasFile.buffer; + const lazData = lazFile.buffer; it('parses a las file to a THREE.BufferGeometry', async () => { const bufferGeometry = await LASParser.parse(lasData); diff --git a/test/unit/orientedimagelayer.js b/test/unit/orientedimagelayer.js index 1531e5860b..a0b342f29a 100644 --- a/test/unit/orientedimagelayer.js +++ b/test/unit/orientedimagelayer.js @@ -1,76 +1,98 @@ import proj4 from 'proj4'; import assert from 'assert'; +import fs from 'fs'; import OrientedImageLayer from 'Layer/OrientedImageLayer'; import OrientedImageSource from 'Source/OrientedImageSource'; import { HttpsProxyAgent } from 'https-proxy-agent'; import Coordinates from 'Core/Geographic/Coordinates'; import GlobeView from 'Core/Prefab/GlobeView'; -import path from 'path'; +import sinon from 'sinon'; +import Fetcher from 'Provider/Fetcher'; import Renderer from './bootstrap'; +// import panoData from '../data/unitTest/OrientedImage/panoramicsMetaDataParis.geojson'; +import camCalibration from '../data/unitTest/OrientedImage/cameraCalibration.json'; + +const panoData = fs.readFileSync('./test/data/unitTest/OrientedImage/panoramicsMetaDataParis.geojson'); + +const orientationsUrl = 'https://raw.githubusercontent.com/iTowns/iTowns2-sample-data/master/immersive/exampleParis1/panoramicsMetaDataParis.geojson'; +const calibrationUrl = 'https://raw.githubusercontent.com/iTowns/iTowns2-sample-data/master/immersive/exampleParis1/cameraCalibration.json'; + +const resources = { + [orientationsUrl]: panoData, + [calibrationUrl]: camCalibration, +}; + describe('Oriented Image Layer', function () { - proj4.defs('EPSG:2154', '+proj=lcc +lat_1=49 +lat_2=44 +lat_0=46.5 +lon_0=3 +x_0=700000 +y_0=6600000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs'); - const renderer = new Renderer(); + let orImgLayer; + let context; + let stubFetcherJson; + + before(function () { + stubFetcherJson = sinon.stub(Fetcher, 'json') + .callsFake(url => Promise.resolve(JSON.parse(resources[url]))); + proj4.defs('EPSG:2154', '+proj=lcc +lat_1=49 +lat_2=44 +lat_0=46.5 +lon_0=3 +x_0=700000 +y_0=6600000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs'); + const renderer = new Renderer(); - const p = { - coord: new Coordinates('EPSG:4326', 2.33481381, 48.85060296), - range: 25, - }; - const viewer = new GlobeView(renderer.domElement, p, - { renderer, - noControls: true, - handleCollision: false, - sseSubdivisionThreshold: 10, + const p = { + coord: new Coordinates('EPSG:4326', 2.33481381, 48.85060296), + range: 25, + }; + const viewer = new GlobeView(renderer.domElement, p, + { renderer, + noControls: true, + handleCollision: false, + sseSubdivisionThreshold: 10, + }); + + // Prepare oriented image source + const orientedImageSource = new OrientedImageSource({ + url: 'http://www.itowns-project.org/itowns-sample-data-small/images/140616/Paris-140616_0740-{cameraId}-00001_0000{panoId}.jpg', + // Url to a GEOJSON file describing feature points. It describes position and orientation of each panoramic. + orientationsUrl: 'https://raw.githubusercontent.com/iTowns/iTowns2-sample-data/master/immersive/exampleParis1/panoramicsMetaDataParis.geojson', + // Url of a a JSON file with calibration for all cameras. see [CameraCalibrationParser]{@link module:CameraCalibrationParser.parse} + // in this example, we have the ladybug, it's a set of 6 cameras + calibrationUrl: 'https://raw.githubusercontent.com/iTowns/iTowns2-sample-data/master/immersive/exampleParis1/cameraCalibration.json', + networkOptions: process.env.HTTPS_PROXY ? { agent: new HttpsProxyAgent(process.env.HTTPS_PROXY) } : {}, }); - const orientationsUrl = path.join(process.cwd(), 'test', 'data', 'unitTest', 'OrientedImage', 'panoramicsMetaDataParis.geojson'); - const calibrationUrl = path.join(process.cwd(), 'test', 'data', 'unitTest', 'OrientedImage', 'cameraCalibration.json'); + // Create oriented image layer + orImgLayer = new OrientedImageLayer('demo_orientedImage', { + // Radius in meter of the sphere used as a background. + backgroundDistance: 1200, + source: orientedImageSource, + crs: viewer.referenceCrs, + useMask: false, + }); - // Prepare oriented image source - const orientedImageSource = new OrientedImageSource({ - url: 'http://www.itowns-project.org/itowns-sample-data-small/images/140616/Paris-140616_0740-{cameraId}-00001_0000{panoId}.jpg', - // Url to a GEOJSON file describing feature points. It describes position and orientation of each panoramic. - // orientationsUrl: 'https://raw.githubusercontent.com/iTowns/iTowns2-sample-data/master/immersive/exampleParis1/panoramicsMetaDataParis.geojson', - orientationsUrl, - // Url of a a JSON file with calibration for all cameras. see [CameraCalibrationParser]{@link module:CameraCalibrationParser.parse} - // in this example, we have the ladybug, it's a set of 6 cameras - calibrationUrl, - // calibrationUrl: 'https://raw.githubusercontent.com/iTowns/iTowns2-sample-data/master/immersive/exampleParis1/cameraCalibration.json', - networkOptions: process.env.HTTPS_PROXY ? { agent: new HttpsProxyAgent(process.env.HTTPS_PROXY) } : {}, - }); + viewer.addLayer(orImgLayer, viewer.tileLayer); - // Create oriented image layer - const olayer = new OrientedImageLayer('demo_orientedImage', { - // Radius in meter of the sphere used as a background. - backgroundDistance: 1200, - source: orientedImageSource, - crs: viewer.referenceCrs, - useMask: false, + context = { + camera: viewer.camera, + engine: viewer.mainLoop.gfxEngine, + scheduler: viewer.mainLoop.scheduler, + view: viewer, + }; }); - viewer.addLayer(olayer, viewer.tileLayer); - - const context = { - camera: viewer.camera, - engine: viewer.mainLoop.gfxEngine, - scheduler: viewer.mainLoop.scheduler, - view: viewer, - }; + after(function () { + stubFetcherJson.restore(); + }); it('Add oriented image layer', function (done) { - olayer.whenReady + orImgLayer.whenReady .then(() => { - assert.equal(olayer.cameras.length, 5); + assert.equal(orImgLayer.cameras.length, 5); done(); }).catch(done); }); it('PreUpdate oriented image layer', function (done) { - olayer.whenReady + orImgLayer.whenReady .then(() => { - assert.equal(olayer.currentPano, undefined); - olayer.preUpdate(context); - assert.equal(olayer.currentPano.id, 482); + assert.equal(orImgLayer.currentPano, undefined); + orImgLayer.preUpdate(context); + assert.equal(orImgLayer.currentPano.id, 482); done(); }).catch(done); }); diff --git a/test/unit/potree.js b/test/unit/potree.js index 23a829f450..3f122ee49e 100644 --- a/test/unit/potree.js +++ b/test/unit/potree.js @@ -1,4 +1,5 @@ import assert from 'assert'; +import fs from 'fs'; import PotreeLayer from 'Layer/PotreeLayer'; import PotreeSource from 'Source/PotreeSource'; import View from 'Core/View'; @@ -8,25 +9,46 @@ import Coordinates from 'Core/Geographic/Coordinates'; import PotreeNode from 'Core/PotreeNode'; import PointsMaterial from 'Renderer/PointsMaterial'; import OrientedImageMaterial from 'Renderer/OrientedImageMaterial'; +import sinon from 'sinon'; +import Fetcher from 'Provider/Fetcher'; import Renderer from './bootstrap'; -describe('Potree', function () { - const url = 'test/data/unitTest/potree'; +import fileJson from '../data/unitTest/potree/eglise_saint_blaise_arles.json'; + +const urlPotreeFile = 'https://raw.githubusercontent.com/gmaillet/dataset/master'; +const fileName = 'eglise_saint_blaise_arles'; + +const potreeRRhrc = fs.readFileSync('./test/data/unitTest/potree/eglise_saint_blaise_arles/r/r.hrc'); +const potreeRRbin = fs.readFileSync('./test/data/unitTest/potree/eglise_saint_blaise_arles/r/r.bin'); +const potreeRR0bin = fs.readFileSync('./test/data/unitTest/potree/eglise_saint_blaise_arles/r/r0.bin'); + +const resources = new Map([ + [`${urlPotreeFile}/${fileName}/r/r.hrc`, potreeRRhrc.buffer], + [`${urlPotreeFile}/${fileName}/r/r.bin`, potreeRRbin.buffer], + [`${urlPotreeFile}/${fileName}/r/r0.bin`, potreeRR0bin.buffer], +]); +describe('Potree', function () { const placement = { coord: new Coordinates('EPSG:4326', 4.631512, 43.675626), range: 250 }; let renderer; let viewer; let potreeLayer; let context; let elt; + let stubFetcherJson; + let stubFetcherArrayBuf; before(function () { + stubFetcherJson = sinon.stub(Fetcher, 'json') + .callsFake(() => Promise.resolve(JSON.parse(fileJson))); + stubFetcherArrayBuf = sinon.stub(Fetcher, 'arrayBuffer') + .callsFake(url => Promise.resolve(resources.get(url))); renderer = new Renderer(); viewer = new GlobeView(renderer.domElement, placement, { renderer }); const source = new PotreeSource({ file: 'eglise_saint_blaise_arles.json', - url, + url: urlPotreeFile, networkOptions: process.env.HTTPS_PROXY ? { agent: new HttpsProxyAgent(process.env.HTTPS_PROXY) } : {}, }); @@ -46,6 +68,11 @@ describe('Potree', function () { }; }); + after(function () { + stubFetcherJson.restore(); + stubFetcherArrayBuf.restore(); + }); + it('Add point potree layer', function (done) { View.prototype.addLayer.call(viewer, potreeLayer) .then((layer) => { diff --git a/test/unit/potreelayerparsing.js b/test/unit/potreelayerparsing.js index 886673105a..575f340d7e 100644 --- a/test/unit/potreelayerparsing.js +++ b/test/unit/potreelayerparsing.js @@ -1,18 +1,34 @@ import assert from 'assert'; +import fs from 'fs'; import PotreeLayer from 'Layer/PotreeLayer'; import PotreeSource from 'Source/PotreeSource'; import Coordinates from 'Core/Geographic/Coordinates'; import GlobeView from 'Core/Prefab/GlobeView'; import View from 'Core/View'; import { HttpsProxyAgent } from 'https-proxy-agent'; +import sinon from 'sinon'; +import Fetcher from 'Provider/Fetcher'; import Renderer from './bootstrap'; -describe('Potree Provider', function () { - const url = 'test/data/unitTest/potree'; +const potreeRRhrc = fs.readFileSync('./test/data/unitTest/potree/eglise_saint_blaise_arles/r/r.hrc'); - const renderer = new Renderer(); +describe('Potree Provider', function () { const placement = { coord: new Coordinates('EPSG:4326', 1.5, 43), range: 300000 }; - const view = new GlobeView(renderer.domElement, placement, { renderer }); + + let renderer; + let view; + let stubFetcherArrayBuf; + + before(function () { + stubFetcherArrayBuf = sinon.stub(Fetcher, 'arrayBuffer') + .callsFake(() => Promise.resolve(potreeRRhrc.buffer)); + + renderer = new Renderer(); + view = new GlobeView(renderer.domElement, placement, { renderer }); + }); + after(function () { + stubFetcherArrayBuf.restore(); + }); describe('cloud information parsing', function _() { it('cloud with no normal information', function _it(done) { @@ -26,8 +42,7 @@ describe('Potree Provider', function () { const source = new PotreeSource({ file: 'eglise_saint_blaise_arles.json', - url, - // url: 'https://raw.githubusercontent.com/gmaillet/dataset/master/', + url: 'https://raw.githubusercontent.com/gmaillet/dataset/master/', networkOptions: process.env.HTTPS_PROXY ? { agent: new HttpsProxyAgent(process.env.HTTPS_PROXY) } : {}, cloud, }); @@ -52,8 +67,7 @@ describe('Potree Provider', function () { const source = new PotreeSource({ file: 'eglise_saint_blaise_arles.json', - url, - // url: 'https://raw.githubusercontent.com/gmaillet/dataset/master/', + url: 'https://raw.githubusercontent.com/gmaillet/dataset/master/', networkOptions: process.env.HTTPS_PROXY ? { agent: new HttpsProxyAgent(process.env.HTTPS_PROXY) } : {}, cloud, }); @@ -78,8 +92,7 @@ describe('Potree Provider', function () { }; const source = new PotreeSource({ file: 'eglise_saint_blaise_arles.json', - url, - // url: 'https://raw.githubusercontent.com/gmaillet/dataset/master/', + url: 'https://raw.githubusercontent.com/gmaillet/dataset/master/', networkOptions: process.env.HTTPS_PROXY ? { agent: new HttpsProxyAgent(process.env.HTTPS_PROXY) } : {}, cloud, }); @@ -104,8 +117,7 @@ describe('Potree Provider', function () { }; const source = new PotreeSource({ file: 'eglise_saint_blaise_arles.json', - url, - // url: 'https://raw.githubusercontent.com/gmaillet/dataset/master/', + url: 'https://raw.githubusercontent.com/gmaillet/dataset/master/', networkOptions: process.env.HTTPS_PROXY ? { agent: new HttpsProxyAgent(process.env.HTTPS_PROXY) } : {}, cloud, }); diff --git a/test/unit/source.js b/test/unit/source.js index b4ee8bede1..494b871a9c 100644 --- a/test/unit/source.js +++ b/test/unit/source.js @@ -1,6 +1,7 @@ import { Matrix4 } from 'three'; import assert from 'assert'; -import Source from 'Source/Source'; +import fs from 'fs'; +import Source, { supportedFetchers } from 'Source/Source'; import Layer from 'Layer/Layer'; import WFSSource from 'Source/WFSSource'; import WMTSSource from 'Source/WMTSSource'; @@ -12,13 +13,21 @@ import C3DTilesSource from 'Source/C3DTilesSource'; import C3DTilesIonSource from 'Source/C3DTilesIonSource'; import Extent from 'Core/Geographic/Extent'; import { HttpsProxyAgent } from 'https-proxy-agent'; +import sinon from 'sinon'; +import Fetcher from 'Provider/Fetcher'; + +import tileset from '../data/unitTest/3dTiles/tileset.json'; + +const urlFilesource = 'https://raw.githubusercontent.com/gregoiredavid/france-geojson/master/departements/09-ariege/departement-09-ariege.geojson'; +const url3dTileset = 'https://raw.githubusercontent.com/iTowns/iTowns2-sample-data/master/3DTiles/lyon_1_4978/tileset.json'; +const fileSource = fs.readFileSync('./test/data/unitTest/filesource/departement-09-ariege.geojson'); + +const resources = { + [urlFilesource]: fileSource, + [url3dTileset]: tileset, +}; describe('Sources', function () { - // geojson url to parse - // const urlFilesource = 'https://raw.githubusercontent.com/gregoiredavid/france-geojson/master/departements/09-ariege/departement-09-ariege.geojson'; - const urlFilesource = 'test/data/unitTest/filesource/departement-09-ariege.geojson'; - // const url3dTiles = 'https://raw.githubusercontent.com/iTowns/iTowns2-sample-data/master/3DTiles/lyon_1_4978/tileset.json'; - const url3dTiles = 'test/data/unitTest/3dTiles/tileset.json'; const vendorSpecific = { buffer: 4096, format_options: 'dpi:300;quantizer:octree', @@ -213,6 +222,22 @@ describe('Sources', function () { let fetchedData; describe('FileSource', function () { + let stubSuppFetcher; + before(function () { + stubSuppFetcher = sinon.stub(supportedFetchers, 'get') + .callsFake((format) => { + if (format === 'application/json') { + return () => Promise.resolve(JSON.parse(fileSource)); + } else { + throw new Error(`format (${format}) non supported`); + } + }); + }); + + after(function () { + stubSuppFetcher.restore(); + }); + it('should instance FileSource with no source.fetchedData', function _it(done) { const source = new FileSource({ url: urlFilesource, @@ -276,6 +301,7 @@ describe('Sources', function () { const source = new FileSource({ features: { foo: 'bar', crs: 'EPSG:4326', extent, matrixWorld: new Matrix4() }, crs: 'EPSG:4326', + format: 'application/json', }); source.onLayerAdded({ out: { crs: source.crs } }); assert.ok(source.urlFromExtent(extent).startsWith('fake-file-url')); @@ -289,39 +315,36 @@ describe('Sources', function () { assert.throws(() => new FileSource({ crs: 'EPSG:4326' }), Error); }); - describe('should set the crs projection from features', function () { - it('with the crs', function () { - const source = new FileSource({ - features: { crs: 'EPSG:4326' }, - }); - assert.strictEqual(source.crs, 'EPSG:4326'); - }); - - it('with the crs projection', function () { - const source = new FileSource({ - features: { crs: 'EPSG:4326' }, - }); - assert.strictEqual(source.crs, 'EPSG:4326'); + it('should set the crs projection from features', function () { + const source = new FileSource({ + features: { crs: 'EPSG:4326' }, + format: 'application/json', }); + assert.strictEqual(source.crs, 'EPSG:4326'); }); }); describe('C3DTilesSource', function () { - const params3DTiles = { - url: url3dTiles, - }; + let stubFetcherJson; + before(function () { + stubFetcherJson = sinon.stub(Fetcher, 'json') + .callsFake(url => Promise.resolve(resources[url])); + }); + after(function () { + stubFetcherJson.restore(); + }); it('should throw an error for having no required parameters', function () { assert.throws(() => new C3DTilesSource({}), Error); }); it('should instance C3DTilesSource', function (done) { - const source = new C3DTilesSource(params3DTiles); + const source = new C3DTilesSource({ url: url3dTileset }); source.whenReady .then(() => { assert.ok(source.isC3DTilesSource); - assert.strictEqual(source.url, params3DTiles.url); - assert.strictEqual(source.baseUrl, params3DTiles.url.slice(0, params3DTiles.url.lastIndexOf('/') + 1)); + assert.strictEqual(source.url, url3dTileset); + assert.strictEqual(source.baseUrl, url3dTileset.slice(0, url3dTileset.lastIndexOf('/') + 1)); done(); }).catch(done); });