Spock does not execute when clause - grails

One of my spock tests is skipping the when clause and moving right to the then clause.
#Unroll
void "test refresh metadata with #consumerNames"() {
setup:
consumerNames.each {
new CredentialConsumer(name: it).save(validate: false)
}
when:
service.refreshMetadata()
then:
consumerNames.each { consumerName ->
Metadata metadata = new Metadata(content: "Metadata for $consumerName")
ConsumerDefinition consumerDefinition = new ConsumerDefinition(name: consumerName, metadata: metadata)
1 * mockApplicationLibraryService.fetchConsumerDefinition(consumerName) >> consumerDefinition
assert CredentialConsumer.findByName(consumerName)?.metadata?.content == metadata.content
}
where:
consumerNames | _
["bacon"] | _
["bacon", "eggs"] | _
}
I get the following results...
Condition not satisfied:
CredentialConsumer.findByName(consumerName)?.metadata?.content == metadata.content
| | | | | | |
| bacon null null | | Metadata for bacon
| | com.datapriviasoftware.completesso.configuration.Metadata#487cd177
| false
com.datapriviasoftware.completesso.CredentialConsumer : 1
Expected :Metadata for bacon
Actual :null
When I step through it with the debugger, it executes the setup clause, skips the when clause, and immediately executes the then clause.

So, I knew that Spock uses AST transformations to process mocks in the then clause before it executes the when clause. When I thought through it, I realized that processing the mocks in the then clause required the entire each loop to execute, so I needed to separate the explicit assertion from the mock definition.
This works...
#Unroll
void "test refresh metadata with #consumerNames"() {
setup:
consumerNames.each {
new CredentialConsumer(name: it).save(validate: false)
}
when:
service.refreshMetadata()
then:
consumerNames.each { consumerName ->
Metadata metadata = new Metadata(content: "Metadata for $consumerName")
ConsumerDefinition consumerDefinition = new ConsumerDefinition(name: consumerName, metadata: metadata)
1 * mockApplicationLibraryService.fetchConsumerDefinition(consumerName) >> consumerDefinition
}
and:
consumerNames.each { consumerName ->
assert CredentialConsumer.findByName(consumerName)?.metadata?.content == "Metadata for $consumerName"
}
where:
consumerNames | _
["bacon"] | _
["bacon", "eggs"] | _
}

Related

F# Bolero how to set the code apart to make the project structure clear?

