@ -0,0 +1,51 @@
|
||||
kind: pipeline
|
||||
type: docker
|
||||
name: CI
|
||||
|
||||
trigger:
|
||||
event:
|
||||
- push
|
||||
|
||||
steps:
|
||||
# Les fichiers swagger.[yml|json] doivent être dans le répertoire /docs
|
||||
- name: build
|
||||
image: hub.codefirst.iut.uca.fr/marc.chevaldonne/codefirst-dotnet7-maui:latest
|
||||
commands:
|
||||
- cd Sources/
|
||||
- dotnet restore LeagueOfLegends.sln
|
||||
- dotnet build LeagueOfLegends.sln -c Release --no-restore /p:AndroidSdkDirectory=$ANDROID_SDK_ROOT -property:Aapt2ToolPath=$ANDROID_SDK_ROOT/build-tools/33.0.0
|
||||
- dotnet publish LolApp/LolApp.csproj -c Release --no-restore -o $CI_PROJECT_DIR/build/release -f:net7.0-android /p:AndroidSdkDirectory=/usr/lib/android-sdk
|
||||
|
||||
- name: tests
|
||||
image: hub.codefirst.iut.uca.fr/marc.chevaldonne/codefirst-dotnet7-maui:latest
|
||||
commands:
|
||||
- cd Sources/
|
||||
- dotnet restore LeagueOfLegends.sln
|
||||
- dotnet test LeagueOfLegends.sln --no-restore /p:AndroidSdkDirectory=$ANDROID_SDK_ROOT -property:Aapt2ToolPath=$ANDROID_SDK_ROOT/build-tools/33.0.0
|
||||
depends_on: [build]
|
||||
|
||||
- name: code-analysis
|
||||
image: hub.codefirst.iut.uca.fr/marc.chevaldonne/codefirst-dronesonarplugin-dotnet7-maui
|
||||
commands:
|
||||
- cd Sources/
|
||||
- dotnet restore LeagueOfLegends.sln
|
||||
- dotnet sonarscanner begin /k:$${project_key} /d:sonar.host.url=$${sonar_host} /d:sonar.coverageReportPaths="coveragereport/SonarQube.xml" /d:sonar.coverage.exclusions=$${coverage_exclusions} /d:sonar.login=$${sonar_token}
|
||||
- dotnet build LeagueOfLegends.sln -c Release --no-restore /p:AndroidSdkDirectory=$ANDROID_SDK_ROOT -property:Aapt2ToolPath=$ANDROID_SDK_ROOT/build-tools/33.0.0
|
||||
- dotnet test LeagueOfLegends.sln --logger trx --no-restore /p:AndroidSdkDirectory=$ANDROID_SDK_ROOT -property:Aapt2ToolPath=$ANDROID_SDK_ROOT/build-tools/33.0.0 /p:CollectCoverage=true /p:CoverletOutputFormat=cobertura --collect "XPlat Code Coverage"
|
||||
- reportgenerator -reports:"**/coverage.cobertura.xml" -reporttypes:SonarQube -targetdir:"coveragereport"
|
||||
- dotnet publish LolApp/LolApp.csproj -c Release --no-restore -o $CI_PROJECT_DIR/build/release -f:net7.0-android /p:AndroidSdkDirectory=/usr/lib/android-sdk
|
||||
- dotnet sonarscanner end /d:sonar.login=$${sonar_token}
|
||||
secrets: [ SECRET_SONAR_LOGIN ]
|
||||
environment:
|
||||
sonar_host: https://codefirst.iut.uca.fr/sonar/
|
||||
sonar_token:
|
||||
from_secret: SECRET_SONAR_LOGIN
|
||||
project_key: efLol
|
||||
coverage_exclusions: "Tests/**"
|
||||
# when:
|
||||
# branch:
|
||||
# - master
|
||||
# event:
|
||||
# - push
|
||||
# - pull_request
|
||||
depends_on: [tests]
|
After Width: | Height: | Size: 497 KiB |
After Width: | Height: | Size: 258 KiB |
After Width: | Height: | Size: 1.6 MiB |
After Width: | Height: | Size: 228 KiB |
After Width: | Height: | Size: 352 KiB |
After Width: | Height: | Size: 881 KiB |
After Width: | Height: | Size: 204 KiB |
After Width: | Height: | Size: 229 KiB |
After Width: | Height: | Size: 354 KiB |
@ -0,0 +1,200 @@
|
||||
# prepaLoL
|
||||
|
||||
## Enoncé
|
||||
Réaliser une application MAUI avec un MVVM "maison".
|
||||
Je vous fournis le modèle, et peut-être quelques vues au fur et à mesure.
|
||||
|
||||
J'attends de vous :
|
||||
- la réalisation d'un toolkit MVVM (bibliothèque de classes),
|
||||
- le _wrapping_ des classes du modèle par des VM (à chaque fois que c'est nécessaire),
|
||||
- l'utilisation de commandes pour les différentes fonctionnalités,
|
||||
- l'utilisation d'une VM _applicative_ (navigation, index, sélection...).
|
||||
|
||||
Faites ce que vous pouvez avec, dans l'ordre :
|
||||
1. l'affichage de la collection de Champions. La possibilité de naviguer de n en n champions (5 champions par page, ou 10, etc.) et la pagination doivent être gérées.
|
||||
2. Permettez la sélection d'un champion pour le voir dans une page (on n'utilisera que ses propriétés simples (```Name```, ```Bio```, ```Icon```) puis ```LargeImage```).
|
||||
3. Ajoutez la gestion des caractéristiques (```Characteristics```).
|
||||
4. Ajoutez la gestion de la classe du champion.
|
||||
5. Permettez la modification d'un champion existant (depuis la page du champion, et depuis un swipe sur l'item sélectionné dans la collection).
|
||||
6. Permettez l'ajout d'un nouveau champion.
|
||||
7. Ajoutez la gestion des skills.
|
||||
8. Ajoutez la gestion des skins.
|
||||
|
||||
## Captures d'écrans
|
||||
Quelques captures d'écrans comme attendus :
|
||||
<img src="./Documentation/IMG_5744.PNG" width=200/>
|
||||
<img src="./Documentation/IMG_5745.PNG" width=200/>
|
||||
<img src="./Documentation/IMG_5746.PNG" width=200/>
|
||||
<img src="./Documentation/IMG_5747.PNG" width=200/>
|
||||
<img src="./Documentation/IMG_5748.PNG" width=200/>
|
||||
<img src="./Documentation/IMG_5749.PNG" width=200/>
|
||||
<img src="./Documentation/IMG_5750.PNG" width=200/>
|
||||
<img src="./Documentation/IMG_5751.PNG" width=200/>
|
||||
<img src="./Documentation/IMG_5752.PNG" width=200/>
|
||||
|
||||
## Diagramme de classes du modèle
|
||||
```mermaid
|
||||
classDiagram
|
||||
class LargeImage{
|
||||
+/Base64 : string
|
||||
}
|
||||
class Champion{
|
||||
+/Name : string
|
||||
+/Bio : string
|
||||
+/Icon : string
|
||||
+/Characteristics : Dictionary~string, int~
|
||||
~ AddSkin(skin : Skin) bool
|
||||
~ RemoveSkin(skin: Skin) bool
|
||||
+ AddSkill(skill: Skill) bool
|
||||
+ RemoveSkill(skill: Skill) bool
|
||||
+ AddCharacteristics(someCharacteristics : params Tuple~string, int~[])
|
||||
+ RemoveCharacteristics(label : string) bool
|
||||
+ this~label : string~ : int?
|
||||
}
|
||||
Champion --> "1" LargeImage : Image
|
||||
class ChampionClass{
|
||||
<<enumeration>>
|
||||
Unknown,
|
||||
Assassin,
|
||||
Fighter,
|
||||
Mage,
|
||||
Marksman,
|
||||
Support,
|
||||
Tank,
|
||||
}
|
||||
Champion --> "1" ChampionClass : Class
|
||||
class Skin{
|
||||
+/Name : string
|
||||
+/Description : string
|
||||
+/Icon : string
|
||||
+/Price : float
|
||||
}
|
||||
Skin --> "1" LargeImage : Image
|
||||
Champion "1" -- "*" Skin
|
||||
class Skill{
|
||||
+/Name : string
|
||||
+/Description : string
|
||||
}
|
||||
class SkillType{
|
||||
<<enumeration>>
|
||||
Unknown,
|
||||
Basic,
|
||||
Passive,
|
||||
Ultimate,
|
||||
}
|
||||
Skill --> "1" SkillType : Type
|
||||
Champion --> "*" Skill
|
||||
class Rune{
|
||||
+/Name : string
|
||||
+/Description : string
|
||||
}
|
||||
Rune --> "1" LargeImage : Image
|
||||
class RuneFamily{
|
||||
<<enumeration>>
|
||||
Unknown,
|
||||
Precision,
|
||||
Domination
|
||||
}
|
||||
Rune --> "1" RuneFamily : Family
|
||||
class Category{
|
||||
<<enumeration>>
|
||||
Major,
|
||||
Minor1,
|
||||
Minor2,
|
||||
Minor3,
|
||||
OtherMinor1,
|
||||
OtherMinor2
|
||||
}
|
||||
class RunePage{
|
||||
+/Name : string
|
||||
+/this[category : Category] : Rune?
|
||||
- CheckRunes(newRuneCategory : Category)
|
||||
- CheckFamilies(cat1 : Category, cat2 : Category) bool?
|
||||
- UpdateMajorFamily(minor : Category, expectedValue : bool)
|
||||
}
|
||||
RunePage --> "*" Rune : Dictionary~Category,Rune~
|
||||
```
|
||||
|
||||
## Diagramme de classes des interfaces de gestion de l'accès aux données
|
||||
```mermaid
|
||||
classDiagram
|
||||
direction LR;
|
||||
class IGenericDataManager~T~{
|
||||
<<interface>>
|
||||
GetNbItems() Task~int~
|
||||
GetItems(index : int, count : int, orderingPropertyName : string?, descending : bool) Task~IEnumerable~T~~
|
||||
GetNbItemsByName(substring : string)
|
||||
GetItemsByName(substring : string, index : int, count : int, orderingPropertyName : string?, descending : bool) Task~IEnumerable~T~~
|
||||
UpdateItem(oldItem : T, newItem : T) Task~T~~
|
||||
AddItem(item : T) Task~T~
|
||||
DeleteItem(item : T) Task~bool~
|
||||
}
|
||||
class IChampionsManager{
|
||||
<<interface>>
|
||||
GetNbItemsByCharacteristic(charName : string)
|
||||
GetItemsByCharacteristic(charName : string, index : int, count : int, orderingPropertyName : string?, descending : bool) Task~IEnumerable~Champion?~~
|
||||
GetNbItemsByClass(championClass : ChampionClass)
|
||||
GetItemsByClass(championClass : ChampionClass, index : int, count : int, orderingPropertyName : string?, descending : bool) Task~IEnumerable~Champion?~~
|
||||
GetNbItemsBySkill(skill : Skill?)
|
||||
GetItemsBySkill(skill : Skill?, index : int, count : int, orderingPropertyName : string?, descending : bool) Task~IEnumerable~Champion?~~
|
||||
GetNbItemsBySkill(skill : string)
|
||||
GetItemsBySkill(skill : string, index : int, count : int, orderingPropertyName : string?, descending : bool) Task~IEnumerable~Champion?~~
|
||||
GetNbItemsByRunePage(runePage : RunePage?)
|
||||
GetItemsByRunePage(runePage : RunePage?, index : int, count : int, orderingPropertyName : string?, descending : bool) Task~IEnumerable~Champion?~~
|
||||
}
|
||||
class ISkinsManager{
|
||||
<<interface>>
|
||||
GetNbItemsByChampion(champion : Champion?)
|
||||
GetItemsByChampion(champion : Champion?, index : int, count : int, orderingPropertyName : string?, descending : bool) Task~IEnumerable~Skin?~~
|
||||
}
|
||||
class IRunesManager{
|
||||
<<interface>>
|
||||
GetNbItemsByFamily(family : RuneFamily)
|
||||
GetItemsByFamily(family : RuneFamily, index : int, count : int, orderingPropertyName : string?, descending : bool) Task~IEnumerable~Rune?~~
|
||||
}
|
||||
class IRunePagesManager{
|
||||
<<interface>>
|
||||
GetNbItemsByRune(rune : Rune?)
|
||||
GetItemsByRune(rune : Rune?, index : int, count : int, orderingPropertyName : string?, descending : bool) Task~IEnumerable~RunePage?~~
|
||||
GetNbItemsByChampion(champion : Champion?)
|
||||
GetItemsByChampion(champion : Champion?, index : int, count : int, orderingPropertyName : string?, descending : bool) Task~IEnumerable~RunePage?~~
|
||||
}
|
||||
|
||||
IGenericDataManager~Champion?~ <|.. IChampionsManager : T--Champion?
|
||||
IGenericDataManager~Skin?~ <|.. ISkinsManager : T--Skin?
|
||||
IGenericDataManager~Rune?~ <|.. IRunesManager : T--Rune?
|
||||
IGenericDataManager~RunePage?~ <|.. IRunePagesManager : T--RunePage?
|
||||
class IDataManager{
|
||||
<<interface>>
|
||||
}
|
||||
IChampionsManager <-- IDataManager : ChampionsMgr
|
||||
ISkinsManager <-- IDataManager : SkinsMgr
|
||||
IRunesManager <-- IDataManager : RunesMgr
|
||||
IRunePagesManager <-- IDataManager : RunePagesMgr
|
||||
```
|
||||
|
||||
## Diagramme de classes simplifié du Stub
|
||||
```mermaid
|
||||
classDiagram
|
||||
direction TB;
|
||||
|
||||
IDataManager <|.. StubData
|
||||
|
||||
ChampionsManager ..|> IChampionsManager
|
||||
StubData --> ChampionsManager
|
||||
|
||||
RunesManager ..|> IRunesManager
|
||||
StubData --> RunesManager
|
||||
|
||||
RunePagesManager ..|> IRunePagesManager
|
||||
StubData --> RunePagesManager
|
||||
|
||||
SkinsManager ..|> ISkinsManager
|
||||
StubData --> SkinsManager
|
||||
|
||||
StubData --> RunesManager
|
||||
StubData --> "*" Champion
|
||||
StubData --> "*" Rune
|
||||
StubData --> "*" RunePages
|
||||
StubData --> "*" Skins
|
||||
```
|
@ -0,0 +1,18 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="enums\" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="enums\" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Shared\Shared.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
@ -0,0 +1,9 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
@ -0,0 +1,12 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Model\Model.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
@ -0,0 +1,20 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Model\Model.csproj" />
|
||||
<ProjectReference Include="..\..\StubLib\StubLib.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Remove="Microsoft.Extensions.DependencyInjection" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="7.0.0" />
|
||||
</ItemGroup>
|
||||
</Project>
|