<commit_before>// @flow
/* eslint import/no-extraneous-dependencies: ["error", {"peerDependencies": true}] */

// Integration tests for skeleton.js

import test from "ava";
import mockRequire from "mock-require";
import _ from "lodash";
import { getSkeletonTracing } from "oxalis/model/accessors/skeletontracing_accessor";
import {
  createNodeAction,
  createTreeAction,
  deleteNodeAction,
  createBranchPointAction,
  setNodeRadiusAction,
} from "oxalis/model/actions/skeletontracing_actions";

mockRequire.stopAll();
mockRequire("app", { currentUser: { firstName: "SCM", lastName: "Boy" } });
mockRequire("libs/window", {
  alert: console.log.bind(console),
  requestAnimationFrame: resolve => resolve(),
  app: null,
});
const Utils = mockRequire.reRequire("libs/utils").default;
const NodeShader = mockRequire.reRequire("oxalis/geometries/materials/node_shader");
const Store = mockRequire.reRequire("oxalis/store").default;
const Skeleton = mockRequire.reRequire("oxalis/geometries/skeleton").default;

test.before(t => {
  const rotation = [0.5, 0.5, 0.5];
  const viewport = 0;
  const resolution = 0;

  // create 20 trees with 100 nodes each
  for (let i = 0; i < 2000; i++) {
    if (i % 100 === 0) {
      Store.dispatch(createTreeAction());
    }
    Store.dispatch(createNodeAction([i, i, i], rotation, viewport, resolution));
  }

  getSkeletonTracing(Store.getState().tracing).map(skeletonTracing => {
    const trees = skeletonTracing.trees;
    t.is(_.size(trees), 20);
    for (const tree of Object.values(trees)) {
      t.is(_.size(tree.nodes), 100);
    }
  });
});

test.serial("Skeleton should initialize correctly using the store's state", t => {
  getSkeletonTracing(Store.getState().tracing).map(skeletonTracing => {
    const trees = skeletonTracing.trees;
    const skeleton = new Skeleton();

    t.is(skeleton.nodes.buffers.length, 1);
    t.is(skeleton.edges.buffers.length, 1);

    const nodeCapacity = 2000;
    const edgeCapacity = 1980;

    let nodePositions = [];
    const nodeTypes = [];
    const nodeRadii = [];
    const nodeIds = [];
    const nodeTreeIds = [];
    let edgePositions = [];
    const edgeTreeIds = [];
    let treeColors = [0, 0, 0, 0]; // tree ids start at index 1 so add one bogus RGB value

    for (const tree of Object.values(trees)) {
      treeColors = treeColors.concat(skeleton.getTreeRGBA(tree.color, tree.isVisible));
      for (const node of Object.values(tree.nodes)) {
        nodePositions = nodePositions.concat(node.position);
        nodeTreeIds.push(tree.treeId);
        nodeRadii.push(node.radius);
        nodeIds.push(node.id);
        nodeTypes.push(NodeShader.NodeTypes.NORMAL);
      }
      for (const edge of tree.edges) {
        const sourcePosition = tree.nodes[edge.source].position;
        const targetPosition = tree.nodes[edge.target].position;
        edgePositions = edgePositions.concat(sourcePosition).concat(targetPosition);
        edgeTreeIds.push(tree.treeId, tree.treeId);
      }
    }

    const nodeBufferGeometryAttributes = skeleton.nodes.buffers[0].geometry.attributes;
    t.is(nodeBufferGeometryAttributes.position.array.length, 3 * nodeCapacity);
    t.is(nodeBufferGeometryAttributes.radius.array.length, nodeCapacity);
    t.is(nodeBufferGeometryAttributes.type.array.length, nodeCapacity);
    t.is(nodeBufferGeometryAttributes.nodeId.array.length, nodeCapacity);
    t.is(nodeBufferGeometryAttributes.treeId.array.length, nodeCapacity);

    t.deepEqual(nodeBufferGeometryAttributes.position.array, new Float32Array(nodePositions));
    t.deepEqual(nodeBufferGeometryAttributes.radius.array, new Float32Array(nodeRadii));
    t.deepEqual(nodeBufferGeometryAttributes.type.array, new Float32Array(nodeTypes));
    t.deepEqual(nodeBufferGeometryAttributes.nodeId.array, new Float32Array(nodeIds));
    t.deepEqual(nodeBufferGeometryAttributes.treeId.array, new Float32Array(nodeTreeIds));

    const edgeBufferGeometryAttributes = skeleton.edges.buffers[0].geometry.attributes;
    t.is(edgeBufferGeometryAttributes.position.array.length, 6 * edgeCapacity);
    t.is(edgeBufferGeometryAttributes.treeId.array.length, 2 * edgeCapacity);

    t.deepEqual(edgeBufferGeometryAttributes.position.array, new Float32Array(edgePositions));
    t.deepEqual(edgeBufferGeometryAttributes.treeId.array, new Float32Array(edgeTreeIds));

    const textureData = new Float32Array(
      NodeShader.COLOR_TEXTURE_WIDTH * NodeShader.COLOR_TEXTURE_WIDTH * 4,
    );
    textureData.set(treeColors);
    t.deepEqual(skeleton.treeColorTexture.image.data, textureData);
  });
});

