
# Krav til applikasjonen

## Delbeskrivelser


### Del 1 - Grunnklasser og brukergrensesnitt

```
I denne delen skal dere lage de grunnleggende klassene i appen deres. Klassene skal realisere
hovedfunksjonaliteten i appen, men dere trenger ikke å implementere feilhåndtering og lagring i
denne delen (det kommer senere). Tilstanden til objektene i appen deres skal være innkapslet,
og et objekt skal administrere sin egen tilstand.
I tillegg til grunnklassene skal dere lage et brukergrensesnitt i FXML. Vi anbefaler at dere
tenker litt over dette grensesnittet, gjerne skissér det på forhånd for å se at det virker greit å
bruke. Om dere har tatt eller tar TDT4180 - Menneske-maskin-interaksjon kan det være lærerikt
å bruke noen av konseptene dere har lært der (men merk at dere ikke vurderes ut i fra det i dette
faget).

Dere skal også lage Controller- og App-klasser som starter appen og kobler sammen brukergrensesnitt 
og underliggende klasser. Merk at appen deres skal bygges etter Model-ViewController-prinsippet. 
Det betyr at det skal være et klart skille mellom modell (model), grensesnitt (view), og 
kontroller (controller) i appen. Her er grensesnittet definert av FXML-filene deres,
og modellene er de underliggende klassene. Kontrollerens jobb er å binde sammen grensesnitt og
modeller, altså å holde verdiene i grensesnittet oppdatert i forhold til modellene, og å reagere på
brukerinput i grensesnittet og kalle passende metoder i modellene.
```


### Del 2 - Filbehandling

```
Her skal dere utvide appen til å kunne lese fra og skrive til filer. Dere må selv bestemme hva som
skal lagres, og formatet det skal lagres på. Altså må dere finne en måte å strukturere tilstanden
i objektene deres som en tekstfil.

For å gjøre det enklere å bytte filformat på et senere tidspunkt, eller å gjøre det mulig å lagre
i forskjellige formater, skal dere lage et grensesnitt (interface) med metoder for lesing fra og
skriving til fil. Deretter må dere lage minimum en ny klasse (altså ikke en av klassene dere har
lagd tidligere i prosjektet) som implementerer grensesnittet og realiserer funksjonaliteten.
```



### Del 3 - Feilhåndtering

```
I de aller fleste programmer vil det være mulighet for at feil skjer under kjøring, uavhengig av
om koden er skrevet riktig. Det kan f.eks. være ved ugyldig input fra brukere, filer som ikke
eksisterer, manglende internett, eller lignende. Om denne type feil ikke håndteres, vil det enten
føre til at appen oppfører seg feil, eller at den krasjer.

I denne delen av prosjektet skal dere utvide appen deres til å håndtere feil på passende måter.
For å gjøre dette må dere finne ut:

• Hvor i appen deres det kan oppstå feil.
• Hvordan appen bør respondere på slik feil.

Deretter må dere implementere feilhånderingen dere har funnet ut at er hensiktsmessig.
```

### Del 4 - Testing

```
Siste del av prosjektet handler om å skrive enhetstester til appen deres. Dere bør teste alle
metoder med funksjonalitet utover helt enkle get- og set-metoder. Dere trenger heller ikke å
teste Controller- og App-klassene deres, da det ikke skal være logikk i disse. Har dere logikk
liggende i Controller-klassen bør dere flytte dette til en passende underliggende klasse før dere
begynner på denne delen.

Når dere skriver testene bør dere først tenke over hvilke deler av koden det er viktig å sjekke
at fungerer som den skal. Deretter bør dere prøve å komme på (kombinasjoner av) input-verdier
og tilstander som kan føre til uventet oppførsel i disse delene. Slike edge-cases bør det skrives
tester for, i tillegg til å teste for at funksjonaliteten fungerer med ”snillere” verdier. Til slutt er
det viktig at testene skal sjekke at koden fungerer, ikke motsatt. Om dere er sikre på at en testen
er riktig, men den feiler, så må dere sannsynligvis endre koden i klassen som testes – ikke testen
deres.
```

