Skip to content

Commit e8e8c76

Browse files
committed
Refactored Cache to better reflect Words functionality and improved the Any API for Words
1 parent 1fed756 commit e8e8c76

22 files changed

+156
-175
lines changed

TestStack.Dossier.Tests/DataSources/Dictionaries/CacheTests.cs

Lines changed: 0 additions & 62 deletions
This file was deleted.
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
using System;
2+
using System.IO;
3+
using Shouldly;
4+
using TestStack.Dossier.DataSources.Dictionaries;
5+
using Xunit;
6+
7+
namespace TestStack.Dossier.Tests.DataSources.Dictionaries
8+
{
9+
public class WordsCacheTests : IDisposable
10+
{
11+
private const string DictionaryThatDoesNotExist = "DictionaryThatDoesNotExist";
12+
13+
public WordsCacheTests()
14+
{
15+
WordsCache.Clear();
16+
}
17+
18+
[Fact]
19+
public void WhenRequestingAnItemInTheCache_ThenReturnsSameItem()
20+
{
21+
var words1 = WordsCache.Get(FromDictionary.InternetUrl);
22+
var words2 = WordsCache.Get(FromDictionary.InternetUrl);
23+
words1.ShouldBeSameAs(words2);
24+
}
25+
26+
[Fact]
27+
public void WhenRequestingAnItemNotInTheCache_ThenReturnsWordsSourceForItemDictionary()
28+
{
29+
var words = WordsCache.Get(DictionaryThatDoesNotExist);
30+
words.DictionaryName.ShouldBe(DictionaryThatDoesNotExist);
31+
}
32+
33+
[Fact]
34+
public void WhenUsingCachedWordsForNonExistentDictionary_ThenWordsSourceThrowsFileNotFoundException()
35+
{
36+
var words = WordsCache.Get(DictionaryThatDoesNotExist);
37+
Should.Throw<FileNotFoundException>(() => words.Next());
38+
}
39+
40+
public void Dispose()
41+
{
42+
WordsCache.Clear();
43+
}
44+
}
45+
}

TestStack.Dossier.Tests/TestStack.Dossier.Tests.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@
8484
<Compile Include="TestHelpers\Objects\Entities\Customer.cs" />
8585
<Compile Include="TestHelpers\Objects\Entities\CustomerClass.cs" />
8686
<Compile Include="DataSources\DataSourceTests.cs" />
87-
<Compile Include="DataSources\Dictionaries\CacheTests.cs" />
87+
<Compile Include="DataSources\Dictionaries\WordsCacheTests.cs" />
8888
<Compile Include="DataSources\Dictionaries\CachedFileDictionaryRepositoryIntegrationTests.cs" />
8989
<Compile Include="DataSources\Dictionaries\WordsTests.cs" />
9090
<Compile Include="DataSources\Dictionaries\Resources\FileDataConventions.cs" />

TestStack.Dossier/AnonymousValueFixture.cs

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ static AnonymousValueFixture()
2828
new DefaultValueTypeValueSupplier(),
2929
new DefaultValueSupplier()
3030
};
31-
_dictionaries = new ConcurrentDictionary<string, Words>();
3231
}
3332

3433
/// <summary>
@@ -114,17 +113,13 @@ public object Get(Type type, string propertyName)
114113
/// <summary>
115114
/// Gets a data source for a file dictionary, which can be built-in or a user-supplied text file.
116115
/// </summary>
117-
/// <param name="dictionaryName">The name of the file dictionary, without the extension</param>
116+
/// <param name="dictionaryName">The name of the file dictionary, without the extension.
117+
/// Recommended to use the FromDictionary list of constants for the built-in file dictionaries.
118+
/// Just use a normal string for user-supplied text files.</param>
118119
/// <returns></returns>
119-
public Words DictionaryFor(string dictionaryName)
120+
public Words Words(string dictionaryName)
120121
{
121-
if (!_dictionaries.ContainsKey(dictionaryName))
122-
{
123-
_dictionaries[dictionaryName] = new Words(dictionaryName);
124-
}
125-
return _dictionaries[dictionaryName];
122+
return WordsCache.Get(dictionaryName);
126123
}
127-
128-
private static ConcurrentDictionary<string, Words> _dictionaries;
129124
}
130125
}

TestStack.Dossier/DataSources/Dictionaries/Cache.cs

Lines changed: 0 additions & 30 deletions
This file was deleted.

