Commit 665a10e
Changed files (5)
product
service
specs
unit
service
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" />