I'm new to F# and Bolero. and after initialize the project as the docs shows, I find that sample application demonstrates 3 types of web applications but main codes is in one file called Main.fs .
here is part codes:
type Message =
| SetPage of Page
| Increment
| Decrement
| SetCounter of int
| GetBooks
| GotBooks of Book[]
| SetUsername of string
| SetPassword of string
| GetSignedInAs
| RecvSignedInAs of option<string>
| SendSignIn
| RecvSignIn of option<string>
| SendSignOut
| RecvSignOut
| Error of exn
| ClearError
let update remote message model =
let onSignIn = function
| Some _ -> Cmd.ofMsg GetBooks
| None -> Cmd.none
match message with
| SetPage page ->
{ model with page = page }, Cmd.none
| Increment ->
{ model with counter = model.counter + 1 }, Cmd.none
| Decrement ->
{ model with counter = model.counter - 1 }, Cmd.none
| SetCounter value ->
{ model with counter = value }, Cmd.none
| GetBooks ->
let cmd = Cmd.OfAsync.either remote.getBooks () GotBooks Error
{ model with books = None }, cmd
| GotBooks books ->
{ model with books = Some books }, Cmd.none
| SetUsername s ->
{ model with username = s }, Cmd.none
| SetPassword s ->
{ model with password = s }, Cmd.none
| GetSignedInAs ->
model, Cmd.OfAuthorized.either remote.getUsername () RecvSignedInAs Error
| RecvSignedInAs username ->
{ model with signedInAs = username }, onSignIn username
| SendSignIn ->
model, Cmd.OfAsync.either remote.signIn (model.username, model.password) RecvSignIn Error
| RecvSignIn username ->
{ model with signedInAs = username; signInFailed = Option.isNone username }, onSignIn username
| SendSignOut ->
model, Cmd.OfAsync.either remote.signOut () (fun () -> RecvSignOut) Error
| RecvSignOut ->
{ model with signedInAs = None; signInFailed = false }, Cmd.none
| Error RemoteUnauthorizedException ->
{ model with error = Some "You have been logged out."; signedInAs = None }, Cmd.none
| Error exn ->
{ model with error = Some exn.Message }, Cmd.none
| ClearError ->
{ model with error = None }, Cmd.none
As you can see, the code is too long to manage. if I add more functionality I can barely imagine what the file will be like.
so how can I split the code into different files ?
The most basic thing you could do is to split your Message type into multiple separate types and have one corresponding to different aspects of the logic. For example:
type CounterMessage =
| Increment
| Decrement
| SetCounter of int
type BooksMessage =
| GetBooks
| GotBooks of Book[]
type Message =
| SetPage of Page
| CounterMessage of CounterMessage
| BooksMessage of BooksMessage
Then you can similarly split your update function - and move each of the message-specific functions to a separate file:
let updateCounter remote message model =
match message with
| Increment ->
{ model with counter = model.counter + 1 }, Cmd.none
| Decrement ->
{ model with counter = model.counter - 1 }, Cmd.none
| SetCounter value ->
{ model with counter = value }, Cmd.none
let update remote message model =
match message with
| SetPage page ->
{ model with page = page }, Cmd.none
| CounterMessage msg ->
updateCounter remote message model
// (...)
This is something using just basic F# langauge mechanisms. Perhaps Bolero has some more sophisticated methods for structuring projects, but this is simple option will always work. The disadvantage is that you need to handle the "forwarding" of the messages yourself (and this is something that a more sophisticated option may alleviate) - but I think that for a moderately sized project, it is not such a bad things (and it helps making things explicit and clear).

Is it possible to have F# able to recognize an overlap of DU and use the right one itself?