TestStack.Dossier/DataSources/Dictionaries/CachedFileDictionaryRepository.cs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,6 @@ internal class CachedFileDictionaryRepository : IDictionaryRepository
1212
{
1313
public IList<string> GetWordsFrom(string dictionary)
1414
{
15-
if (Cache.Contains(dictionary))
16-
{
17-
return Cache.Get(dictionary);
18-
}
19-
2015
var words = new List<string>();
2116

2217
var name = string.Format("{0}.txt", dictionary);
@@ -30,7 +25,6 @@ public IList<string> GetWordsFrom(string dictionary)
3025
words = GetWordsFromEmbeddedResource(GetType().Assembly, resourceName).ToList();
3126
}
3227

33-
Cache.Set(dictionary, words);
3428
return words;
3529
}
3630

TestStack.Dossier/DataSources/Dictionaries/Words.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ internal Words(IGenerator generator, IDictionaryRepository repository, string di
2525
_dictionaryName = dictionaryName;
2626
}
2727

28+
internal string DictionaryName => _dictionaryName;
29+
2830
/// <inheritdoc />
2931
protected override IList<string> InitializeDataSource()
3032
{
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
using System.Collections.Concurrent;
2+
3+
namespace TestStack.Dossier.DataSources.Dictionaries
4+
{
5+
/// <summary>
6+
/// Just caches a file dictionary <see cref="Words"/> data source the first time it is accessed and returns the same instance
7+
/// each subsequent request. The Words data source is then responsible for lazy loading its dictionary contents
8+
/// the first time it is accessed. At that point an exception will be thrown if the dictionary does not exist.
9+
/// </summary>
10+
internal static class WordsCache
11+
{
12+
private static ConcurrentDictionary<string, Words> _cache = new ConcurrentDictionary<string, Words>();
13+
14+
/// <summary>
15+
/// Gets the Words in the file with the specified dictionary name.
16+
/// This method is used by <see cref="AnonymousValueFixture"/>.
17+
/// </summary>
18+
/// <param name="dictionaryName">Name of the dictionary file.</param>
19+
/// <returns></returns>
20+
internal static Words Get(string dictionaryName)
21+
{
22+
if (!_cache.ContainsKey(dictionaryName))
23+
{
24+
_cache[dictionaryName] = new Words(dictionaryName);
25+
}
26+
return _cache[dictionaryName];
27+
}
28+
29+
/// <summary>
30+
/// Just exposed for testing purposes.
31+
/// </summary>
32+
internal static void Clear()
33+
{
34+
_cache = new ConcurrentDictionary<string, Words>();
35+
}
36+
}
37+
}

TestStack.Dossier/EquivalenceClasses/AddressAusEquivalence.cs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ public static class AddressAusEquivalence
1515
/// <returns>The generated value.</returns>
1616
public static string AddressAusCity(this AnonymousValueFixture fixture)
1717
{
18-
return fixture.DictionaryFor(FromDictionary.AddressAusCity).Next();
18+
return fixture.Words(FromDictionary.AddressAusCity).Next();
1919
}
2020

2121
/// <summary>
@@ -25,7 +25,7 @@ public static string AddressAusCity(this AnonymousValueFixture fixture)
2525
/// <returns>The generated value.</returns>
2626
public static string AddressAusCompany(this AnonymousValueFixture fixture)
2727
{
28-
return fixture.DictionaryFor(FromDictionary.AddressAusCompany).Next();
28+
return fixture.Words(FromDictionary.AddressAusCompany).Next();
2929
}
3030

3131
/// <summary>
@@ -35,7 +35,7 @@ public static string AddressAusCompany(this AnonymousValueFixture fixture)
3535
/// <returns>The generated value.</returns>
3636
public static string AddressAusPhone(this AnonymousValueFixture fixture)
3737
{
38-
return fixture.DictionaryFor(FromDictionary.AddressAusPhone).Next();
38+
return fixture.Words(FromDictionary.AddressAusPhone).Next();
3939
}
4040

4141
/// <summary>
@@ -45,7 +45,7 @@ public static string AddressAusPhone(this AnonymousValueFixture fixture)
4545
/// <returns>The generated value.</returns>
4646
public static string AddressAusPostCode(this AnonymousValueFixture fixture)
4747
{
48-
return fixture.DictionaryFor(FromDictionary.AddressAusPostCode).Next();
48+
return fixture.Words(FromDictionary.AddressAusPostCode).Next();
4949
}
5050

5151
/// <summary>
@@ -55,7 +55,7 @@ public static string AddressAusPostCode(this AnonymousValueFixture fixture)
5555
/// <returns>The generated value.</returns>
5656
public static string AddressAusState(this AnonymousValueFixture fixture)
5757
{
58-
return fixture.DictionaryFor(FromDictionary.AddressAusState).Next();
58+
return fixture.Words(FromDictionary.AddressAusState).Next();
5959
}
6060

6161
/// <summary>
@@ -65,7 +65,7 @@ public static string AddressAusState(this AnonymousValueFixture fixture)
6565
/// <returns>The generated value.</returns>
6666
public static string AddressAusStateAbbreviation(this AnonymousValueFixture fixture)
6767
{
68-
return fixture.DictionaryFor(FromDictionary.AddressAusStateAbbreviation).Next();
68+
return fixture.Words(FromDictionary.AddressAusStateAbbreviation).Next();
6969
}
7070

7171
/// <summary>
@@ -75,7 +75,7 @@ public static string AddressAusStateAbbreviation(this AnonymousValueFixture fixt
7575
/// <returns>The generated value.</returns>
7676
public static string AddressAusStreet(this AnonymousValueFixture fixture)
7777
{
78-
return fixture.DictionaryFor(FromDictionary.AddressAusStreet).Next();
78+
return fixture.Words(FromDictionary.AddressAusStreet).Next();
7979
}
8080

8181
/// <summary>
@@ -85,7 +85,7 @@ public static string AddressAusStreet(this AnonymousValueFixture fixture)
8585
/// <returns>The generated value.</returns>
8686
public static string AddressAusWebsite(this AnonymousValueFixture fixture)
8787
{
88-
return fixture.DictionaryFor(FromDictionary.AddressAusWebsite).Next();
88+
return fixture.Words(FromDictionary.AddressAusWebsite).Next();
8989
}
9090

9191
}

TestStack.Dossier/EquivalenceClasses/AddressUkEquivalence.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ public static class AddressUkEquivalence
1515
/// <returns>The generated value.</returns>
1616
public static string AddressUkCity(this AnonymousValueFixture fixture)
1717
{
18-
return fixture.DictionaryFor(FromDictionary.AddressUkCity).Next();
18+
return fixture.Words(FromDictionary.AddressUkCity).Next();
1919
}
2020

2121
/// <summary>
@@ -25,7 +25,7 @@ public static string AddressUkCity(this AnonymousValueFixture fixture)
2525
/// <returns>The generated value.</returns>
2626
public static string AddressUkCompany(this AnonymousValueFixture fixture)
2727
{
28-
return fixture.DictionaryFor(FromDictionary.AddressUkCompany).Next();
28+
return fixture.Words(FromDictionary.AddressUkCompany).Next();
2929
}
3030

3131
/// <summary>
@@ -35,7 +35,7 @@ public static string AddressUkCompany(this AnonymousValueFixture fixture)
3535
/// <returns>The generated value.</returns>
3636
public static string AddressUkCounty(this AnonymousValueFixture fixture)
3737
{
38-
return fixture.DictionaryFor(FromDictionary.AddressUkCounty).Next();
38+
return fixture.Words(FromDictionary.AddressUkCounty).Next();
3939
}
4040

4141
/// <summary>
@@ -45,7 +45,7 @@ public static string AddressUkCounty(this AnonymousValueFixture fixture)
4545
/// <returns>The generated value.</returns>
4646
public static string AddressUkPhone(this AnonymousValueFixture fixture)
4747
{
48-
return fixture.DictionaryFor(FromDictionary.AddressUkPhone).Next();
48+
return fixture.Words(FromDictionary.AddressUkPhone).Next();
4949
}
5050

5151
/// <summary>
@@ -55,7 +55,7 @@ public static string AddressUkPhone(this AnonymousValueFixture fixture)
5555
/// <returns>The generated value.</returns>
5656
public static string AddressUkPostCode(this AnonymousValueFixture fixture)
5757
{
58-
return fixture.DictionaryFor(FromDictionary.AddressUkPostCode).Next();
58+
return fixture.Words(FromDictionary.AddressUkPostCode).Next();
5959
}
6060

6161
/// <summary>
@@ -65,7 +65,7 @@ public static string AddressUkPostCode(this AnonymousValueFixture fixture)
6565
/// <returns>The generated value.</returns>
6666
public static string AddressUkStreet(this AnonymousValueFixture fixture)
6767
{
68-
return fixture.DictionaryFor(FromDictionary.AddressUkStreet).Next();
68+
return fixture.Words(FromDictionary.AddressUkStreet).Next();
6969
}
7070

7171
/// <summary>
@@ -75,7 +75,7 @@ public static string AddressUkStreet(this AnonymousValueFixture fixture)
7575
/// <returns>The generated value.</returns>
7676
public static string AddressUkWebsite(this AnonymousValueFixture fixture)
7777
{
78-
return fixture.DictionaryFor(FromDictionary.AddressUkWebsite).Next();
78+
return fixture.Words(FromDictionary.AddressUkWebsite).Next();
7979
}
8080

8181
}

0 commit comments

Comments
 (0)