Commit 665a10e

mo <email@solidware.ca>
2011-03-29 03:49:14
add identity map.
1 parent 91b15ea
product/service/orm/IdentityMap.cs
@@ -0,0 +1,14 @@
+using System.Collections.Generic;
+
+namespace solidware.financials.service.orm
+{
+    public interface IdentityMap<TKey, TValue>
+    {
+        IEnumerable<TValue> all();
+        void add(TKey key, TValue value);
+        void update_the_item_for(TKey key, TValue new_value);
+        bool contains_an_item_for(TKey key);
+        TValue item_that_belongs_to(TKey key);
+        void evict(TKey key);
+    }
+}
\ No newline at end of file
product/service/orm/SimpleIdentityMap.cs
@@ -0,0 +1,49 @@
+using System.Collections.Generic;
+
+namespace solidware.financials.service.orm
+{
+    public class SimpleIdentityMap<TKey, TValue> : IdentityMap<TKey, TValue>
+    {
+        readonly IDictionary<TKey, TValue> items_in_map;
+
+        public SimpleIdentityMap() : this(new Dictionary<TKey, TValue>())
+        {
+        }
+
+        public SimpleIdentityMap(IDictionary<TKey, TValue> items_in_map)
+        {
+            this.items_in_map = items_in_map;
+        }
+
+        public IEnumerable<TValue> all()
+        {
+            return items_in_map.Values;
+        }
+
+        public void add(TKey key, TValue value)
+        {
+            items_in_map.Add(key, value);
+        }
+
+        public void update_the_item_for(TKey key, TValue new_value)
+        {
+            if (contains_an_item_for(key)) items_in_map[key] = new_value;
+            else add(key, new_value);
+        }
+
+        public bool contains_an_item_for(TKey key)
+        {
+            return items_in_map.ContainsKey(key);
+        }
+
+        public TValue item_that_belongs_to(TKey key)
+        {
+            return contains_an_item_for(key) ? items_in_map[key] : default(TValue);
+        }
+
+        public void evict(TKey key)
+        {
+            if (contains_an_item_for(key)) items_in_map.Remove(key);
+        }
+    }
+}
\ No newline at end of file
product/service/service.csproj
@@ -123,6 +123,8 @@
     <Compile Include="orm\DB4OPersonRepository.cs" />
     <Compile Include="orm\Disposable.cs" />
     <Compile Include="orm\EmptyUnitOfWork.cs" />
+    <Compile Include="orm\IdentityMap.cs" />
+    <Compile Include="orm\SimpleIdentityMap.cs" />
     <Compile Include="orm\InMemoryDatabase.cs" />
     <Compile Include="orm\LastOpened.cs" />
     <Compile Include="orm\PersonRepository.cs" />
product/specs/unit/service/orm/SimpleIdentityMapSpecs.cs
@@ -0,0 +1,123 @@
+using Machine.Specifications;
+using solidware.financials.service.orm;
+
+namespace specs.unit.service.orm
+{
+    public class SimpleIdentityMapSpecs
+    {
+        [Concern(typeof (SimpleIdentityMap<,>))]
+        public abstract class behaves_like_identity_map
+        {
+            Establish context = () =>
+            {
+                sut = new SimpleIdentityMap<int, string>();
+            };
+
+            static protected IdentityMap<int, string> sut;
+        }
+
+        [Concern(typeof (SimpleIdentityMap<,>))]
+        public class when_getting_an_item_from_the_identity_map_for_an_item_that_has_been_added : behaves_like_identity_map
+        {
+            It should_return_the_item_that_was_added_for_the_given_key = () =>
+            {
+                result.should_be_equal_to("1");
+            };
+
+            Because b = () =>
+            {
+                sut.add(1, "1");
+                result = sut.item_that_belongs_to(1);
+            };
+
+            static string result;
+        }
+
+        [Concern(typeof (SimpleIdentityMap<,>))]
+        public class when_getting_an_item_from_the_identity_map_that_has_not_been_added : behaves_like_identity_map
+        {
+            It should_return_the_default_value_for_that_type = () =>
+            {
+                result.should_be_equal_to(null);
+            };
+
+            Because b = () =>
+            {
+                result = sut.item_that_belongs_to(2);
+            };
+
+            static string result;
+        }
+
+        [Concern(typeof (SimpleIdentityMap<,>))]
+        public class when_checking_if_an_item_has_been_added_to_the_identity_map_that_has_been_added :
+            behaves_like_identity_map
+        {
+            It should_return_true = () =>
+            {
+                result.should_be_true();
+            };
+
+            Because b = () =>
+            {
+                sut.add(10, "10");
+                result = sut.contains_an_item_for(10);
+            };
+
+            static bool result;
+        }
+
+        [Concern(typeof (SimpleIdentityMap<,>))]
+        public class when_checking_if_an_item_has_been_added_to_the_identity_map_that_has_not_been_added :
+            behaves_like_identity_map
+        {
+            It should_return_false = () =>
+            {
+                result.should_be_false();
+            };
+
+            Because b = () =>
+            {
+                result = sut.contains_an_item_for(9);
+            };
+
+            static bool result;
+        }
+
+        [Concern(typeof (SimpleIdentityMap<,>))]
+        public class when_updating_the_value_for_a_key_that_has_already_been_added_to_the_identity_map :
+            behaves_like_identity_map
+        {
+            It should_replace_the_old_item_with_the_new_one = () =>
+            {
+                result.should_be_equal_to("7");
+            };
+
+            Because b = () =>
+            {
+                sut.add(6, "6");
+                sut.update_the_item_for(6, "7");
+                result = sut.item_that_belongs_to(6);
+            };
+
+            static string result;
+        }
+
+        [Concern(typeof (SimpleIdentityMap<,>))]
+        public class when_updating_the_value_for_a_key_that_has_not_been_added_to_the_identity_map : behaves_like_identity_map
+        {
+            It should_add_the_new_item = () =>
+            {
+                result.should_be_equal_to("3");
+            };
+
+            Because b = () =>
+            {
+                sut.update_the_item_for(3, "3");
+                result = sut.item_that_belongs_to(3);
+            };
+
+            static string result;
+        }
+    }
+}
\ No newline at end of file
product/specs/specs.csproj
@@ -96,6 +96,7 @@
     <Compile Include="unit\service\orm\DB4OUnitOfWorkFactorySpecs.cs" />
     <Compile Include="unit\service\orm\DB4OUnitOfWorkSpecs.cs" />
     <Compile Include="unit\service\orm\EmptyUnitOfWorkSpecs.cs" />
+    <Compile Include="unit\service\orm\SimpleIdentityMapSpecs.cs" />
     <Compile Include="unit\service\orm\UnitOfWorkInterceptorSpecs.cs" />
     <Compile Include="unit\ui\InMemoryApplicationStateSpecs.cs" />
     <Compile Include="unit\ui\presenters\AddFamilyMemberPresenterSpecs.cs" />