enhanced test
continuous-integration/drone/push Build is passing Details

master
Marc CHEVALDONNE 7 months ago
parent c47f1013e3
commit 3b524e7069

@ -23,6 +23,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{162D6E80
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestModel", "basics\Tests\TestModel\TestModel.csproj", "{DA282291-A2AD-428B-8899-C6EC2299C4FF}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestDataManager", "basics\Tests\TestDataManager\TestDataManager.csproj", "{0BD88157-82ED-4C52-A74C-3A7A046B2D13}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -57,6 +59,10 @@ Global
{DA282291-A2AD-428B-8899-C6EC2299C4FF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DA282291-A2AD-428B-8899-C6EC2299C4FF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DA282291-A2AD-428B-8899-C6EC2299C4FF}.Release|Any CPU.Build.0 = Release|Any CPU
{0BD88157-82ED-4C52-A74C-3A7A046B2D13}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0BD88157-82ED-4C52-A74C-3A7A046B2D13}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0BD88157-82ED-4C52-A74C-3A7A046B2D13}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0BD88157-82ED-4C52-A74C-3A7A046B2D13}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -70,5 +76,6 @@ Global
{E0A3410E-10BC-4E6C-B280-5CD389E36E4E} = {DFAECDF9-BEF0-4D05-B7C7-238D78986BD0}
{162D6E80-9B72-4A78-8481-39E3AC255C99} = {DFAECDF9-BEF0-4D05-B7C7-238D78986BD0}
{DA282291-A2AD-428B-8899-C6EC2299C4FF} = {162D6E80-9B72-4A78-8481-39E3AC255C99}
{0BD88157-82ED-4C52-A74C-3A7A046B2D13} = {162D6E80-9B72-4A78-8481-39E3AC255C99}
EndGlobalSection
EndGlobal