type GenericResult =
| Ok
| Error of string
type LoginResult =
| Ok
| UserNotFound
| WrongPassword
let check something:GenericResult =
match something with
//| true -> Ok // error:This expression was expected to be of type "GenericREsult" but here has type "LoginResult"
| true -> GenericResult.Ok // I'm forced to specify GenericResult.Ok
| false -> Error "aargg!"
let checkLogin something:LoginResult =
match something with
| true -> Ok // here I don't need to specify the DU because this is defined after
| _ -> WrongPassword
I'd like to use just "Ok" in both the methods, without the need to specify the DU.
I see that in case of clashing of the value the last one is the "predefined".
Ideally I'd like to have a sort of inheritance
to reuse part of a DU in another DU.
For example:
type GenericResult =
| Ok
| Error of string
type LoginResult =
//| GenericResult.Ok
| UserNotFound
| WrongPassword
type SaveResult =
| Created
| Updated
//| GenericResult.Error
let checkLogin something: LoginResult | GenericResult.Ok =
match something with
| true -> Ok
| _ -> WrongPassword
[EDIT]
The real scenario where I feel the need for this feature is this with 3 different results from 3 different logic classes.
There will be in the future more cases so the multiplication of duplicated DU values will increase.
// DUs ordered from the most specific to the most generic
type BalanceUpdateResult =
| Created
| Updated
| InvalidRequest of string
type DeleteResult =
| Ok
| InvalidRequest of string
type Result<'T> =
| Ok of 'T
| NotValid of string
| Error of string
The goal is to have a clean match syntax in the consumer, where the value of the DU will evenctually be used to raise an exception or to return the created value, for example.
// balance update function (result is BalanceUpdateResult):
match result with
| Created -> this.createOkWithStatus 201
| Updated -> this.createOkWithStatus 200
| InvalidRequest error -> this.createErrorForConflict error
// company creation function (result is Result<Company>):
match result with
| Result.Ok newItem ->
context.Logger.Log $"Company created. New Id:{newItem.Id}, Name:{newItem.Name}."
this.createCreated newItem
| NotValid error -> base.createErrorForConflict error
| Error error -> base.createError error
Here, for example, InvalidRequest is not accepted in the second case because it belongs to the wrong DU.
Having to specify the DU everywhere results in a mess like the following example (see the many Result<_>.):
interface ICompanyLogic with
member this.Create(company:Company):Result<Company> =
match normalize company |> validate with
| NotValid msg -> Result<_>.NotValid msg
| Valid validCompany ->
match companyRepository.Exists(validCompany.Name) with
| true -> Result<_>.NotValid($"A company with name \"{validCompany.Name}\" already exists.")
| _ ->
let newCompany = assignNewId validCompany
companyRepository.Create(newCompany)
Result<_>.Ok(newCompany)
member this.Update (company:Company):Result<Company> =
let checkNameExists company =
match companyRepository.GetByName company.Name with
| Some c when c.Id <> company.Id -> NotValid $"A company with name \"{company.Name}\" already exists."
| _ -> Valid company
match normalize company |> validate with
| NotValid msg -> Result<_>.NotValid msg
| Valid c -> match checkNameExists c with
| Valid c -> companyRepository.Update c; Result<_>.Ok c
| NotValid msg -> Result<_>.NotValid msg
I think the best way to achieve what you are trying to do would be to start with a generic Result type that has a type parameter representing the error type:
type Result<'TError> =
| Ok
| Error of 'TError
This allows you to use different types for representing errors, including string, but also another DU to capture more specific error types. You can then define GenericResult and LoginResult as two type aliases:
type LoginError =
| UserNotFound
| WrongPassword
type GenericResult = Result<string>
type LoginResult = Result<LoginError>
To report a login error, you would now use Error WrongPassword to wrap the specific error in the generic Error constructor. The implementation of your two functions looks as follows:
let check something:GenericResult =
match something with
| true -> Ok
| false -> Error "aargg!"
let checkLogin something:LoginResult =
match something with
| true -> Ok
| _ -> Error WrongPassword
Unlike TypeScript union type, F# DU are meant to be composed and not extensible - see Thomas answer for a solution using this approach.
Since F# does not offer a direct solution, you may consider renaming cases like InvalidRequest in order to be more specific and to help differentiate them when reading the code. With these specific names, you can also merge all result types into a big Event DU like what's usually done in an event sourced system:
type Event =
// BalanceUpdateResult
| BalanceCreated
| BalanceUpdated
| BalanceUpdateError of string
// DeleteResult
| DeleteOk
| DeleteError of string
// ...
Ok, as explained by Romain multiple DUs cannot solve my problem.
I decided to use the built-in type Result<'T,'TError>.
It allows me to avoid create many DUs that inevitably will have clash of names, forcing the use the full DU prefix in the code.
I solved the problem that drove me to create custom DUs with the inspiring example from Thomas reply.
(with Result<,>) I have the possibility to have dinstinct Errors or Oks.
(note the Result<unit,_> and the Result<BalanceUpdateRequest,_>)
type ICompanyLogic =
abstract member Create:Company -> Result<Company, string> // CreateResult
abstract member Update:Company -> Result<Company, string> // UpdateResult
abstract member Delete:string -> Result<unit,string> // DeleteResult
type BalanceUpdateResult =
| Created
| Updated
type IBalanceLogic =
abstract member CreateOrUpdate: request:BalanceUpdateRequest -> Result<BalanceUpdateResult, string>
Apart BalanceUpdateResult all the other DUs where replaced buy the Result<'T,'TError>.
I just maintained a couple one for specific tasks:
type CompanyValidation = Valid of Company | NotValid of string
type ValidateResult = Valid | NotValid of string
In the end with this solution:
I don't need to define many DUs
I can customize the Result... within as many values I want (storing a sub-DU in the Ok or Error union case)
I don't need to use prefix or use synonims to avoid clash (code result much cleaner)

Using KQL 'let' to combine two queries in the same table

