Repository: jquense/yup
Pull request #456 (2019-02-10 10:59:21)

feat: allow withMutation() nesting
Number 3 from #454

```js
mixed().withMutation(schema => {
  schema.withMutation(changeA);
  changeB(schema);
}); // now changeB gets mutable instance
```


Patch:
diff --git a/src/mixed.js b/src/mixed.js
index 27f781c..2e4824a 100644
--- a/src/mixed.js
+++ b/src/mixed.js
@@ -96,9 +96,10 @@ const proto = (SchemaType.prototype = {
   },
 
   withMutation(fn) {
+    let before = this._mutate;
     this._mutate = true;
     let result = fn(this);
-    this._mutate = false;
+    this._mutate = before;
     return result;
   },
 
@@ -296,9 +297,9 @@ const proto = (SchemaType.prototype = {
     return next;
   },
 
-  strict() {
+  strict(isStrict = true) {
     var next = this.clone();
-    next._options.strict = true;
+    next._options.strict = isStrict;
     return next;
   },
 
@@ -312,9 +313,9 @@ const proto = (SchemaType.prototype = {
     return next;
   },
 
-  nullable(value) {
+  nullable(isNullable = true) {
     var next = this.clone();
-    next._nullable = value === false ? false : true;
+    next._nullable = isNullable;
     return next;
   },
 
@@ -512,3 +513,4 @@ for (const method of ['validate', 'validateSync'])
 
 for (const alias of ['equals', 'is']) proto[alias] = proto.oneOf;
 for (const alias of ['not', 'nope']) proto[alias] = proto.notOneOf;
+proto.optional = proto.notRequired;
diff --git a/src/object.js b/src/object.js
index 417e83b..fdd5110 100644
--- a/src/object.js
+++ b/src/object.js
@@ -245,6 +245,10 @@ inherits(ObjectSchema, MixedSchema, {
     return next;
   },
 
+  unknown(allow = true, message = locale.noUnknown) {
+    return this.noUnknown(!allow, message);
+  },
+
   transformKeys(fn) {
     return this.transform(obj => obj && mapKeys(obj, (_, key) => fn(key)));
   },


Test patch:
diff --git a/test/mixed.js b/test/mixed.js
index c012857..2c62038 100644
--- a/test/mixed.js
+++ b/test/mixed.js
@@ -521,6 +521,55 @@ describe('Mixed Types ', () => {
       });
   });
 
+  describe('withMutation', () => {
+    it('should pass the same instance to a provided function', () => {
+      let inst = mixed();
+      let func = sinon.spy();
+
+      inst.withMutation(func);
+
+      func.should.have.been.calledOnceWithExactly(inst);
+    });
+
+    it('should temporarily make mutable', () => {
+      let inst = mixed();
+
+      let update = () => {
+        inst.withMutation(inst => {
+          inst.test('a', () => true);
+        });
+      };
+
+      update.should.increase(() => inst.tests.length).by(1);
+    });
+
+    it('should return immutability', () => {
+      let inst = mixed();
+      inst.withMutation(() => {});
+
+      let update = () => {
+        inst.test('a', () => true);
+      };
+
+      update.should.not.increase(() => inst.tests.length);
+    });
+
+    it('should work with nesting', () => {
+      let inst = mixed();
+
+      let update = () => {
+        inst.withMutation(inst => {
+          inst.withMutation(inst => {
+            inst.test('a', () => true);
+          });
+          inst.test('b', () => true);
+        });
+      };
+
+      update.should.increase(() => inst.tests.length).by(2);
+    });
+  });
+
   describe('concat', () => {
     let next;
     let inst = object({