Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ADD : Period & ITimeBlock depuis Lucca #63

Open
wants to merge 5 commits into
base: master
Choose a base branch
from

Conversation

nfaugout-lucca
Copy link
Contributor

Récupération de ITimeBlock de Lucca, avec une approche légèrement différente. Plutôt que d'avoir toutes les propriétés de Period en get;set; on passe par des méthodes explicites pour changer les propriétés.
Ceci permet à une classe de mettre de la logique métier dans ces méthodes, plus élégant je trouve que de mettre ça dans les setters.
Ca permet aussi à une classe qui refuse qu'on lui change ses valeurs (immutabilité) de lancer des exceptions (ailleurs que dans le setter du coup)

Implémentation de l'égalité entre 2 Periods.

Quelques règles :

  • une Period ne peut pas être négative (end strictement plus petit que start), ça pète des tests sur le monolithe qui autorisait cette situation
  • la Duration peut ne pas être égale à end-start, notamment dans le cas d'UD avec une période correspond à une journée et une duration plus longue

Remplacement de TimeInitials par une Culture, et reprise des traductions des initiales d'après ce qui est dans le monolithe

PS : PR à suivre sur Lucca pour intégrer tout ça

Copy link

@sonarqubecloud sonarqubecloud bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SonarQube analysis found issues:
Bug Bugs: 0
Vulnerability Vulnerabilities: 0
Code Smell Code Smells: 2

See all issues in SonarCloud

@codecov
Copy link

codecov bot commented Nov 2, 2018

Codecov Report

Merging #63 into master will increase coverage by 3%.
The diff coverage is 55.37%.

Impacted file tree graph

@@           Coverage Diff            @@
##           master      #63    +/-   ##
========================================
+ Coverage   32.19%   35.19%    +3%     
========================================
  Files          30       32     +2     
  Lines        1662     1895   +233     
  Branches      186      193     +7     
========================================
+ Hits          535      667   +132     
- Misses       1105     1203    +98     
- Partials       22       25     +3
Impacted Files Coverage Δ
...xtends/Primitives/TimeSpans/TimeSpan.extensions.cs 58.82% <15.38%> (-6.05%) ⬇️
.../Primitives/DateTimes/NegativeDurationException.cs 50% <50%> (ø)
NExtends/Primitives/DateTimes/Period.cs 56.52% <56.81%> (-29.2%) ⬇️
NExtends/Primitives/DateTimes/Date.cs 57.39% <57.39%> (ø)
...xtends/Primitives/DateTimes/DateTime.extensions.cs 54.97% <60%> (+0.64%) ⬆️
NExtends/Primitives/TimeSpans/TimeInitials.cs 83.33% <66.66%> (-16.67%) ⬇️
NExtends/Primitives/Strings/String.extensions.cs 28.43% <0%> (+1.47%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 3353e5b...cb618ee. Read the comment docs.

Récupération de ITimeBlock de Lucca, avec une approche légèrement différente. Plutôt que d'avoir toutes les propriétés de Period en get;set; on passe par des méthodes explicites pour changer les propriétés.
Ceci permet à une classe de mettre de la logique métier dans ces méthodes, plus élégant je trouve que de mettre ça dans les setters.
Ca permet aussi à une classe qui refuse qu'on lui change ses valeurs (immutabilité) de lancer des exceptions (ailleurs que dans le setter du coup)

Implémentation de l'égalité entre 2 Periods.

Quelques règles :
- une Period ne peut pas être négative (end strictement plus petit que start), ça pète des tests sur le monolithe qui autorisait cette situation
- la Duration peut ne pas être égale à end-start, notamment dans le cas d'UD avec une période correspond à une journée et une duration plus longue

Remplacement de TimeInitials par une Culture, et reprise des traductions des initiales d'après ce qui est dans le monolithe

PS : PR à suivre sur Lucca pour intégrer tout ça
Copy link

@sonarqubecloud sonarqubecloud bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SonarQube analysis found issues:
Bug Bugs: 0
Vulnerability Vulnerabilities: 0
Code Smell Code Smells: 2

See all issues in SonarCloud

Copy link
Contributor

@rducom rducom left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Je te propose plutôt de laisser struct Period struct et immutable, de lui implémenter IEquatable, et de proposer des méthodes d’extensions retournant une nouvelle valeur de struct Period


return Equals(obj as Period);
}
public override int GetHashCode()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Il est interdit d'implémenter GetHashCode() sur une une instance mutable, car la plupart des primitives de liste gardent le hashcode calculé en cache. Hors si l'instance est mutable, alors une fois modifiée, le HashCode n'est plus valide, mais il ne sera pas pour autant calculé.
C'est le genre d'effet de bord à se taper la tête contre les murs lors du débug.
D'autre part, pour des class, toujours implémenter un IEqualityComparer<T> plutôt que IEquatable<T>.

