Skip to content

Commit b4046aa

Browse files
committed
Fail validation of counter and quantity if value is not int
1 parent 6da8fad commit b4046aa

File tree

4 files changed

+33
-4
lines changed

4 files changed

+33
-4
lines changed

glean/src/core/metrics/types/counter.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import type { CommonMetricData } from "../index.js";
66
import type { JSONValue } from "../../utils.js";
77
import { MetricType } from "../index.js";
8-
import { isUndefined, isNumber } from "../../utils.js";
8+
import { isUndefined, isInteger } from "../../utils.js";
99
import { Context } from "../../context.js";
1010
import { Metric } from "../metric.js";
1111
import { ErrorType, recordError, testGetNumRecordedErrors } from "../../error_recording.js";
@@ -16,7 +16,7 @@ export class CounterMetric extends Metric<number, number> {
1616
}
1717

1818
validate(v: unknown): v is number {
19-
if (!isNumber(v)) {
19+
if (!isInteger(v)) {
2020
return false;
2121
}
2222

glean/src/core/metrics/types/quantity.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
import type { CommonMetricData } from "../index.js";
66
import { MetricType } from "../index.js";
7-
import { isNumber } from "../../utils.js";
7+
import { isInteger } from "../../utils.js";
88
import { Context } from "../../context.js";
99
import { Metric } from "../metric.js";
1010
import { ErrorType, recordError, testGetNumRecordedErrors } from "../../error_recording.js";
@@ -15,7 +15,7 @@ export class QuantityMetric extends Metric<number, number> {
1515
}
1616

1717
validate(v: unknown): v is number {
18-
if (!isNumber(v)) {
18+
if (!isInteger(v)) {
1919
return false;
2020
}
2121

glean/src/core/utils.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,21 @@ export function isNumber(v: unknown): v is number {
101101
return ((typeof v === "number" || (typeof v === "object" && v !== null && v.constructor === Number)) && !isNaN(v));
102102
}
103103

104+
/**
105+
* Checks whether or not `v` is an integer.
106+
*
107+
* @param v The value to verify.
108+
*
109+
* @returns A special Typescript value (which compiles down to a boolean)
110+
* stating whether `v` is a number.
111+
*/
112+
export function isInteger(v: unknown): v is number {
113+
// Decided against using `Number.isInteger` here,
114+
// because that fails if you pass it a number created through `new Number(...)`.
115+
return isNumber(v) && v % 1 === 0;
116+
}
117+
118+
104119
/**
105120
* Generates a pipeline-friendly string
106121
* that replaces non alphanumeric characters with dashes.

glean/tests/core/utils.spec.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,20 @@ describe("utils", function() {
7979
assert.strictEqual(utils.isNumber(new Number(10)), true);
8080
});
8181

82+
it("isInteger validates correctly", function() {
83+
// Invalid values
84+
assert.strictEqual(utils.isInteger(undefined), false);
85+
assert.strictEqual(utils.isInteger("10"), false);
86+
assert.strictEqual(utils.isInteger({}), false);
87+
assert.strictEqual(utils.isInteger(NaN), false);
88+
assert.strictEqual(utils.isInteger(0.1), false);
89+
90+
// Valid values
91+
assert.strictEqual(utils.isInteger(10), true);
92+
assert.strictEqual(utils.isInteger(-10), true);
93+
assert.strictEqual(utils.isInteger(new Number(10)), true);
94+
});
95+
8296
it("sanitizeApplicationId works correctly", function() {
8397
assert.strictEqual(utils.sanitizeApplicationId("org.mozilla.test-app"), "org-mozilla-test-app");
8498
assert.strictEqual(utils.sanitizeApplicationId("org.mozilla..test---app"), "org-mozilla-test-app");

0 commit comments

Comments
 (0)