test.serial("Skeleton should increase its buffers once the max capacity is reached", async t => {
  const skeleton = new Skeleton();<commit_msg>speed up unit tests by removing a deep comparison (#2032)<commit_after>// @flow
/* eslint import/no-extraneous-dependencies: ["error", {"peerDependencies": true}] */

// Integration tests for skeleton.js

import test from "ava";
import mockRequire from "mock-require";
import _ from "lodash";
import { getSkeletonTracing } from "oxalis/model/accessors/skeletontracing_accessor";
import {
  createNodeAction,
  createTreeAction,
  deleteNodeAction,
  createBranchPointAction,
  setNodeRadiusAction,
} from "oxalis/model/actions/skeletontracing_actions";

mockRequire.stopAll();
mockRequire("app", { currentUser: { firstName: "SCM", lastName: "Boy" } });
mockRequire("libs/window", {
  alert: console.log.bind(console),
  requestAnimationFrame: resolve => resolve(),
  app: null,
});
const Utils = mockRequire.reRequire("libs/utils").default;
const NodeShader = mockRequire.reRequire("oxalis/geometries/materials/node_shader");
const Store = mockRequire.reRequire("oxalis/store").default;
const Skeleton = mockRequire.reRequire("oxalis/geometries/skeleton").default;

test.before(t => {
  const rotation = [0.5, 0.5, 0.5];
  const viewport = 0;
  const resolution = 0;

  // create 20 trees with 100 nodes each
  for (let i = 0; i < 2000; i++) {
    if (i % 100 === 0) {
      Store.dispatch(createTreeAction());
    }
    Store.dispatch(createNodeAction([i, i, i], rotation, viewport, resolution));
  }

  getSkeletonTracing(Store.getState().tracing).map(skeletonTracing => {
    const trees = skeletonTracing.trees;
    t.is(_.size(trees), 20);
    for (const tree of Object.values(trees)) {
      t.is(_.size(tree.nodes), 100);
    }
  });
});

test.serial("Skeleton should initialize correctly using the store's state", t => {
  getSkeletonTracing(Store.getState().tracing).map(skeletonTracing => {
    const trees = skeletonTracing.trees;
    const skeleton = new Skeleton();

    t.is(skeleton.nodes.buffers.length, 1);
    t.is(skeleton.edges.buffers.length, 1);

    const nodeCapacity = 2000;
    const edgeCapacity = 1980;

    let nodePositions = [];
    const nodeTypes = [];
    const nodeRadii = [];
    const nodeIds = [];
    const nodeTreeIds = [];
    let edgePositions = [];
    const edgeTreeIds = [];
    let treeColors = [0, 0, 0, 0]; // tree ids start at index 1 so add one bogus RGB value

    for (const tree of Object.values(trees)) {
      treeColors = treeColors.concat(skeleton.getTreeRGBA(tree.color, tree.isVisible));
      for (const node of Object.values(tree.nodes)) {
        nodePositions = nodePositions.concat(node.position);
        nodeTreeIds.push(tree.treeId);
        nodeRadii.push(node.radius);
        nodeIds.push(node.id);
        nodeTypes.push(NodeShader.NodeTypes.NORMAL);
      }
      for (const edge of tree.edges) {
        const sourcePosition = tree.nodes[edge.source].position;
        const targetPosition = tree.nodes[edge.target].position;
        edgePositions = edgePositions.concat(sourcePosition).concat(targetPosition);
        edgeTreeIds.push(tree.treeId, tree.treeId);
      }
    }

    const nodeBufferGeometryAttributes = skeleton.nodes.buffers[0].geometry.attributes;
    t.is(nodeBufferGeometryAttributes.position.array.length, 3 * nodeCapacity);
    t.is(nodeBufferGeometryAttributes.radius.array.length, nodeCapacity);
    t.is(nodeBufferGeometryAttributes.type.array.length, nodeCapacity);
    t.is(nodeBufferGeometryAttributes.nodeId.array.length, nodeCapacity);
    t.is(nodeBufferGeometryAttributes.treeId.array.length, nodeCapacity);

    t.deepEqual(nodeBufferGeometryAttributes.position.array, new Float32Array(nodePositions));
    t.deepEqual(nodeBufferGeometryAttributes.radius.array, new Float32Array(nodeRadii));
    t.deepEqual(nodeBufferGeometryAttributes.type.array, new Float32Array(nodeTypes));
    t.deepEqual(nodeBufferGeometryAttributes.nodeId.array, new Float32Array(nodeIds));
    t.deepEqual(nodeBufferGeometryAttributes.treeId.array, new Float32Array(nodeTreeIds));

    const edgeBufferGeometryAttributes = skeleton.edges.buffers[0].geometry.attributes;
    t.is(edgeBufferGeometryAttributes.position.array.length, 6 * edgeCapacity);
    t.is(edgeBufferGeometryAttributes.treeId.array.length, 2 * edgeCapacity);

    t.deepEqual(edgeBufferGeometryAttributes.position.array, new Float32Array(edgePositions));
    t.deepEqual(edgeBufferGeometryAttributes.treeId.array, new Float32Array(edgeTreeIds));

    const textureData = new Float32Array(
      NodeShader.COLOR_TEXTURE_WIDTH * NodeShader.COLOR_TEXTURE_WIDTH * 4,
    );
    textureData.set(treeColors);
    // Do not use t.deepEqual here, it's extremely slow and takes >15s
    t.true(_.isEqual(skeleton.treeColorTexture.image.data, textureData));
  });
});

test.serial("Skeleton should increase its buffers once the max capacity is reached", async t => {
  const skeleton = new Skeleton();
{'fraction_non_alphanumeric': 0.12462101411395714, 'fraction_numerical': 0.014009409304756927, 'mean_word_length': 4.386261261261262, 'pattern_counts': {'":': 2, '<': 5, '<?xml version=': 0, '>': 16, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4039825', 'n_tokens_mistral': 3008, 'n_tokens_neox': 2837, 'n_words': 569}