I am trying to learn KQL and had a query where I wanted to take 2 values from Windows Event codes 4624 (login) and 4634 (logout) and return them for different scenarios I'm still trying to build.
But primarily I would just like to be able to return the values in a table (print or project?)
let login = SecurityEvent
| where TimeGenerated > ago(1h)
| where EventID == '4624'
| project loginTime = TimeGenerated;
let logout = SecurityEvent
| where TimeGenerated > ago(1h)
| where EventID == '4634'
| project logoutTime = TimeGenerated;
print login
The error I am getting is "'project' operator: Failed to resolve scalar expression named 'login'"
What I would have hoped to see is:
loginTime | logoutTime
----------------------------------------------
01/02/2021 18:46:30 | 01/02/2021 18:45:45
01/02/2021 18:47:30 | 01/02/2021 18:47:45
01/02/2021 18:48:30 | 01/02/2021 18:48:45
Would a join be better? It is in the same table (SecurityEvent), so I thought it would be possible to do it this way?
The dataset is from the MS provided Azure portal: https://portal.azure.com/#blade/Microsoft_Azure_Monitoring_Logs/DemoLogsBlade
Thanks for the help!
The problem is that "login" is a table type but print is expecting a scalar type.
let login = SecurityEvent
| where TimeGenerated > ago(1h)
| where EventID == '4624'
| project loginTime = TimeGenerated;
let logout = SecurityEvent
| where TimeGenerated > ago(1h)
| where EventID == '4634'
| project logoutTime = TimeGenerated;
print toscalar (login)
As to the result you are trying to get, I think this might be what you need:
Updated to improve clarity/perf
let login = SecurityEvent
| where TimeGenerated > ago(1h)
| where EventID == '4624'
| project TargetLogonId, loginTime = TimeGenerated;
let logout = SecurityEvent
| where TimeGenerated > ago(1h)
| where EventID == '4634'
| project TargetLogonId, logoutTime = TimeGenerated;
login
| join kind=leftouter logout on TargetLogonId
| project loginTime, logoutTime
I added some changes that encompass #GenericUser and #Slavik-N suggested and brings out the information that I was looking to calculate:
let login = SecurityEvent
| where TimeGenerated > ago(1h)
| where EventID == '4624'
| where AccountType == 'User'
| project Computer,Account ,TargetLogonId, loginTime = TimeGenerated;
let logout = SecurityEvent
| where TimeGenerated > ago(1h)
| where EventID == '4634'
| where AccountType == 'User'
| project Computer,Account,TargetLogonId, logoutTime = TimeGenerated;
login
| join kind=inner logout on TargetLogonId
| project Computer,Account,loginTime, logoutTime, minute = datetime_diff('minute',logoutTime,loginTime)
| where minute >0
| sort by minute desc

String to Bool value f#

I'm trying to create a function that converts a string to a bool.
This is what I have for now
let iscomb=
Table.parseTable table
|>> fun row -> row.["IsComb"] |> Models.Bool //returns true or false from a table cell
let Bool (s:string) =
match (s) with
| "true" -> true
| "false" -> false
| _-> sprintf "Error: returns %s" s
This return the type bool does not match the type string
So what I have understod is that we cannot mix different types in a match.
Any suggestion on what I could do?
Thanks in advace.
Just for fun, I thought I would demonstrate using Active Patterns for this. Only really worthwhile if you are checking this often and wanting to do different things based on that and you want to expand what is accepted beyond "true" / "false". It also can remove typo errors like "fasle".
First, we create 2 partial Active Patterns that just cleanup checking for Int32 and bool from string.
Note: You could just use the Bool AP below and stop there.
// Partial active pattern that matches on Int32
let (|Int|_|) (value:string) =
match (System.Int32.TryParse(value)) with
| (true, i) -> Some i
| (false,_) -> None
// Partial active pattern that matches on Bool
let (|Bool|_|) (value:string) =
match (System.Boolean.TryParse(value)) with
| (true,b) -> Some b
| _ -> None
Next, we use those 2 partial Active Patterns to cleanly test our string in an active pattern with 2 choices.
// Active pattern that buckets a string into True or False (or throws)
let(|True|False|) (value:string) =
match value with
| null -> False
| Int i when i > 0 -> True
| Int i when i <= 0 -> False
| Bool true -> True
| Bool false -> False
| _ -> failwithf "Cannot convert %s to bool." value
So how would we use this? Here is a test function where we use the Active Pattern to test a few results.
// quick little function to test a string
let test s =
match s with
| True -> printfn "The value %s is true" s
| False -> printfn "The value %s is false" s
Resulting in the following:
// testing
test "true" // The value true is true
test "TRUE" // The value TRUE is true
test "false" // The value false is false
test "False" // The value False is false
test "-1" // The value -1 is false
test "42" // The value 42 is true
test null // The value is false
test "abc" // System.Exception: Cannot convert abc to bool.
For more info:
FSharp for fun and Profit
F# Online meetup talk
You could replace sprintf for failwith, throwing an exception:
let Bool s =
match s with
| "true" -> true
| "false" -> false
| _-> failwith("Error: returns " + s)

