Ver Fonte

Isolator >> model:modify:

Herbert Vojčík há 12 anos atrás
pai
commit
7bda352d85
6 ficheiros alterados com 558 adições e 0 exclusões
  1. 201 0
      js/Trapped-Tests.deploy.js
  2. 241 0
      js/Trapped-Tests.js
  3. 13 0
      js/Trapped.deploy.js
  4. 18 0
      js/Trapped.js
  5. 78 0
      st/Trapped-Tests.st
  6. 7 0
      st/Trapped.st

+ 201 - 0
js/Trapped-Tests.deploy.js

@@ -19,6 +19,70 @@ return self}
 }),
 smalltalk.IsolatorTest);
 
+smalltalk.addMethod(
+"_testNontrivialModelGetsAppropriateValueForModification",
+smalltalk.method({
+selector: "testNontrivialModelGetsAppropriateValueForModification",
+fn: function (){
+var self=this;
+var $1,$2;
+var bb;
+var model;
+var result;
+bb=smalltalk.send((smalltalk.Isolator || Isolator),"_on_",[smalltalk.HashedCollection._fromPairs_([smalltalk.send("foo","__minus_gt",[["bar", [(1), [(2), (5)]], "baz"]]),smalltalk.send("moo","__minus_gt",["zoo"])])]);
+$1=smalltalk.send((smalltalk.EavModel || EavModel),"_new",[]);
+smalltalk.send($1,"_getBlock_",[(function(x){
+return smalltalk.send(smalltalk.send(smalltalk.send(x,"_root",[]),"_at_",["foo"]),"_at_",[(2)]);
+})]);
+$2=smalltalk.send($1,"_putBlock_",[(function(x,y){
+return smalltalk.send(smalltalk.send(smalltalk.send(x,"_root",[]),"_at_",["foo"]),"_at_put_",[(2),y]);
+})]);
+model=$2;
+smalltalk.send(bb,"_model_modify_",[model,(function(r){
+result=r;
+return result;
+})]);
+smalltalk.send(self,"_assert_equals_",[[(1), [(2), (5)]],result]);
+return self}
+}),
+smalltalk.IsolatorTest);
+
+smalltalk.addMethod(
+"_testNontrivialModelModifiesAppropriateValue",
+smalltalk.method({
+selector: "testNontrivialModelModifiesAppropriateValue",
+fn: function (){
+var self=this;
+var $1,$2;
+var bb;
+var model;
+var result;
+bb=smalltalk.send((smalltalk.Isolator || Isolator),"_on_",[smalltalk.HashedCollection._fromPairs_([smalltalk.send("foo","__minus_gt",[["bar", [(1), [(2), (3)]], "baz"]]),smalltalk.send("moo","__minus_gt",["zoo"])])]);
+$1=smalltalk.send((smalltalk.EavModel || EavModel),"_new",[]);
+smalltalk.send($1,"_getBlock_",[(function(x){
+return smalltalk.send(smalltalk.send(smalltalk.send(x,"_root",[]),"_at_",["foo"]),"_at_",[(2)]);
+})]);
+$2=smalltalk.send($1,"_putBlock_",[(function(x,y){
+return smalltalk.send(smalltalk.send(smalltalk.send(x,"_root",[]),"_at_",["foo"]),"_at_put_",[(2),y]);
+})]);
+model=$2;
+smalltalk.send(bb,"_model_modify_",[model,(function(r){
+return smalltalk.symbolFor("new");
+})]);
+smalltalk.send(bb,"_model_read_",[model,(function(r){
+result=r;
+return result;
+})]);
+smalltalk.send(self,"_assert_equals_",[smalltalk.symbolFor("new"),result]);
+smalltalk.send(bb,"_model_read_",[self["@rootModel"],(function(r){
+result=r;
+return result;
+})]);
+smalltalk.send(self,"_assert_equals_",[smalltalk.HashedCollection._fromPairs_([smalltalk.send("foo","__minus_gt",[["bar", smalltalk.symbolFor("new"), "baz"]]),smalltalk.send("moo","__minus_gt",["zoo"])]),result]);
+return self}
+}),
+smalltalk.IsolatorTest);
+
 smalltalk.addMethod(
 "_testNontrivialModelReturnsAppropriateValue",
 smalltalk.method({
@@ -41,6 +105,143 @@ return self}
 }),
 smalltalk.IsolatorTest);
 
