<commit_before>///<reference path="../testReference.ts" />

describe("Plots", () => {
  describe("PiePlot", () => {
    describe("Labels", () => {
      let svg: d3.Selection<void>;
      let piePlot: Plottable.Plots.Pie;

      beforeEach(() => {
        svg = TestMethods.generateSVG(500, 500);
        piePlot = new Plottable.Plots.Pie();
        piePlot.sectorValue((d) => d.value);
        piePlot.labelsEnabled(true);
      });

      it("does not erase or add labels when rendered twice", () => {
        let data = [
          { value: 1 },
          { value: 2 },
          { value: 3 }
        ];
        let dataset = new Plottable.Dataset(data);
        piePlot.addDataset(dataset);
        piePlot.renderTo(svg);
        let labels = piePlot.content().selectAll("text");
        assert.strictEqual(labels.size(), data.length, "one label per slice");
        piePlot.render();
        labels = piePlot.content().selectAll("text");
        assert.strictEqual(labels.size(), data.length, "one label per slice after re-render()ing");
        svg.remove();
      });

      it("updates labels when data changes", () => {
        let data1 = [
          { value: 1 },
          { value: 1 },
          { value: 1 }
        ];
        let dataset = new Plottable.Dataset(data1);
        piePlot.addDataset(dataset);
        piePlot.renderTo(svg);
        let labels = piePlot.content().selectAll("text");
        assert.strictEqual(labels.size(), data1.length, "one label per datum");
        labels.each(function() {
          let labelText = d3.select(this).text();
          assert.strictEqual(labelText, "1", "label has correct text");
        });
        let data2 = [
          { value: 2 },
          { value: 2 }
        ];
        dataset.data(data2);
        labels = piePlot.content().selectAll("text");
        assert.strictEqual(labels.size(), data2.length, "one label per datum");
        labels.each(function() {
          let labelText = d3.select(this).text();
          assert.strictEqual(labelText, "2", "label text was updated");
        });
        svg.remove();
      });

      it("removes labels when they are disabled after rendering", () => {
        let data1 = [
          { value: 1 },
          { value: 1 },
          { value: 1 }
        ];
        let dataset = new Plottable.Dataset(data1);
        piePlot.addDataset(dataset);
        piePlot.renderTo(svg);
        let labels = piePlot.content().selectAll("text");
        assert.strictEqual(labels.size(), data1.length, "one label per datum");
        piePlot.labelsEnabled(false);
        labels = piePlot.content().selectAll("text");
        assert.strictEqual(labels.size(), 0, "labels were removed");
        svg.remove();
      });

      it("hides labels if slices are too small", () => {
        let data = [
          { key: "A", value: 1 }, { key: "B", value: 50 },
          { key: "C", value: 1 }, { key: "D", value: 50 },
          { key: "E", value: 1 }, { key: "F", value: 50 }
        ];
        let dataset = new Plottable.Dataset(data);
        piePlot.addDataset(dataset);
        piePlot.renderTo(svg);
        let labelGs = piePlot.content().select(".label-area").selectAll(".label-area > g");
        labelGs.each(function(d, i) {
          let visibility = d3.select(this).style("visibility");
          if (data[i].value === 1) {
            assert.strictEqual(visibility, "hidden", "label hidden when slice is too small");
          } else {
            assert.include(["visible", "inherit"], visibility, "label shown when slice is appropriately sized");
          }
        });
        svg.remove();
      });

      it("uses its formatter to format labels", () => {
        let data = [
          { value: 5 },
          { value: 15 }
        ];
        let dataset = new Plottable.Dataset(data);
        piePlot.addDataset(dataset);
        piePlot.labelFormatter((n: number) => n + " m");
        piePlot.renderTo(svg);
        let texts = svg.selectAll("text")[0].map((n: any) => d3.select(n).text());
        assert.lengthOf(texts, 2, "both labels are drawn");
        assert.strictEqual(texts[0], "5 m", "The formatter was used to format the first label");
        assert.strictEqual(texts[1], "15 m", "The formatter was used to format the second label");
        svg.remove();
      });

      it("hides labels if they don't fit", () => {
        let data = [
          { value: 1 }, { value: 50 },
          { value: 1 }, { value: 50 },
          { value: 1 }, { value: 50 }
        ];
        let dataset = new Plottable.Dataset(data);
        piePlot.addDataset(dataset);
        piePlot.renderTo(svg);

        let texts = svg.selectAll("text");
        assert.strictEqual(texts.size(), data.length, "One label is rendered for each piece of data");

        texts.each(function(d, i) {
          let visibility = d3.select(this).style("visibility");
          if (i % 2 === 0) {
            assert.strictEqual(visibility, "hidden", "label hidden when slice is too small");
          } else {
            assert.include(["visible", "inherit"], visibility, "label shown when slice is appropriately sized");
          }
        });

        svg.remove();
      });

      it("hides labels outside of the render area", () => {
        let data = [
          { value: 5000 },
          { value: 5000 },
          { value: 5000 }];
        let dataset = new Plottable.Dataset(data);
        piePlot.addDataset(dataset).outerRadius(500);
        piePlot.renderTo(svg);

        let texts = svg.selectAll("text");
        assert.strictEqual(texts.size(), data.length, "One label is rendered for each piece of data");

        texts.each(function(d, i) {
          let visibility = d3.select(this).style("visibility");
          if (i === 1) {
            assert.strictEqual(visibility, "hidden", "label hidden when cut off by the lower margin");
          } else {
            assert.include(["visible", "inherit"], visibility, "label shown when in the renderArea");
          }
        });
        svg.remove();
      });

      it("does not show labels for invalid data", () => {
        let data = [
          { value: 1 },
          { value: "value" },
          { value: 2 }];
        let dataset = new Plottable.Dataset(data);
        piePlot.addDataset(dataset);
        piePlot.renderTo(svg);

        let texts = svg.selectAll("text")[0].map((n: any) => d3.select(n).text());
        assert.lengthOf(texts, 2, "One label is rendered for each valid of data");
        assert.strictEqual(texts[0], "1", "Label for the first valid data is shown");
        assert.strictEqual(texts[1], "2", "Label for the second valid data is shown");
        svg.remove();
      });
    });

    describe("Rendering", () => {
      let svg: d3.Selection<void>;
      let simpleDataset: Plottable.Dataset;
      let simpleData: any[];
      let piePlot: Plottable.Plots.Pie;

      beforeEach(() => {
        svg = TestMethods.generateSVG(500, 500);
        simpleData = [{value: 5}, {value: 15}];
        simpleDataset = new Plottable.Dataset(simpleData);
        piePlot = new Plottable.Plots.Pie();
        piePlot.addDataset(simpleDataset);
        piePlot.sectorValue((d) => d.value);
        piePlot.renderTo(svg);
      });

      it("draws a fill path and a stroke path for each slice", () => {
        let arcPaths = piePlot.content().selectAll(".arc");
        let arcFillPaths = piePlot.content().selectAll(".arc.fill");
        let arcOutlinePaths = piePlot.content().selectAll(".arc.outline");
        assert.strictEqual(arcPaths.size(), simpleData.length * 2, "2 paths per datum");
        assert.strictEqual(arcFillPaths.size(), simpleData.length, "1 fill path per datum");
        assert.strictEqual(arcOutlinePaths.size(), simpleData.length, "1 outline path per datum");
        assert.strictEqual(arcFillPaths.style("stroke"), "none", "fill paths have no stroke");
        assert.strictEqual(arcOutlinePaths.style("fill"), "none", "outline paths have no fill");
        svg.remove();
      });

      it("draws slices proportional in angle to their value", () => {
        let arcPaths = piePlot.content().selectAll(".arc.fill");
        assert.lengthOf(arcPaths[0], 2, "only has two sectors");
        let arcPath0 = d3.select(arcPaths[0][0]);
        let pathPoints0 = TestMethods.normalizePath(arcPath0.attr("d")).split(/[A-Z]/).slice(1, 4);

        let firstPathPoints0 = pathPoints0[0].split(",");
        assert.closeTo(parseFloat(firstPathPoints0[0]), 0, 1, "draws line vertically at beginning");
        assert.operator(parseFloat(firstPathPoints0[1]), "<", 0, "draws line upwards");

        let arcDestPoint0 = pathPoints0[1].split(",").slice(5);
        assert.operator(parseFloat(arcDestPoint0[0]), ">", 0, "arcs line to the right");
        assert.closeTo(parseFloat(arcDestPoint0[1]), 0, 1, "ends on same level of svg");

        let secondPathPoints0 = pathPoints0[2].split(",");
        assert.closeTo(parseFloat(secondPathPoints0[0]), 0, 1, "draws line to origin");
        assert.closeTo(parseFloat(secondPathPoints0[1]), 0, 1, "draws line to origin");

        let arcPath1 = d3.select(arcPaths[0][1]);
        let pathPoints1 = TestMethods.normalizePath(arcPath1.attr("d")).split(/[A-Z]/).slice(1, 4);

        let firstPathPoints1 = pathPoints1[0].split(",");
        assert.operator(parseFloat(firstPathPoints1[0]), ">", 0, "draws line to the right");
        assert.closeTo(parseFloat(firstPathPoints1[1]), 0, 1, "draws line horizontally");

        let arcDestPoint1 = pathPoints1[1].split(",").slice(5);
        assert.closeTo(parseFloat(arcDestPoint1[0]), 0, 1, "ends at x origin");
        assert.operator(parseFloat(arcDestPoint1[1]), "<", 0, "ends above 0");

        let secondPathPoints1 = pathPoints1[2].split(",");
        assert.closeTo(parseFloat(secondPathPoints1[0]), 0, 1, "draws line to origin");
        assert.closeTo(parseFloat(secondPathPoints1[1]), 0, 1, "draws line to origin");
        svg.remove();
      });

      it("uses a plottable-colors color scale to color sectors by default", () => {
        let arcPaths = piePlot.content().selectAll(".arc");

        let arcPath0 = d3.select(arcPaths[0][0]);
        assert.strictEqual(arcPath0.attr("fill"), "#5279c7", "first sector filled appropriately");

        let arcPath1 = d3.select(arcPaths[0][1]);
        assert.strictEqual(arcPath1.attr("fill"), "#fd373e", "second sector filled appropriately");
        svg.remove();
      });

      it("updates slices when data changes", () => {
        let originalPathStrings: String[] = [];
        piePlot.content().selectAll("path").each(function() { originalPathStrings.push(d3.select(this).attr("d")); });
        assert.lengthOf(originalPathStrings, simpleData.length * 2, "2 paths per datum");

        let oneMoreSliceData = simpleData.slice();
        oneMoreSliceData.push({ value: 5 });
        simpleDataset.data(oneMoreSliceData);

        let oneMoreSlicePathStrings: String[] = [];
        piePlot.content().selectAll("path").each(function() { oneMoreSlicePathStrings.push(d3.select(this).attr("d")); });
        assert.lengthOf(oneMoreSlicePathStrings, oneMoreSliceData.length * 2, "2 paths per datum");

        originalPathStrings.forEach((pathString, index) => {
          assert.notStrictEqual(pathString, oneMoreSlicePathStrings[index], "slices were updated when data changed");
        });
        svg.remove();
      });

      it("can set innerRadius", () => {
        let expectedInnerRadius = 5;
        piePlot.innerRadius(expectedInnerRadius);
        let arcPaths = piePlot.content().selectAll(".arc.fill");
        assert.lengthOf(arcPaths[0], 2, "only has two sectors");

        let pathPoints0 = TestMethods.normalizePath(d3.select(arcPaths[0][0]).attr("d")).split(/[A-Z]/).slice(1, 5);

        let radiusPath0 = pathPoints0[2].split(",").map((coordinate: string) => parseFloat(coordinate));
        assert.closeTo(radiusPath0[0], expectedInnerRadius, 1, "stops line at innerRadius point");
        assert.closeTo(radiusPath0[1], 0, 1, "stops line at innerRadius point");

        let innerArcPath0 = pathPoints0[3].split(",").map((coordinate: string) => parseFloat(coordinate));
        assert.closeTo(innerArcPath0[0], expectedInnerRadius, 1, "makes inner arc of correct radius");
        assert.closeTo(innerArcPath0[1], expectedInnerRadius, 1, "makes inner arc of correct radius");
        assert.closeTo(innerArcPath0[5], 0, 1, "make inner arc to center");
        assert.closeTo(innerArcPath0[6], -expectedInnerRadius, 1, "makes inner arc to top of inner circle");

        svg.remove();
      });

      it("can set outerRadius", () => {
        let expectedOuterRadius = 150;
        piePlot.outerRadius(() => expectedOuterRadius);
        let arcPaths = piePlot.content().selectAll(".arc.fill");
        assert.lengthOf(arcPaths[0], 2, "only has two sectors");

        let pathPoints0 = TestMethods.normalizePath(d3.select(arcPaths[0][0]).attr("d")).split(/[A-Z]/).slice(1, 5);

        let radiusPath0 = pathPoints0[0].split(",").map((coordinate: string) => parseFloat(coordinate));
        assert.closeTo(radiusPath0[0], 0, 1, "starts at outerRadius point");
        assert.closeTo(radiusPath0[1], -expectedOuterRadius, 1, "starts at outerRadius point");

        let outerArcPath0 = pathPoints0[1].split(",").map((coordinate: string) => parseFloat(coordinate));
        assert.closeTo(outerArcPath0[0], expectedOuterRadius, 1, "makes outer arc of correct radius");
        assert.closeTo(outerArcPath0[1], expectedOuterRadius, 1, "makes outer arc of correct radius");
        assert.closeTo(outerArcPath0[5], expectedOuterRadius, 1, "makes outer arc to right edge");
        assert.closeTo(outerArcPath0[6], 0, 1, "makes outer arc to right edge");
<commit_msg>[Plots.Pie test refactor] Move "Rendering" describe to top of file<commit_after>///<reference path="../testReference.ts" />

describe("Plots", () => {
  describe("PiePlot", () => {
    describe("Rendering", () => {
      let svg: d3.Selection<void>;
      let simpleDataset: Plottable.Dataset;
      let simpleData: any[];
      let piePlot: Plottable.Plots.Pie;

      beforeEach(() => {
        svg = TestMethods.generateSVG(500, 500);
        simpleData = [{value: 5}, {value: 15}];
        simpleDataset = new Plottable.Dataset(simpleData);
        piePlot = new Plottable.Plots.Pie();
        piePlot.addDataset(simpleDataset);
        piePlot.sectorValue((d) => d.value);
        piePlot.renderTo(svg);
      });

      it("draws a fill path and a stroke path for each slice", () => {
        let arcPaths = piePlot.content().selectAll(".arc");
        let arcFillPaths = piePlot.content().selectAll(".arc.fill");
        let arcOutlinePaths = piePlot.content().selectAll(".arc.outline");
        assert.strictEqual(arcPaths.size(), simpleData.length * 2, "2 paths per datum");
        assert.strictEqual(arcFillPaths.size(), simpleData.length, "1 fill path per datum");
        assert.strictEqual(arcOutlinePaths.size(), simpleData.length, "1 outline path per datum");
        assert.strictEqual(arcFillPaths.style("stroke"), "none", "fill paths have no stroke");
        assert.strictEqual(arcOutlinePaths.style("fill"), "none", "outline paths have no fill");
        svg.remove();
      });

      it("draws slices proportional in angle to their value", () => {
        let arcPaths = piePlot.content().selectAll(".arc.fill");
        assert.lengthOf(arcPaths[0], 2, "only has two sectors");
        let arcPath0 = d3.select(arcPaths[0][0]);
        let pathPoints0 = TestMethods.normalizePath(arcPath0.attr("d")).split(/[A-Z]/).slice(1, 4);

        let firstPathPoints0 = pathPoints0[0].split(",");
        assert.closeTo(parseFloat(firstPathPoints0[0]), 0, 1, "draws line vertically at beginning");
        assert.operator(parseFloat(firstPathPoints0[1]), "<", 0, "draws line upwards");

        let arcDestPoint0 = pathPoints0[1].split(",").slice(5);
        assert.operator(parseFloat(arcDestPoint0[0]), ">", 0, "arcs line to the right");
        assert.closeTo(parseFloat(arcDestPoint0[1]), 0, 1, "ends on same level of svg");

        let secondPathPoints0 = pathPoints0[2].split(",");
        assert.closeTo(parseFloat(secondPathPoints0[0]), 0, 1, "draws line to origin");
        assert.closeTo(parseFloat(secondPathPoints0[1]), 0, 1, "draws line to origin");

        let arcPath1 = d3.select(arcPaths[0][1]);
        let pathPoints1 = TestMethods.normalizePath(arcPath1.attr("d")).split(/[A-Z]/).slice(1, 4);

        let firstPathPoints1 = pathPoints1[0].split(",");
        assert.operator(parseFloat(firstPathPoints1[0]), ">", 0, "draws line to the right");
        assert.closeTo(parseFloat(firstPathPoints1[1]), 0, 1, "draws line horizontally");

        let arcDestPoint1 = pathPoints1[1].split(",").slice(5);
        assert.closeTo(parseFloat(arcDestPoint1[0]), 0, 1, "ends at x origin");
        assert.operator(parseFloat(arcDestPoint1[1]), "<", 0, "ends above 0");

        let secondPathPoints1 = pathPoints1[2].split(",");
        assert.closeTo(parseFloat(secondPathPoints1[0]), 0, 1, "draws line to origin");
        assert.closeTo(parseFloat(secondPathPoints1[1]), 0, 1, "draws line to origin");
        svg.remove();
      });

      it("uses a plottable-colors color scale to color sectors by default", () => {
        let arcPaths = piePlot.content().selectAll(".arc");

        let arcPath0 = d3.select(arcPaths[0][0]);
        assert.strictEqual(arcPath0.attr("fill"), "#5279c7", "first sector filled appropriately");

        let arcPath1 = d3.select(arcPaths[0][1]);
        assert.strictEqual(arcPath1.attr("fill"), "#fd373e", "second sector filled appropriately");
        svg.remove();
      });

      it("updates slices when data changes", () => {
        let originalPathStrings: String[] = [];
        piePlot.content().selectAll("path").each(function() { originalPathStrings.push(d3.select(this).attr("d")); });
        assert.lengthOf(originalPathStrings, simpleData.length * 2, "2 paths per datum");

        let oneMoreSliceData = simpleData.slice();
        oneMoreSliceData.push({ value: 5 });
        simpleDataset.data(oneMoreSliceData);

        let oneMoreSlicePathStrings: String[] = [];
        piePlot.content().selectAll("path").each(function() { oneMoreSlicePathStrings.push(d3.select(this).attr("d")); });
        assert.lengthOf(oneMoreSlicePathStrings, oneMoreSliceData.length * 2, "2 paths per datum");

        originalPathStrings.forEach((pathString, index) => {
          assert.notStrictEqual(pathString, oneMoreSlicePathStrings[index], "slices were updated when data changed");
        });
        svg.remove();
      });

      it("can set innerRadius", () => {
        let expectedInnerRadius = 5;
        piePlot.innerRadius(expectedInnerRadius);
        let arcPaths = piePlot.content().selectAll(".arc.fill");
        assert.lengthOf(arcPaths[0], 2, "only has two sectors");

        let pathPoints0 = TestMethods.normalizePath(d3.select(arcPaths[0][0]).attr("d")).split(/[A-Z]/).slice(1, 5);

        let radiusPath0 = pathPoints0[2].split(",").map((coordinate: string) => parseFloat(coordinate));
        assert.closeTo(radiusPath0[0], expectedInnerRadius, 1, "stops line at innerRadius point");
        assert.closeTo(radiusPath0[1], 0, 1, "stops line at innerRadius point");

        let innerArcPath0 = pathPoints0[3].split(",").map((coordinate: string) => parseFloat(coordinate));
        assert.closeTo(innerArcPath0[0], expectedInnerRadius, 1, "makes inner arc of correct radius");
        assert.closeTo(innerArcPath0[1], expectedInnerRadius, 1, "makes inner arc of correct radius");
        assert.closeTo(innerArcPath0[5], 0, 1, "make inner arc to center");
        assert.closeTo(innerArcPath0[6], -expectedInnerRadius, 1, "makes inner arc to top of inner circle");

        svg.remove();
      });

      it("can set outerRadius", () => {
        let expectedOuterRadius = 150;
        piePlot.outerRadius(() => expectedOuterRadius);
        let arcPaths = piePlot.content().selectAll(".arc.fill");
        assert.lengthOf(arcPaths[0], 2, "only has two sectors");

        let pathPoints0 = TestMethods.normalizePath(d3.select(arcPaths[0][0]).attr("d")).split(/[A-Z]/).slice(1, 5);

        let radiusPath0 = pathPoints0[0].split(",").map((coordinate: string) => parseFloat(coordinate));
        assert.closeTo(radiusPath0[0], 0, 1, "starts at outerRadius point");
        assert.closeTo(radiusPath0[1], -expectedOuterRadius, 1, "starts at outerRadius point");

        let outerArcPath0 = pathPoints0[1].split(",").map((coordinate: string) => parseFloat(coordinate));
        assert.closeTo(outerArcPath0[0], expectedOuterRadius, 1, "makes outer arc of correct radius");
        assert.closeTo(outerArcPath0[1], expectedOuterRadius, 1, "makes outer arc of correct radius");
        assert.closeTo(outerArcPath0[5], expectedOuterRadius, 1, "makes outer arc to right edge");
        assert.closeTo(outerArcPath0[6], 0, 1, "makes outer arc to right edge");

        svg.remove();
      });
    });

    describe("Labels", () => {
      let svg: d3.Selection<void>;
      let piePlot: Plottable.Plots.Pie;

      beforeEach(() => {
        svg = TestMethods.generateSVG(500, 500);
        piePlot = new Plottable.Plots.Pie();
        piePlot.sectorValue((d) => d.value);
        piePlot.labelsEnabled(true);
      });

      it("does not erase or add labels when rendered twice", () => {
        let data = [
          { value: 1 },
          { value: 2 },
          { value: 3 }
        ];
        let dataset = new Plottable.Dataset(data);
        piePlot.addDataset(dataset);
        piePlot.renderTo(svg);
        let labels = piePlot.content().selectAll("text");
        assert.strictEqual(labels.size(), data.length, "one label per slice");
        piePlot.render();
        labels = piePlot.content().selectAll("text");
        assert.strictEqual(labels.size(), data.length, "one label per slice after re-render()ing");
        svg.remove();
      });

      it("updates labels when data changes", () => {
        let data1 = [
          { value: 1 },
          { value: 1 },
          { value: 1 }
        ];
        let dataset = new Plottable.Dataset(data1);
        piePlot.addDataset(dataset);
        piePlot.renderTo(svg);
        let labels = piePlot.content().selectAll("text");
        assert.strictEqual(labels.size(), data1.length, "one label per datum");
        labels.each(function() {
          let labelText = d3.select(this).text();
          assert.strictEqual(labelText, "1", "label has correct text");
        });
        let data2 = [
          { value: 2 },
          { value: 2 }
        ];
        dataset.data(data2);
        labels = piePlot.content().selectAll("text");
        assert.strictEqual(labels.size(), data2.length, "one label per datum");
        labels.each(function() {
          let labelText = d3.select(this).text();
          assert.strictEqual(labelText, "2", "label text was updated");
        });
        svg.remove();
      });

      it("removes labels when they are disabled after rendering", () => {
        let data1 = [
          { value: 1 },
          { value: 1 },
          { value: 1 }
        ];
        let dataset = new Plottable.Dataset(data1);
        piePlot.addDataset(dataset);
        piePlot.renderTo(svg);
        let labels = piePlot.content().selectAll("text");
        assert.strictEqual(labels.size(), data1.length, "one label per datum");
        piePlot.labelsEnabled(false);
        labels = piePlot.content().selectAll("text");
        assert.strictEqual(labels.size(), 0, "labels were removed");
        svg.remove();
      });

      it("hides labels if slices are too small", () => {
        let data = [
          { key: "A", value: 1 }, { key: "B", value: 50 },
          { key: "C", value: 1 }, { key: "D", value: 50 },
          { key: "E", value: 1 }, { key: "F", value: 50 }
        ];
        let dataset = new Plottable.Dataset(data);
        piePlot.addDataset(dataset);
        piePlot.renderTo(svg);
        let labelGs = piePlot.content().select(".label-area").selectAll(".label-area > g");
        labelGs.each(function(d, i) {
          let visibility = d3.select(this).style("visibility");
          if (data[i].value === 1) {
            assert.strictEqual(visibility, "hidden", "label hidden when slice is too small");
          } else {
            assert.include(["visible", "inherit"], visibility, "label shown when slice is appropriately sized");
          }
        });
        svg.remove();
      });

      it("uses its formatter to format labels", () => {
        let data = [
          { value: 5 },
          { value: 15 }
        ];
        let dataset = new Plottable.Dataset(data);
        piePlot.addDataset(dataset);
        piePlot.labelFormatter((n: number) => n + " m");
        piePlot.renderTo(svg);
        let texts = svg.selectAll("text")[0].map((n: any) => d3.select(n).text());
        assert.lengthOf(texts, 2, "both labels are drawn");
        assert.strictEqual(texts[0], "5 m", "The formatter was used to format the first label");
        assert.strictEqual(texts[1], "15 m", "The formatter was used to format the second label");
        svg.remove();
      });

      it("hides labels if they don't fit", () => {
        let data = [
          { value: 1 }, { value: 50 },
          { value: 1 }, { value: 50 },
          { value: 1 }, { value: 50 }
        ];
        let dataset = new Plottable.Dataset(data);
        piePlot.addDataset(dataset);
        piePlot.renderTo(svg);

        let texts = svg.selectAll("text");
        assert.strictEqual(texts.size(), data.length, "One label is rendered for each piece of data");

        texts.each(function(d, i) {
          let visibility = d3.select(this).style("visibility");
          if (i % 2 === 0) {
            assert.strictEqual(visibility, "hidden", "label hidden when slice is too small");
          } else {
            assert.include(["visible", "inherit"], visibility, "label shown when slice is appropriately sized");
          }
        });

        svg.remove();
      });

      it("hides labels outside of the render area", () => {
        let data = [
          { value: 5000 },
          { value: 5000 },
          { value: 5000 }];
        let dataset = new Plottable.Dataset(data);
        piePlot.addDataset(dataset).outerRadius(500);
        piePlot.renderTo(svg);

        let texts = svg.selectAll("text");
        assert.strictEqual(texts.size(), data.length, "One label is rendered for each piece of data");

        texts.each(function(d, i) {
          let visibility = d3.select(this).style("visibility");
          if (i === 1) {
            assert.strictEqual(visibility, "hidden", "label hidden when cut off by the lower margin");
          } else {
            assert.include(["visible", "inherit"], visibility, "label shown when in the renderArea");
          }
        });
        svg.remove();
      });

      it("does not show labels for invalid data", () => {
        let data = [
          { value: 1 },
          { value: "value" },
          { value: 2 }];
        let dataset = new Plottable.Dataset(data);
        piePlot.addDataset(dataset);
        piePlot.renderTo(svg);

        let texts = svg.selectAll("text")[0].map((n: any) => d3.select(n).text());
        assert.lengthOf(texts, 2, "One label is rendered for each valid of data");
        assert.strictEqual(texts[0], "1", "Label for the first valid data is shown");
        assert.strictEqual(texts[1], "2", "Label for the second valid data is shown");
{'fraction_non_alphanumeric': 0.15604968674175207, 'fraction_numerical': 0.020714880672147176, 'mean_word_length': 2.7050852005903665, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 77, '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': '6116310', 'n_tokens_mistral': 8547, 'n_tokens_neox': 8077, 'n_words': 1921}