Skip to content

Commit f7072ac

Browse files
authored
fix issue #235 (#239)
* fix issue 235
1 parent d1bf0c3 commit f7072ac

File tree

6 files changed

+60
-11
lines changed

6 files changed

+60
-11
lines changed

lib/helpers/replace.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
function convertible(value) {
2+
if (value === undefined) return "";
3+
if (value === null) return "";
4+
if (typeof value.toString === "function") return value;
5+
return typeof value;
6+
}
7+
8+
module.exports = (string, searchValue, newValue) => string.replace(searchValue, convertible(newValue));

lib/validator.js

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ try {
55
AsyncFunction = (new Function("return Object.getPrototypeOf(async function(){}).constructor"))();
66
} catch(err) { /* async is not supported */}
77

8-
//const flatten = require("./helpers/flatten");
98
const deepExtend = require("./helpers/deep-extend");
9+
const replace = require("./helpers/replace");
1010

1111
function loadMessages() {
1212
return Object.assign({} , require("./messages"));
@@ -167,7 +167,10 @@ class Validator {
167167
async: schema.$$async === true,
168168
rules: [],
169169
fn: [],
170-
customs: {}
170+
customs: {},
171+
utils: {
172+
replace,
173+
},
171174
};
172175
this.cache.clear();
173176
delete schema.$$async;
@@ -205,11 +208,11 @@ class Validator {
205208
sourceCode.push("if (errors.length) {");
206209
sourceCode.push(`
207210
return errors.map(err => {
208-
if (err.message)
209-
err.message = err.message
210-
.replace(/\\{field\\}/g, err.field || "")
211-
.replace(/\\{expected\\}/g, err.expected != null ? err.expected : "")
212-
.replace(/\\{actual\\}/g, err.actual != null ? err.actual : "");
211+
if (err.message) {
212+
err.message = context.utils.replace(err.message, /\\{field\\}/g, err.field);
213+
err.message = context.utils.replace(err.message, /\\{expected\\}/g, err.expected);
214+
err.message = context.utils.replace(err.message, /\\{actual\\}/g, err.actual);
215+
}
213216
214217
return err;
215218
});

test/helpers/replace.spec.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
const replace = require("../../lib/helpers/replace");
2+
3+
describe("replace", () => {
4+
it("should replace string", () => {
5+
expect(replace("foo bar", "foo", "zoo")).toBe("zoo bar");
6+
});
7+
8+
it("should replace if newValue is null or undefined", () => {
9+
expect(replace("foo bar", "foo", undefined)).toBe(" bar");
10+
expect(replace("foo bar", "foo", null)).toBe(" bar");
11+
});
12+
13+
it("should replace if newValue has valid toString prototype", () => {
14+
expect(replace("foo bar", "foo", { a: "b" })).toBe("[object Object] bar");
15+
expect(replace("foo bar", "foo", ["a", "b"])).toBe("a,b bar");
16+
});
17+
18+
it("should replace if newValue has invalid toString prototype", () => {
19+
expect(replace("foo bar", "foo", { toString: 1 })).toBe("object bar");
20+
});
21+
});

test/integration.spec.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1285,3 +1285,20 @@ describe("Test context meta", () => {
12851285
expect(obj).toEqual({ name: "from-meta" });
12861286
});
12871287
});
1288+
1289+
describe("edge cases", () => {
1290+
const v = new Validator({ useNewCustomCheckerFunction: true });
1291+
1292+
it("issue #235 bug", () => {
1293+
const schema = { name: { type: "string" } };
1294+
const check = v.compile(schema);
1295+
expect(check({ name: { toString: 1 } })).toEqual([
1296+
{
1297+
actual: { toString: 1 },
1298+
field: "name",
1299+
message: "The 'name' field must be a string.",
1300+
type: "string",
1301+
},
1302+
]);
1303+
});
1304+
});

test/typescript/validator.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,13 +116,13 @@ describe('TypeScript Definitions', () => {
116116

117117
check = v.compile(schema);
118118

119-
const context = {
119+
const context = expect.objectContaining({
120120
customs: expect.any(Object),
121121
rules: expect.any(Array),
122122
fn: expect.any(Array),
123123
index: 2,
124124
async: false
125-
};
125+
});
126126

127127
expect(validFn).toHaveBeenCalledTimes(1);
128128
expect(validFn).toHaveBeenCalledWith(expect.any(Object), 'a', context);

test/validator.spec.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -154,13 +154,13 @@ describe("Test add", () => {
154154

155155
check = v.compile(schema);
156156

157-
const context = {
157+
const context = expect.objectContaining({
158158
customs: expect.any(Object),
159159
rules: expect.any(Array),
160160
fn: expect.any(Array),
161161
index: 2,
162162
async: false
163-
};
163+
});
164164

165165

166166
expect(validFn).toHaveBeenCalledTimes(1);

0 commit comments

Comments
 (0)