## Detaljerte krav

### Del 1 - Grunnklasser og brukergrensesnitt

1. **Appen skal bestå av minimum to interagerende klasser, i tillegg til Controller- og Appklassene, og brukergrensesnittet laget i FXML.**

Andre klasser:
  - [service/][service-folder]
  - [model/][model-folder]

App-klasse:
  - [Main.java][Main-file]

Controller klasser:
  - [MainController.java][MainController-file]
  - [controllers/][controllers-folder]

Brukergrensesnitt:
  [resources/fxml/][fxml-folder]

I denne delen har vi laget én Application-klasse som laster én hoved-FXML-fil + kontroller, som internt linker til flere andre fxml filer med hver sine kontrollere. Kontrollerne binder sammen sine relevante grensesnittsparametere med en global [`Model`][Model-file]-klasse og setter opp event-lyttere på de relevante FXML-elementene, i tillegg til å sette opp en eventbus mellom seg og de andre kontrollerne for kommunikasjon dem imellom. Eventbus bruker dataklasser arvet fra [`Event`][Event-file]-klassen, som beskrivelse på hvilken type melding som blir sendt. Basert på typen av meldingen skiller eventbusen hvilke funksjoner som skal fyres av. Dette er en variant av observatør-observert metoden.

Her er et diagram over koblingene i programmet:

<div align="center">
<img src=".gitlab/graphics/FXML-diagram.png">
</div>


2. **Minimum en av klassene må ha noe funksjonalitet utover ren datalagring, en form for kalkulasjoner (i en utvidet betydning av begrepet).**

Klassene som blir brukt for kalkulasjon har vi lagt i [app/service][service-folder]

3. **Det skal implementeres korrekt innkapsling og validering for tilstandene til objektene i appen.**

Ettersom vi bruker en eventbus, så ligger innkapslingen og valideringen for tilstandene i events og i funksjonene som tar input fra brukergrensesnittet. 
Eksempler på dette kan dere se her: 

- [events/LanguageChangedEvent.java][LanguageChangedEvent-file]
- [events/EditorChangedEvent.java][EditorChangedEvent-file]
- [events/ThemeChangedEvent.java][ThemeChangedEvent-file]

4. **Appen skal organiseres etter Model-View-Controller prinsippet, som beskrevet ovenfor.**

Hovedbitene med state som skal være global for hele applikasjonen ligger i en klasse som heter [Model][Model-file]. All annen tilstand er lokal til FXML-elementene hvor den hører hjemme, og ved enhver oppdatering av den tilstanden vil det bli sent ut relevante events til alle andre kontrollere for at de skal oppdatere sine FXML-elementer sin indre tilstand. Dermed er Model, View, og Controllers separert.

### Del 2 - Filbehandling

1. **Et grensesnitt som minimum har en metode for lesing fra og en for skriving til fil.**

Dette finner dere i [settings/SettingsProviderI.java][interface-file]
Her er metodene for lesing fra og skriving til fil som innebærer programtilstandene.  

2. **Minimum en ny klasse (altså ikke en av klassene dere har lagd tidligere i prosjketet) som implementerer grensesnittet. Klassen skal altså lagre (deler av) tilstanden til appen deres til et valgfritt format og lese inn det samme formatet til appen.**

Dette finner dere i [settings/SettingsProvider.java][settings-file]
SettingsProvider-filen implementerer grensesnittet og realiserer funksjonaliteten. Her blir tilstandene til innstillings-objektene strukturert over i et tekstformat. 


3. **Brukergrensesnittet i appen må utvides med mulighet for å skrive tilstanden til og lese fra fil.**

Dette finner dere i [MenubarController.java][MenubarController-file]

### Del 3 - Feilhåndtering

1. **Det skal være implementert hensiktsmessig feilhåndtering i alle utsatte deler av appen deres.**

På lik måte som det er lagt inn innkapsling der hvor programmet får input ifra brukeren, er det er det meste av feilhåndteringen blir gjort. Et eksempel på dette finner dere i [service/FileOperations.java][FileOperations-file]