How do I iterate over tests in Grails Spock testing when I wish to perform the same tests on many similar fields?

I have a domain class with property pairs:
Boolean statement1
Boolean statement1Missing
These pairs number up to nine.
The following constraints apply to each pairing:
statement1 nullable: true
statement1Missing validator: {val, obj ->
if ( val == true &&
(obj.statement1 == true || obj.statement1 == false)) {
return ['statement.not.missing', 1]
}
if (obj.statement1 == null && val == false) {
return ['statement.is.missing', 1]
}
}
I have devised an integration test that can accommodate one pair of statements:
#Unroll
def "Validation of custom validation for statement1"() {
given: "New data"
def participant = new Data(studyId: "M00001",
formVersion: Version.get(7)
)
and: "an initial set of test values"
participant.statement1 = statement1
participant.statement1Missing = statement1Missing
when: "the validator is invoked"
def isValidConsentData = participant.validate()
then: "the appropriate fields are flagged as errors"
isValidConsentData == anticipatedValid
participant.errors.getFieldError(fieldInError)?.code == errorCode
where:
statement1 | statement1Missing | anticipatedValid | fieldInError | errorCode
true | false | true | null | null
false | false | true | null | null
null | true | true | null | null
null | false | false | "statement1Missing" | "statement.is.missing"
true | true | false | "statement1Missing" | "statement.not.missing"
false | true | false | "statement1Missing" | "statement.not.missing"
}
This handles all the combinations for statement1 that I wish to test.
I have been trying to work out how I can repeat this test for all nine statement pairs. I have tried putting in a loop like this:
(1..9).each { statementNo
...
and ...
participant.("statement" + statementNo) = ("statement" + statementNo)
...
where:
("statement" + StatementNo) | ("statement" + StatementNo + Missing) | ...
}
I have used this type of iteration before when wanting to iterate over properties, but it does not work in Spock. The test is just ignored completely. I really do not want to repeat this code for each statement pair.
I have investigated the use of this type of structure http://www.christianoestreich.com/2012/11/domain-constraints-grails-spock-updated/ but this only allows you to test one property value at a time, whereas I want to test one property value many times.
The other option is to explicitly include every property pair in the 'where' block and every possible outcome, but that would be very cumbersome.
Please provide some suggestions as to how I can use an iterative structure to perform these tests.
How about something like:
...
and: "an initial set of test values"
(1..9).each { statementNo ->
participant."statement$statementNo" = statement
participant."statement${statementNo}Missing" = statementMissing
}
when: "the validator is invoked"
def isValidConsentData = participant.validate()
then: "the appropriate fields are flagged as errors"
(1..9).each { statementNo ->
def fieldInError
if (anticipatedValid) {
fieldInError = null
} else {
fieldInError = "statement${statementNo}Missing"
}
assert isValidConsentData == anticipatedValid
assert participant.errors.getFieldError(fieldInError)?.code == errorCode
}
where:
statement | statementMissing | anticipatedValid | errorCode
true | false | true | null
false | false | true | null
null | true | true | null
null | false | false | "statement.is.missing"
true | true | false | "statement.not.missing"
false | true | false | "statement.not.missing"
Not sure how it behaves for getFieldError(fieldName) when there are is no error for a given field so you may need to add some condition for the second assert using !anticipatedValid if exception would be thrown.
Important is that implicit assert are necessary as each is void thus there would be nothing checked by the test at all otherwise.

Resources