-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Showing
13 changed files
with
617 additions
and
17 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
// Copyright 2020 ONIXLabs | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
namespace OnixLabs.Core.UnitTests.Data; | ||
|
||
public sealed record Location(string City, string Country) | ||
{ | ||
public static readonly Location London = new("London", "England"); | ||
public static readonly Location Paris = new("Paris", "France"); | ||
public static readonly Location Lisbon = new("Lisbon", "Postugal"); | ||
public static readonly Location Berlin = new("Berlin", "Germany"); | ||
public static readonly Location Brussels = new("Brussels", "Belgium"); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
// Copyright 2020 ONIXLabs | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
using System.Collections.Generic; | ||
|
||
namespace OnixLabs.Core.UnitTests.Data; | ||
|
||
public sealed record Person(string Name, int Age, IEnumerable<Location> Locations) | ||
{ | ||
public static readonly Person Alice = new("Alice", 12, [Location.London, Location.Paris]); | ||
public static readonly Person Bob = new("Bob", 23, [Location.Lisbon, Location.London]); | ||
public static readonly Person Charlie = new("Charlie", 34, [Location.Berlin, Location.Brussels]); | ||
|
||
public static readonly IEnumerable<Person> People = [Alice, Bob, Charlie]; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
// Copyright 2020 ONIXLabs | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
using System; | ||
using System.Linq; | ||
using System.Linq.Expressions; | ||
|
||
namespace OnixLabs.Core.UnitTests.Data; | ||
|
||
public class PersonSpecification(Expression<Func<Person, bool>> expression) : | ||
CriteriaSpecification<Person>(expression); | ||
|
||
public sealed class PersonNameEqualsSpecification(string name) : | ||
PersonSpecification(person => person.Name == name); | ||
|
||
public sealed class PersonNameStartsWithSpecification(string name) : | ||
PersonSpecification(person => person.Name.StartsWith(name)); | ||
|
||
public sealed class PersonOlderThanSpecification(int age) : | ||
PersonSpecification(person => person.Age > age); | ||
|
||
public sealed class PersonHasLocationSpecification(Location location) : | ||
PersonSpecification(person => person.Locations.Contains(location)); | ||
|
||
public sealed class PersonHasLocationCitySpecification(string city) : | ||
PersonSpecification(person => person.Locations.Any(location => location.City == city)); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,175 @@ | ||
// Copyright 2020 ONIXLabs | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
using System.Collections.Generic; | ||
using System.Linq; | ||
using OnixLabs.Core.Linq; | ||
using OnixLabs.Core.UnitTests.Data; | ||
using Xunit; | ||
|
||
namespace OnixLabs.Core.UnitTests; | ||
|
||
public sealed class SpecificationTests | ||
{ | ||
[Fact(DisplayName = "PersonNameEqualsSpecification should return the expected result")] | ||
public void PersonNameEqualsSpecificationShouldReturnExpectedResult() | ||
{ | ||
// Given | ||
PersonNameEqualsSpecification specification = new("Alice"); | ||
|
||
// When | ||
IEnumerable<Person> result = Person.People.Where(specification).ToList(); | ||
|
||
// Then | ||
Assert.Single(result); | ||
Assert.Contains(Person.Alice, result); | ||
} | ||
|
||
[Fact(DisplayName = "PersonNameStartsWithSpecification should return the expected result")] | ||
public void PersonNameStartsWithSpecificationShouldReturnExpectedResult() | ||
{ | ||
// Given | ||
PersonNameStartsWithSpecification specification = new("A"); | ||
|
||
// When | ||
IEnumerable<Person> result = Person.People.Where(specification).ToList(); | ||
|
||
// Then | ||
Assert.Single(result); | ||
Assert.Contains(Person.Alice, result); | ||
} | ||
|
||
[Fact(DisplayName = "PersonOlderThanSpecification should return the expected result")] | ||
public void PersonOlderThanSpecificationShouldReturnExpectedResult() | ||
{ | ||
// Given | ||
PersonOlderThanSpecification specification = new(20); | ||
|
||
// When | ||
IEnumerable<Person> result = Person.People.Where(specification).ToList(); | ||
|
||
// Then | ||
Assert.Equal(2, IEnumerableExtensions.Count(result)); | ||
Assert.Contains(Person.Bob, result); | ||
Assert.Contains(Person.Charlie, result); | ||
} | ||
|
||
[Fact(DisplayName = "PersonHasLocationSpecification should return the expected result")] | ||
public void PersonHasLocationSpecificationShouldReturnExpectedResult() | ||
{ | ||
// Given | ||
PersonHasLocationSpecification specification = new(Location.London); | ||
|
||
// When | ||
IEnumerable<Person> result = Person.People.Where(specification).ToList(); | ||
|
||
// Then | ||
Assert.Equal(2, IEnumerableExtensions.Count(result)); | ||
Assert.Contains(Person.Alice, result); | ||
Assert.Contains(Person.Bob, result); | ||
} | ||
|
||
[Fact(DisplayName = "PersonHasLocationCitySpecification should return the expected result")] | ||
public void PersonHasLocationCitySpecificationShouldReturnExpectedResult() | ||
{ | ||
// Given | ||
PersonHasLocationCitySpecification specification = new(Location.London.City); | ||
|
||
// When | ||
IEnumerable<Person> result = Person.People.Where(specification).ToList(); | ||
|
||
// Then | ||
Assert.Equal(2, IEnumerableExtensions.Count(result)); | ||
Assert.Contains(Person.Alice, result); | ||
Assert.Contains(Person.Bob, result); | ||
} | ||
|
||
[Fact(DisplayName = "PersonSpecification.And should return the expected result")] | ||
public void PersonSpecificationAndShouldReturnExpectedResult() | ||
{ | ||
// Given | ||
Specification<Person> specification = PersonSpecification.And( | ||
new PersonOlderThanSpecification(20), | ||
new PersonHasLocationCitySpecification("London") | ||
); | ||
|
||
// When | ||
IEnumerable<Person> result = Person.People.Where(specification).ToList(); | ||
|
||
// Then | ||
Assert.Single(result); | ||
Assert.Contains(Person.Bob, result); | ||
} | ||
|
||
[Fact(DisplayName = "PersonSpecification.And should return true for an empty collection")] | ||
public void PersonSpecificationAndShouldReturnTrueForEmptyCollection() | ||
{ | ||
// Given | ||
Specification<Person> specification = PersonSpecification.And(); | ||
|
||
// When | ||
bool result = specification.IsSatisfiedBy(Person.Alice); | ||
|
||
// Then | ||
Assert.True(result); | ||
} | ||
|
||
[Fact(DisplayName = "PersonSpecification.Or should return the expected result")] | ||
public void PersonSpecificationOrShouldReturnExpectedResult() | ||
{ | ||
// Given | ||
Specification<Person> specification = PersonSpecification.Or( | ||
new PersonNameStartsWithSpecification("A"), | ||
new PersonHasLocationCitySpecification("Lisbon") | ||
); | ||
|
||
// When | ||
IEnumerable<Person> result = Person.People.Where(specification).ToList(); | ||
|
||
// Then | ||
Assert.Equal(2, result.Count()); | ||
Assert.Contains(Person.Alice, result); | ||
Assert.Contains(Person.Bob, result); | ||
} | ||
|
||
[Fact(DisplayName = "PersonSpecification.Or should return false for an empty collection")] | ||
public void PersonSpecificationOrShouldReturnFalseForEmptyCollection() | ||
{ | ||
// Given | ||
Specification<Person> specification = PersonSpecification.Or(); | ||
|
||
// When | ||
bool result = specification.IsSatisfiedBy(Person.Alice); | ||
|
||
// Then | ||
Assert.False(result); | ||
} | ||
|
||
[Fact(DisplayName = "PersonSpecification.Not should return the expected result")] | ||
public void PersonSpecificationNotShouldReturnExpectedResult() | ||
{ | ||
// Given | ||
Specification<Person> specification = PersonSpecification.Or( | ||
new PersonNameStartsWithSpecification("A"), | ||
new PersonHasLocationCitySpecification("Lisbon") | ||
); | ||
|
||
// When | ||
IEnumerable<Person> result = Person.People.WhereNot(specification).ToList(); | ||
|
||
// Then | ||
Assert.Single(result); | ||
Assert.Contains(Person.Charlie, result); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.