+smalltalk.addMethod(
+"_testRootModelExaminesThenModifiesRoot",
+smalltalk.method({
+selector: "testRootModelExaminesThenModifiesRoot",
+fn: function (){
+var self=this;
+var bb;
+var result;
+bb=smalltalk.send((smalltalk.Isolator || Isolator),"_on_",[[(1), [(2), (3)]]]);
+smalltalk.send(bb,"_model_modify_",[self["@rootModel"],(function(r){
+return smalltalk.send(r,"_second",[]);
+})]);
+smalltalk.send(bb,"_model_read_",[self["@rootModel"],(function(r){
+result=r;
+return result;
+})]);
+smalltalk.send(self,"_assert_equals_",[[(2), (3)],result]);
+return self}
+}),
+smalltalk.IsolatorTest);
+
+smalltalk.addMethod(
+"_testRootModelGetsRootForModification",
+smalltalk.method({
+selector: "testRootModelGetsRootForModification",
+fn: function (){
+var self=this;
+var bb;
+var result;
+bb=smalltalk.send((smalltalk.Isolator || Isolator),"_on_",[[(2), [(1), (0)]]]);
+smalltalk.send(bb,"_model_modify_",[self["@rootModel"],(function(r){
+result=r;
+return result;
+})]);
+smalltalk.send(self,"_assert_equals_",[[(2), [(1), (0)]],result]);
+return self}
+}),
+smalltalk.IsolatorTest);
+
+smalltalk.addMethod(
+"_testRootModelModifiesAndDeeplyIsolatesInPlaceModifiedRoot",
+smalltalk.method({
+selector: "testRootModelModifiesAndDeeplyIsolatesInPlaceModifiedRoot",
+fn: function (){
+var self=this;
+var bb;
+var result;
+var newValue;
+bb=smalltalk.send((smalltalk.Isolator || Isolator),"_on_",[[(1), [(2), (3)]]]);
+smalltalk.send(bb,"_model_modify_",[self["@rootModel"],(function(r){
+newValue=r;
+newValue;
+smalltalk.send(r,"_at_put_",[(1),(4)]);
+return r;
+})]);
+smalltalk.send(newValue,"_at_put_",[(2),"bar"]);
+smalltalk.send(bb,"_model_read_",[self["@rootModel"],(function(r){
+result=r;
+return result;
+})]);
+smalltalk.send(newValue,"_at_put_",[(2),"baz"]);
+smalltalk.send(self,"_assert_equals_",[[(4), [(2), (3)]],result]);
+return self}
+}),
+smalltalk.IsolatorTest);
+
+smalltalk.addMethod(
+"_testRootModelModifiesAndDeeplyIsolatesRoot",
+smalltalk.method({
+selector: "testRootModelModifiesAndDeeplyIsolatesRoot",
+fn: function (){
+var self=this;
+var bb;
+var result;
+var newValue;
+bb=smalltalk.send((smalltalk.Isolator || Isolator),"_on_",[[(1), [(2), (3)]]]);
+newValue=smalltalk.HashedCollection._fromPairs_([smalltalk.send("foo","__minus_gt",[[(4), (5), (6)]])]);
+smalltalk.send(bb,"_model_modify_",[self["@rootModel"],(function(r){
+return newValue;
+})]);
+smalltalk.send(smalltalk.send(newValue,"_at_",["foo"]),"_at_put_",[(1),"bar"]);
+smalltalk.send(bb,"_model_read_",[self["@rootModel"],(function(r){
+result=r;
+return result;
+})]);
+smalltalk.send(smalltalk.send(newValue,"_at_",["foo"]),"_at_put_",[(3),"baz"]);
+smalltalk.send(self,"_assert_equals_",[smalltalk.HashedCollection._fromPairs_([smalltalk.send("foo","__minus_gt",[[(4), (5), (6)]])]),result]);
+return self}
+}),
+smalltalk.IsolatorTest);
+
+smalltalk.addMethod(
+"_testRootModelModifiesAndIsolatesRoot",
+smalltalk.method({
+selector: "testRootModelModifiesAndIsolatesRoot",
+fn: function (){
+var self=this;
+var bb;
+var result;
+var newValue;
+bb=smalltalk.send((smalltalk.Isolator || Isolator),"_on_",[[(1), [(2), (3)]]]);
+newValue=smalltalk.HashedCollection._fromPairs_([smalltalk.send("foo","__minus_gt",[[(4), (5), (6)]])]);
+smalltalk.send(bb,"_model_modify_",[self["@rootModel"],(function(r){
+return newValue;
+})]);
+smalltalk.send(newValue,"_at_put_",["foo","bar"]);
+smalltalk.send(bb,"_model_read_",[self["@rootModel"],(function(r){
+result=r;
+return result;
+})]);
+smalltalk.send(newValue,"_at_put_",["foo","baz"]);
+smalltalk.send(self,"_assert_equals_",[smalltalk.HashedCollection._fromPairs_([smalltalk.send("foo","__minus_gt",[[(4), (5), (6)]])]),result]);
+return self}
+}),
+smalltalk.IsolatorTest);
+
+smalltalk.addMethod(
+"_testRootModelModifiesRoot",
+smalltalk.method({
+selector: "testRootModelModifiesRoot",
+fn: function (){
+var self=this;
+var bb;
+var result;
+bb=smalltalk.send((smalltalk.Isolator || Isolator),"_on_",[[(1), [(2), (3)]]]);
+smalltalk.send(bb,"_model_modify_",[self["@rootModel"],(function(r){
+return smalltalk.HashedCollection._fromPairs_([smalltalk.send("foo","__minus_gt",[[(4), (5), (6)]])]);
+})]);
+smalltalk.send(bb,"_model_read_",[self["@rootModel"],(function(r){
+result=r;
+return result;
+})]);
+smalltalk.send(self,"_assert_equals_",[smalltalk.HashedCollection._fromPairs_([smalltalk.send("foo","__minus_gt",[[(4), (5), (6)]])]),result]);
+return self}
+}),
+smalltalk.IsolatorTest);
+
 smalltalk.addMethod(
 "_testRootModelReturnsDeeplyIsolatedRoot",
 smalltalk.method({

+ 241 - 0
js/Trapped-Tests.js

@@ -24,6 +24,80 @@ referencedClasses: ["EavModel"]
 }),
 smalltalk.IsolatorTest);
 
