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

@ -3,15 +3,15 @@ namespace Model;
public interface IDataManager public interface IDataManager
{ {
Task<IEnumerable<Book>> GetBooks(int index, int count); Task<IEnumerable<Book>> GetBooks(int index, int count);
Task<IEnumerable<Book>> GetBooksByTitle(string title, 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>> GetBooksByAuthor(string? author, int index, int count);
Task<IEnumerable<Book>> GetBooksByIsbn(string isbn, int index, int count); Task<IEnumerable<Book>> GetBooksByIsbn(string? isbn, int index, int count);
Task<Book?> GetBookById(long id); Task<Book?> GetBookById(long id);
Task<IEnumerable<Person>> GetPersons(int index, int count); 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<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> CreateBook(string title, string author, string isbn);
Task<Book?> UpdateBook(long id, Book book); 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,10 +2,11 @@
namespace Stub; namespace Stub;
public class StubDataManager : IDataManager public class StubDataManager : EmptyStubDataManager
{ {
private readonly static List<Book> books = new() public StubDataManager() : base()
{ {
books.AddRange([
new Book(1, "Les Trois Mousquetaires", "Alexandre Dumas", "979-8415441792"), new Book(1, "Les Trois Mousquetaires", "Alexandre Dumas", "979-8415441792"),
new Book(2, "Vingt Ans Après", "Alexandre Dumas", "979-8805372019"), 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(3, "Le Vicomte de Bragelonne - Livre Premier", "Alexandre Dumas", "979-8376127575"),
@ -16,26 +17,23 @@ public class StubDataManager : IDataManager
new Book(8, "Les Misérables", "Victor Hugo", "979-8850172916"), new Book(8, "Les Misérables", "Victor Hugo", "979-8850172916"),
new Book(9, "Notre-Dame de Paris", "Victor Hugo", "979-8863757285"), new Book(9, "Notre-Dame de Paris", "Victor Hugo", "979-8863757285"),
new Book(10, "Quatrevingt-treize", "Victor Hugo", "979-8863954202"), new Book(10, "Quatrevingt-treize", "Victor Hugo", "979-8863954202"),
new Book(11, "Han d'Islande", "Victor Hugo", "979-8864251553"), new Book(11, "Han d'Islande", "Victor Hugo", "979-8864251553")
}; ]);
private readonly static List<Person> persons = new() bookId = 12;
{
persons.AddRange([
new Person(1, "Chick", "Corea"), new Person(1, "Chick", "Corea"),
new Person(2, "Stanley", "Clarke"), new Person(2, "Stanley", "Clarke"),
new Person(3, "Lenny", "White"), new Person(3, "Lenny", "White"),
new Person(4, "Frank", "Gambale"), new Person(4, "Frank", "Gambale"),
new Person(5, "Jean-Luc", "Ponty"), new Person(5, "Jean-Luc", "Ponty"),
new Person(6, "Al", "Di Meola"), new Person(6, "Al", "Di Meola"),
new Person(7, "Steve", "Gadd"), new Person(7, "Steve", "Gadd")
}; ]);
private long bookId = 12;
private long personId = 8; personId = 8;
static StubDataManager()
{
books[0].Borrower = persons[0]; books[0].Borrower = persons[0];
persons[0].BorrowBook(books[0]); persons[0].BorrowBook(books[0]);
@ -63,163 +61,4 @@ public class StubDataManager : IDataManager
books[10].Borrower = persons[3]; books[10].Borrower = persons[3];
persons[3].BorrowBook(books[10]); 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