Minor refactor, added another DU

caught up on some tests as well
This commit is contained in:
Daniel J. Summers 2019-03-16 23:08:46 -05:00
parent 50f8b56871
commit bce2d5dbcc
5 changed files with 118 additions and 21 deletions

View File

@ -14,11 +14,11 @@ module private Helpers =
/// Central place to append sort criteria for prayer request queries
let reqSort sort (query : IQueryable<PrayerRequest>) =
match sort with
| "D" ->
| SortByDate ->
query.OrderByDescending(fun pr -> pr.updatedDate)
.ThenByDescending(fun pr -> pr.enteredDate)
.ThenBy(fun pr -> pr.requestor)
| _ ->
| SortByRequestor ->
query.OrderBy(fun pr -> pr.requestor)
.ThenByDescending(fun pr -> pr.updatedDate)
.ThenByDescending(fun pr -> pr.enteredDate)

View File

@ -54,31 +54,65 @@ with
| "L" -> LongDate
| _ -> invalidArg "code" (sprintf "Unknown code %s" code)
/// Convert this DU case to a single-character string
member this.toCode () =
member this.code =
match this with
| NoDisplay -> "N"
| ShortDate -> "S"
| LongDate -> "L"
/// How requests should be sorted
type RequestSort =
/// Sort by date, then by requestor/subject
| SortByDate
/// Sort by requestor/subject, then by date
| SortByRequestor
with
/// Convert to a DU case from a single-character string
static member fromCode code =
match code with
| "D" -> SortByDate
| "R" -> SortByRequestor
| _ -> invalidArg "code" (sprintf "Unknown code %s" code)
/// Convert this DU case to a single-character string
member this.code =
match this with
| SortByDate -> "D"
| SortByRequestor -> "R"
module Converters =
open Microsoft.EntityFrameworkCore.Storage.ValueConversion
open Microsoft.FSharp.Linq.RuntimeHelpers
open System.Linq.Expressions
let private fromDU =
<@ Func<AsOfDateDisplay, string>(fun (x : AsOfDateDisplay) -> x.toCode ()) @>
let private asOfFromDU =
<@ Func<AsOfDateDisplay, string>(fun (x : AsOfDateDisplay) -> x.code) @>
|> LeafExpressionConverter.QuotationToExpression
|> unbox<Expression<Func<AsOfDateDisplay, string>>>
let private toDU =
let private asOfToDU =
<@ Func<string, AsOfDateDisplay>(AsOfDateDisplay.fromCode) @>
|> LeafExpressionConverter.QuotationToExpression
|> unbox<Expression<Func<string, AsOfDateDisplay>>>
let private sortFromDU =
<@ Func<RequestSort, string>(fun (x : RequestSort) -> x.code) @>
|> LeafExpressionConverter.QuotationToExpression
|> unbox<Expression<Func<RequestSort, string>>>
let private sortToDU =
<@ Func<string, RequestSort>(RequestSort.fromCode) @>
|> LeafExpressionConverter.QuotationToExpression
|> unbox<Expression<Func<string, RequestSort>>>
/// Conversion between a string and an AsOfDateDisplay DU value
type AsOfDateDisplayConverter () =
inherit ValueConverter<AsOfDateDisplay, string> (fromDU, toDU)
inherit ValueConverter<AsOfDateDisplay, string> (asOfFromDU, asOfToDU)
/// Conversion between a string and a RequestSort DU value
type RequestSortConverter () =
inherit ValueConverter<RequestSort, string> (sortFromDU, sortToDU)
/// Statistics for churches
@ -189,7 +223,7 @@ and [<CLIMutable; NoComparison; NoEquality>] ListPreferences =
/// The font size for the text on the prayer request list
textFontSize : int
/// The order in which the prayer requests are sorted
requestSort : string
requestSort : RequestSort
/// The password used for "small group login" (view-only request list)
groupPassword : string
/// The default e-mail type for this class
@ -219,7 +253,7 @@ and [<CLIMutable; NoComparison; NoEquality>] ListPreferences =
lineColor = "navy"
headingFontSize = 16
textFontSize = 12
requestSort = "D"
requestSort = SortByDate
groupPassword = ""
defaultEmailType = EmailType.Html
isPublic = false
@ -289,7 +323,7 @@ and [<CLIMutable; NoComparison; NoEquality>] ListPreferences =
.HasColumnName("RequestSort")
.IsRequired()
.HasMaxLength(1)
.HasDefaultValue "D"
.HasDefaultValue SortByDate
|> ignore
m.Property(fun e -> e.groupPassword)
.HasColumnName("GroupPassword")
@ -323,6 +357,8 @@ and [<CLIMutable; NoComparison; NoEquality>] ListPreferences =
.HasDefaultValue NoDisplay
|> ignore)
|> ignore
mb.Model.FindEntityType(typeof<ListPreferences>).FindProperty("requestSort")
.SetValueConverter(Converters.RequestSortConverter ())
mb.Model.FindEntityType(typeof<ListPreferences>).FindProperty("asOfDateDisplay")
.SetValueConverter(Converters.AsOfDateDisplayConverter ())

View File

@ -5,6 +5,33 @@ open NodaTime.Testing
open NodaTime
open System
[<Tests>]
let asOfDateDisplayTests =
testList "AsOfDateDisplay" [
test "NoDisplay code is correct" {
Expect.equal NoDisplay.code "N" "The code for NoDisplay should have been \"N\""
}
test "ShortDate code is correct" {
Expect.equal ShortDate.code "S" "The code for ShortDate should have been \"S\""
}
test "LongDate code is correct" {
Expect.equal LongDate.code "L" "The code for LongDate should have been \"N\""
}
test "fromCode N should return NoDisplay" {
Expect.equal (AsOfDateDisplay.fromCode "N") NoDisplay "\"N\" should have been converted to NoDisplay"
}
test "fromCode S should return ShortDate" {
Expect.equal (AsOfDateDisplay.fromCode "S") ShortDate "\"S\" should have been converted to ShortDate"
}
test "fromCode L should return LongDate" {
Expect.equal (AsOfDateDisplay.fromCode "L") LongDate "\"L\" should have been converted to LongDate"
}
test "fromCode X should raise" {
Expect.throws (fun () -> AsOfDateDisplay.fromCode "X" |> ignore)
"An unknown code should have raised an exception"
}
]
[<Tests>]
let churchTests =
testList "Church" [
@ -38,7 +65,7 @@ let listPreferencesTests =
Expect.equal mt.lineColor "navy" "The default heding line color should have been navy"
Expect.equal mt.headingFontSize 16 "The default heading font size should have been 16"
Expect.equal mt.textFontSize 12 "The default text font size should have been 12"
Expect.equal mt.requestSort "D" "The default request sort should have been D (date)"
Expect.equal mt.requestSort SortByDate "The default request sort should have been by date"
Expect.equal mt.groupPassword "" "The default group password should have been blank"
Expect.equal mt.defaultEmailType EmailType.Html "The default e-mail type should have been HTML"
Expect.isFalse mt.isPublic "The isPublic flag should not have been set"
@ -130,6 +157,26 @@ let prayerRequestTests =
}
]
[<Tests>]
let requestSortTests =
testList "RequestSort" [
test "SortByDate code is correct" {
Expect.equal SortByDate.code "D" "The code for SortByDate should have been \"D\""
}
test "SortByRequestor code is correct" {
Expect.equal SortByRequestor.code "R" "The code for SortByRequestor should have been \"R\""
}
test "fromCode D should return SortByDate" {
Expect.equal (RequestSort.fromCode "D") SortByDate "\"D\" should have been converted to SortByDate"
}
test "fromCode R should return SortByRequestor" {
Expect.equal (RequestSort.fromCode "R") SortByRequestor "\"R\" should have been converted to SortByRequestor"
}
test "fromCode Q should raise" {
Expect.throws (fun () -> RequestSort.fromCode "Q" |> ignore) "An unknown code should have raised an exception"
}
]
[<Tests>]
let smallGroupTests =
testList "SmallGroup" [

View File

@ -15,6 +15,18 @@ let countAll _ = true
module ReferenceListTests =
[<Tests>]
let asOfDateListTests =
testList "ReferenceList.asOfDateList" [
test "has all three options listed" {
let asOf = ReferenceList.asOfDateList _s
Expect.hasCountOf asOf 3u countAll "There should have been 3 as-of choices returned"
Expect.exists asOf (fun (x, _) -> x = NoDisplay.code) "The option for no display was not found"
Expect.exists asOf (fun (x, _) -> x = ShortDate.code) "The option for a short date was not found"
Expect.exists asOf (fun (x, _) -> x = LongDate.code) "The option for a full date was not found"
}
]
[<Tests>]
let emailTypeListTests =
testList "ReferenceList.emailTypeList" [
@ -248,7 +260,7 @@ let editPreferencesTests =
Expect.equal edit.expireDays prefs.daysToExpire "The expiration days were not filled correctly"
Expect.equal edit.daysToKeepNew prefs.daysToKeepNew "The days to keep new were not filled correctly"
Expect.equal edit.longTermUpdateWeeks prefs.longTermUpdateWeeks "The weeks for update were not filled correctly"
Expect.equal edit.requestSort prefs.requestSort "The request sort was not filled correctly"
Expect.equal edit.requestSort prefs.requestSort.code "The request sort was not filled correctly"
Expect.equal edit.emailFromName prefs.emailFromName "The e-mail from name was not filled correctly"
Expect.equal edit.emailFromAddress prefs.emailFromAddress "The e-mail from address was not filled correctly"
Expect.equal edit.defaultEmailType prefs.defaultEmailType "The default e-mail type was not filled correctly"
@ -572,7 +584,9 @@ let requestListTests =
let newList =
{ reqList with
listGroup =
{ reqList.listGroup with preferences = { reqList.listGroup.preferences with requestSort = "R" } }
{ reqList.listGroup with
preferences = { reqList.listGroup.preferences with requestSort = SortByRequestor }
}
}
let reqs = newList.requestsInCategory RequestType.Current
Expect.hasCountOf reqs 2u countAll "There should have been two requests"

View File

@ -12,9 +12,9 @@ module ReferenceList =
/// A localized list of the AsOfDateDisplay DU cases
let asOfDateList (s : IStringLocalizer) =
[ NoDisplay.toCode (), s.["Do not display the “as of” date"]
ShortDate.toCode (), s.["Display a short “as of” date"]
LongDate.toCode (), s.["Display a full “as of” date"]
[ NoDisplay.code, s.["Do not display the “as of” date"]
ShortDate.code, s.["Display a short “as of” date"]
LongDate.code, s.["Display a full “as of” date"]
]
/// A list of e-mail type options
@ -289,7 +289,7 @@ with
{ expireDays = prefs.daysToExpire
daysToKeepNew = prefs.daysToKeepNew
longTermUpdateWeeks = prefs.longTermUpdateWeeks
requestSort = prefs.requestSort
requestSort = prefs.requestSort.code
emailFromName = prefs.emailFromName
emailFromAddress = prefs.emailFromAddress
defaultEmailType = prefs.defaultEmailType
@ -303,7 +303,7 @@ with
timeZone = prefs.timeZoneId
groupPassword = Some prefs.groupPassword
pageSize = prefs.pageSize
asOfDate = prefs.asOfDateDisplay.toCode ()
asOfDate = prefs.asOfDateDisplay.code
listVisibility =
match true with
| _ when prefs.isPublic -> RequestVisibility.``public``
@ -322,7 +322,7 @@ with
daysToExpire = this.expireDays
daysToKeepNew = this.daysToKeepNew
longTermUpdateWeeks = this.longTermUpdateWeeks
requestSort = this.requestSort
requestSort = RequestSort.fromCode this.requestSort
emailFromName = this.emailFromName
emailFromAddress = this.emailFromAddress
defaultEmailType = this.defaultEmailType
@ -573,8 +573,8 @@ with
|> Seq.ofList
|> Seq.filter (fun req -> req.requestType = cat)
match this.listGroup.preferences.requestSort with
| "D" -> reqs |> Seq.sortByDescending (fun req -> req.updatedDate)
| _ -> reqs |> Seq.sortBy (fun req -> req.requestor)
| SortByDate -> reqs |> Seq.sortByDescending (fun req -> req.updatedDate)
| SortByRequestor -> reqs |> Seq.sortBy (fun req -> req.requestor)
|> List.ofSeq
/// Is this request new?
member this.isNew (req : PrayerRequest) =