+smalltalk.addMethod(
+"_testNontrivialModelGetsAppropriateValueForModification",
+smalltalk.method({
+selector: "testNontrivialModelGetsAppropriateValueForModification",
+category: 'tests',
+fn: function (){
+var self=this;
+var $1,$2;
+var bb;
+var model;
+var result;
+bb=smalltalk.send((smalltalk.Isolator || Isolator),"_on_",[smalltalk.HashedCollection._fromPairs_([smalltalk.send("foo","__minus_gt",[["bar", [(1), [(2), (5)]], "baz"]]),smalltalk.send("moo","__minus_gt",["zoo"])])]);
+$1=smalltalk.send((smalltalk.EavModel || EavModel),"_new",[]);
+smalltalk.send($1,"_getBlock_",[(function(x){
+return smalltalk.send(smalltalk.send(smalltalk.send(x,"_root",[]),"_at_",["foo"]),"_at_",[(2)]);
+})]);
+$2=smalltalk.send($1,"_putBlock_",[(function(x,y){
+return smalltalk.send(smalltalk.send(smalltalk.send(x,"_root",[]),"_at_",["foo"]),"_at_put_",[(2),y]);
+})]);
+model=$2;
+smalltalk.send(bb,"_model_modify_",[model,(function(r){
+result=r;
+return result;
+})]);
+smalltalk.send(self,"_assert_equals_",[[(1), [(2), (5)]],result]);
+return self},
+args: [],
+source: "testNontrivialModelGetsAppropriateValueForModification\x0a| bb model result |\x0abb := Isolator on: #{ 'foo' -> #('bar' #(1 #(2 5)) 'baz'). 'moo' -> 'zoo' }.\x0amodel := EavModel new\x0a\x09getBlock: [ :x | (x root at: 'foo') at: 2 ];\x0a\x09putBlock: [ :x :y | (x root at: 'foo') at: 2 put: y].\x0abb model: model modify: [:r|result := r].\x0aself assert: #(1 #(2 5)) equals: result\x0a",
+messageSends: ["on:", "->", "getBlock:", "at:", "root", "new", "putBlock:", "at:put:", "model:modify:", "assert:equals:"],
+referencedClasses: ["Isolator", "EavModel"]
+}),
+smalltalk.IsolatorTest);
+
+smalltalk.addMethod(
+"_testNontrivialModelModifiesAppropriateValue",
+smalltalk.method({
+selector: "testNontrivialModelModifiesAppropriateValue",
+category: 'tests',
+fn: function (){
+var self=this;
+var $1,$2;
+var bb;
+var model;
+var result;
+bb=smalltalk.send((smalltalk.Isolator || Isolator),"_on_",[smalltalk.HashedCollection._fromPairs_([smalltalk.send("foo","__minus_gt",[["bar", [(1), [(2), (3)]], "baz"]]),smalltalk.send("moo","__minus_gt",["zoo"])])]);
+$1=smalltalk.send((smalltalk.EavModel || EavModel),"_new",[]);
+smalltalk.send($1,"_getBlock_",[(function(x){
+return smalltalk.send(smalltalk.send(smalltalk.send(x,"_root",[]),"_at_",["foo"]),"_at_",[(2)]);
+})]);
+$2=smalltalk.send($1,"_putBlock_",[(function(x,y){
+return smalltalk.send(smalltalk.send(smalltalk.send(x,"_root",[]),"_at_",["foo"]),"_at_put_",[(2),y]);
+})]);
+model=$2;
+smalltalk.send(bb,"_model_modify_",[model,(function(r){
+return smalltalk.symbolFor("new");
+})]);
+smalltalk.send(bb,"_model_read_",[model,(function(r){
+result=r;
+return result;
+})]);
+smalltalk.send(self,"_assert_equals_",[smalltalk.symbolFor("new"),result]);
+smalltalk.send(bb,"_model_read_",[self["@rootModel"],(function(r){
+result=r;
+return result;
+})]);
+smalltalk.send(self,"_assert_equals_",[smalltalk.HashedCollection._fromPairs_([smalltalk.send("foo","__minus_gt",[["bar", smalltalk.symbolFor("new"), "baz"]]),smalltalk.send("moo","__minus_gt",["zoo"])]),result]);
+return self},
+args: [],
+source: "testNontrivialModelModifiesAppropriateValue\x0a| bb model result |\x0abb := Isolator on: #{ 'foo' -> #('bar' #(1 #(2 3)) 'baz'). 'moo' -> 'zoo' }.\x0amodel := EavModel new\x0a\x09getBlock: [ :x | (x root at: 'foo') at: 2 ];\x0a\x09putBlock: [ :x :y | (x root at: 'foo') at: 2 put: y].\x0abb model: model modify: [:r|#new].\x0abb model: model read: [:r|result := r].\x0aself assert: #new equals: result.\x0abb model: rootModel read: [:r|result := r].\x0aself assert: #{ 'foo' -> #('bar' #new 'baz'). 'moo' -> 'zoo' } equals: result\x0a",
+messageSends: ["on:", "->", "getBlock:", "at:", "root", "new", "putBlock:", "at:put:", "model:modify:", "model:read:", "assert:equals:"],
+referencedClasses: ["Isolator", "EavModel"]
+}),
+smalltalk.IsolatorTest);
+
 smalltalk.addMethod(
 "_testNontrivialModelReturnsAppropriateValue",
 smalltalk.method({
@@ -51,6 +125,173 @@ referencedClasses: ["Isolator", "EavModel"]
 }),
 smalltalk.IsolatorTest);
 