@ -3,15 +3,15 @@ namespace Model;
public interface IDataManager
{
Task<IEnumerable<Book>> GetBooks(int index, int count);
Task<IEnumerable<Book>> GetBooksByTitle(string title, int index, int count);
Task<IEnumerable<Book>> GetBooksByAuthor(string author, int index, int count);
Task<IEnumerable<Book>> GetBooksByIsbn(string isbn, int index, int count);
Task<IEnumerable<Book>> GetBooksByTitle(string? title, int index, int count);
Task<IEnumerable<Book>> GetBooksByAuthor(string? author, int index, int count);
Task<IEnumerable<Book>> GetBooksByIsbn(string? isbn, int index, int count);
Task<Book?> GetBookById(long id);
Task<IEnumerable<Person>> GetPersons(int index, int count);
Task<IEnumerable<Person>> GetPersonsByName(string name, int index, int count);
Task<IEnumerable<Person>> GetPersonsByName(string? name, int index, int count);
Task<Person?> GetPersonById(long id);
Task<IEnumerable<Book>> GetBooksBorrowedBy(Person person, int index, int count);
Task<IEnumerable<Book>> GetBooksBorrowedBy(Person? person, int index, int count);
Task<Book> CreateBook(string title, string author, string isbn);
Task<Book?> UpdateBook(long id, Book book);

@ -0,0 +1,186 @@
using System;
using Model;
namespace Stub;
public class EmptyStubDataManager : IDataManager
{
protected readonly List<Book> books = new();
protected readonly List<Person> persons = new();
protected long bookId;
protected long personId;
public Task<bool> BorrowBook(Book book, Person person)
{
if(book == null || person == null) return Task.FromResult(false);
var foundBook = GetBookById(book.Id).Result;
var foundPerson = GetPersonById(person.Id).Result;
if(foundBook == null || foundPerson == null)
return Task.FromResult(false);
if(foundBook.Borrower != null && !foundBook.Borrower.Equals(foundPerson))
{
return Task.FromResult(false);
}
foundBook.Borrower = foundPerson;
foundPerson.BorrowBook(foundBook);
return Task.FromResult(true);
}
public Task<Book> CreateBook(string title, string author, string isbn)
{
Book book = new Book(bookId, title, author, isbn);
books.Add(book);
bookId++;
return Task.FromResult(book);
}
public Task<Person> CreatePerson(string firstName, string lastName)
{
Person person = new Person(personId, firstName, lastName);
persons.Add(person);
personId++;
return Task.FromResult(person);
}
public Task<bool> DeleteBook(long id)
{
Book? book = books.SingleOrDefault(b => b.Id == id);
if(book == null)
{
return Task.FromResult(false);
}
book.Borrower?.ReturnBook(book);
books.Remove(book);
return Task.FromResult(true);
}
public Task<bool> DeletePerson(long id)
{
Person? person = persons.SingleOrDefault(p => p.Id == id);
if(person == null)
{
return Task.FromResult(false);
}
foreach(var book in person.Books)
{
book.Borrower = null;
}
persons.Remove(person);
return Task.FromResult(true);
}
public Task<Book?> GetBookById(long id)
{
return Task.FromResult(books.SingleOrDefault(b => b.Id == id));
}
public Task<IEnumerable<Book>> GetBooks(int index, int count)
{
var foundBooks = books.Skip(index*count).Take(count);
return Task.FromResult(foundBooks);
}
public Task<IEnumerable<Book>> GetBooksBorrowedBy(Person? person, int index, int count)
{
if(person == null) return Task.FromResult(Enumerable.Empty<Book>());
var foundBooks = books.Where(b => person.Equals(b.Borrower))
.Skip(index*count).Take(count);
return Task.FromResult(foundBooks);
}
public Task<IEnumerable<Book>> GetBooksByAuthor(string? author, int index, int count)
{
if(string.IsNullOrWhiteSpace(author)) return Task.FromResult(Enumerable.Empty<Book>());
var foundBooks = books.Where(b => b.Author.Contains(author, StringComparison.InvariantCultureIgnoreCase))
.Skip(index*count).Take(count);
return Task.FromResult(foundBooks);
}
public Task<IEnumerable<Book>> GetBooksByIsbn(string? isbn, int index, int count)
{
if(string.IsNullOrWhiteSpace(isbn)) return Task.FromResult(Enumerable.Empty<Book>());
var foundBooks = books.Where(b => b.Isbn.Equals(isbn))
.Skip(index*count).Take(count);
return Task.FromResult(foundBooks);
}
public Task<IEnumerable<Book>> GetBooksByTitle(string? title, int index, int count)
{
if(string.IsNullOrWhiteSpace(title)) return Task.FromResult(Enumerable.Empty<Book>());
var foundBooks = books.Where(b => b.Title.Contains(title, StringComparison.InvariantCultureIgnoreCase))
.Skip(index*count).Take(count);
return Task.FromResult(foundBooks);
}
public Task<Person?> GetPersonById(long id)
{
return Task.FromResult(persons.SingleOrDefault(p => p.Id == id));
}
public Task<IEnumerable<Person>> GetPersons(int index, int count)
{
var foundPersons = persons.Skip(index*count).Take(count);
return Task.FromResult(foundPersons);
}
public Task<IEnumerable<Person>> GetPersonsByName(string? name, int index, int count)
{
if(string.IsNullOrWhiteSpace(name)) return Task.FromResult(Enumerable.Empty<Person>());
var foundPersons = persons.Where(b => b.FirstName.Contains(name, StringComparison.InvariantCultureIgnoreCase)
|| b.LastName.Contains(name, StringComparison.InvariantCultureIgnoreCase))
.Skip(index*count).Take(count);
return Task.FromResult(foundPersons);
}
public Task<bool> ReturnBook(Book book, Person person)
{
var foundBook = GetBookById(book.Id).Result;
var foundPerson = GetPersonById(person.Id).Result;
if(foundBook == null || foundPerson == null)
return Task.FromResult(false);
if(!foundPerson.Books.Contains(foundBook) || !foundPerson.Equals(foundBook.Borrower))
return Task.FromResult(false);
foundPerson.ReturnBook(foundBook);
foundBook.Borrower = null;
return Task.FromResult(true);
}
public Task<Book?> UpdateBook(long id, Book book)
{
var foundBook = GetBookById(id).Result;
if(foundBook == null)
return Task.FromResult((Book?)null);
foundBook.Author = book.Author;
foundBook.Isbn = book.Isbn;
foundBook.Title = book.Title;
return Task.FromResult((Book?)foundBook);
}
public Task<Person?> UpdatePerson(long id, Person person)
{
var foundPerson = GetPersonById(id).Result;
if(foundPerson == null)
return Task.FromResult((Person?)null);
foundPerson.FirstName = person.FirstName;
foundPerson.LastName = person.LastName;
return Task.FromResult((Person?)foundPerson);
}
}

@ -2,40 +2,38 @@
namespace Stub;
public class StubDataManager : IDataManager
public class StubDataManager : EmptyStubDataManager
{
private readonly static List<Book> books = new()
{
new Book(1, "Les Trois Mousquetaires", "Alexandre Dumas", "979-8415441792"),
new Book(2, "Vingt Ans Après", "Alexandre Dumas", "979-8805372019"),
new Book(3, "Le Vicomte de Bragelonne - Livre Premier", "Alexandre Dumas", "979-8376127575"),
new Book(4, "Le Vicomte de Bragelonne - Livre Second", "Alexandre Dumas", "979-8376430019"),
new Book(5, "Vingt mille lieues sous les Mers", "Jules Verne", "979-8489937313"),
new Book(6, "L'île mystérieuse", "Jules Verne", "979-8492533861"),
new Book(7, "Les enfants du capitaine Grant", "Jules Verne", "979-8757717418"),
new Book(8, "Les Misérables", "Victor Hugo", "979-8850172916"),
new Book(9, "Notre-Dame de Paris", "Victor Hugo", "979-8863757285"),
new Book(10, "Quatrevingt-treize", "Victor Hugo", "979-8863954202"),
new Book(11, "Han d'Islande", "Victor Hugo", "979-8864251553"),
};
private readonly static List<Person> persons = new()
{
new Person(1, "Chick", "Corea"),
new Person(2, "Stanley", "Clarke"),
new Person(3, "Lenny", "White"),
new Person(4, "Frank", "Gambale"),
new Person(5, "Jean-Luc", "Ponty"),
new Person(6, "Al", "Di Meola"),
new Person(7, "Steve", "Gadd"),
};
private long bookId = 12;
private long personId = 8;
public StubDataManager() : base()
{
books.AddRange([
new Book(1, "Les Trois Mousquetaires", "Alexandre Dumas", "979-8415441792"),
new Book(2, "Vingt Ans Après", "Alexandre Dumas", "979-8805372019"),
new Book(3, "Le Vicomte de Bragelonne - Livre Premier", "Alexandre Dumas", "979-8376127575"),
new Book(4, "Le Vicomte de Bragelonne - Livre Second", "Alexandre Dumas", "979-8376430019"),
new Book(5, "Vingt mille lieues sous les Mers", "Jules Verne", "979-8489937313"),
new Book(6, "L'île mystérieuse", "Jules Verne", "979-8492533861"),
new Book(7, "Les enfants du capitaine Grant", "Jules Verne", "979-8757717418"),
new Book(8, "Les Misérables", "Victor Hugo", "979-8850172916"),
new Book(9, "Notre-Dame de Paris", "Victor Hugo", "979-8863757285"),
new Book(10, "Quatrevingt-treize", "Victor Hugo", "979-8863954202"),
new Book(11, "Han d'Islande", "Victor Hugo", "979-8864251553")
]);
bookId = 12;
persons.AddRange([
new Person(1, "Chick", "Corea"),
new Person(2, "Stanley", "Clarke"),
new Person(3, "Lenny", "White"),
new Person(4, "Frank", "Gambale"),
new Person(5, "Jean-Luc", "Ponty"),
new Person(6, "Al", "Di Meola"),
new Person(7, "Steve", "Gadd")
]);
personId = 8;
static StubDataManager()
{
books[0].Borrower = persons[0];
persons[0].BorrowBook(books[0]);
@ -63,163 +61,4 @@ public class StubDataManager : IDataManager
books[10].Borrower = persons[3];
persons[3].BorrowBook(books[10]);
}
public Task<bool> BorrowBook(Book book, Person person)
{
var foundBook = GetBookById(book.Id).Result;
var foundPerson = GetPersonById(person.Id).Result;
if(foundBook == null || foundPerson == null)
return Task.FromResult(false);
if(foundBook.Borrower != null)
{
return Task.FromResult(false);
}
foundBook.Borrower = foundPerson;
foundPerson.BorrowBook(foundBook);
return Task.FromResult(true);
}
public Task<Book> CreateBook(string title, string author, string isbn)
{
Book book = new Book(bookId, title, author, isbn);
books.Add(book);
bookId++;
return Task.FromResult(book);
}
public Task<Person> CreatePerson(string firstName, string lastName)
{
Person person = new Person(personId, firstName, lastName);
persons.Add(person);
personId++;
return Task.FromResult(person);
}
public Task<bool> DeleteBook(long id)
{
Book? book = books.SingleOrDefault(b => b.Id == id);
if(book == null)
{
return Task.FromResult(false);
}
book.Borrower?.ReturnBook(book);
books.Remove(book);
return Task.FromResult(true);
}
public Task<bool> DeletePerson(long id)
{
Person? person = persons.SingleOrDefault(p => p.Id == id);
if(person == null)
{
return Task.FromResult(false);
}
foreach(var book in person.Books)
{
book.Borrower = null;
}
persons.Remove(person);
return Task.FromResult(true);
}
public Task<Book?> GetBookById(long id)
{
return Task.FromResult(books.SingleOrDefault(b => b.Id == id));
}
public Task<IEnumerable<Book>> GetBooks(int index, int count)
{
var foundBooks = books.Skip(index*count).Take(count);
return Task.FromResult(foundBooks);
}
public Task<IEnumerable<Book>> GetBooksBorrowedBy(Person person, int index, int count)
{
var foundBooks = books.Where(b => person.Equals(b.Borrower))
.Skip(index*count).Take(count);
return Task.FromResult(foundBooks);
}
public Task<IEnumerable<Book>> GetBooksByAuthor(string author, int index, int count)
{
var foundBooks = books.Where(b => b.Author.Contains(author, StringComparison.InvariantCultureIgnoreCase))
.Skip(index*count).Take(count);
return Task.FromResult(foundBooks);
}
public Task<IEnumerable<Book>> GetBooksByIsbn(string isbn, int index, int count)
{
var foundBooks = books.Where(b => b.Isbn.Equals(isbn))
.Skip(index*count).Take(count);
return Task.FromResult(foundBooks);
}
public Task<IEnumerable<Book>> GetBooksByTitle(string title, int index, int count)
{
var foundBooks = books.Where(b => b.Title.Contains(title, StringComparison.InvariantCultureIgnoreCase))
.Skip(index*count).Take(count);
return Task.FromResult(foundBooks);
}
public Task<Person?> GetPersonById(long id)
{
return Task.FromResult(persons.SingleOrDefault(p => p.Id == id));
}
public Task<IEnumerable<Person>> GetPersons(int index, int count)
{
var foundPersons = persons.Skip(index*count).Take(count);
return Task.FromResult(foundPersons);
}
public Task<IEnumerable<Person>> GetPersonsByName(string name, int index, int count)
{
var foundPersons = persons.Where(b => b.FirstName.Contains(name, StringComparison.InvariantCultureIgnoreCase)
|| b.LastName.Contains(name, StringComparison.InvariantCultureIgnoreCase))
.Skip(index*count).Take(count);
return Task.FromResult(foundPersons);
}
public Task<bool> ReturnBook(Book book, Person person)
{
var foundBook = GetBookById(book.Id).Result;
var foundPerson = GetPersonById(person.Id).Result;
if(foundBook == null || foundPerson == null)
return Task.FromResult(false);
if(!foundPerson.Books.Contains(foundBook) || !foundPerson.Equals(foundBook.Borrower))
return Task.FromResult(false);
foundPerson.ReturnBook(foundBook);
foundBook.Borrower = null;
return Task.FromResult(true);
}
public Task<Book?> UpdateBook(long id, Book book)
{
var foundBook = GetBookById(id).Result;
if(foundBook == null)
return Task.FromResult((Book?)null);
foundBook.Author = book.Author;
foundBook.Isbn = book.Isbn;
foundBook.Title = book.Title;
return Task.FromResult((Book?)foundBook);
}
public Task<Person?> UpdatePerson(long id, Person person)
{
var foundPerson = GetPersonById(id).Result;
if(foundPerson == null)
return Task.FromResult((Person?)null);
foundPerson.FirstName = person.FirstName;
foundPerson.LastName = person.LastName;
return Task.FromResult((Person?)foundPerson);
}
}

@ -0,0 +1,33 @@
using Model;
namespace TestDataManager;
public class DataManagerTest
{
[Theory]
[ClassData(typeof(TestData_BorrowBook))]
public async void TestBorrowBook(bool expectedResult, Book bookToBorrow, Person borrower, IDataManager dataManager)
{
bool result = await dataManager.BorrowBook(bookToBorrow, borrower);
Book? book = (await dataManager.GetBooksByIsbn(bookToBorrow?.Isbn, 0, 100)).SingleOrDefault();
Person? person = (await dataManager.GetPersonsByName(borrower?.LastName, 0, 100)).SingleOrDefault();
Assert.Equal(expectedResult, result);
if(result)
{
Assert.NotNull(book);
Assert.NotNull(person);
Assert.Contains(book, person.Books);
Assert.Equal(person, book.Borrower);
}
else
{
if(person != null && book != null)
{
Assert.DoesNotContain(book, person.Books);
Assert.NotEqual(person, book.Borrower);
}
}
}
}

@ -0,0 +1,28 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="6.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
<PackageReference Include="xunit" Version="2.5.3" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.3" />
</ItemGroup>
<ItemGroup>
<Using Include="Xunit" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Model\Model.csproj" />
<ProjectReference Include="..\..\Stub\Stub.csproj" />
</ItemGroup>
</Project>

@ -0,0 +1,67 @@
using System;
using System.Collections;
using Model;
using Stub;
namespace TestDataManager;
public class BorrowBookStub : EmptyStubDataManager
{
public BorrowBookStub() : base()
{
books.AddRange([
new Book(1, "Les Trois Mousquetaires", "Alexandre Dumas", "979-8415441792"),
new Book(2, "Les Misérables", "Victor Hugo", "979-8850172916")
]);
bookId = 3;
persons.AddRange([
new Person(1, "Chick", "Corea"),
new Person(2, "Stanley", "Clarke")
]);
personId = 3;
books[0].Borrower = persons[0];
persons[0].BorrowBook(books[0]);
}
}
public class TestData_BorrowBook : IEnumerable<object[]>
{
public IEnumerator<object[]> GetEnumerator()
{
//no book and no borrower
yield return new object[] { false, null, null, new BorrowBookStub() };
//no book
yield return new object[] { false, null, new Person("John", "Coltrane"), new StubDataManager() };
//no borrower
yield return new object[] { false, new Book( "Les Pardaillan", "Michel Zévaco", "978-2221098417"), null, new BorrowBookStub() };
//new book and new borrower
yield return new object[] { false, new Book( "Les Pardaillan", "Michel Zévaco", "978-2221098417"), new Person("John", "Coltrane"), new BorrowBookStub() };
//new book and already known borrower
yield return new object[] { false, new Book( "Les Pardaillan", "Michel Zévaco", "978-2221098417"), new Person(1, "Chick", "Corea"), new BorrowBookStub() };
//already known but free book and new borrower
yield return new object[] { false, new Book(2, "Les Misérables", "Victor Hugo", "979-8850172916"), new Person("John", "Coltrane"), new BorrowBookStub() };
//already known but already borrowed book and new borrower
yield return new object[] { false, new Book(1, "Les Trois Mousquetaires", "Alexandre Dumas", "979-8415441792"), new Person("John", "Coltrane"), new BorrowBookStub() };
//already known but free book and already known borrower
yield return new object[] { true, new Book(2, "Les Misérables", "Victor Hugo", "979-8850172916"), new Person(1, "Chick", "Corea"), new BorrowBookStub() };
//already known but already borrowed book by another borrower and already known borrower
yield return new object[] { false, new Book(1, "Les Trois Mousquetaires", "Alexandre Dumas", "979-8415441792"), new Person(2, "Stanley", "Clarke"), new BorrowBookStub() };
//already known but already borrowed book by this borrower and already known borrower
yield return new object[] { true, new Book(1, "Les Trois Mousquetaires", "Alexandre Dumas", "979-8415441792"), new Person(1, "Chick", "Corea"), new BorrowBookStub() };
}
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}
Loading…
Cancel
Save