From bee248312bcb4b1db5b9ea24baa6fec397b2ae6f Mon Sep 17 00:00:00 2001 From: Javier Abadia Date: Mon, 20 Jan 2014 00:30:40 +0100 Subject: [PATCH 1/8] it's nearly working --- lib/edit/graphicsStore.js | 26 +++++++ test/SpecRunner.gs.html | 122 +++++++++++++++++++++++++++++++++ test/spec/graphicsStoreSpec.js | 52 ++++++++++++++ 3 files changed, 200 insertions(+) create mode 100644 lib/edit/graphicsStore.js create mode 100644 test/SpecRunner.gs.html create mode 100644 test/spec/graphicsStoreSpec.js diff --git a/lib/edit/graphicsStore.js b/lib/edit/graphicsStore.js new file mode 100644 index 0000000..d61b3b6 --- /dev/null +++ b/lib/edit/graphicsStore.js @@ -0,0 +1,26 @@ +"use strict" + +define(["esri/graphic"],function(Graphic) +{ + return { + serialize: function(graphic) + { + var json = graphic.toJson(); + var str = JSON.stringify(json); + console.log("graphic",graphic); + // console.log("json", json); + // console.log("str", str); + return str; + }, + + deserialize: function(str) + { + var json = JSON.parse(str); + var graphic = new Graphic(json); + // console.log("str", str); + // console.log("json",json); + console.log("graphic",graphic); + return graphic; + } + } +}); diff --git a/test/SpecRunner.gs.html b/test/SpecRunner.gs.html new file mode 100644 index 0000000..0383dc7 --- /dev/null +++ b/test/SpecRunner.gs.html @@ -0,0 +1,122 @@ + + + + Jasmine Spec Runner - Graphics Store + + + + + + + + + + + + + + + + + + + +
+ + + diff --git a/test/spec/graphicsStoreSpec.js b/test/spec/graphicsStoreSpec.js new file mode 100644 index 0000000..10c4323 --- /dev/null +++ b/test/spec/graphicsStoreSpec.js @@ -0,0 +1,52 @@ +"use strict" + +describe("Serialize/Deserialize Graphics", function() +{ + it("validate geometry objects", function() + { + // sanity checks on test data + expect(typeof(g_test)).toBe("object"); + + // geometry + expect(typeof(g_test.point)).toBe("object"); + expect(g_test.point.declaredClass).toBe("esri.geometry.Point"); + expect(g_test.point.type).toBe("point"); + expect(g_test.point.spatialReference.wkid).toEqual(4326); + + expect(typeof(g_test.line)).toBe("object"); + expect(g_test.line.declaredClass).toBe("esri.geometry.Polyline"); + expect(g_test.line.type).toBe("polyline"); + expect(g_test.line.spatialReference.wkid).toEqual(4326); + + expect(typeof(g_test.polygon)).toBe("object"); + expect(g_test.polygon.declaredClass).toBe("esri.geometry.Polygon"); + expect(g_test.polygon.type).toBe("polygon"); + expect(g_test.polygon.spatialReference.wkid).toEqual(4326); + + // symbols + expect(typeof(g_test.pointSymbol)).toBe("object"); + expect(g_test.pointSymbol.declaredClass).toBe("esri.symbol.SimpleMarkerSymbol"); + expect(g_test.pointSymbol.style).toBe("circle"); + + // features + expect(typeof(g_test.pointFeature)).toBe("object"); + expect(g_test.pointFeature.declaredClass).toBe("esri.Graphic"); + expect(g_test.pointFeature.geometry).toEqual(g_test.point); + expect(g_test.pointFeature.symbol).toEqual(g_test.pointSymbol); + expect(typeof(g_test.pointFeature.attributes)).toBe("object"); + }); + + var str; + + it("serialize graphic - point", function() + { + str = g_graphicsStore.serialize(g_test.pointFeature); + expect(typeof(str)).toBe("string"); + }); + + it("deserialize graphic - point", function() + { + var graphic = g_graphicsStore.deserialize(str); + expect(graphic).toEqual(g_test.pointFeature); + }); +}); \ No newline at end of file From 88752ba1fb26023d82f16f2d8d51b6018ad59147 Mon Sep 17 00:00:00 2001 From: Javier Abadia Date: Mon, 20 Jan 2014 11:55:43 +0100 Subject: [PATCH 2/8] serialization/deserialization: simple and correct --- lib/edit/graphicsStore.js | 13 +-- test/SpecRunner.gs.html | 32 +++++- test/spec/graphicsStoreSpec.js | 197 +++++++++++++++++++++++++++------ 3 files changed, 195 insertions(+), 47 deletions(-) diff --git a/lib/edit/graphicsStore.js b/lib/edit/graphicsStore.js index d61b3b6..fe2b197 100644 --- a/lib/edit/graphicsStore.js +++ b/lib/edit/graphicsStore.js @@ -6,10 +6,12 @@ define(["esri/graphic"],function(Graphic) serialize: function(graphic) { var json = graphic.toJson(); - var str = JSON.stringify(json); - console.log("graphic",graphic); - // console.log("json", json); - // console.log("str", str); + var jsonClean = // keep only attributes and geometry, that are the values that get sent to the server by applyEdits() + { + attributes: json.attributes, + geometry: json.geometry + } + var str = JSON.stringify(jsonClean); return str; }, @@ -17,9 +19,6 @@ define(["esri/graphic"],function(Graphic) { var json = JSON.parse(str); var graphic = new Graphic(json); - // console.log("str", str); - // console.log("json",json); - console.log("graphic",graphic); return graphic; } } diff --git a/test/SpecRunner.gs.html b/test/SpecRunner.gs.html index 0383dc7..c0c7bd3 100644 --- a/test/SpecRunner.gs.html +++ b/test/SpecRunner.gs.html @@ -2,6 +2,7 @@ "http://www.w3.org/TR/html4/loose.dtd"> + Jasmine Spec Runner - Graphics Store @@ -30,14 +31,14 @@ var g_graphicsStore; require(["esri/map", - "esri/layers/GraphicsLayer", "esri/graphic", "esri/symbols/SimpleFillSymbol", "esri/symbols/SimpleMarkerSymbol", "esri/SpatialReference", - "esri/geometry", + "esri/layers/GraphicsLayer", "esri/graphic", "esri/symbols/SimpleFillSymbol", "esri/symbols/SimpleMarkerSymbol", "esri/symbols/SimpleLineSymbol", + "esri/SpatialReference","esri/geometry", "edit/graphicsStore", "dojo/dom", "dojo/on", "dojo/query", "dojo/dom-construct", "dojo/domReady!"], function(Map, - GraphicsLayer, Graphic, SimpleFillSymbol, SimpleMarkerSymbol, SpatialReference, - geometry, + GraphicsLayer, Graphic, SimpleFillSymbol, SimpleMarkerSymbol, SimpleLineSymbol, + SpatialReference, geometry, graphicsStore, dom, on, query, domConstruct) @@ -68,9 +69,28 @@ }); // some symbols - g_test.pointSymbol = new SimpleMarkerSymbol(); + g_test.pointSymbol = new SimpleMarkerSymbol({"color": [255,255,255,64], + "size": 12, "angle": -30, + "xoffset": 0, "yoffset": 0, + "type": "esriSMS", "style": "esriSMSCircle", + "outline": { "color": [0,0,0,255], "width": 1, "type": "esriSLS", "style": "esriSLSSolid"} + }); - g_test.pointFeature = new Graphic( g_test.point, g_test.pointSymbol, {"name": "the name of the feature", "objectid":2} ); + g_test.lineSymbol = new SimpleLineSymbol({ + "type": "esriSLS", "style": "esriSLSDot", + "color": [115,76,0,255],"width": 1 + }); + + g_test.polygonSymbol = new SimpleFillSymbol({ + "type": "esriSFS", + "style": "esriSFSSolid", + "color": [115,76,0,255], + "outline": { "type": "esriSLS", "style": "esriSLSSolid", "color": [110,110,110,255], "width": 1 } + }); + + g_test.pointFeature = new Graphic( g_test.point, g_test.pointSymbol, {"name": "the name of the feature", "objectid":2}); + g_test.lineFeature = new Graphic( g_test.line, g_test.lineSymbol, {"nombre": "España","objectid":5}); + g_test.polygonFeature = new Graphic( g_test.polygon, g_test.polygonSymbol, {"nombre": "España","timestamp": new Date().getTime(), "objectid":5}); console.log(g_test); } diff --git a/test/spec/graphicsStoreSpec.js b/test/spec/graphicsStoreSpec.js index 10c4323..93b76d3 100644 --- a/test/spec/graphicsStoreSpec.js +++ b/test/spec/graphicsStoreSpec.js @@ -2,51 +2,180 @@ describe("Serialize/Deserialize Graphics", function() { - it("validate geometry objects", function() + describe("Sanity Check", function() { - // sanity checks on test data - expect(typeof(g_test)).toBe("object"); + it("validate geometry objects", function() + { + // sanity checks on test data + expect(typeof(g_test)).toBe("object"); - // geometry - expect(typeof(g_test.point)).toBe("object"); - expect(g_test.point.declaredClass).toBe("esri.geometry.Point"); - expect(g_test.point.type).toBe("point"); - expect(g_test.point.spatialReference.wkid).toEqual(4326); + // geometry + expect(typeof(g_test.point)).toBe("object"); + expect(g_test.point.declaredClass).toBe("esri.geometry.Point"); + expect(g_test.point.type).toBe("point"); + expect(g_test.point.spatialReference.wkid).toEqual(4326); - expect(typeof(g_test.line)).toBe("object"); - expect(g_test.line.declaredClass).toBe("esri.geometry.Polyline"); - expect(g_test.line.type).toBe("polyline"); - expect(g_test.line.spatialReference.wkid).toEqual(4326); + expect(typeof(g_test.line)).toBe("object"); + expect(g_test.line.declaredClass).toBe("esri.geometry.Polyline"); + expect(g_test.line.type).toBe("polyline"); + expect(g_test.line.spatialReference.wkid).toEqual(4326); - expect(typeof(g_test.polygon)).toBe("object"); - expect(g_test.polygon.declaredClass).toBe("esri.geometry.Polygon"); - expect(g_test.polygon.type).toBe("polygon"); - expect(g_test.polygon.spatialReference.wkid).toEqual(4326); + expect(typeof(g_test.polygon)).toBe("object"); + expect(g_test.polygon.declaredClass).toBe("esri.geometry.Polygon"); + expect(g_test.polygon.type).toBe("polygon"); + expect(g_test.polygon.spatialReference.wkid).toEqual(4326); + }); - // symbols - expect(typeof(g_test.pointSymbol)).toBe("object"); - expect(g_test.pointSymbol.declaredClass).toBe("esri.symbol.SimpleMarkerSymbol"); - expect(g_test.pointSymbol.style).toBe("circle"); + it("validate symbols", function() + { + // symbols + expect(typeof(g_test.pointSymbol)).toBe("object"); + expect(g_test.pointSymbol.declaredClass).toBe("esri.symbol.SimpleMarkerSymbol"); + expect(g_test.pointSymbol.style).toBe("circle"); - // features - expect(typeof(g_test.pointFeature)).toBe("object"); - expect(g_test.pointFeature.declaredClass).toBe("esri.Graphic"); - expect(g_test.pointFeature.geometry).toEqual(g_test.point); - expect(g_test.pointFeature.symbol).toEqual(g_test.pointSymbol); - expect(typeof(g_test.pointFeature.attributes)).toBe("object"); + expect(typeof(g_test.lineSymbol)).toBe("object"); + expect(g_test.lineSymbol.declaredClass).toBe("esri.symbol.SimpleLineSymbol"); + expect(g_test.lineSymbol.style).toBe("dot"); + + expect(typeof(g_test.polygonSymbol)).toBe("object"); + expect(g_test.polygonSymbol.declaredClass).toBe("esri.symbol.SimpleFillSymbol"); + expect(g_test.polygonSymbol.style).toBe("solid"); + }); + + it("validate features", function() + { + // features + expect(typeof(g_test.pointFeature)).toBe("object"); + expect(g_test.pointFeature.declaredClass).toBe("esri.Graphic"); + expect(g_test.pointFeature.geometry).toEqual(g_test.point); + expect(g_test.pointFeature.symbol).toEqual(g_test.pointSymbol); + expect(typeof(g_test.pointFeature.attributes)).toBe("object"); + + expect(typeof(g_test.lineFeature)).toBe("object"); + expect(g_test.lineFeature.declaredClass).toBe("esri.Graphic"); + expect(g_test.lineFeature.geometry).toEqual(g_test.line); + expect(g_test.lineFeature.symbol).toEqual(g_test.lineSymbol); + expect(typeof(g_test.lineFeature.attributes)).toBe("object"); + + expect(typeof(g_test.polygonFeature)).toBe("object"); + expect(g_test.polygonFeature.declaredClass).toBe("esri.Graphic"); + expect(g_test.polygonFeature.geometry).toEqual(g_test.polygon); + expect(g_test.polygonFeature.symbol).toEqual(g_test.polygonSymbol); + expect(typeof(g_test.polygonFeature.attributes)).toBe("object"); + }); }); - var str; - - it("serialize graphic - point", function() + describe("Serialize/Deserialize Point", function() { - str = g_graphicsStore.serialize(g_test.pointFeature); - expect(typeof(str)).toBe("string"); + var str, graphic; + + it("serialize", function() + { + str = g_graphicsStore.serialize(g_test.pointFeature); + expect(typeof(str)).toBe("string"); + }); + + it("deserialize", function() + { + graphic = g_graphicsStore.deserialize(str); + expect(typeof(graphic)).toBe("object"); + expect(graphic.declaredClass).toEqual("esri.Graphic"); + }); + + it("deserialize - attributes", function() + { + expect(graphic.attributes).toEqual(g_test.pointFeature.attributes); + }); + + it("deserialize - geometry", function() + { + expect(graphic.geometry).toEqual(g_test.pointFeature.geometry); + }); + + it("deserialize - symbol should be null", function() + { + expect(graphic.symbol).toBeNull(); + }); + + it("deserialize - infoTemplate should be null", function() + { + expect(graphic.infoTemplate).toBeNull(); + }); }); - it("deserialize graphic - point", function() + describe("Serialize/Deserialize Polyline", function() { - var graphic = g_graphicsStore.deserialize(str); - expect(graphic).toEqual(g_test.pointFeature); + var str, graphic; + + it("serialize", function() + { + str = g_graphicsStore.serialize(g_test.lineFeature); + expect(typeof(str)).toBe("string"); + }); + + it("deserialize", function() + { + graphic = g_graphicsStore.deserialize(str); + expect(typeof(graphic)).toBe("object"); + expect(graphic.declaredClass).toEqual("esri.Graphic"); + }); + + it("deserialize - attributes", function() + { + expect(graphic.attributes).toEqual(g_test.lineFeature.attributes); + }); + + it("deserialize - geometry", function() + { + expect(graphic.geometry).toEqual(g_test.lineFeature.geometry); + }); + + it("deserialize - symbol should be null", function() + { + expect(graphic.symbol).toBeNull(); + }); + + it("deserialize - infoTemplate should be null", function() + { + expect(graphic.infoTemplate).toBeNull(); + }); + }); + + describe("Serialize/Deserialize Polygon", function() + { + var str, graphic; + + it("serialize", function() + { + str = g_graphicsStore.serialize(g_test.polygonFeature); + expect(typeof(str)).toBe("string"); + }); + + it("deserialize", function() + { + graphic = g_graphicsStore.deserialize(str); + expect(typeof(graphic)).toBe("object"); + expect(graphic.declaredClass).toEqual("esri.Graphic"); + }); + + it("deserialize - attributes", function() + { + expect(graphic.attributes).toEqual(g_test.polygonFeature.attributes); + }); + + it("deserialize - geometry", function() + { + expect(graphic.geometry).toEqual(g_test.polygonFeature.geometry); + }); + + it("deserialize - symbol should be null", function() + { + expect(graphic.symbol).toBeNull(); + }); + + it("deserialize - infoTemplate should be null", function() + { + expect(graphic.infoTemplate).toBeNull(); + }); }); }); \ No newline at end of file From f09579dd6a8bf32d318bc95daddb8deadb019b0d Mon Sep 17 00:00:00 2001 From: Javier Abadia Date: Mon, 20 Jan 2014 12:26:52 +0100 Subject: [PATCH 3/8] better explanation --- lib/edit/graphicsStore.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/edit/graphicsStore.js b/lib/edit/graphicsStore.js index fe2b197..b68c584 100644 --- a/lib/edit/graphicsStore.js +++ b/lib/edit/graphicsStore.js @@ -5,8 +5,11 @@ define(["esri/graphic"],function(Graphic) return { serialize: function(graphic) { + // keep only attributes and geometry, that are the values that get sent to the server by applyEdits() + // see http://resources.arcgis.com/en/help/arcgis-rest-api/index.html#/Apply_Edits_Feature_Service_Layer/02r3000000r6000000/ + // use graphic's built-in serializing method var json = graphic.toJson(); - var jsonClean = // keep only attributes and geometry, that are the values that get sent to the server by applyEdits() + var jsonClean = { attributes: json.attributes, geometry: json.geometry From f3f1d9fc531ce79e7ed2538e1587b7281045d42e Mon Sep 17 00:00:00 2001 From: Javier Abadia Date: Mon, 20 Jan 2014 17:58:57 +0100 Subject: [PATCH 4/8] low level management of pending edits storage in localStorage, looking very good --- lib/edit/graphicsStore.js | 108 +++++++++++++++++++++++++++++++++ test/spec/graphicsStoreSpec.js | 25 ++++++++ 2 files changed, 133 insertions(+) diff --git a/lib/edit/graphicsStore.js b/lib/edit/graphicsStore.js index b68c584..f4e83d4 100644 --- a/lib/edit/graphicsStore.js +++ b/lib/edit/graphicsStore.js @@ -2,7 +2,83 @@ define(["esri/graphic"],function(Graphic) { + /* private consts */ + var EDITS_QUEUE_KEY = "esriEditsQueue"; + var REDO_QUEUE_KEY = "esriRedoQueue"; + var SEPARATOR = "|@|"; + return { + + // + // edit queue management + // + + ADD: "add", + UPDATE: "update", + DELETE:"delete", + + appendEdit: function(operation,layer,graphic) + { + var edit = { + operation: operation, + layer: layer, + graphic: this.serialize(graphic) + } + + var edits = this._retrieveEditsQueue(); + edits.push(edit); + this._storeEditsQueue(edits); + }, + + pendingEditsCount: function() + { + var storedValue = window.localStorage.getItem(this.EDITS_QUEUE_KEY) || ""; + + if( storedValue == "" ) + return 0; // fast easy case + + var editsArray = this._unpackArrayOfEdits(storedValue); + return editsArray.length; + }, + + resetEditsQueue: function() + { + window.localStorage.setItem(this.EDITS_QUEUE_KEY, ""); + }, + + popFirstEdit: function() + { + throw("not implemented"); + }, + + canUndoEdit: function() + { + var storedValue = window.localStorage.getItem(this.EDITS_QUEUE_KEY) || ""; + + return (storedValue != ""); + }, + + undoEdit: function() + { + throw("not implemented"); + + }, + + canRedoEdit: function() + { + throw("not implemented"); + + }, + + redoEdit: function() + { + throw("not implemented"); + + }, + + // + // graphic serialization/deserialization + // serialize: function(graphic) { // keep only attributes and geometry, that are the values that get sent to the server by applyEdits() @@ -23,6 +99,38 @@ define(["esri/graphic"],function(Graphic) var json = JSON.parse(str); var graphic = new Graphic(json); return graphic; + }, + + // + // internal methods + // + _retrieveEditsQueue: function() + { + var storedValue = window.localStorage.getItem(this.EDITS_QUEUE_KEY) || ""; + return this._unpackArrayOfEdits(storedValue); + }, + + _storeEditsQueue: function(edits) + { + var serializedEdits = this._packArrayOfEdits(edits); + window.localStorage.setItem(this.EDITS_QUEUE_KEY, serializedEdits); + }, + + _packArrayOfEdits: function(edits) + { + var serializedEdits = []; + edits.forEach(function(edit) + { + serializedEdits.push( JSON.stringify(edit) ); + }); + return serializedEdits.join(this.SEPARATOR); + }, + + _unpackArrayOfEdits: function(serializedEdits) + { + var edits = serializedEdits.split(this.SEPARATOR); + return edits; } + } }); diff --git a/test/spec/graphicsStoreSpec.js b/test/spec/graphicsStoreSpec.js index 93b76d3..87fc852 100644 --- a/test/spec/graphicsStoreSpec.js +++ b/test/spec/graphicsStoreSpec.js @@ -178,4 +178,29 @@ describe("Serialize/Deserialize Graphics", function() expect(graphic.infoTemplate).toBeNull(); }); }); +}); + +describe("Edit queue management", function() +{ + it("Reset edits queue", function() + { + g_graphicsStore.resetEditsQueue(); + expect(g_graphicsStore.pendingEditsCount()).toBe(0); + }); + + it("Add edits to edits queue", function() + { + g_graphicsStore.appendEdit(g_graphicsStore.ADD, 6, g_test.pointFeature); + expect(g_graphicsStore.pendingEditsCount()).toBe(1); + }); + + it("Pops edit from edits queue", function() + { + g_graphicsStore.pop + }); + + it("Undo/Redo management", function() + { + + }); }); \ No newline at end of file From f7ff11f572b43e603393b6737f860467da71ae5d Mon Sep 17 00:00:00 2001 From: Javier Abadia Date: Mon, 20 Jan 2014 23:07:48 +0100 Subject: [PATCH 5/8] serialize/deserialize don't need to be public operations serialize graphics only to JSON object... the 'edit' will be serialized to string --- lib/edit/graphicsStore.js | 34 ++++++++++++++++++---------------- test/spec/graphicsStoreSpec.js | 22 +++++++++++++--------- 2 files changed, 31 insertions(+), 25 deletions(-) diff --git a/lib/edit/graphicsStore.js b/lib/edit/graphicsStore.js index f4e83d4..eb25342 100644 --- a/lib/edit/graphicsStore.js +++ b/lib/edit/graphicsStore.js @@ -22,7 +22,7 @@ define(["esri/graphic"],function(Graphic) var edit = { operation: operation, layer: layer, - graphic: this.serialize(graphic) + graphic: this._serialize(graphic) } var edits = this._retrieveEditsQueue(); @@ -32,7 +32,7 @@ define(["esri/graphic"],function(Graphic) pendingEditsCount: function() { - var storedValue = window.localStorage.getItem(this.EDITS_QUEUE_KEY) || ""; + var storedValue = window.localStorage.getItem(EDITS_QUEUE_KEY) || ""; if( storedValue == "" ) return 0; // fast easy case @@ -43,7 +43,7 @@ define(["esri/graphic"],function(Graphic) resetEditsQueue: function() { - window.localStorage.setItem(this.EDITS_QUEUE_KEY, ""); + window.localStorage.setItem(EDITS_QUEUE_KEY, ""); }, popFirstEdit: function() @@ -53,7 +53,7 @@ define(["esri/graphic"],function(Graphic) canUndoEdit: function() { - var storedValue = window.localStorage.getItem(this.EDITS_QUEUE_KEY) || ""; + var storedValue = window.localStorage.getItem(EDITS_QUEUE_KEY) || ""; return (storedValue != ""); }, @@ -76,10 +76,14 @@ define(["esri/graphic"],function(Graphic) }, + // + // internal methods + // + // // graphic serialization/deserialization // - serialize: function(graphic) + _serialize: function(graphic) { // keep only attributes and geometry, that are the values that get sent to the server by applyEdits() // see http://resources.arcgis.com/en/help/arcgis-rest-api/index.html#/Apply_Edits_Feature_Service_Layer/02r3000000r6000000/ @@ -90,30 +94,25 @@ define(["esri/graphic"],function(Graphic) attributes: json.attributes, geometry: json.geometry } - var str = JSON.stringify(jsonClean); - return str; + return jsonClean; }, - deserialize: function(str) + _deserialize: function(json) { - var json = JSON.parse(str); var graphic = new Graphic(json); return graphic; }, - // - // internal methods - // _retrieveEditsQueue: function() { - var storedValue = window.localStorage.getItem(this.EDITS_QUEUE_KEY) || ""; + var storedValue = window.localStorage.getItem(EDITS_QUEUE_KEY) || ""; return this._unpackArrayOfEdits(storedValue); }, _storeEditsQueue: function(edits) { var serializedEdits = this._packArrayOfEdits(edits); - window.localStorage.setItem(this.EDITS_QUEUE_KEY, serializedEdits); + window.localStorage.setItem(EDITS_QUEUE_KEY, serializedEdits); }, _packArrayOfEdits: function(edits) @@ -123,12 +122,15 @@ define(["esri/graphic"],function(Graphic) { serializedEdits.push( JSON.stringify(edit) ); }); - return serializedEdits.join(this.SEPARATOR); + return serializedEdits.join(SEPARATOR); }, _unpackArrayOfEdits: function(serializedEdits) { - var edits = serializedEdits.split(this.SEPARATOR); + if( !serializedEdits ) + return []; + + var edits = serializedEdits.split(SEPARATOR); return edits; } diff --git a/test/spec/graphicsStoreSpec.js b/test/spec/graphicsStoreSpec.js index 87fc852..bc8e6a8 100644 --- a/test/spec/graphicsStoreSpec.js +++ b/test/spec/graphicsStoreSpec.js @@ -71,13 +71,13 @@ describe("Serialize/Deserialize Graphics", function() it("serialize", function() { - str = g_graphicsStore.serialize(g_test.pointFeature); - expect(typeof(str)).toBe("string"); + str = g_graphicsStore._serialize(g_test.pointFeature); + expect(typeof(str)).toBe("object"); }); it("deserialize", function() { - graphic = g_graphicsStore.deserialize(str); + graphic = g_graphicsStore._deserialize(str); expect(typeof(graphic)).toBe("object"); expect(graphic.declaredClass).toEqual("esri.Graphic"); }); @@ -109,13 +109,13 @@ describe("Serialize/Deserialize Graphics", function() it("serialize", function() { - str = g_graphicsStore.serialize(g_test.lineFeature); - expect(typeof(str)).toBe("string"); + str = g_graphicsStore._serialize(g_test.lineFeature); + expect(typeof(str)).toBe("object"); }); it("deserialize", function() { - graphic = g_graphicsStore.deserialize(str); + graphic = g_graphicsStore._deserialize(str); expect(typeof(graphic)).toBe("object"); expect(graphic.declaredClass).toEqual("esri.Graphic"); }); @@ -147,13 +147,13 @@ describe("Serialize/Deserialize Graphics", function() it("serialize", function() { - str = g_graphicsStore.serialize(g_test.polygonFeature); - expect(typeof(str)).toBe("string"); + str = g_graphicsStore._serialize(g_test.polygonFeature); + expect(typeof(str)).toBe("object"); }); it("deserialize", function() { - graphic = g_graphicsStore.deserialize(str); + graphic = g_graphicsStore._deserialize(str); expect(typeof(graphic)).toBe("object"); expect(graphic.declaredClass).toEqual("esri.Graphic"); }); @@ -192,6 +192,10 @@ describe("Edit queue management", function() { g_graphicsStore.appendEdit(g_graphicsStore.ADD, 6, g_test.pointFeature); expect(g_graphicsStore.pendingEditsCount()).toBe(1); + g_graphicsStore.appendEdit(g_graphicsStore.UPDATE, 6, g_test.polygonFeature); + expect(g_graphicsStore.pendingEditsCount()).toBe(2); + g_graphicsStore.appendEdit(g_graphicsStore.DELETE, 6, g_test.lineFeature); + expect(g_graphicsStore.pendingEditsCount()).toBe(3); }); it("Pops edit from edits queue", function() From 5733080102327a2fcc7c95d11aff55f435d7fa73 Mon Sep 17 00:00:00 2001 From: Javier Abadia Date: Tue, 21 Jan 2014 00:15:27 +0100 Subject: [PATCH 6/8] undo/redo management & tests --- lib/edit/graphicsStore.js | 108 ++++++++++++--- test/spec/graphicsStoreSpec.js | 238 ++++++++++++++++++++++++++++++--- 2 files changed, 312 insertions(+), 34 deletions(-) diff --git a/lib/edit/graphicsStore.js b/lib/edit/graphicsStore.js index eb25342..ce01f08 100644 --- a/lib/edit/graphicsStore.js +++ b/lib/edit/graphicsStore.js @@ -4,7 +4,7 @@ define(["esri/graphic"],function(Graphic) { /* private consts */ var EDITS_QUEUE_KEY = "esriEditsQueue"; - var REDO_QUEUE_KEY = "esriRedoQueue"; + var REDO_STACK_KEY = "esriRedoStack"; var SEPARATOR = "|@|"; return { @@ -26,8 +26,27 @@ define(["esri/graphic"],function(Graphic) } var edits = this._retrieveEditsQueue(); - edits.push(edit); - this._storeEditsQueue(edits); + if( this._isEditDuplicated(edit,edits) ) + { + // I still think that we shouldn't be concerned with duplicates: + // they just shouldn't exist, and if they do, then it is a bug in upper level code + console.log("duplicated", edit); + console.log("current store is", edits); + return false; // fail + } + else + { + edits.push(edit); + this._storeEditsQueue(edits); + this._storeRedoStack([]); + return true; // success + } + }, + + hasPendingEdits: function() + { + var storedValue = window.localStorage.getItem(EDITS_QUEUE_KEY) || ""; + return ( storedValue != "" ) }, pendingEditsCount: function() @@ -48,32 +67,58 @@ define(["esri/graphic"],function(Graphic) popFirstEdit: function() { - throw("not implemented"); + var edits = this._retrieveEditsQueue(); + + if( edits ) + { + var firstEdit = edits.shift(); + this._storeEditsQueue(edits); + firstEdit.graphic = this._deserialize(firstEdit.graphic); + return firstEdit; + } + else + return null; }, canUndoEdit: function() { - var storedValue = window.localStorage.getItem(EDITS_QUEUE_KEY) || ""; - - return (storedValue != ""); + return this.hasPendingEdits(); }, undoEdit: function() { - throw("not implemented"); + if(!this.canUndoEdit()) + return false; + var edits = this._retrieveEditsQueue(); + var redoStack = this._retrieveRedoStack(); + var editToUndo = edits.pop(); + redoStack.push(editToUndo); + this._storeEditsQueue(edits); + this._storeRedoStack(redoStack); + + return true; }, canRedoEdit: function() { - throw("not implemented"); - + var storedValue = window.localStorage.getItem(REDO_STACK_KEY) || ""; + return ( storedValue != "" ) }, redoEdit: function() { - throw("not implemented"); + if(!this.canRedoEdit()) + return false; + var edits = this._retrieveEditsQueue(); + var redoStack = this._retrieveRedoStack(); + var editToRedo = redoStack.pop(); + edits.push(editToRedo); + this._storeEditsQueue(edits); + this._storeRedoStack(redoStack); + + return true; }, // @@ -94,12 +139,12 @@ define(["esri/graphic"],function(Graphic) attributes: json.attributes, geometry: json.geometry } - return jsonClean; + return JSON.stringify(jsonClean); }, _deserialize: function(json) { - var graphic = new Graphic(json); + var graphic = new Graphic(JSON.parse(json)); return graphic; }, @@ -115,6 +160,18 @@ define(["esri/graphic"],function(Graphic) window.localStorage.setItem(EDITS_QUEUE_KEY, serializedEdits); }, + _retrieveRedoStack: function() + { + var storedValue = window.localStorage.getItem(REDO_STACK_KEY) || ""; + return this._unpackArrayOfEdits(storedValue); + }, + + _storeRedoStack: function(edits) + { + var serializedEdits = this._packArrayOfEdits(edits); + window.localStorage.setItem(REDO_STACK_KEY, serializedEdits); + }, + _packArrayOfEdits: function(edits) { var serializedEdits = []; @@ -130,9 +187,28 @@ define(["esri/graphic"],function(Graphic) if( !serializedEdits ) return []; - var edits = serializedEdits.split(SEPARATOR); - return edits; - } + var edits = []; + serializedEdits.split(SEPARATOR).forEach( function(serializedEdit) + { + edits.push( JSON.parse(serializedEdit) ); + }); + return edits; + }, + + _isEditDuplicated: function(newEdit,edits) + { + for(var i=0; i Date: Tue, 21 Jan 2014 00:26:11 +0100 Subject: [PATCH 7/8] reorganized tests and methods --- lib/edit/graphicsStore.js | 37 +- test/spec/graphicsStoreSpec.js | 743 +++++++++++++++++---------------- 2 files changed, 402 insertions(+), 378 deletions(-) diff --git a/lib/edit/graphicsStore.js b/lib/edit/graphicsStore.js index ce01f08..82fb0a9 100644 --- a/lib/edit/graphicsStore.js +++ b/lib/edit/graphicsStore.js @@ -10,14 +10,16 @@ define(["esri/graphic"],function(Graphic) return { // - // edit queue management + // public interface // + // enum + ADD: "add", UPDATE: "update", DELETE:"delete", - appendEdit: function(operation,layer,graphic) + pushEdit: function(operation,layer,graphic) { var edit = { operation: operation, @@ -43,6 +45,21 @@ define(["esri/graphic"],function(Graphic) } }, + popFirstEdit: function() + { + var edits = this._retrieveEditsQueue(); + + if( edits ) + { + var firstEdit = edits.shift(); + this._storeEditsQueue(edits); + firstEdit.graphic = this._deserialize(firstEdit.graphic); + return firstEdit; + } + else + return null; + }, + hasPendingEdits: function() { var storedValue = window.localStorage.getItem(EDITS_QUEUE_KEY) || ""; @@ -63,22 +80,10 @@ define(["esri/graphic"],function(Graphic) resetEditsQueue: function() { window.localStorage.setItem(EDITS_QUEUE_KEY, ""); + window.localStorage.setItem(REDO_STACK_KEY,""); }, - popFirstEdit: function() - { - var edits = this._retrieveEditsQueue(); - - if( edits ) - { - var firstEdit = edits.shift(); - this._storeEditsQueue(edits); - firstEdit.graphic = this._deserialize(firstEdit.graphic); - return firstEdit; - } - else - return null; - }, + // undo / redo canUndoEdit: function() { diff --git a/test/spec/graphicsStoreSpec.js b/test/spec/graphicsStoreSpec.js index 7fdca36..2f9cc93 100644 --- a/test/spec/graphicsStoreSpec.js +++ b/test/spec/graphicsStoreSpec.js @@ -1,412 +1,431 @@ "use strict" -describe("Serialize/Deserialize Graphics", function() +describe("Internal Methods", function() { - describe("Sanity Check", function() + describe("Serialize/Deserialize Graphics", function() { - it("validate geometry objects", function() + describe("Sanity Check", function() { - // sanity checks on test data - expect(typeof(g_test)).toBe("object"); + it("validate geometry objects", function() + { + // sanity checks on test data + expect(typeof(g_test)).toBe("object"); - // geometry - expect(typeof(g_test.point)).toBe("object"); - expect(g_test.point.declaredClass).toBe("esri.geometry.Point"); - expect(g_test.point.type).toBe("point"); - expect(g_test.point.spatialReference.wkid).toEqual(4326); + // geometry + expect(typeof(g_test.point)).toBe("object"); + expect(g_test.point.declaredClass).toBe("esri.geometry.Point"); + expect(g_test.point.type).toBe("point"); + expect(g_test.point.spatialReference.wkid).toEqual(4326); - expect(typeof(g_test.line)).toBe("object"); - expect(g_test.line.declaredClass).toBe("esri.geometry.Polyline"); - expect(g_test.line.type).toBe("polyline"); - expect(g_test.line.spatialReference.wkid).toEqual(4326); + expect(typeof(g_test.line)).toBe("object"); + expect(g_test.line.declaredClass).toBe("esri.geometry.Polyline"); + expect(g_test.line.type).toBe("polyline"); + expect(g_test.line.spatialReference.wkid).toEqual(4326); - expect(typeof(g_test.polygon)).toBe("object"); - expect(g_test.polygon.declaredClass).toBe("esri.geometry.Polygon"); - expect(g_test.polygon.type).toBe("polygon"); - expect(g_test.polygon.spatialReference.wkid).toEqual(4326); + expect(typeof(g_test.polygon)).toBe("object"); + expect(g_test.polygon.declaredClass).toBe("esri.geometry.Polygon"); + expect(g_test.polygon.type).toBe("polygon"); + expect(g_test.polygon.spatialReference.wkid).toEqual(4326); + }); + + it("validate symbols", function() + { + // symbols + expect(typeof(g_test.pointSymbol)).toBe("object"); + expect(g_test.pointSymbol.declaredClass).toBe("esri.symbol.SimpleMarkerSymbol"); + expect(g_test.pointSymbol.style).toBe("circle"); + + expect(typeof(g_test.lineSymbol)).toBe("object"); + expect(g_test.lineSymbol.declaredClass).toBe("esri.symbol.SimpleLineSymbol"); + expect(g_test.lineSymbol.style).toBe("dot"); + + expect(typeof(g_test.polygonSymbol)).toBe("object"); + expect(g_test.polygonSymbol.declaredClass).toBe("esri.symbol.SimpleFillSymbol"); + expect(g_test.polygonSymbol.style).toBe("solid"); + }); + + it("validate features", function() + { + // features + expect(typeof(g_test.pointFeature)).toBe("object"); + expect(g_test.pointFeature.declaredClass).toBe("esri.Graphic"); + expect(g_test.pointFeature.geometry).toEqual(g_test.point); + expect(g_test.pointFeature.symbol).toEqual(g_test.pointSymbol); + expect(typeof(g_test.pointFeature.attributes)).toBe("object"); + + expect(typeof(g_test.lineFeature)).toBe("object"); + expect(g_test.lineFeature.declaredClass).toBe("esri.Graphic"); + expect(g_test.lineFeature.geometry).toEqual(g_test.line); + expect(g_test.lineFeature.symbol).toEqual(g_test.lineSymbol); + expect(typeof(g_test.lineFeature.attributes)).toBe("object"); + + expect(typeof(g_test.polygonFeature)).toBe("object"); + expect(g_test.polygonFeature.declaredClass).toBe("esri.Graphic"); + expect(g_test.polygonFeature.geometry).toEqual(g_test.polygon); + expect(g_test.polygonFeature.symbol).toEqual(g_test.polygonSymbol); + expect(typeof(g_test.polygonFeature.attributes)).toBe("object"); + }); }); - it("validate symbols", function() + describe("Serialize/Deserialize Point", function() { - // symbols - expect(typeof(g_test.pointSymbol)).toBe("object"); - expect(g_test.pointSymbol.declaredClass).toBe("esri.symbol.SimpleMarkerSymbol"); - expect(g_test.pointSymbol.style).toBe("circle"); + var str, graphic; - expect(typeof(g_test.lineSymbol)).toBe("object"); - expect(g_test.lineSymbol.declaredClass).toBe("esri.symbol.SimpleLineSymbol"); - expect(g_test.lineSymbol.style).toBe("dot"); + it("serialize", function() + { + str = g_graphicsStore._serialize(g_test.pointFeature); + expect(typeof(str)).toBe("string"); + }); - expect(typeof(g_test.polygonSymbol)).toBe("object"); - expect(g_test.polygonSymbol.declaredClass).toBe("esri.symbol.SimpleFillSymbol"); - expect(g_test.polygonSymbol.style).toBe("solid"); + it("deserialize", function() + { + graphic = g_graphicsStore._deserialize(str); + expect(typeof(graphic)).toBe("object"); + expect(graphic.declaredClass).toEqual("esri.Graphic"); + }); + + it("deserialize - attributes", function() + { + expect(graphic.attributes).toEqual(g_test.pointFeature.attributes); + }); + + it("deserialize - geometry", function() + { + expect(graphic.geometry).toEqual(g_test.pointFeature.geometry); + }); + + it("deserialize - symbol should be null", function() + { + expect(graphic.symbol).toBeNull(); + }); + + it("deserialize - infoTemplate should be null", function() + { + expect(graphic.infoTemplate).toBeNull(); + }); }); - it("validate features", function() + describe("Serialize/Deserialize Polyline", function() { - // features - expect(typeof(g_test.pointFeature)).toBe("object"); - expect(g_test.pointFeature.declaredClass).toBe("esri.Graphic"); - expect(g_test.pointFeature.geometry).toEqual(g_test.point); - expect(g_test.pointFeature.symbol).toEqual(g_test.pointSymbol); - expect(typeof(g_test.pointFeature.attributes)).toBe("object"); + var str, graphic; - expect(typeof(g_test.lineFeature)).toBe("object"); - expect(g_test.lineFeature.declaredClass).toBe("esri.Graphic"); - expect(g_test.lineFeature.geometry).toEqual(g_test.line); - expect(g_test.lineFeature.symbol).toEqual(g_test.lineSymbol); - expect(typeof(g_test.lineFeature.attributes)).toBe("object"); + it("serialize", function() + { + str = g_graphicsStore._serialize(g_test.lineFeature); + expect(typeof(str)).toBe("string"); + }); - expect(typeof(g_test.polygonFeature)).toBe("object"); - expect(g_test.polygonFeature.declaredClass).toBe("esri.Graphic"); - expect(g_test.polygonFeature.geometry).toEqual(g_test.polygon); - expect(g_test.polygonFeature.symbol).toEqual(g_test.polygonSymbol); - expect(typeof(g_test.polygonFeature.attributes)).toBe("object"); - }); - }); + it("deserialize", function() + { + graphic = g_graphicsStore._deserialize(str); + expect(typeof(graphic)).toBe("object"); + expect(graphic.declaredClass).toEqual("esri.Graphic"); + }); - describe("Serialize/Deserialize Point", function() - { - var str, graphic; + it("deserialize - attributes", function() + { + expect(graphic.attributes).toEqual(g_test.lineFeature.attributes); + }); - it("serialize", function() - { - str = g_graphicsStore._serialize(g_test.pointFeature); - expect(typeof(str)).toBe("string"); + it("deserialize - geometry", function() + { + expect(graphic.geometry).toEqual(g_test.lineFeature.geometry); + }); + + it("deserialize - symbol should be null", function() + { + expect(graphic.symbol).toBeNull(); + }); + + it("deserialize - infoTemplate should be null", function() + { + expect(graphic.infoTemplate).toBeNull(); + }); }); - it("deserialize", function() + describe("Serialize/Deserialize Polygon", function() { - graphic = g_graphicsStore._deserialize(str); - expect(typeof(graphic)).toBe("object"); - expect(graphic.declaredClass).toEqual("esri.Graphic"); - }); + var str, graphic; - it("deserialize - attributes", function() - { - expect(graphic.attributes).toEqual(g_test.pointFeature.attributes); - }); + it("serialize", function() + { + str = g_graphicsStore._serialize(g_test.polygonFeature); + expect(typeof(str)).toBe("string"); + }); - it("deserialize - geometry", function() - { - expect(graphic.geometry).toEqual(g_test.pointFeature.geometry); - }); + it("deserialize", function() + { + graphic = g_graphicsStore._deserialize(str); + expect(typeof(graphic)).toBe("object"); + expect(graphic.declaredClass).toEqual("esri.Graphic"); + }); - it("deserialize - symbol should be null", function() - { - expect(graphic.symbol).toBeNull(); - }); + it("deserialize - attributes", function() + { + expect(graphic.attributes).toEqual(g_test.polygonFeature.attributes); + }); - it("deserialize - infoTemplate should be null", function() - { - expect(graphic.infoTemplate).toBeNull(); + it("deserialize - geometry", function() + { + expect(graphic.geometry).toEqual(g_test.polygonFeature.geometry); + }); + + it("deserialize - symbol should be null", function() + { + expect(graphic.symbol).toBeNull(); + }); + + it("deserialize - infoTemplate should be null", function() + { + expect(graphic.infoTemplate).toBeNull(); + }); }); }); - describe("Serialize/Deserialize Polyline", function() + describe("Pack/Unpack array of edits",function() { - var str, graphic; - - it("serialize", function() - { - str = g_graphicsStore._serialize(g_test.lineFeature); - expect(typeof(str)).toBe("string"); - }); - - it("deserialize", function() - { - graphic = g_graphicsStore._deserialize(str); - expect(typeof(graphic)).toBe("object"); - expect(graphic.declaredClass).toEqual("esri.Graphic"); - }); - - it("deserialize - attributes", function() - { - expect(graphic.attributes).toEqual(g_test.lineFeature.attributes); - }); - - it("deserialize - geometry", function() - { - expect(graphic.geometry).toEqual(g_test.lineFeature.geometry); - }); - - it("deserialize - symbol should be null", function() - { - expect(graphic.symbol).toBeNull(); - }); - - it("deserialize - infoTemplate should be null", function() - { - expect(graphic.infoTemplate).toBeNull(); - }); + // TODO }); +}); - describe("Serialize/Deserialize Polygon", function() +describe("Public Interface", function() +{ + describe("Edit queue management", function() { - var str, graphic; - - it("serialize", function() + describe("Normal edits", function() { - str = g_graphicsStore._serialize(g_test.polygonFeature); - expect(typeof(str)).toBe("string"); + it("reset edits queue", function() + { + g_graphicsStore.resetEditsQueue(); + expect(g_graphicsStore.pendingEditsCount()).toBe(0); + }); + + it("add edits to edits queue", function() + { + var success; + success = g_graphicsStore.pushEdit(g_graphicsStore.ADD, 6, g_test.pointFeature); + expect(success).toBeTruthy(); + expect(g_graphicsStore.pendingEditsCount()).toBe(1); + success = g_graphicsStore.pushEdit(g_graphicsStore.UPDATE, 3, g_test.polygonFeature); + expect(success).toBeTruthy(); + expect(g_graphicsStore.pendingEditsCount()).toBe(2); + success = g_graphicsStore.pushEdit(g_graphicsStore.DELETE, 2, g_test.lineFeature); + expect(success).toBeTruthy(); + expect(g_graphicsStore.pendingEditsCount()).toBe(3); + }); + + it("pending edits", function() + { + expect(g_graphicsStore.hasPendingEdits()).toBeTruthy(); + }); + + it("pop edit from edits queue - 1", function() + { + var firstEdit = g_graphicsStore.popFirstEdit(); + expect(g_graphicsStore.pendingEditsCount()).toBe(2); + expect(typeof(firstEdit)).toBe("object"); + expect(firstEdit.operation).toBe(g_graphicsStore.ADD); + expect(firstEdit.layer).toBe(6); + expect(firstEdit.graphic.attributes).toEqual(g_test.pointFeature.attributes); + expect(firstEdit.graphic.geometry).toEqual(g_test.pointFeature.geometry); + expect(firstEdit.graphic.symbol).toEqual(null); + }); + + it("pop edit from edits queue - 2", function() + { + var secondEdit = g_graphicsStore.popFirstEdit(); + expect(g_graphicsStore.pendingEditsCount()).toBe(1); + expect(typeof(secondEdit)).toBe("object"); + expect(secondEdit.operation).toBe(g_graphicsStore.UPDATE); + expect(secondEdit.layer).toBe(3); + expect(secondEdit.graphic.attributes).toEqual(g_test.polygonFeature.attributes); + expect(secondEdit.graphic.geometry).toEqual(g_test.polygonFeature.geometry); + expect(secondEdit.graphic.symbol).toEqual(null); + }); + + it("pop edit from edits queue - 3", function() + { + var thirdEdit = g_graphicsStore.popFirstEdit(); + expect(g_graphicsStore.pendingEditsCount()).toBe(0); + expect(typeof(thirdEdit)).toBe("object"); + expect(thirdEdit.operation).toBe(g_graphicsStore.DELETE); + expect(thirdEdit.layer).toBe(2); + expect(thirdEdit.graphic.attributes).toEqual(g_test.lineFeature.attributes); + expect(thirdEdit.graphic.geometry).toEqual(g_test.lineFeature.geometry); + expect(thirdEdit.graphic.symbol).toEqual(null); + }); + + it("pending edits", function() + { + expect(g_graphicsStore.hasPendingEdits()).toBeFalsy(); + }); }); - it("deserialize", function() + describe("Duplicate edit detection", function() { - graphic = g_graphicsStore._deserialize(str); - expect(typeof(graphic)).toBe("object"); - expect(graphic.declaredClass).toEqual("esri.Graphic"); + it("reset edits queue", function() + { + g_graphicsStore.resetEditsQueue(); + expect(g_graphicsStore.pendingEditsCount()).toBe(0); + }); + + it("try to add duplicate edits to edits queue", function() + { + var success; + success = g_graphicsStore.pushEdit(g_graphicsStore.ADD, 6, g_test.pointFeature); + expect(g_graphicsStore.pendingEditsCount()).toBe(1); + expect(success).toBeTruthy(); + success = g_graphicsStore.pushEdit(g_graphicsStore.UPDATE, 3, g_test.polygonFeature); + expect(success).toBeTruthy(); + expect(g_graphicsStore.pendingEditsCount()).toBe(2); + + success = g_graphicsStore.pushEdit(g_graphicsStore.ADD, 6, g_test.pointFeature); + expect(g_graphicsStore.pendingEditsCount()).toBe(2); + expect(success).toBeFalsy(); + }); }); - it("deserialize - attributes", function() + describe("Undo/Redo management", function() { - expect(graphic.attributes).toEqual(g_test.polygonFeature.attributes); - }); + it("reset edits queue", function() + { + g_graphicsStore.resetEditsQueue(); + expect(g_graphicsStore.pendingEditsCount()).toBe(0); + }); - it("deserialize - geometry", function() - { - expect(graphic.geometry).toEqual(g_test.polygonFeature.geometry); - }); + it("can undo? - no", function() + { + expect(g_graphicsStore.canUndoEdit()).toBeFalsy(); + }); - it("deserialize - symbol should be null", function() - { - expect(graphic.symbol).toBeNull(); - }); + it("can redo? - no", function() + { + expect(g_graphicsStore.canRedoEdit()).toBeFalsy(); + }); - it("deserialize - infoTemplate should be null", function() - { - expect(graphic.infoTemplate).toBeNull(); + it("add edits to edits queue", function() + { + var success; + success = g_graphicsStore.pushEdit(g_graphicsStore.ADD, 6, g_test.pointFeature); + expect(success).toBeTruthy(); + expect(g_graphicsStore.pendingEditsCount()).toBe(1); + success = g_graphicsStore.pushEdit(g_graphicsStore.UPDATE, 3, g_test.polygonFeature); + expect(success).toBeTruthy(); + expect(g_graphicsStore.pendingEditsCount()).toBe(2); + success = g_graphicsStore.pushEdit(g_graphicsStore.DELETE, 2, g_test.lineFeature); + expect(success).toBeTruthy(); + expect(g_graphicsStore.pendingEditsCount()).toBe(3); + }); + + it("pending edits", function() + { + expect(g_graphicsStore.hasPendingEdits()).toBeTruthy(); + }); + + it("can undo? - yes", function() + { + expect(g_graphicsStore.canUndoEdit()).toBeTruthy(); + }); + + it("can redo? - no", function() + { + expect(g_graphicsStore.canRedoEdit()).toBeFalsy(); + }); + + it("undo", function() + { + expect(g_graphicsStore.pendingEditsCount()).toBe(3); + g_graphicsStore.undoEdit(); + expect(g_graphicsStore.pendingEditsCount()).toBe(2); + }); + + it("can undo? - yes", function() + { + expect(g_graphicsStore.canUndoEdit()).toBeTruthy(); + }); + + it("can redo? - yes", function() + { + expect(g_graphicsStore.canRedoEdit()).toBeTruthy(); + }); + + it("redo", function() + { + expect(g_graphicsStore.pendingEditsCount()).toBe(2); + g_graphicsStore.redoEdit(); + expect(g_graphicsStore.pendingEditsCount()).toBe(3); + }); + + it("can undo? - yes", function() + { + expect(g_graphicsStore.canUndoEdit()).toBeTruthy(); + }); + + it("can redo? - no", function() + { + expect(g_graphicsStore.canRedoEdit()).toBeFalsy(); + }); + + it("undo x 3", function() + { + expect(g_graphicsStore.pendingEditsCount()).toBe(3); + g_graphicsStore.undoEdit(); + expect(g_graphicsStore.pendingEditsCount()).toBe(2); + g_graphicsStore.undoEdit(); + expect(g_graphicsStore.pendingEditsCount()).toBe(1); + g_graphicsStore.undoEdit(); + expect(g_graphicsStore.pendingEditsCount()).toBe(0); + }); + + it("can undo? - no", function() + { + expect(g_graphicsStore.canUndoEdit()).toBeFalsy(); + }); + + it("can redo? - yes", function() + { + expect(g_graphicsStore.canRedoEdit()).toBeTruthy(); + }); + + it("redo x 2", function() + { + expect(g_graphicsStore.pendingEditsCount()).toBe(0); + g_graphicsStore.redoEdit(); + expect(g_graphicsStore.pendingEditsCount()).toBe(1); + g_graphicsStore.redoEdit(); + expect(g_graphicsStore.pendingEditsCount()).toBe(2); + }); + + it("can undo? - yes", function() + { + expect(g_graphicsStore.canUndoEdit()).toBeTruthy(); + }); + + it("can redo? - yes", function() + { + expect(g_graphicsStore.canRedoEdit()).toBeTruthy(); + }); + + it("add new edit", function() + { + var success; + success = g_graphicsStore.pushEdit(g_graphicsStore.ADD, 10, g_test.pointFeature); + expect(success).toBeTruthy(); + expect(g_graphicsStore.pendingEditsCount()).toBe(3); + }); + + it("can redo? - no", function() + { + expect(g_graphicsStore.canRedoEdit()).toBeFalsy(); + }); }); }); }); -describe("Edit queue management", function() +describe("Reset store", function() { - describe("Normal edits", function() + it("reset the store", function() { - it("reset edits queue", function() - { - g_graphicsStore.resetEditsQueue(); - expect(g_graphicsStore.pendingEditsCount()).toBe(0); - }); - - it("add edits to edits queue", function() - { - var success; - success = g_graphicsStore.appendEdit(g_graphicsStore.ADD, 6, g_test.pointFeature); - expect(success).toBeTruthy(); - expect(g_graphicsStore.pendingEditsCount()).toBe(1); - success = g_graphicsStore.appendEdit(g_graphicsStore.UPDATE, 3, g_test.polygonFeature); - expect(success).toBeTruthy(); - expect(g_graphicsStore.pendingEditsCount()).toBe(2); - success = g_graphicsStore.appendEdit(g_graphicsStore.DELETE, 2, g_test.lineFeature); - expect(success).toBeTruthy(); - expect(g_graphicsStore.pendingEditsCount()).toBe(3); - }); - - it("pending edits", function() - { - expect(g_graphicsStore.hasPendingEdits()).toBeTruthy(); - }); - - it("pop edit from edits queue - 1", function() - { - var firstEdit = g_graphicsStore.popFirstEdit(); - expect(g_graphicsStore.pendingEditsCount()).toBe(2); - expect(typeof(firstEdit)).toBe("object"); - expect(firstEdit.operation).toBe(g_graphicsStore.ADD); - expect(firstEdit.layer).toBe(6); - expect(firstEdit.graphic.attributes).toEqual(g_test.pointFeature.attributes); - expect(firstEdit.graphic.geometry).toEqual(g_test.pointFeature.geometry); - expect(firstEdit.graphic.symbol).toEqual(null); - }); - - it("pop edit from edits queue - 2", function() - { - var secondEdit = g_graphicsStore.popFirstEdit(); - expect(g_graphicsStore.pendingEditsCount()).toBe(1); - expect(typeof(secondEdit)).toBe("object"); - expect(secondEdit.operation).toBe(g_graphicsStore.UPDATE); - expect(secondEdit.layer).toBe(3); - expect(secondEdit.graphic.attributes).toEqual(g_test.polygonFeature.attributes); - expect(secondEdit.graphic.geometry).toEqual(g_test.polygonFeature.geometry); - expect(secondEdit.graphic.symbol).toEqual(null); - }); - - it("pop edit from edits queue - 3", function() - { - var thirdEdit = g_graphicsStore.popFirstEdit(); - expect(g_graphicsStore.pendingEditsCount()).toBe(0); - expect(typeof(thirdEdit)).toBe("object"); - expect(thirdEdit.operation).toBe(g_graphicsStore.DELETE); - expect(thirdEdit.layer).toBe(2); - expect(thirdEdit.graphic.attributes).toEqual(g_test.lineFeature.attributes); - expect(thirdEdit.graphic.geometry).toEqual(g_test.lineFeature.geometry); - expect(thirdEdit.graphic.symbol).toEqual(null); - }); - - it("pending edits", function() - { - expect(g_graphicsStore.hasPendingEdits()).toBeFalsy(); - }); - }); - - describe("Duplicate edit detection", function() - { - it("reset edits queue", function() - { - g_graphicsStore.resetEditsQueue(); - expect(g_graphicsStore.pendingEditsCount()).toBe(0); - }); - - it("try to add duplicate edits to edits queue", function() - { - var success; - success = g_graphicsStore.appendEdit(g_graphicsStore.ADD, 6, g_test.pointFeature); - expect(g_graphicsStore.pendingEditsCount()).toBe(1); - expect(success).toBeTruthy(); - success = g_graphicsStore.appendEdit(g_graphicsStore.UPDATE, 3, g_test.polygonFeature); - expect(success).toBeTruthy(); - expect(g_graphicsStore.pendingEditsCount()).toBe(2); - - success = g_graphicsStore.appendEdit(g_graphicsStore.ADD, 6, g_test.pointFeature); - expect(g_graphicsStore.pendingEditsCount()).toBe(2); - expect(success).toBeFalsy(); - }); - }); - - describe("Undo/Redo management", function() - { - it("reset edits queue", function() - { - g_graphicsStore.resetEditsQueue(); - expect(g_graphicsStore.pendingEditsCount()).toBe(0); - }); - - it("can undo? - no", function() - { - expect(g_graphicsStore.canUndoEdit()).toBeFalsy(); - }); - - it("can redo? - no", function() - { - expect(g_graphicsStore.canRedoEdit()).toBeFalsy(); - }); - - it("add edits to edits queue", function() - { - var success; - success = g_graphicsStore.appendEdit(g_graphicsStore.ADD, 6, g_test.pointFeature); - expect(success).toBeTruthy(); - expect(g_graphicsStore.pendingEditsCount()).toBe(1); - success = g_graphicsStore.appendEdit(g_graphicsStore.UPDATE, 3, g_test.polygonFeature); - expect(success).toBeTruthy(); - expect(g_graphicsStore.pendingEditsCount()).toBe(2); - success = g_graphicsStore.appendEdit(g_graphicsStore.DELETE, 2, g_test.lineFeature); - expect(success).toBeTruthy(); - expect(g_graphicsStore.pendingEditsCount()).toBe(3); - }); - - it("pending edits", function() - { - expect(g_graphicsStore.hasPendingEdits()).toBeTruthy(); - }); - - it("can undo? - yes", function() - { - expect(g_graphicsStore.canUndoEdit()).toBeTruthy(); - }); - - it("can redo? - no", function() - { - expect(g_graphicsStore.canRedoEdit()).toBeFalsy(); - }); - - it("undo", function() - { - expect(g_graphicsStore.pendingEditsCount()).toBe(3); - g_graphicsStore.undoEdit(); - expect(g_graphicsStore.pendingEditsCount()).toBe(2); - }); - - it("can undo? - yes", function() - { - expect(g_graphicsStore.canUndoEdit()).toBeTruthy(); - }); - - it("can redo? - yes", function() - { - expect(g_graphicsStore.canRedoEdit()).toBeTruthy(); - }); - - it("redo", function() - { - expect(g_graphicsStore.pendingEditsCount()).toBe(2); - g_graphicsStore.redoEdit(); - expect(g_graphicsStore.pendingEditsCount()).toBe(3); - }); - - it("can undo? - yes", function() - { - expect(g_graphicsStore.canUndoEdit()).toBeTruthy(); - }); - - it("can redo? - no", function() - { - expect(g_graphicsStore.canRedoEdit()).toBeFalsy(); - }); - - it("undo x 3", function() - { - expect(g_graphicsStore.pendingEditsCount()).toBe(3); - g_graphicsStore.undoEdit(); - expect(g_graphicsStore.pendingEditsCount()).toBe(2); - g_graphicsStore.undoEdit(); - expect(g_graphicsStore.pendingEditsCount()).toBe(1); - g_graphicsStore.undoEdit(); - expect(g_graphicsStore.pendingEditsCount()).toBe(0); - }); - - it("can undo? - no", function() - { - expect(g_graphicsStore.canUndoEdit()).toBeFalsy(); - }); - - it("can redo? - yes", function() - { - expect(g_graphicsStore.canRedoEdit()).toBeTruthy(); - }); - - it("redo x 2", function() - { - expect(g_graphicsStore.pendingEditsCount()).toBe(0); - g_graphicsStore.redoEdit(); - expect(g_graphicsStore.pendingEditsCount()).toBe(1); - g_graphicsStore.redoEdit(); - expect(g_graphicsStore.pendingEditsCount()).toBe(2); - }); - - it("can undo? - yes", function() - { - expect(g_graphicsStore.canUndoEdit()).toBeTruthy(); - }); - - it("can redo? - yes", function() - { - expect(g_graphicsStore.canRedoEdit()).toBeTruthy(); - }); - - it("add new edit", function() - { - var success; - success = g_graphicsStore.appendEdit(g_graphicsStore.ADD, 10, g_test.pointFeature); - expect(success).toBeTruthy(); - expect(g_graphicsStore.pendingEditsCount()).toBe(3); - }); - - it("can redo? - no", function() - { - expect(g_graphicsStore.canRedoEdit()).toBeFalsy(); - }); - }); -}); \ No newline at end of file + g_graphicsStore.resetEditsQueue(); + }) +}); From 008edaf67b1157cd827c1acfab37788189d1cb61 Mon Sep 17 00:00:00 2001 From: Javier Abadia Date: Tue, 21 Jan 2014 10:24:58 +0100 Subject: [PATCH 8/8] renamed graphicsStore -> editsStore --- lib/edit/{graphicsStore.js => editsStore.js} | 0 ...ner.gs.html => SpecRunner.editsStore.html} | 10 +- ...graphicsStoreSpec.js => editsStoreSpec.js} | 152 +++++++++--------- 3 files changed, 81 insertions(+), 81 deletions(-) rename lib/edit/{graphicsStore.js => editsStore.js} (100%) rename test/{SpecRunner.gs.html => SpecRunner.editsStore.html} (96%) rename test/spec/{graphicsStoreSpec.js => editsStoreSpec.js} (65%) diff --git a/lib/edit/graphicsStore.js b/lib/edit/editsStore.js similarity index 100% rename from lib/edit/graphicsStore.js rename to lib/edit/editsStore.js diff --git a/test/SpecRunner.gs.html b/test/SpecRunner.editsStore.html similarity index 96% rename from test/SpecRunner.gs.html rename to test/SpecRunner.editsStore.html index c0c7bd3..4b783f0 100644 --- a/test/SpecRunner.gs.html +++ b/test/SpecRunner.editsStore.html @@ -22,24 +22,24 @@ - +