Implémentation du type Date qui correspond à une Date sans "time".
Une Period est instanciée soit avec des DateTime soit avec des Date, dans les 2 cas elle sait exposer ses start/end en date (startsOn) ou en temps (startsAt).
Pour l'instant aucun projet n'utilite la version Date, mais ça pourra venir
Start/End tout court sont dépréciés car pas assez explicites, il faut utiliser StartsAt ou StartsOn désormais

Un ITimeBlock doit renvoyer un ITimeBlock à chaque fois qu'on modifier ses propriétés
- pour une classe mutable, l'objet se renverra lui-même
- pour un struct comme Period, on renvoie une nouvelle instance à chaque fois

Ca permet de gérer la transition class/struct en douceur côté Lucca sans pour autant devoir faire des refactos trops massifs

NB : toute la partie sur l'égalité disparaît puisque Period redevient un struct.
Copy link

@sonarqubecloud sonarqubecloud bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SonarQube analysis found issues:
Bug Bugs: 1
Vulnerability Vulnerabilities: 0
Code Smell Code Smells: 5

See all issues in SonarCloud

ADD Tests
@nfaugout-lucca
Copy link
Contributor Author

@rducom je suis arrivé à une version "compatible" avec le monolithe, c'était pas gagné ;)

Je te laisse regarder.

Copy link
Contributor

@rducom rducom left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • tu introduit la classe Date mais sans s'en servir ailleurs. Est-ce vraiment utile ?
  • côté monolithe, il y a aussi le struct DateInterval qui overlap avec Period. Ça vaudrait le coup de regrouper


public static Date operator -(Date d, TimeSpan t)
{
return new Date(d._dt - t);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ici : possibilité de créer un objet Date avec minutes / sec / ms. Contrat rompu

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Non, car le constructeur en question fait une division euclidienne et ne garde donc que la partie entière du TimeSpan.

Mais ce serait peut-être plus logique en effet de ne prendre que le .TotalDays du TimeSpan.

Après c'est une lib externe donc j'ai pas voulu faire de refacto, déjà que j'ai fixé les retours de Sonar..


public static Date operator +(Date d, TimeSpan t)
{
return new Date(d._dt + t);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Idem

@@ -3,11 +3,12 @@
<PropertyGroup>
<TargetFrameworks>netstandard2.0</TargetFrameworks>
<ProjectGuid>{6319D598-FF7C-4B48-8C46-53F1E87C8220}</ProjectGuid>
<PackageVersion>2.3.7</PackageVersion>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pas besoin c'est la CI qui gère

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oui c'est ça un oubli de revert dans de commit, je l'enlèverai plus tard

</PropertyGroup>

<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
<PackageReference Include="System.ComponentModel.Annotations" Version="4.5.0" />
<PackageReference Include="System.ComponentModel.Annotations" Version="4.4.1" />
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

parce que le monolithe est en 4.4.1 et que j'ai pas envie de le passer en 4.5.0 (breaking changes potentiels) tout de suite.

ou alors je vais faire une PR à part sur le monolithe pour le passer en 4.5.0...

public TimeSpan Duration { get { return End - Start; } }
public DateTime StartsAt { get; }
public DateTime EndsAt { get; }
public TimeSpan Duration { get; }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Si Duration n'est plus calculé, ça veut dire qu'on doit à chaque fois s'assurer de la cohérence des données, en amont, je pense pas que ce soit une bonne chose

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Regarde les tests, y'en a un qui garanti que Duration "peut" être différent de End-Start, c'est dans le cas particulier d'une période de date à date avec une Duration qui "déborde". Y'a des cas dans le monolithe.

On pourra revenir dessus plus tard via une Issue, mais faudra déjà fixer le "pb" dans le monolithe.

}
}

ITimeBlock ITimeBlock.ChangeStartsAt(DateTime startsAt)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dommage d'avoir une implémentation d'interface explicite là où elle peut être normale

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

au contraire, ici je trouve que Period ne devrait pas avoir ce genre de méthode (car on ne devrait pas essayer de changer une propriété d'un type immutable). Du coup quand tu utilises Period en tant que tel, tu n'auras pas ces méthodes. Y'a alors que sur ITimeBlock, qui est utilisé à la fois par Period et par des types mutables dans le monolithe que ces méthodes sont exposées.

var absSpan = new TimeSpan(Math.Abs(timeSpan.Ticks));
var totalHours = Math.Floor(absSpan.TotalHours);
var initials = TimeInitials.FromCulture(culture);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

on pourrait s'appuyer sur https://github.com/Humanizr/Humanizer pour ce genre de choses

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not, on peut faire ça dans une version ultérieure avec une Issue dédiée.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants