public void TestRetrievalDictionaryPrimary([Values(true, false)] bool useTryGetValue, [Values(true, false)] bool targetPrimary)
        {
            //--Arrange
            var primary   = RetrievalDictionary.Build((Guid id) => id.ToString());
            var underTest = new OneToOneDictionary <Guid, string>(primary);

            //--Act/Assert
            foreach (var key in Enumerable.Range(0, 10).Select(x => Guid.NewGuid()))
            {
                if (targetPrimary)
                {
                    Assert.IsFalse(underTest.ContainsKey(key));
                    Assert.IsFalse(underTest.ContainsKey(key.ToString()));

                    var value = underTest[key];
                    Assert.AreEqual(key.ToString(), value);
                    Assert.IsTrue(underTest.ContainsKey(key));
                    Assert.IsTrue(underTest.ContainsKey(key.ToString()));
                }
                else if (useTryGetValue)
                {
                    var success = underTest.TryGetValue(key.ToString(), out var value);
                    Assert.IsFalse(success);
                    Assert.AreEqual(Guid.Empty, value);
                }
                else
                {
                    Guid value;
                    Assert.Throws <KeyNotFoundException>(() => value = underTest[key.ToString()]);
                }
            }
        }
        public void TestRetrievedValueCanBeOverwritten()
        {
            //--Arrange
            var guid     = Guid.NewGuid();
            var repoMock = new Mock <IExpensiveOperationRepository>();

            repoMock.Setup(x => x.RunQueryThatTakesForever(It.IsAny <Guid>()))
            .Returns((Guid id) => new TestSchema.Employee {
                Id = id, CompanyId = Guid.NewGuid()
            });
            var mockObject = repoMock.Object;

            //--Act
            var retrievalDictionary = RetrievalDictionary.Build((Guid id) => mockObject.RunQueryThatTakesForever(id));
            var results             = Enumerable.Range(0, 10).Select(x => retrievalDictionary[guid]).ToList();

            retrievalDictionary[guid] = new TestSchema.Employee {
                Id = guid, CompanyId = Guid.NewGuid()
            };
            results.AddRange(Enumerable.Range(0, 10).Select(x => retrievalDictionary[guid]));

            //--Assert
            Assert.AreEqual(2, results.GroupBy(x => x.CompanyId).Count());
            Assert.AreEqual(1, results.Take(10).GroupBy(x => x.CompanyId).Count());
            Assert.AreEqual(1, results.Skip(10).GroupBy(x => x.CompanyId).Count());
        }
        public void TestRetrievalDoesntHappenWhenPreloaded()
        {
            //--Arrange
            var ids        = Enumerable.Range(0, 10).Select(x => Guid.NewGuid()).ToList();
            var repoMock   = new Mock <IExpensiveOperationRepository>();
            var mockObject = repoMock.Object;

            //--Act
            var retrievalDictionary = RetrievalDictionary.Build((Guid id) => mockObject.RunQueryThatTakesForever(id));

            ids.ForEach(id => retrievalDictionary.Add(id, new TestSchema.Employee {
                Id = id, CompanyId = Guid.NewGuid()
            }));
            var resultLookup = ids.Join(Enumerable.Range(0, 10), l => true, r => true, (l, r) => l)
                               .ToLookup(x => x, x => retrievalDictionary[x]);

            //--Assert
            Assert.AreEqual(ids.Count, resultLookup.Count);
            Assert.AreEqual(ids.Count, resultLookup.SelectMany(x => x).Distinct().Count());
            foreach (var(id, results) in resultLookup.AsTuples())
            {
                Assert.AreEqual(10, results.Count);
                Assert.AreEqual(1, results.Distinct().Count());

                repoMock.Verify(x => x.RunQueryThatTakesForever(It.IsAny <Guid>()), Times.Never());
            }
        }
        public void TestTryGetValueAttemptsRetrieval([Values(false, true)] bool shouldFind)
        {
            //--Arrange
            var id       = Guid.NewGuid();
            var repoMock = new Mock <IExpensiveOperationRepository>();

            repoMock.Setup(x => x.RunQueryThatTakesForever(It.IsAny <Guid>()))
            .Returns(() => shouldFind ? new TestSchema.Employee() : throw new NullReferenceException());

            //--Act
            var retrievalDictionary = RetrievalDictionary.Build((Guid id) => repoMock.Object.RunQueryThatTakesForever(id));
            var found = retrievalDictionary.TryGetValue(id, out var result);

            //--Assert
            Assert.AreEqual(shouldFind, found);
            repoMock.Verify(x => x.RunQueryThatTakesForever(id), Times.Exactly(1));
            if (shouldFind)
            {
                Assert.IsNotNull(result);
            }
            else
            {
                Assert.IsNull(result);
            }
        }
        public void TestBackingDictionarySynchronization()
        {
            //--Arrange
            var primary   = new Dictionary <Guid, string>();
            var secondary = RetrievalDictionary.Build((string id) => Guid.Parse(id));
            var underTest = new OneToOneDictionary <Guid, string>(primary, secondary);

            //--Act/Assert
            var id = Guid.NewGuid();

            Assert.IsFalse(primary.ContainsKey(id));
            Assert.IsFalse(secondary.ContainsKey(id.ToString()));

            primary[id] = id.ToString();
            Assert.AreEqual(id.ToString(), underTest[id]);
            Assert.IsTrue(primary.ContainsKey(id));
            Assert.IsTrue(secondary.ContainsKey(id.ToString()));


            id = Guid.NewGuid();
            Assert.IsFalse(primary.ContainsKey(id));
            Assert.IsFalse(secondary.ContainsKey(id.ToString()));

            Assert.AreEqual(id, underTest[id.ToString()]);
            Assert.IsTrue(primary.ContainsKey(id));
            Assert.IsTrue(secondary.ContainsKey(id.ToString()));


            id = Guid.NewGuid();
            Assert.IsFalse(primary.ContainsKey(id));
            Assert.IsFalse(secondary.ContainsKey(id.ToString()));

            primary[id] = id.ToString();
            Assert.IsTrue(underTest.TryGetValue(id, out var value));
            Assert.AreEqual(id.ToString(), value);
            Assert.IsTrue(primary.ContainsKey(id));
            Assert.IsTrue(secondary.ContainsKey(id.ToString()));
        }
 static SqlServerQueryBuilder()
 {
     _tableMaps = RetrievalDictionary.Build((Type type) => TableMapSource.GetTableMap(type));
     _tableMaps.AddRange(TableMapSource.GetTableMaps());
 }
 static ColumnValueProvider()
 {
     _tableMapBuilders = RetrievalDictionary.Build((Type type) => TableMapSource.GetTableMapBuilders(type));
 }