Skip to content

Commit e947958

Browse files
committed
feat: general improvements and minor bugs
1 parent 16d4f72 commit e947958

25 files changed

Lines changed: 936 additions & 454 deletions

src/WebExpress.WebIndex.Test/Queries/UnitTestQuery.cs

Lines changed: 55 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,10 @@ public void DefaultQuery()
3030
}
3131

3232
/// <summary>
33-
/// Verifies that the class implements mutable behavior when applying filters.
33+
/// Verifies that the class implements immutable behavior when applying filters.
3434
/// </summary>
3535
[Fact]
36-
public void Mutable()
36+
public void Immutable()
3737
{
3838
// arrange
3939
var q1 = new Query<IndexItem>();
@@ -42,10 +42,10 @@ public void Mutable()
4242
var q2 = q1.Where(x => x.Value > 10);
4343

4444
// validation
45-
Assert.Same(q1, q2);
46-
Assert.Single(q1.Filters);
45+
Assert.NotSame(q1, q2);
46+
Assert.Empty(q1.Filters);
4747
Assert.Single(q2.Filters);
48-
Assert.Equal(q1.Filters, q2.Filters);
48+
Assert.NotEqual(q1.Filters, q2.Filters);
4949
}
5050

5151
/// <summary>
@@ -331,6 +331,56 @@ public void WhereEndsWithIgnoreCase()
331331
Assert.False(filter(new IndexItem { Email = "user@other.com" }));
332332
}
333333

334+
/// <summary>
335+
/// Verifies that the `And` method correctly combines filters using a logical AND operation.
336+
/// </summary>
337+
[Fact]
338+
public void And()
339+
{
340+
// arrange
341+
Expression<Func<IndexItem, bool>> filter1 = x => x.IsActive;
342+
Expression<Func<IndexItem, bool>> filter2 = x => x.Name == "Test";
343+
344+
// act
345+
var query = new Query<IndexItem>()
346+
.And(filter1)
347+
.And(filter2);
348+
349+
// validation
350+
Assert.Single(query.Filters);
351+
352+
var combinedFilter = query.Filters.First().Compile();
353+
354+
Assert.True(combinedFilter(new IndexItem { IsActive = true, Name = "Test" }));
355+
Assert.False(combinedFilter(new IndexItem { IsActive = false, Name = "Test" }));
356+
Assert.False(combinedFilter(new IndexItem { IsActive = true, Name = "Nope" }));
357+
}
358+
359+
/// <summary>
360+
/// Verifies that the `Or` method correctly combines filters using a logical OR operation.
361+
/// </summary>
362+
[Fact]
363+
public void Or()
364+
{
365+
// arrange
366+
Expression<Func<IndexItem, bool>> filter1 = x => x.IsActive;
367+
Expression<Func<IndexItem, bool>> filter2 = x => x.Name == "Test";
368+
369+
// act
370+
var query = new Query<IndexItem>()
371+
.Or(filter1)
372+
.Or(filter2);
373+
374+
// validation
375+
Assert.Single(query.Filters);
376+
377+
var combinedFilter = query.Filters.First().Compile();
378+
379+
Assert.True(combinedFilter(new IndexItem { IsActive = true, Name = "Nope" }));
380+
Assert.True(combinedFilter(new IndexItem { IsActive = false, Name = "Test" }));
381+
Assert.False(combinedFilter(new IndexItem { IsActive = false, Name = "Nope" }));
382+
}
383+
334384
/// <summary>
335385
/// Verifies that calling OrderByAsc on a Query<IndexItem> correctly sets the
336386
/// OrderBy property to the specified key expression and leaves OrderByDescending unset.

src/WebExpress.WebIndex.Test/TestDocument/UnitTestIndexTestDocumentFactoryC.cs

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,26 +24,37 @@ public static List<UnitTestIndexTestDocumentC> GenerateTestData()
2424
/// </returns>
2525
public static IEnumerable<UnitTestIndexTestDocumentC> GenerateTestData(int itemCount, int wordCount, int vocabulary, int wordLength)
2626
{
27-
var set = GenerateVocabulary(vocabulary, 3, wordLength);
27+
// generate a vocabulary with the specified size and word length
28+
var set = GenerateVocabulary(vocabulary, 3, wordLength).ToList(); // convert to list for efficient indexing
29+
if (set.Count == 0)
30+
{
31+
throw new ArgumentException("Vocabulary must contain at least one word.", nameof(vocabulary));
32+
}
33+
34+
// check bounds for generation
35+
if (itemCount <= 0) throw new ArgumentOutOfRangeException(nameof(itemCount), "Item count must be greater than zero.");
36+
if (wordCount <= 0) throw new ArgumentOutOfRangeException(nameof(wordCount), "Word count must be greater than zero.");
37+
38+
var random = new Random();
2839

2940
for (int i = 0; i < itemCount; i++)
3041
{
3142
var words = new List<string>();
32-
//for (int j = 0; j < Rand.Next(wordCount / 2, wordCount); j++)
43+
3344
for (int j = 0; j < wordCount; j++)
3445
{
35-
words.Add(set.Skip(Rand.Next() % set.Count()).FirstOrDefault());
46+
// select a random word from the vocabulary
47+
var randomWord = set[random.Next(set.Count)];
48+
words.Add(randomWord);
3649
}
3750

3851
yield return new UnitTestIndexTestDocumentC
3952
{
4053
Id = Guid.NewGuid(),
41-
Text = string.Join(" ", words),
42-
Number = i
54+
Text = string.Join(" ", words), // create a space-separated text
55+
Number = i // assign a unique number to each record
4356
};
4457
}
45-
46-
yield break;
4758
}
4859
}
4960
}

src/WebExpress.WebIndex.Test/WQL/UnitTestWqlSearchFuzzyA.cs

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ public void ParseValidWql()
2626
{
2727
// act
2828
var wql = Fixture.ExecuteWql("text~'Helena' ~ 80");
29+
30+
// validation
2931
Assert.False(wql.HasErrors);
3032

3133
Assert.NotNull(wql.Filter);
@@ -41,6 +43,8 @@ public void ParseValidWqlOrderBy()
4143
{
4244
// act
4345
var wql = Fixture.ExecuteWql("text~'Helena' ~ 80 Order by text");
46+
47+
// validation
4448
Assert.False(wql.HasErrors);
4549

4650
Assert.NotNull(wql.Filter);
@@ -56,13 +60,18 @@ public void ParseValidWqlAnd1()
5660
{
5761
// act
5862
var wql = Fixture.ExecuteWql("text~'Helena' ~ 80 And text = 'Helge' Order by text skip 1");
63+
64+
// validation
5965
Assert.False(wql.HasErrors);
6066

6167
Assert.NotNull(wql.Filter);
6268
Assert.NotNull(wql.Order);
6369
Assert.NotNull(wql.Partitioning);
6470

71+
// act
6572
wql = Fixture.ExecuteWql("text~'Helena' ~ 80 & text = 'Helge' Order by text take 10");
73+
74+
// validation
6675
Assert.False(wql.HasErrors);
6776

6877
Assert.NotNull(wql.Filter);
@@ -78,6 +87,8 @@ public void ParseValidWqlAnd2()
7887
{
7988
// act
8089
var wql = Fixture.ExecuteWql("text~'Helena' ~ 80 & text = 'Helge' Order by text take 10");
90+
91+
// validation
8192
Assert.False(wql.HasErrors);
8293

8394
Assert.NotNull(wql.Filter);
@@ -93,6 +104,8 @@ public void ParseInvalidWql()
93104
{
94105
// act
95106
var wql = Fixture.ExecuteWql("text~'Helena' ~a0");
107+
108+
// validation
96109
Assert.True(wql.HasErrors);
97110
}
98111

@@ -104,6 +117,8 @@ public void ParseInvalidWqlIn()
104117
{
105118
// act
106119
var wql = Fixture.ExecuteWql("text in ('Helena' ~ 80)");
120+
121+
// validation
107122
Assert.True(wql.HasErrors);
108123
}
109124

@@ -118,6 +133,7 @@ public void Fuzzy()
118133
var res = wql?.Apply();
119134
var item = res?.FirstOrDefault();
120135

136+
// validation
121137
Assert.NotNull(res);
122138
Assert.NotNull(item);
123139
Assert.Equal(4, res.Count());
@@ -131,20 +147,27 @@ public void Fuzzy()
131147
/// Tests the wildcard search.
132148
/// </summary>
133149
[Fact]
134-
public void FuzzyFromQueryable()
150+
public void FuzzyQuery()
135151
{
136-
// act
152+
// arrange
137153
var wql = Fixture.ExecuteWql("text~'Hel' ~50");
138-
var res = wql?.Apply(Fixture.TestData.AsQueryable());
154+
var data = Fixture.TestData.AsQueryable();
155+
156+
// act
157+
var query = wql.ToQuery();
158+
159+
// validation
160+
var res = query.Apply(data);
139161
var item = res?.FirstOrDefault();
140162

141-
Assert.NotNull(res);
142-
Assert.NotNull(item);
143-
Assert.Equal(6, res.Count());
144-
Assert.Equal("Text ~ 'Hel' ~50", wql.ToString());
145-
Assert.NotNull(wql.Filter);
146-
Assert.Null(wql.Order);
147-
Assert.Null(wql.Partitioning);
163+
// validation
164+
Assert.NotNull(res); // ensure the result set is not null
165+
Assert.NotNull(item); // ensure there is at least one result
166+
Assert.Equal(6, res.Count()); // check if 6 results are returned
167+
Assert.Equal("Text ~ 'Hel' ~50", wql.ToString()); // validate the WQL query string representation
168+
Assert.NotNull(wql.Filter); // verify that a filter is applied
169+
Assert.Null(wql.Order); // ensure no explicit ordering is applied
170+
Assert.Null(wql.Partitioning); // ensure no partitioning is applied
148171
}
149172
}
150173
}

src/WebExpress.WebIndex.Test/WQL/UnitTestWqlSearchProximityC.cs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,15 @@ public class UnitTestWqlSearchProximityC(UnitTestIndexFixtureWqlC fixture, ITest
2525
public void ProximityMatch1()
2626
{
2727
// arrange
28-
var term = Fixture.RandomItem.Text.Split(' ').Skip(5).FirstOrDefault();
29-
var secondTerm = Fixture.RandomItem.Text.Split(' ').Skip(10).FirstOrDefault();
28+
var randomItem = Fixture.RandomItem;
29+
var term = randomItem.Text.Split(' ').Skip(5).FirstOrDefault();
30+
var secondTerm = randomItem.Text.Split(' ').Skip(6).FirstOrDefault();
3031

3132
// act
32-
var wql = Fixture.ExecuteWql($"text~'{secondTerm} {term}':12");
33+
var wql = Fixture.ExecuteWql($"text~'{secondTerm} {term}':1");
3334
var res = wql?.Apply();
3435

36+
// valdation
3537
Assert.NotNull(res);
3638
foreach (var item in res)
3739
{
@@ -53,6 +55,7 @@ public void ProximityMatch2()
5355
var wql = Fixture.ExecuteWql($"text~'{secondTerm} {term}':3");
5456
var res = wql?.Apply();
5557

58+
// valdation
5659
Assert.NotNull(res);
5760
foreach (var item in res)
5861
{

0 commit comments

Comments
 (0)