1f244194创建于 2024年12月9日历史提交
import DataTile, {
  asArrayLike,
  asImageLike,
  toArray,
} from '../../../../src/ol/DataTile.js';
import TileState from '../../../../src/ol/TileState.js';
import {listenOnce} from '../../../../src/ol/events.js';

describe('ol/DataTile', function () {
  /**
   * @type {Promise<import('../../../../src/ol/DataTile.js').Data>}
   */
  let loader;
  beforeEach(function () {
    loader = function () {
      return new Promise((resolve) => {
        const canvas = document.createElement('canvas');
        canvas.width = 256;
        canvas.height = 256;
        const context = canvas.getContext('2d');
        context.fillStyle = 'red';
        context.fillRect(0, 0, 256, 256);
        resolve(context.getImageData(0, 0, 256, 256).data);
      });
    };
  });

  describe('constructor', function () {
    it('sets options', function () {
      const tileCoord = [0, 0, 0];
      const tile = new DataTile({
        tileCoord: tileCoord,
        loader: loader,
        transition: 200,
      });
      expect(tile.tileCoord).to.equal(tileCoord);
      expect(tile.transition_).to.be(200);
      expect(tile.loader_).to.equal(loader);
    });
  });

  describe('#getSize()', function () {
    it('returns [256, 256] by default', function () {
      const tileCoord = [0, 0, 0];
      const tile = new DataTile({
        tileCoord: tileCoord,
        loader: loader,
      });
      expect(tile.getSize()).to.eql([256, 256]);
    });

    it('respects what is provided in the constructor', function () {
      const size = [123, 456];
      const tileCoord = [0, 0, 0];
      const tile = new DataTile({
        size: size,
        tileCoord: tileCoord,
        loader: loader,
      });
      expect(tile.getSize()).to.eql(size);
    });
  });

  describe('#load()', function () {
    it('handles loading states correctly', function (done) {
      const tileCoord = [0, 0, 0];
      const tile = new DataTile({
        tileCoord: tileCoord,
        loader: loader,
      });
      expect(tile.getState()).to.be(TileState.IDLE);
      tile.load();
      expect(tile.getState()).to.be(TileState.LOADING);
      listenOnce(tile, 'change', () => {
        expect(tile.getState()).to.be(TileState.LOADED);
        done();
      });
    });

    it('reloads tiles in an error state', function (done) {
      const tileCoord = [0, 0, 0];
      const tile = new DataTile({
        tileCoord: tileCoord,
        loader: loader,
      });
      tile.state = TileState.ERROR;

      tile.load();
      expect(tile.getState()).to.be(TileState.LOADING);
      listenOnce(tile, 'change', () => {
        expect(tile.getState()).to.be(TileState.LOADED);
        done();
      });
    });
  });

  describe('#getData() #asArrayLike() #asImageLike() #toArray()', function () {
    it('handles array data correctly', function (done) {
      const tileCoord = [0, 0, 0];
      const tile = new DataTile({
        tileCoord: tileCoord,
        loader: loader,
      });
      tile.load();
      listenOnce(tile, 'change', () => {
        expect(tile.getState()).to.be(TileState.LOADED);
        const data = tile.getData();
        expect(data).to.be.an(Uint8ClampedArray);
        expect(data.length).to.be(262144);
        const expected = [255, 0, 0, 255, 255, 0, 0, 255];
        expect(Array.from(data.slice(0, 8))).to.eql(expected);
        expect(asImageLike(data)).to.be(null);
        expect(asArrayLike(data)).to.be(data);
        done();
      });
    });

    it('handles image data correctly', function (done) {
      const loadImage = function (src) {
        return new Promise((resolve, reject) => {
          const img = new Image();
          img.addEventListener('load', () => resolve(img));
          img.addEventListener('error', () => reject(new Error('load failed')));
          img.src = src;
        });
      };
      const loader = async function () {
        const canvas = document.createElement('canvas');
        canvas.width = 256;
        canvas.height = 256;
        const context = canvas.getContext('2d');
        context.fillStyle = 'red';
        context.fillRect(0, 0, 256, 256);
        const src = canvas.toDataURL();
        const image = await loadImage(src);
        return image;
      };
      const tileCoord = [0, 0, 0];
      const tile = new DataTile({
        tileCoord: tileCoord,
        loader: loader,
      });
      tile.load();
      listenOnce(tile, 'change', () => {
        expect(tile.getState()).to.be(TileState.LOADED);
        const data = tile.getData();
        expect(data).to.be.an(Image);
        expect(data.width).to.be(256);
        expect(data.height).to.be(256);
        expect(asArrayLike(data)).to.be(null);
        expect(asImageLike(data)).to.be(data);
        const imageData = toArray(asImageLike(data));
        expect(imageData).to.be.an(Uint8ClampedArray);
        expect(imageData.length).to.be(262144);
        const expected = [255, 0, 0, 255, 255, 0, 0, 255];
        expect(Array.from(imageData.slice(0, 8))).to.eql(expected);
        done();
      });
    });
  });
});