I FileOperations er det lagt inn omfattende feilhåndtering for filer.
Dette finner dere i [service/FileTreeOperations.java][FileTreeOperations-file]


### Del 4 - Testing

[![Coverage](https://gitlab.stud.idi.ntnu.no/oysteikt/h20-tdt4100-project/badges/master/coverage.svg?)](https://oysteikt.pages.stud.idi.ntnu.no/h20-tdt4100-project/)

1. **Alle relevante deler av koden deres skal enhetstestes.**

Dere finner testene i [src/test/java/app][tests-folder]

2. **Enhetstestene skal skrives i JUnit 5.**

Alle testene er skrevet i JUnit 5, med hjelp fra et par andre biblioteker og plugins som bygger på toppen av JUnit.

Disse inluderer:

  - [TestFX](http://testfx.github.io/TestFX/)
  - [Hamcrest](http://hamcrest.org/JavaHamcrest/)
  - [Mockito](https://site.mockito.org/)
  - [Monocle](https://wiki.openjdk.java.net/display/OpenJFX/Monocle)
  - [Jacoco](https://www.eclemma.org/jacoco/)


[Model-file]: https://gitlab.stud.idi.ntnu.no/oysteikt/h20-tdt4100-project/-/blob/master/src/main/java/app/model/Model.java
[Event-file]: https://gitlab.stud.idi.ntnu.no/oysteikt/h20-tdt4100-project/-/blob/master/src/main/java/app/events/Event.java
[model-folder]: https://gitlab.stud.idi.ntnu.no/oysteikt/h20-tdt4100-project/-/tree/master/src/main/java/app/model
[service-folder]: https://gitlab.stud.idi.ntnu.no/oysteikt/h20-tdt4100-project/-/tree/master/src/main/java/app/service
[Main-file]: https://gitlab.stud.idi.ntnu.no/oysteikt/h20-tdt4100-project/-/tree/master/src/main/java/app/Main.java
[MainController-file]: https://gitlab.stud.idi.ntnu.no/oysteikt/h20-tdt4100-project/-/tree/master/src/main/java/app/MainController.java
[controllers-folder]: https://gitlab.stud.idi.ntnu.no/oysteikt/h20-tdt4100-project/-/tree/master/src/main/java/app/controllers
[fxml-folder]: https://gitlab.stud.idi.ntnu.no/oysteikt/h20-tdt4100-project/-/tree/master/src/main/resources/fxml/
[tests-folder]: https://gitlab.stud.idi.ntnu.no/oysteikt/h20-tdt4100-project/-/tree/master/src/test/java/app
[interface-file]: https://gitlab.stud.idi.ntnu.no/oysteikt/h20-tdt4100-project/-/blob/master/src/main/java/app/settings/SettingsProviderI.java
[settings-file]: https://gitlab.stud.idi.ntnu.no/oysteikt/h20-tdt4100-project/-/blob/master/src/main/java/app/settings/SettingsProvider.java
[MenubarController-file]: https://gitlab.stud.idi.ntnu.no/oysteikt/h20-tdt4100-project/-/blob/master/src/main/java/app/controllers/MenubarController.java
[LanguageChangedEvent-file]: https://gitlab.stud.idi.ntnu.no/oysteikt/h20-tdt4100-project/-/blob/master/src/main/java/app/events/LanguageChangedEvent.java
[EditorChangedEvent-file]: https://gitlab.stud.idi.ntnu.no/oysteikt/h20-tdt4100-project/-/blob/master/src/main/java/app/events/EditorChangedEvent.java
[ThemeChangedEvent-file]: https://gitlab.stud.idi.ntnu.no/oysteikt/h20-tdt4100-project/-/blob/master/src/main/java/app/events/ThemeChangedEvent.java
[FileOperations-file]: https://gitlab.stud.idi.ntnu.no/oysteikt/h20-tdt4100-project/-/blob/master/src/main/java/app/service/FileOperations.java
[FileTreeOperations-file]: https://gitlab.stud.idi.ntnu.no/oysteikt/h20-tdt4100-project/-/blob/master/src/main/java/app/service/FiletreeOperations.java



