Browse Source

Isolator->Axxord; Backend,Tests empty, deleted.

Herbert Vojčík 6 years ago
parent
commit
346447e15e
4 changed files with 888 additions and 0 deletions
  1. 603 0
      src/Axxord-Tests.js
  2. 136 0
      src/Axxord-Tests.st
  3. 113 0
      src/Axxord.js
  4. 36 0
      src/Axxord.st

+ 603 - 0
src/Axxord-Tests.js

@@ -7,6 +7,609 @@ $core.addPackage("Axxord-Tests");
 $core.packages["Axxord-Tests"].innerEval = function (expr) { return eval(expr); };
 $core.packages["Axxord-Tests"].transport = {"type":"amd","amdNamespace":"axxord"};
 
+$core.addClass("AxolatorTest", $globals.TestCase, ["rootModel"], "Axxord-Tests");
+$core.addMethod(
+$core.method({
+selector: "setUp",
+protocol: "running",
+fn: function (){
+var self=this,$self=this;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx1) {
+//>>excludeEnd("ctx");
+var $1;
+$1=$recv($globals.EavModel)._new();
+$recv($1)._getBlock_((function(x){
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx2) {
+//>>excludeEnd("ctx");
+return $recv(x)._root();
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx2) {$ctx2.fillBlock({x:x},$ctx1,1)});
+//>>excludeEnd("ctx");
+}));
+$self["@rootModel"]=$recv($1)._putBlock_((function(x,y){
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx2) {
+//>>excludeEnd("ctx");
+return $recv(x)._root_(y);
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx2) {$ctx2.fillBlock({x:x,y:y},$ctx1,2)});
+//>>excludeEnd("ctx");
+}));
+return self;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"setUp",{},$globals.AxolatorTest)});
+//>>excludeEnd("ctx");
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: [],
+source: "setUp\x0a\x0arootModel := EavModel new\x0a\x09getBlock: [:x | x root];\x0a    putBlock: [:x :y | x root: y].",
+referencedClasses: ["EavModel"],
+//>>excludeEnd("ide");
+messageSends: ["getBlock:", "new", "root", "putBlock:", "root:"]
+}),
+$globals.AxolatorTest);
+
+$core.addMethod(
+$core.method({
+selector: "testNontrivialModelGetsAppropriateValueForModification",
+protocol: "tests",
+fn: function (){
+var self=this,$self=this;
+var isolator,model,result;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx1) {
+//>>excludeEnd("ctx");
+var $1,$3,$2;
+result=nil;
+isolator=$recv($globals.Axolator)._on_($globals.HashedCollection._newFromPairs_(["foo",["bar", [(1), [(2), (5)]], "baz"],"moo","zoo"]));
+$1=$recv($globals.EavModel)._new();
+$recv($1)._getBlock_((function(x){
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx2) {
+//>>excludeEnd("ctx");
+$3=$recv(x)._root();
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx2.sendIdx["root"]=1;
+//>>excludeEnd("ctx");
+$2=$recv($3)._at_("foo");
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx2.sendIdx["at:"]=2;
+//>>excludeEnd("ctx");
+return $recv($2)._at_((2));
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx2.sendIdx["at:"]=1;
+//>>excludeEnd("ctx");
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx2) {$ctx2.fillBlock({x:x},$ctx1,1)});
+//>>excludeEnd("ctx");
+}));
+model=$recv($1)._putBlock_((function(x,y){
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx2) {
+//>>excludeEnd("ctx");
+return $recv($recv($recv(x)._root())._at_("foo"))._at_put_((2),y);
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx2) {$ctx2.fillBlock({x:x,y:y},$ctx1,2)});
+//>>excludeEnd("ctx");
+}));
+$recv(isolator)._model_modify_(model,(function(r){
+result=r;
+return result;
+
+}));
+$self._assert_equals_([(1), [(2), (5)]],result);
+return self;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"testNontrivialModelGetsAppropriateValueForModification",{isolator:isolator,model:model,result:result},$globals.AxolatorTest)});
+//>>excludeEnd("ctx");
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: [],
+source: "testNontrivialModelGetsAppropriateValueForModification\x0a| isolator model result |\x0aresult := nil.\x0aisolator := Axolator 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].\x0aisolator model: model modify: [:r|result := r].\x0aself assert: #(1 #(2 5)) equals: result",
+referencedClasses: ["Axolator", "EavModel"],
+//>>excludeEnd("ide");
+messageSends: ["on:", "getBlock:", "new", "at:", "root", "putBlock:", "at:put:", "model:modify:", "assert:equals:"]
+}),
+$globals.AxolatorTest);
+
+$core.addMethod(
+$core.method({
+selector: "testNontrivialModelModifiesAppropriateValue",
+protocol: "tests",
+fn: function (){
+var self=this,$self=this;
+var isolator,model,result;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx1) {
+//>>excludeEnd("ctx");
+var $1,$3,$2;
+result=nil;
+isolator=$recv($globals.Axolator)._on_($globals.HashedCollection._newFromPairs_(["foo",["bar", [(1), [(2), (3)]], "baz"],"moo","zoo"]));
+$1=$recv($globals.EavModel)._new();
+$recv($1)._getBlock_((function(x){
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx2) {
+//>>excludeEnd("ctx");
+$3=$recv(x)._root();
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx2.sendIdx["root"]=1;
+//>>excludeEnd("ctx");
+$2=$recv($3)._at_("foo");
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx2.sendIdx["at:"]=2;
+//>>excludeEnd("ctx");
+return $recv($2)._at_((2));
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx2.sendIdx["at:"]=1;
+//>>excludeEnd("ctx");
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx2) {$ctx2.fillBlock({x:x},$ctx1,1)});
+//>>excludeEnd("ctx");
+}));
+model=$recv($1)._putBlock_((function(x,y){
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx2) {
+//>>excludeEnd("ctx");
+return $recv($recv($recv(x)._root())._at_("foo"))._at_put_((2),y);
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx2) {$ctx2.fillBlock({x:x,y:y},$ctx1,2)});
+//>>excludeEnd("ctx");
+}));
+$recv(isolator)._model_modify_(model,(function(r){
+return "new";
+
+}));
+$recv(isolator)._model_read_(model,(function(r){
+result=r;
+return result;
+
+}));
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["model:read:"]=1;
+//>>excludeEnd("ctx");
+$self._assert_equals_("new",result);
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["assert:equals:"]=1;
+//>>excludeEnd("ctx");
+$recv(isolator)._model_read_($self["@rootModel"],(function(r){
+result=r;
+return result;
+
+}));
+$self._assert_equals_($globals.HashedCollection._newFromPairs_(["foo",["bar", "new", "baz"],"moo","zoo"]),result);
+return self;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"testNontrivialModelModifiesAppropriateValue",{isolator:isolator,model:model,result:result},$globals.AxolatorTest)});
+//>>excludeEnd("ctx");
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: [],
+source: "testNontrivialModelModifiesAppropriateValue\x0a| isolator model result |\x0aresult := nil.\x0aisolator := Axolator 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].\x0aisolator model: model modify: [:r|#new].\x0aisolator model: model read: [:r|result := r].\x0aself assert: #new equals: result.\x0aisolator model: rootModel read: [:r|result := r].\x0aself assert: #{ 'foo' -> #('bar' #new 'baz'). 'moo' -> 'zoo' } equals: result",
+referencedClasses: ["Axolator", "EavModel"],
+//>>excludeEnd("ide");
+messageSends: ["on:", "getBlock:", "new", "at:", "root", "putBlock:", "at:put:", "model:modify:", "model:read:", "assert:equals:"]
+}),
+$globals.AxolatorTest);
+
+$core.addMethod(
+$core.method({
+selector: "testNontrivialModelReturnsAppropriateValue",
+protocol: "tests",
+fn: function (){
+var self=this,$self=this;
+var isolator,model,result;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx1) {
+//>>excludeEnd("ctx");
+result=nil;
+isolator=$recv($globals.Axolator)._on_($globals.HashedCollection._newFromPairs_(["foo",["bar", [(1), [(2), (3)]], "baz"],"moo","zoo"]));
+model=$recv($recv($globals.EavModel)._new())._getBlock_((function(x){
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx2) {
+//>>excludeEnd("ctx");
+return $recv($recv($recv(x)._root())._at_("foo"))._at_((2));
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx2.sendIdx["at:"]=1;
+//>>excludeEnd("ctx");
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx2) {$ctx2.fillBlock({x:x},$ctx1,1)});
+//>>excludeEnd("ctx");
+}));
+$recv(isolator)._model_read_(model,(function(r){
+result=r;
+return result;
+
+}));
+$self._assert_equals_([(1), [(2), (3)]],result);
+return self;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"testNontrivialModelReturnsAppropriateValue",{isolator:isolator,model:model,result:result},$globals.AxolatorTest)});
+//>>excludeEnd("ctx");
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: [],
+source: "testNontrivialModelReturnsAppropriateValue\x0a| isolator model result |\x0aresult := nil.\x0aisolator := Axolator on: #{ 'foo' -> #('bar' #(1 #(2 3)) 'baz'). 'moo' -> 'zoo' }.\x0amodel := EavModel new getBlock: [ :x | (x root at: 'foo') at: 2 ].\x0aisolator model: model read: [:r|result := r].\x0aself assert: #(1 #(2 3)) equals: result",
+referencedClasses: ["Axolator", "EavModel"],
+//>>excludeEnd("ide");
+messageSends: ["on:", "getBlock:", "new", "at:", "root", "model:read:", "assert:equals:"]
+}),
+$globals.AxolatorTest);
+
+$core.addMethod(
+$core.method({
+selector: "testRootModelExaminesThenModifiesRoot",
+protocol: "tests",
+fn: function (){
+var self=this,$self=this;
+var isolator,result;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx1) {
+//>>excludeEnd("ctx");
+result=nil;
+isolator=$recv($globals.Axolator)._on_([(1), [(2), (3)]]);
+$recv(isolator)._model_modify_($self["@rootModel"],(function(r){
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx2) {
+//>>excludeEnd("ctx");
+return $recv(r)._second();
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx2) {$ctx2.fillBlock({r:r},$ctx1,1)});
+//>>excludeEnd("ctx");
+}));
+$recv(isolator)._model_read_($self["@rootModel"],(function(r){
+result=r;
+return result;
+
+}));
+$self._assert_equals_([(2), (3)],result);
+return self;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"testRootModelExaminesThenModifiesRoot",{isolator:isolator,result:result},$globals.AxolatorTest)});
+//>>excludeEnd("ctx");
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: [],
+source: "testRootModelExaminesThenModifiesRoot\x0a| isolator result |\x0aresult := nil.\x0aisolator := Axolator on: #(1 #(2 3)).\x0aisolator model: rootModel modify: [:r|r second].\x0aisolator model: rootModel read: [:r|result := r].\x0aself assert: #(2 3) equals: result",
+referencedClasses: ["Axolator"],
+//>>excludeEnd("ide");
+messageSends: ["on:", "model:modify:", "second", "model:read:", "assert:equals:"]
+}),
+$globals.AxolatorTest);
+
+$core.addMethod(
+$core.method({
+selector: "testRootModelGetsRootForModification",
+protocol: "tests",
+fn: function (){
+var self=this,$self=this;
+var isolator,result;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx1) {
+//>>excludeEnd("ctx");
+result=nil;
+isolator=$recv($globals.Axolator)._on_([(2), [(1), (0)]]);
+$recv(isolator)._model_modify_($self["@rootModel"],(function(r){
+result=r;
+return result;
+
+}));
+$self._assert_equals_([(2), [(1), (0)]],result);
+return self;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"testRootModelGetsRootForModification",{isolator:isolator,result:result},$globals.AxolatorTest)});
+//>>excludeEnd("ctx");
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: [],
+source: "testRootModelGetsRootForModification\x0a| isolator result |\x0aresult := nil.\x0aisolator := Axolator on: #(2 #(1 0)).\x0aisolator model: rootModel modify: [:r|result := r].\x0aself assert: #(2 #(1 0)) equals: result",
+referencedClasses: ["Axolator"],
+//>>excludeEnd("ide");
+messageSends: ["on:", "model:modify:", "assert:equals:"]
+}),
+$globals.AxolatorTest);
+
+$core.addMethod(
+$core.method({
+selector: "testRootModelModifiesAndDeeplyIsolatesInPlaceModifiedRoot",
+protocol: "tests",
+fn: function (){
+var self=this,$self=this;
+var isolator,result,newValue;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx1) {
+//>>excludeEnd("ctx");
+result=nil;
+newValue=nil;
+isolator=$recv($globals.Axolator)._on_([(1), [(2), (3)]]);
+$recv(isolator)._model_modify_($self["@rootModel"],(function(r){
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx2) {
+//>>excludeEnd("ctx");
+newValue=r;
+newValue;
+$recv(r)._at_put_((1),(4));
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx2.sendIdx["at:put:"]=1;
+//>>excludeEnd("ctx");
+return r;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx2) {$ctx2.fillBlock({r:r},$ctx1,1)});
+//>>excludeEnd("ctx");
+}));
+$recv(newValue)._at_put_((2),"bar");
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["at:put:"]=2;
+//>>excludeEnd("ctx");
+$recv(isolator)._model_read_($self["@rootModel"],(function(r){
+result=r;
+return result;
+
+}));
+$recv(newValue)._at_put_((2),"baz");
+$self._assert_equals_([(4), [(2), (3)]],result);
+return self;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"testRootModelModifiesAndDeeplyIsolatesInPlaceModifiedRoot",{isolator:isolator,result:result,newValue:newValue},$globals.AxolatorTest)});
+//>>excludeEnd("ctx");
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: [],
+source: "testRootModelModifiesAndDeeplyIsolatesInPlaceModifiedRoot\x0a| isolator result newValue |\x0aresult := nil. newValue := nil.\x0aisolator := Axolator on: #(1 #(2 3)).\x0aisolator model: rootModel modify: [:r|newValue := r. r at: 1 put: 4. r].\x0anewValue at: 2 put: 'bar'.\x0aisolator model: rootModel read: [:r|result := r].\x0anewValue at: 2 put: 'baz'.\x0aself assert: #(4 #(2 3)) equals: result",
+referencedClasses: ["Axolator"],
+//>>excludeEnd("ide");
+messageSends: ["on:", "model:modify:", "at:put:", "model:read:", "assert:equals:"]
+}),
+$globals.AxolatorTest);
+
+$core.addMethod(
+$core.method({
+selector: "testRootModelModifiesAndDeeplyIsolatesRoot",
+protocol: "tests",
+fn: function (){
+var self=this,$self=this;
+var isolator,result,newValue;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx1) {
+//>>excludeEnd("ctx");
+var $1;
+result=nil;
+isolator=$recv($globals.Axolator)._on_([(1), [(2), (3)]]);
+newValue=$globals.HashedCollection._newFromPairs_(["foo",[(4), (5), (6)]]);
+$recv(isolator)._model_modify_($self["@rootModel"],(function(r){
+return newValue;
+
+}));
+$1=$recv(newValue)._at_("foo");
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["at:"]=1;
+//>>excludeEnd("ctx");
+$recv($1)._at_put_((1),"bar");
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["at:put:"]=1;
+//>>excludeEnd("ctx");
+$recv(isolator)._model_read_($self["@rootModel"],(function(r){
+result=r;
+return result;
+
+}));
+$recv($recv(newValue)._at_("foo"))._at_put_((3),"baz");
+$self._assert_equals_($globals.HashedCollection._newFromPairs_(["foo",[(4), (5), (6)]]),result);
+return self;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"testRootModelModifiesAndDeeplyIsolatesRoot",{isolator:isolator,result:result,newValue:newValue},$globals.AxolatorTest)});
+//>>excludeEnd("ctx");
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: [],
+source: "testRootModelModifiesAndDeeplyIsolatesRoot\x0a| isolator result newValue |\x0aresult := nil.\x0aisolator := Axolator on: #(1 #(2 3)).\x0anewValue := #{'foo'->#(4 5 6)}.\x0aisolator model: rootModel modify: [:r|newValue].\x0a(newValue at: 'foo') at: 1 put: 'bar'.\x0aisolator model: rootModel read: [:r|result := r].\x0a(newValue at: 'foo') at: 3 put: 'baz'.\x0aself assert: #{'foo'->#(4 5 6)} equals: result",
+referencedClasses: ["Axolator"],
+//>>excludeEnd("ide");
+messageSends: ["on:", "model:modify:", "at:put:", "at:", "model:read:", "assert:equals:"]
+}),
+$globals.AxolatorTest);
+
+$core.addMethod(
+$core.method({
+selector: "testRootModelModifiesAndIsolatesRoot",
+protocol: "tests",
+fn: function (){
+var self=this,$self=this;
+var isolator,result,newValue;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx1) {
+//>>excludeEnd("ctx");
+result=nil;
+isolator=$recv($globals.Axolator)._on_([(1), [(2), (3)]]);
+newValue=$globals.HashedCollection._newFromPairs_(["foo",[(4), (5), (6)]]);
+$recv(isolator)._model_modify_($self["@rootModel"],(function(r){
+return newValue;
+
+}));
+$recv(newValue)._at_put_("foo","bar");
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["at:put:"]=1;
+//>>excludeEnd("ctx");
+$recv(isolator)._model_read_($self["@rootModel"],(function(r){
+result=r;
+return result;
+
+}));
+$recv(newValue)._at_put_("foo","baz");
+$self._assert_equals_($globals.HashedCollection._newFromPairs_(["foo",[(4), (5), (6)]]),result);
+return self;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"testRootModelModifiesAndIsolatesRoot",{isolator:isolator,result:result,newValue:newValue},$globals.AxolatorTest)});
+//>>excludeEnd("ctx");
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: [],
+source: "testRootModelModifiesAndIsolatesRoot\x0a| isolator result newValue |\x0aresult := nil.\x0aisolator := Axolator on: #(1 #(2 3)).\x0anewValue := #{'foo'->#(4 5 6)}.\x0aisolator model: rootModel modify: [:r|newValue].\x0anewValue at: 'foo' put: 'bar'.\x0aisolator model: rootModel read: [:r|result := r].\x0anewValue at: 'foo' put: 'baz'.\x0aself assert: #{'foo'->#(4 5 6)} equals: result",
+referencedClasses: ["Axolator"],
+//>>excludeEnd("ide");
+messageSends: ["on:", "model:modify:", "at:put:", "model:read:", "assert:equals:"]
+}),
+$globals.AxolatorTest);
+
+$core.addMethod(
+$core.method({
+selector: "testRootModelModifiesRoot",
+protocol: "tests",
+fn: function (){
+var self=this,$self=this;
+var isolator,result;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx1) {
+//>>excludeEnd("ctx");
+result=nil;
+isolator=$recv($globals.Axolator)._on_([(1), [(2), (3)]]);
+$recv(isolator)._model_modify_($self["@rootModel"],(function(r){
+return $globals.HashedCollection._newFromPairs_(["foo",[(4), (5), (6)]]);
+
+}));
+$recv(isolator)._model_read_($self["@rootModel"],(function(r){
+result=r;
+return result;
+
+}));
+$self._assert_equals_($globals.HashedCollection._newFromPairs_(["foo",[(4), (5), (6)]]),result);
+return self;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"testRootModelModifiesRoot",{isolator:isolator,result:result},$globals.AxolatorTest)});
+//>>excludeEnd("ctx");
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: [],
+source: "testRootModelModifiesRoot\x0a| isolator result |\x0aresult := nil.\x0aisolator := Axolator on: #(1 #(2 3)).\x0aisolator model: rootModel modify: [:r|#{'foo'->#(4 5 6)}].\x0aisolator model: rootModel read: [:r|result := r].\x0aself assert: #{'foo'->#(4 5 6)} equals: result",
+referencedClasses: ["Axolator"],
+//>>excludeEnd("ide");
+messageSends: ["on:", "model:modify:", "model:read:", "assert:equals:"]
+}),
+$globals.AxolatorTest);
+
+$core.addMethod(
+$core.method({
+selector: "testRootModelReturnsDeeplyIsolatedRoot",
+protocol: "tests",
+fn: function (){
+var self=this,$self=this;
+var isolator,result;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx1) {
+//>>excludeEnd("ctx");
+result=nil;
+isolator=$recv($globals.Axolator)._on_([(1), [(2), (3)]]);
+$recv(isolator)._model_read_($self["@rootModel"],(function(r){
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx2) {
+//>>excludeEnd("ctx");
+return $recv($recv(r)._at_((2)))._at_put_((1),(0));
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx2) {$ctx2.fillBlock({r:r},$ctx1,1)});
+//>>excludeEnd("ctx");
+}));
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["model:read:"]=1;
+//>>excludeEnd("ctx");
+$recv(isolator)._model_read_($self["@rootModel"],(function(r){
+result=r;
+return result;
+
+}));
+$self._assert_equals_([(1), [(2), (3)]],result);
+return self;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"testRootModelReturnsDeeplyIsolatedRoot",{isolator:isolator,result:result},$globals.AxolatorTest)});
+//>>excludeEnd("ctx");
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: [],
+source: "testRootModelReturnsDeeplyIsolatedRoot\x0a| isolator result |\x0aresult := nil.\x0aisolator := Axolator on: #(1 #(2 3)).\x0aisolator model: rootModel read: [:r|(r at: 2) at: 1 put: 0].\x0aisolator model: rootModel read: [:r|result := r].\x0aself assert: #(1 #(2 3)) equals: result",
+referencedClasses: ["Axolator"],
+//>>excludeEnd("ide");
+messageSends: ["on:", "model:read:", "at:put:", "at:", "assert:equals:"]
+}),
+$globals.AxolatorTest);
+
+$core.addMethod(
+$core.method({
+selector: "testRootModelReturnsIsolatedRoot",
+protocol: "tests",
+fn: function (){
+var self=this,$self=this;
+var isolator,result;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx1) {
+//>>excludeEnd("ctx");
+result=nil;
+isolator=$recv($globals.Axolator)._on_([(1), [(2), (4)]]);
+$recv(isolator)._model_read_($self["@rootModel"],(function(r){
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx2) {
+//>>excludeEnd("ctx");
+return $recv(r)._at_put_((2),nil);
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx2) {$ctx2.fillBlock({r:r},$ctx1,1)});
+//>>excludeEnd("ctx");
+}));
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["model:read:"]=1;
+//>>excludeEnd("ctx");
+$recv(isolator)._model_read_($self["@rootModel"],(function(r){
+result=r;
+return result;
+
+}));
+$self._assert_equals_([(1), [(2), (4)]],result);
+return self;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"testRootModelReturnsIsolatedRoot",{isolator:isolator,result:result},$globals.AxolatorTest)});
+//>>excludeEnd("ctx");
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: [],
+source: "testRootModelReturnsIsolatedRoot\x0a| isolator result |\x0aresult := nil.\x0aisolator := Axolator on: #(1 #(2 4)).\x0aisolator model: rootModel read: [:r|r at: 2 put: nil].\x0aisolator model: rootModel read: [:r|result := r].\x0aself assert: #(1 #(2 4)) equals: result",
+referencedClasses: ["Axolator"],
+//>>excludeEnd("ide");
+messageSends: ["on:", "model:read:", "at:put:", "assert:equals:"]
+}),
+$globals.AxolatorTest);
+
+$core.addMethod(
+$core.method({
+selector: "testRootModelReturnsRoot",
+protocol: "tests",
+fn: function (){
+var self=this,$self=this;
+var isolator,result;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx1) {
+//>>excludeEnd("ctx");
+result=nil;
+isolator=$recv($globals.Axolator)._on_([(1), [(2), (3)]]);
+$recv(isolator)._model_read_($self["@rootModel"],(function(r){
+result=r;
+return result;
+
+}));
+$self._assert_equals_([(1), [(2), (3)]],result);
+return self;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"testRootModelReturnsRoot",{isolator:isolator,result:result},$globals.AxolatorTest)});
+//>>excludeEnd("ctx");
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: [],
+source: "testRootModelReturnsRoot\x0a| isolator result |\x0aresult := nil.\x0aisolator := Axolator on: #(1 #(2 3)).\x0aisolator model: rootModel read: [:r|result := r].\x0aself assert: #(1 #(2 3)) equals: result",
+referencedClasses: ["Axolator"],
+//>>excludeEnd("ide");
+messageSends: ["on:", "model:read:", "assert:equals:"]
+}),
+$globals.AxolatorTest);
+
+
+
 $core.addClass("PlainConsumeTransformTest", $globals.TestCase, [], "Axxord-Tests");
 $core.addMethod(
 $core.method({

+ 136 - 0
src/Axxord-Tests.st

@@ -1,4 +1,140 @@
 Smalltalk createPackage: 'Axxord-Tests'!
+TestCase subclass: #AxolatorTest
+	instanceVariableNames: 'rootModel'
+	package: 'Axxord-Tests'!
+
+!AxolatorTest methodsFor: 'running'!
+
+setUp
+
+rootModel := EavModel new
+	getBlock: [:x | x root];
+    putBlock: [:x :y | x root: y].
+! !
+
+!AxolatorTest methodsFor: 'tests'!
+
+testNontrivialModelGetsAppropriateValueForModification
+| isolator model result |
+result := nil.
+isolator := Axolator 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].
+isolator model: model modify: [:r|result := r].
+self assert: #(1 #(2 5)) equals: result
+!
+
+testNontrivialModelModifiesAppropriateValue
+| isolator model result |
+result := nil.
+isolator := Axolator 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].
+isolator model: model modify: [:r|#new].
+isolator model: model read: [:r|result := r].
+self assert: #new equals: result.
+isolator model: rootModel read: [:r|result := r].
+self assert: #{ 'foo' -> #('bar' #new 'baz'). 'moo' -> 'zoo' } equals: result
+!
+
+testNontrivialModelReturnsAppropriateValue
+| isolator model result |
+result := nil.
+isolator := Axolator on: #{ 'foo' -> #('bar' #(1 #(2 3)) 'baz'). 'moo' -> 'zoo' }.
+model := EavModel new getBlock: [ :x | (x root at: 'foo') at: 2 ].
+isolator model: model read: [:r|result := r].
+self assert: #(1 #(2 3)) equals: result
+!
+
+testRootModelExaminesThenModifiesRoot
+| isolator result |
+result := nil.
+isolator := Axolator on: #(1 #(2 3)).
+isolator model: rootModel modify: [:r|r second].
+isolator model: rootModel read: [:r|result := r].
+self assert: #(2 3) equals: result
+!
+
+testRootModelGetsRootForModification
+| isolator result |
+result := nil.
+isolator := Axolator on: #(2 #(1 0)).
+isolator model: rootModel modify: [:r|result := r].
+self assert: #(2 #(1 0)) equals: result
+!
+
+testRootModelModifiesAndDeeplyIsolatesInPlaceModifiedRoot
+| isolator result newValue |
+result := nil. newValue := nil.
+isolator := Axolator on: #(1 #(2 3)).
+isolator model: rootModel modify: [:r|newValue := r. r at: 1 put: 4. r].
+newValue at: 2 put: 'bar'.
+isolator model: rootModel read: [:r|result := r].
+newValue at: 2 put: 'baz'.
+self assert: #(4 #(2 3)) equals: result
+!
+
+testRootModelModifiesAndDeeplyIsolatesRoot
+| isolator result newValue |
+result := nil.
+isolator := Axolator on: #(1 #(2 3)).
+newValue := #{'foo'->#(4 5 6)}.
+isolator model: rootModel modify: [:r|newValue].
+(newValue at: 'foo') at: 1 put: 'bar'.
+isolator model: rootModel read: [:r|result := r].
+(newValue at: 'foo') at: 3 put: 'baz'.
+self assert: #{'foo'->#(4 5 6)} equals: result
+!
+
+testRootModelModifiesAndIsolatesRoot
+| isolator result newValue |
+result := nil.
+isolator := Axolator on: #(1 #(2 3)).
+newValue := #{'foo'->#(4 5 6)}.
+isolator model: rootModel modify: [:r|newValue].
+newValue at: 'foo' put: 'bar'.
+isolator model: rootModel read: [:r|result := r].
+newValue at: 'foo' put: 'baz'.
+self assert: #{'foo'->#(4 5 6)} equals: result
+!
+
+testRootModelModifiesRoot
+| isolator result |
+result := nil.
+isolator := Axolator on: #(1 #(2 3)).
+isolator model: rootModel modify: [:r|#{'foo'->#(4 5 6)}].
+isolator model: rootModel read: [:r|result := r].
+self assert: #{'foo'->#(4 5 6)} equals: result
+!
+
+testRootModelReturnsDeeplyIsolatedRoot
+| isolator result |
+result := nil.
+isolator := Axolator on: #(1 #(2 3)).
+isolator model: rootModel read: [:r|(r at: 2) at: 1 put: 0].
+isolator model: rootModel read: [:r|result := r].
+self assert: #(1 #(2 3)) equals: result
+!
+
+testRootModelReturnsIsolatedRoot
+| isolator result |
+result := nil.
+isolator := Axolator on: #(1 #(2 4)).
+isolator model: rootModel read: [:r|r at: 2 put: nil].
+isolator model: rootModel read: [:r|result := r].
+self assert: #(1 #(2 4)) equals: result
+!
+
+testRootModelReturnsRoot
+| isolator result |
+result := nil.
+isolator := Axolator on: #(1 #(2 3)).
+isolator model: rootModel read: [:r|result := r].
+self assert: #(1 #(2 3)) equals: result
+! !
+
 TestCase subclass: #PlainConsumeTransformTest
 	instanceVariableNames: ''
 	package: 'Axxord-Tests'!

+ 113 - 0
src/Axxord.js

@@ -208,6 +208,119 @@ messageSends: ["tokenize:", "do:", "whileTrue:", "and:", "notEmpty", "=", "first
 $globals.Axes.a$cls);
 
 
+$core.addClass("Axolator", $globals.Object, ["root"], "Axxord");
+$core.addMethod(
+$core.method({
+selector: "model:modify:",
+protocol: "action",
+fn: function (anEavModel,aBlock){
+var self=this,$self=this;
+var newValue;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx1) {
+//>>excludeEnd("ctx");
+newValue=$recv(aBlock)._value_($recv(anEavModel)._on_(self));
+$recv(anEavModel)._on_put_(self,$recv(newValue)._deepCopy());
+return self;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"model:modify:",{anEavModel:anEavModel,aBlock:aBlock,newValue:newValue},$globals.Axolator)});
+//>>excludeEnd("ctx");
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: ["anEavModel", "aBlock"],
+source: "model: anEavModel modify: aBlock\x0a\x0a| newValue |\x0anewValue := aBlock value: (anEavModel on: self).\x0aanEavModel on: self put: newValue deepCopy",
+referencedClasses: [],
+//>>excludeEnd("ide");
+messageSends: ["value:", "on:", "on:put:", "deepCopy"]
+}),
+$globals.Axolator);
+
+$core.addMethod(
+$core.method({
+selector: "model:read:",
+protocol: "action",
+fn: function (anEavModel,aBlock){
+var self=this,$self=this;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx1) {
+//>>excludeEnd("ctx");
+$recv(aBlock)._value_($recv($recv(anEavModel)._on_(self))._deepCopy());
+return self;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"model:read:",{anEavModel:anEavModel,aBlock:aBlock},$globals.Axolator)});
+//>>excludeEnd("ctx");
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: ["anEavModel", "aBlock"],
+source: "model: anEavModel read: aBlock\x0a\x0aaBlock value: (anEavModel on: self) deepCopy",
+referencedClasses: [],
+//>>excludeEnd("ide");
+messageSends: ["value:", "deepCopy", "on:"]
+}),
+$globals.Axolator);
+
+$core.addMethod(
+$core.method({
+selector: "root",
+protocol: "accessing",
+fn: function (){
+var self=this,$self=this;
+return $self["@root"];
+
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: [],
+source: "root\x0a\x0a^root",
+referencedClasses: [],
+//>>excludeEnd("ide");
+messageSends: []
+}),
+$globals.Axolator);
+
+$core.addMethod(
+$core.method({
+selector: "root:",
+protocol: "accessing",
+fn: function (anObject){
+var self=this,$self=this;
+$self["@root"]=anObject;
+return self;
+
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: ["anObject"],
+source: "root: anObject\x0a\x0aroot := anObject",
+referencedClasses: [],
+//>>excludeEnd("ide");
+messageSends: []
+}),
+$globals.Axolator);
+
+
+$core.addMethod(
+$core.method({
+selector: "on:",
+protocol: "instance creation",
+fn: function (anObject){
+var self=this,$self=this;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx1) {
+//>>excludeEnd("ctx");
+return $recv($self._new())._root_(anObject);
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"on:",{anObject:anObject},$globals.Axolator.a$cls)});
+//>>excludeEnd("ctx");
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: ["anObject"],
+source: "on: anObject\x0a^self new root: anObject",
+referencedClasses: [],
+//>>excludeEnd("ide");
+messageSends: ["root:", "new"]
+}),
+$globals.Axolator.a$cls);
+
+
 $core.addClass("Axon", $globals.Object, ["factory"], "Axxord");
 //>>excludeStart("ide", pragmas.excludeIdeData);
 $globals.Axon.comment="I represent a pub-sub based on a key (called 'aspect').\x0aI manage aspect-block subscriptions (called 'interests') as well as run blocks of dirtied interests.\x0aThe interest objects are responsible of decision if the change of an aspect is relevant for them.\x0aInterest object must be subclasses of `AxonInterest`.\x0a\x0aMy subclasses must provide implementation for:\x0a\x0a - add:\x0a - do:\x0a - clean";

+ 36 - 0
src/Axxord.st

@@ -24,6 +24,42 @@ parse: message
 	^ result
 ! !
 
+Object subclass: #Axolator
+	instanceVariableNames: 'root'
+	package: 'Axxord'!
+
+!Axolator methodsFor: 'accessing'!
+
+root
+
+^root
+!
+
+root: anObject
+
+root := anObject
+! !
+
+!Axolator 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
+! !
+
+!Axolator class methodsFor: 'instance creation'!
+
+on: anObject
+^self new root: anObject
+! !
+
 Object subclass: #Axon
 	instanceVariableNames: 'factory'
 	package: 'Axxord'!