+smalltalk.addMethod(
+"_testRootModelExaminesThenModifiesRoot",
+smalltalk.method({
+selector: "testRootModelExaminesThenModifiesRoot",
+category: 'tests',
+fn: function (){
+var self=this;
+var bb;
+var result;
+bb=smalltalk.send((smalltalk.Isolator || Isolator),"_on_",[[(1), [(2), (3)]]]);
+smalltalk.send(bb,"_model_modify_",[self["@rootModel"],(function(r){
+return smalltalk.send(r,"_second",[]);
+})]);
+smalltalk.send(bb,"_model_read_",[self["@rootModel"],(function(r){
+result=r;
+return result;
+})]);
+smalltalk.send(self,"_assert_equals_",[[(2), (3)],result]);
+return self},
+args: [],
+source: "testRootModelExaminesThenModifiesRoot\x0a| bb result |\x0abb := Isolator on: #(1 #(2 3)).\x0abb model: rootModel modify: [:r|r second].\x0abb model: rootModel read: [:r|result := r].\x0aself assert: #(2 3) equals: result\x0a",
+messageSends: ["on:", "model:modify:", "second", "model:read:", "assert:equals:"],
+referencedClasses: ["Isolator"]
+}),
+smalltalk.IsolatorTest);
+
+smalltalk.addMethod(
+"_testRootModelGetsRootForModification",
+smalltalk.method({
+selector: "testRootModelGetsRootForModification",
+category: 'tests',
+fn: function (){
+var self=this;
+var bb;
+var result;
+bb=smalltalk.send((smalltalk.Isolator || Isolator),"_on_",[[(2), [(1), (0)]]]);
+smalltalk.send(bb,"_model_modify_",[self["@rootModel"],(function(r){
+result=r;
+return result;
+})]);
+smalltalk.send(self,"_assert_equals_",[[(2), [(1), (0)]],result]);
+return self},
+args: [],
+source: "testRootModelGetsRootForModification\x0a| bb result |\x0abb := Isolator on: #(2 #(1 0)).\x0abb model: rootModel modify: [:r|result := r].\x0aself assert: #(2 #(1 0)) equals: result\x0a",
+messageSends: ["on:", "model:modify:", "assert:equals:"],
+referencedClasses: ["Isolator"]
+}),
+smalltalk.IsolatorTest);
+
+smalltalk.addMethod(
+"_testRootModelModifiesAndDeeplyIsolatesInPlaceModifiedRoot",
+smalltalk.method({
+selector: "testRootModelModifiesAndDeeplyIsolatesInPlaceModifiedRoot",
+category: 'tests',
+fn: function (){
+var self=this;
+var bb;
+var result;
+var newValue;
+bb=smalltalk.send((smalltalk.Isolator || Isolator),"_on_",[[(1), [(2), (3)]]]);
+smalltalk.send(bb,"_model_modify_",[self["@rootModel"],(function(r){
+newValue=r;
+newValue;
+smalltalk.send(r,"_at_put_",[(1),(4)]);
+return r;
+})]);
+smalltalk.send(newValue,"_at_put_",[(2),"bar"]);
+smalltalk.send(bb,"_model_read_",[self["@rootModel"],(function(r){
+result=r;
+return result;
+})]);
+smalltalk.send(newValue,"_at_put_",[(2),"baz"]);
+smalltalk.send(self,"_assert_equals_",[[(4), [(2), (3)]],result]);
+return self},
+args: [],
+source: "testRootModelModifiesAndDeeplyIsolatesInPlaceModifiedRoot\x0a| bb result newValue |\x0abb := Isolator on: #(1 #(2 3)).\x0abb model: rootModel modify: [:r|newValue := r. r at: 1 put: 4. r].\x0anewValue at: 2 put: 'bar'.\x0abb model: rootModel read: [:r|result := r].\x0anewValue at: 2 put: 'baz'.\x0aself assert: #(4 #(2 3)) equals: result\x0a",
+messageSends: ["on:", "model:modify:", "at:put:", "model:read:", "assert:equals:"],
+referencedClasses: ["Isolator"]
+}),
+smalltalk.IsolatorTest);
+
+smalltalk.addMethod(
+"_testRootModelModifiesAndDeeplyIsolatesRoot",
+smalltalk.method({
+selector: "testRootModelModifiesAndDeeplyIsolatesRoot",
+category: 'tests',
+fn: function (){
+var self=this;
+var bb;
+var result;
+var newValue;
+bb=smalltalk.send((smalltalk.Isolator || Isolator),"_on_",[[(1), [(2), (3)]]]);
+newValue=smalltalk.HashedCollection._fromPairs_([smalltalk.send("foo","__minus_gt",[[(4), (5), (6)]])]);
+smalltalk.send(bb,"_model_modify_",[self["@rootModel"],(function(r){
+return newValue;
+})]);
+smalltalk.send(smalltalk.send(newValue,"_at_",["foo"]),"_at_put_",[(1),"bar"]);
+smalltalk.send(bb,"_model_read_",[self["@rootModel"],(function(r){
+result=r;
+return result;
+})]);
+smalltalk.send(smalltalk.send(newValue,"_at_",["foo"]),"_at_put_",[(3),"baz"]);
+smalltalk.send(self,"_assert_equals_",[smalltalk.HashedCollection._fromPairs_([smalltalk.send("foo","__minus_gt",[[(4), (5), (6)]])]),result]);
+return self},
+args: [],
+source: "testRootModelModifiesAndDeeplyIsolatesRoot\x0a| bb result newValue |\x0abb := Isolator on: #(1 #(2 3)).\x0anewValue := #{'foo'->#(4 5 6)}.\x0abb model: rootModel modify: [:r|newValue].\x0a(newValue at: 'foo') at: 1 put: 'bar'.\x0abb model: rootModel read: [:r|result := r].\x0a(newValue at: 'foo') at: 3 put: 'baz'.\x0aself assert: #{'foo'->#(4 5 6)} equals: result\x0a",
+messageSends: ["on:", "->", "model:modify:", "at:put:", "at:", "model:read:", "assert:equals:"],
+referencedClasses: ["Isolator"]
+}),
+smalltalk.IsolatorTest);
+
+smalltalk.addMethod(
+"_testRootModelModifiesAndIsolatesRoot",
+smalltalk.method({
+selector: "testRootModelModifiesAndIsolatesRoot",
+category: 'tests',
+fn: function (){
+var self=this;
+var bb;
+var result;
+var newValue;
+bb=smalltalk.send((smalltalk.Isolator || Isolator),"_on_",[[(1), [(2), (3)]]]);
+newValue=smalltalk.HashedCollection._fromPairs_([smalltalk.send("foo","__minus_gt",[[(4), (5), (6)]])]);
+smalltalk.send(bb,"_model_modify_",[self["@rootModel"],(function(r){
+return newValue;
+})]);
+smalltalk.send(newValue,"_at_put_",["foo","bar"]);
+smalltalk.send(bb,"_model_read_",[self["@rootModel"],(function(r){
+result=r;
+return result;
+})]);
+smalltalk.send(newValue,"_at_put_",["foo","baz"]);
+smalltalk.send(self,"_assert_equals_",[smalltalk.HashedCollection._fromPairs_([smalltalk.send("foo","__minus_gt",[[(4), (5), (6)]])]),result]);
+return self},
+args: [],
+source: "testRootModelModifiesAndIsolatesRoot\x0a| bb result newValue |\x0abb := Isolator on: #(1 #(2 3)).\x0anewValue := #{'foo'->#(4 5 6)}.\x0abb model: rootModel modify: [:r|newValue].\x0anewValue at: 'foo' put: 'bar'.\x0abb model: rootModel read: [:r|result := r].\x0anewValue at: 'foo' put: 'baz'.\x0aself assert: #{'foo'->#(4 5 6)} equals: result\x0a",
+messageSends: ["on:", "->", "model:modify:", "at:put:", "model:read:", "assert:equals:"],
+referencedClasses: ["Isolator"]
+}),
+smalltalk.IsolatorTest);
+
+smalltalk.addMethod(
+"_testRootModelModifiesRoot",
+smalltalk.method({
+selector: "testRootModelModifiesRoot",
+category: 'tests',
+fn: function (){
+var self=this;
+var bb;
+var result;
+bb=smalltalk.send((smalltalk.Isolator || Isolator),"_on_",[[(1), [(2), (3)]]]);
+smalltalk.send(bb,"_model_modify_",[self["@rootModel"],(function(r){
+return smalltalk.HashedCollection._fromPairs_([smalltalk.send("foo","__minus_gt",[[(4), (5), (6)]])]);
+})]);
+smalltalk.send(bb,"_model_read_",[self["@rootModel"],(function(r){
+result=r;
+return result;
+})]);
+smalltalk.send(self,"_assert_equals_",[smalltalk.HashedCollection._fromPairs_([smalltalk.send("foo","__minus_gt",[[(4), (5), (6)]])]),result]);
+return self},
+args: [],
+source: "testRootModelModifiesRoot\x0a| bb result |\x0abb := Isolator on: #(1 #(2 3)).\x0abb model: rootModel modify: [:r|#{'foo'->#(4 5 6)}].\x0abb model: rootModel read: [:r|result := r].\x0aself assert: #{'foo'->#(4 5 6)} equals: result\x0a",
+messageSends: ["on:", "model:modify:", "->", "model:read:", "assert:equals:"],
+referencedClasses: ["Isolator"]
+}),
+smalltalk.IsolatorTest);
+
 smalltalk.addMethod(
 "_testRootModelReturnsDeeplyIsolatedRoot",
 smalltalk.method({

+ 13 - 0
js/Trapped.deploy.js

@@ -67,6 +67,19 @@ smalltalk.EavModel);
 
 
 smalltalk.addClass('Isolator', smalltalk.Object, ['root'], 'Trapped');
+smalltalk.addMethod(
+"_model_modify_",
+smalltalk.method({
+selector: "model:modify:",
+fn: function (anEavModel,aBlock){
+var self=this;
+var newValue;
+newValue=smalltalk.send(aBlock,"_value_",[smalltalk.send(anEavModel,"_on_",[self])]);
+smalltalk.send(anEavModel,"_on_put_",[self,smalltalk.send(newValue,"_deepCopy",[])]);
+return self}
+}),
+smalltalk.Isolator);
+
 smalltalk.addMethod(
 "_model_read_",
 smalltalk.method({

+ 18 - 0
js/Trapped.js

@@ -93,6 +93,24 @@ smalltalk.EavModel);
 
 
 smalltalk.addClass('Isolator', smalltalk.Object, ['root'], 'Trapped');
+smalltalk.addMethod(
+"_model_modify_",
+smalltalk.method({
+selector: "model:modify:",
+category: 'action',
+fn: function (anEavModel,aBlock){
+var self=this;
+var newValue;
+newValue=smalltalk.send(aBlock,"_value_",[smalltalk.send(anEavModel,"_on_",[self])]);
+smalltalk.send(anEavModel,"_on_put_",[self,smalltalk.send(newValue,"_deepCopy",[])]);
+return self},
+args: ["anEavModel", "aBlock"],
+source: "model: anEavModel modify: aBlock\x0a\x0a| newValue |\x0anewValue := aBlock value: (anEavModel on: self).\x0aanEavModel on: self put: newValue deepCopy\x0a",
+messageSends: ["value:", "on:", "on:put:", "deepCopy"],
+referencedClasses: []
+}),
+smalltalk.Isolator);
+
 smalltalk.addMethod(
 "_model_read_",
 smalltalk.method({

+ 78 - 0
st/Trapped-Tests.st

@@ -14,6 +14,29 @@ rootModel := EavModel new
 
 !IsolatorTest methodsFor: 'tests'!
 
+testNontrivialModelGetsAppropriateValueForModification
+| bb model result |
+bb := Isolator on: #{ 'foo' -> #('bar' #(1 #(2 5)) 'baz'). 'moo' -> 'zoo' }.
+model := EavModel new
+	getBlock: [ :x | (x root at: 'foo') at: 2 ];
+	putBlock: [ :x :y | (x root at: 'foo') at: 2 put: y].
+bb model: model modify: [:r|result := r].
+self assert: #(1 #(2 5)) equals: result
+!
+
+testNontrivialModelModifiesAppropriateValue
+| bb model result |
+bb := Isolator on: #{ 'foo' -> #('bar' #(1 #(2 3)) 'baz'). 'moo' -> 'zoo' }.
+model := EavModel new
+	getBlock: [ :x | (x root at: 'foo') at: 2 ];
+	putBlock: [ :x :y | (x root at: 'foo') at: 2 put: y].
+bb model: model modify: [:r|#new].
+bb model: model read: [:r|result := r].
+self assert: #new equals: result.
+bb model: rootModel read: [:r|result := r].
+self assert: #{ 'foo' -> #('bar' #new 'baz'). 'moo' -> 'zoo' } equals: result
+!
+
 testNontrivialModelReturnsAppropriateValue
 | bb model result |
 bb := Isolator on: #{ 'foo' -> #('bar' #(1 #(2 3)) 'baz'). 'moo' -> 'zoo' }.
@@ -22,6 +45,61 @@ bb model: model read: [:r|result := r].
 self assert: #(1 #(2 3)) equals: result
 !
 
+testRootModelExaminesThenModifiesRoot
+| bb result |
+bb := Isolator on: #(1 #(2 3)).
+bb model: rootModel modify: [:r|r second].
+bb model: rootModel read: [:r|result := r].
+self assert: #(2 3) equals: result
+!
+
+testRootModelGetsRootForModification
+| bb result |
+bb := Isolator on: #(2 #(1 0)).
+bb model: rootModel modify: [:r|result := r].
+self assert: #(2 #(1 0)) equals: result
+!
+
+testRootModelModifiesAndDeeplyIsolatesInPlaceModifiedRoot
+| bb result newValue |
+bb := Isolator on: #(1 #(2 3)).
+bb model: rootModel modify: [:r|newValue := r. r at: 1 put: 4. r].
+newValue at: 2 put: 'bar'.
+bb model: rootModel read: [:r|result := r].
+newValue at: 2 put: 'baz'.
+self assert: #(4 #(2 3)) equals: result
+!
+
+testRootModelModifiesAndDeeplyIsolatesRoot
+| bb result newValue |
+bb := Isolator on: #(1 #(2 3)).
+newValue := #{'foo'->#(4 5 6)}.
+bb model: rootModel modify: [:r|newValue].
+(newValue at: 'foo') at: 1 put: 'bar'.
+bb model: rootModel read: [:r|result := r].
+(newValue at: 'foo') at: 3 put: 'baz'.
+self assert: #{'foo'->#(4 5 6)} equals: result
+!
+
+testRootModelModifiesAndIsolatesRoot
+| bb result newValue |
+bb := Isolator on: #(1 #(2 3)).
+newValue := #{'foo'->#(4 5 6)}.
+bb model: rootModel modify: [:r|newValue].
+newValue at: 'foo' put: 'bar'.
+bb model: rootModel read: [:r|result := r].
+newValue at: 'foo' put: 'baz'.
+self assert: #{'foo'->#(4 5 6)} equals: result
+!
+
+testRootModelModifiesRoot
+| bb result |
+bb := Isolator on: #(1 #(2 3)).
+bb model: rootModel modify: [:r|#{'foo'->#(4 5 6)}].
+bb model: rootModel read: [:r|result := r].
+self assert: #{'foo'->#(4 5 6)} equals: result
+!
+
 testRootModelReturnsDeeplyIsolatedRoot
 | bb result |
 bb := Isolator on: #(1 #(2 3)).

+ 7 - 0
st/Trapped.st

@@ -55,6 +55,13 @@ root := anObject
 
 !Isolator methodsFor: 'action'!
 
+model: anEavModel modify: aBlock
+
+| newValue |
+newValue := aBlock value: (anEavModel on: self).
+anEavModel on: self put: newValue deepCopy
+!
+
 model: anEavModel read: aBlock
 
 aBlock value: (anEavModel on: self) deepCopy