Adding message in a block of Specs2 test - scala

I am new in Specs2. I read the specs2 documentation but it's kinda confusing. I don't know if it's possible or not.
So I have Specs2 test code roughly like this:
"DataServiceTest" should {
"InsertNewData" in {
val name = "some name here"
val description = "some description here"
// Assumed DataService.insertNewData method execute the insertion
// and returns "Data" model.
Data data = DataService.insertNewData(name, description)
// Checking of equality here
data.name === name
data.description === description
// Assumed the "Data" model has List[SubData] property "subData"
// and the code below is checking the List[SubData]
data.subData.foreach {
...
}
success
}
}
1. Is there a way to give message for these parts?
data.name === name
data.description === description
Something like "Checking data's name" in { data.name === name }. So the message will be shown on the output screen when the test is executed whether it's success or failed.
2. Is there a way to group the sub-code inside the "InsertNewData" by giving a text message like this:
"DataServiceTest" should {
"InsertNewData" in {
val name = "some name here"
val description = "some description here"
// Assumed DataService.insertNewData method execute the insertion
// and returns "Data" model.
Data data = DataService.insertNewData(name, description)
"Checking basic properties of Data" in {
// Checking of equality here
data.name === name
data.description === description
}
"Checking subData" in {
// Assumed the "Data" model has List[SubData] property "subData"
// and the code below is checking the subData
data.subData must have size(3)
data.subData.foreach {
...
}
}
success
}
}
UPDATE:
Based on one of answer here, I tried this:
"Checking of equality" ! e1
def e1 = {
data.name === name
data.description === description
failure
}
It didn't work as it should fail. But the test result is all passed.
UPDATE #2:
I did some experiment of nested in block:
"DataServiceTest" should {
"my test" in {
"hello test" in { // this block is not executed
"hello" !== "hello"
success
}
"world" === "world"
success
}
}
The result is success, but it should fail because of "hello" !== "hello". Looking from console screen, the is no "hello test" message, so it seems nested in block doesn't get executed.
UPDATE #3:
Based on edited answer by eric, I edited the code in Update #2:
"DataServiceTest" >> {
"my test" >> {
"hello test" >> { // this block is not executed
"hello" !== "hello"
success
}
"world" === "world"
success
}
}
Same result, the "hello test" nested block didn't get executed.

An easy way to create small examples based on one "ACT" call is to use a lazy val like this:
"DataServiceTest should" >> {
"InsertNewData" >> {
val name = "some name here"
val description = "some description here"
// Assumed DataService.insertNewData method execute the insertion
// and returns "Data" model.
lazy val data = DataService.insertNewData(name, description)
"name must be ok" >> {
data.name === name
}
"description must be ok" >> {
data.description === description
}
"subdata must be ok" >> {
data.subData.foreach {
...
}
success
}
}

You might find the Specs2 guides helpful:
https://etorreborre.github.io/specs2/guide/org.specs2.guide.Structure.html#Expectations
Look for "Expectations" in the guide.

Spec2 will just show that your tests will pass if the conditions are met. No message will be generated and usually this is sufficient. If your testsuite becomes large enough, then the positive messages will become numerous. You are more interested in failures anyways.
Spec2 does generate clear message by default and will use the variable name, the actual value and what it is supposed to be in general. But if that is not good enough, you can set a custom message. How this can be done can be seen in this stackoverflow answer
If you still want to generate the messages, you can use print statement and loggers. But I would advise you against it.
I would refactor to two different tests:
"DataServiceTest"
should {
"InsertNewData should have correct basic properties" in {
// Arrange
val name = "some name here"
val description = "some description here"
// Act
// Assumed DataService.insertNewData method execute the insertion
// and returns "Data" model.
Data data = DataService.insertNewData(name, description)
// Assert
// Checking of equality here
data.name === name
data.description === description
}
"InsertNewData should have correct subData" in {
// Arrange
val name = "some name here"
val description = "some description here"
// Act
// Assumed DataService.insertNewData method execute the insertion
// and returns "Data" model.
Data data = DataService.insertNewData(name, description)
// Assert
// Assumed the "Data" model has List[SubData] property "subData"
// and the code below is checking the
data.subData must have size(3)
data.subData.foreach {
...
}
}
}

Related

crafting the body for request does not work concurrently

I would like to send simultaneous requests through gatlings for some duration
below is the snippet of my code where I am crafting the requests.
JSON file contents function which is used for crafting the json. its been used in the main request
the TestDevice_dev.csv has list of devices till 30 after 30 I will reuse it.
TestDevice1
TestDevice2
TestDevice3
.
.
.
val dFeeder = csv("TestDevice_dev.csv").circular
val trip_dte_tunnel_1 = scenario("TripSimulation")
.feed(dFeeder)
.exec(session => {
val key = conf.getString("config.env.sign_key")
var bodyTrip = CannedRequests.jsonFileContents("${deviceID}")
//deviceId comes from the feeder
session.set("trip_sign", SignatureGeneration.getSignature(key, bodyTrip))
session.set("tripBody",bodyTrip)
})
.exec(http("trip")
.post(trip_url)
.headers(trip_Headers_withsign)
.body(StringBody("${tripBody}")).asJSON.check(status.is(201)))
.exec(flushSessionCookies)
the scenario is started as below
val scn_trip = scenario("trip simulation")
.repeat{1} {
exec(DataExchange.trip_dte_tunnel_1)
}
setUp(scn_trip.inject(constantUsersPerSec(5) during (5 seconds))) ```
it runs fine if there is 1 user for 5 seconds but not simulatenous users.
the json request which is crafted looks like the below
"events":[
{
"deviceDetailsDataModel":{
"deviceId":"<deviceID>"
},
"eventDateTime":"<timeStamp>",
"tripInfoDataModel":{
"ignitionStatus":"ON",
"ignitionONTime":"<onTimeStamp>"
}
},
{
"deviceDetailsDataModel":{
"deviceId":"<deviceID>"
},
"eventDateTime":"<timeStamp>",
"tripInfoDataModel":{
"ignitionStatus":"ON",
"ignitionONTime":"<onTimeStamp>"
}
},
{
"deviceDetailsDataModel":{
"deviceId":"<deviceID>"
},
"eventDateTime":"<timeStamp>",
"tripInfoDataModel":{
"ignitionOFFTime":"<onTimeStamp>",
"ignitionStatus":"OFF"
}
}
]
}`
`def jsonFileContents(deviceId: String): String= {
val fileName = "trip-data.json"
var stringBuilder=""
var timeStamp1:Long = ZonedDateTime.now(ZoneId.of("America/Chicago")).toInstant().toEpochMilli().toLong - 10000.toLong
for (line <- (Source fromFile fileName).getLines) {
if (line.contains("eventDateTime")) {
var lineReplace=line.replaceAll("<timeStamp>", timeStamp1.toString())
stringBuilder=stringBuilder+lineReplace
timeStamp1 = timeStamp1+1000.toLong
}
else if (line.contains("onTimeStamp")) {
var lineReplace1=line.replaceAll("<onTimeStamp>", timeStamp1.toString)
stringBuilder=stringBuilder+lineReplace1
}
else if (line.contains("deviceID")){
var lineReplace2=line.replace("<deviceID>", deviceId)
stringBuilder=stringBuilder+lineReplace2
}
else {
stringBuilder =stringBuilder+line
}
}
stringBuilder
}
`
Best guess: your feeder contains one single entry and you're using the default queue strategy. Either add more entries in your feeder file to match the number of users, or use a different strategy.
This really is explained in the documentation, including the tutorials. I recommend you take some time to read the documentation before rushing into the code, you'll save lots of time in the end.
You don't need to do your own parameter substitution of values in the json file - Gatling supports passing en ELFileBody as the body where you can have a json file with gatling EL expressions like ${deviceId}.

Adding Values to Custom Attribute using App Script

I have a requirement of adding Value to Custom attribute in G Suite for bulk users, I have added address and other field using App script but don't know how to add values to a custom attribute named "Enhanced Desktop Security" as shown in the image below.
Value to be added is using App Script is: "un:Windows"
Request your help with the Script.
I have been working on this and came to know that 1st you have to identify the schemas of the custom attribute here : https://developers.google.com/admin-sdk/directory/v1/reference/users/list Once you do that you can use the below script. Please make sure that you change the schema in the below script.
Mention "User Email ID", "Value", "Updation Status" in Cloumn A,B,C, respectively in sheet.
function updateCustomE() {
var ss = SpreadsheetApp.openById(""); // Mention ID of the spreadsheet here.
var sheet = ss.getSheetByName(""); // Mention Name of the sheet here.
var values = sheet.getDataRange().getValues();
var fileArray = [["Updation Status"]]
for(i=1; i <values.length; i++)
{
var userKey = values[i][0]
var customValue = values [i][1]
try{
var status = "Value not updated"
var status = AdminDirectory.Users.update({
"customSchemas": {
"Enhanced_desktop_security" : {
"Local_Windows_accounts" : [
{
"type": "custom",
"value": customValue
}
]
}
}
}, userKey);
if (status != "Value not updated"){
status = "Value updated Successfully"
}
}
catch (e) {
Logger.log(e.message)
var status = e.message
}
fileArray.push([status])
}
var range = sheet.getRange(1, 3, fileArray.length, 1).setValues(fileArray)
}

how to setup a for loop inside if statement with correct syntax Play framework Scala Template

I am trying to setup a variable in the scala template. Loop through the roles that user have , if found out the user is customer , then do something with the input. If not then do something else.
But scala isnt that simple , it won't compile on following code.
#var = #{ if(user != null){
#for(role <- user.roles.filter(_.getName()=="customer")) {
var=#customer(input)
}
}
}
#if( var == null){
var=#others(input)
}
It gives me two errors
t.scala.html:275:: identifier expected but 'for' found.
[error] #for(role <- user.roles.filter(_.getName()=="customer"))
t.scala.html:278: expected start of definition
Also , is there a better way to do this in scala ? Thanks
My reference : Scala template set variable
Update:
My goal was trying to do something like below , but in scala template:
result=null
for role in User.roles:
if(role == "customer"):
result=customer(xyz)
break
if(result==null):
result = others(xyz)
To set up a for loop inside of an if statement in a Scala template, you don't need to assign a variable. You can simply use an if block in the template where you want to display stuff. For example
#if(user != null) {
#for(role <- user.roles.filter(_.getName()=="customer")) {
#customer(input)
#* Do other stuff related to 'role' and 'input' here *#
}
} else {
#* Do something else *#
}
For further reference I encourage you to look at the documentation for Play templates. If you really want to define a variable you could do it using the defining helper:
#defining(user.getFirstName() + " " + user.getLastName()) { fullName =>
<div>Hello #fullName</div>
}
Instead of defining a variable you could also define a resusable block, which might be useful in your case. For example,
#customer_loop(input: String) = {
#if(user != null) {
#for(role <- user.roles.filter(_.getName()=="customer")) {
#customer(input)
#* Do other stuff related to 'role' and 'input' here *#
}
} else {
#* Do something else *#
}
}
To declare a variable do
#import scala.Any; var result:Any=null //where Any is the datatype accoding to your requirement
To reassign its value do
#{result = "somevalue"}
So the solution accoding to the pseudo you provided
#import java.lang.String; var result:String=null
#import scala.util.control._;val loop = new Breaks;
#loop.breakable {
#for(role <- roleList) {
#if(role.equals("customer")) {
#{
result = "somevalue"
}
#{loop.break};
}
}
}
#if(result==null){
#{result="notfound"}
}
Also check Similar1,Similar2

validation of fields in a form in scala with lift frame work

I am working with the Lift framework and Scala. I have a form to sign up to my application, and I want to validate all the fields in it. I have a snippet where I access my form values, and one validation class where I wrote my validation functions. The following code is what I've tried so far. In my Snippet:
if(validationClassObject.validateName(first_name)){
if(validationClassObject.validateName(last_name)){
if(validationClassObject.validateEmail(email)){
if(validationClassObject.validateUserName(name)){
// Adding values to the DB
S.redirectTo("/")
}
else{
S.notice("Invalid User Name")
}
}
else{
S.notice("Invalid Mail Id")
}
}
else{
S.notice("Invalid Last name")
}
}
else{
S.notice("Invalid First Name")
}
In the validationClass I wrote the validation code looks like:
//function for validating mail address
def validateEmail(email: String): Boolean =
"""(\w+)#([\w\.]+)""".r.unapplySeq(email).isDefined
//code for validating remaining fileds like above
This is working, but I know this is not the best way of coding this operation in Scala. How could I modify my code in a more scalable way? How can I use case classes here?
You could do:
def av[T,V](validationFunction: => Boolean, error: => T)(f: => V)={
if(!validationFunction) error
else f
}
def v[V](validationFunction: => Boolean, error: => String)(f: => V)=av(validationFunction,S.notice(error))(f)
import validationCalssObject._
v(validateName(last_name),"Invalid Last name"){v(validateName(name),"Invalid User Name"){...}}
av is a abstract method with T and V as result types for the error function and continue function f. v is the more specific function what expects a string for error and encapsulates the notice() call. we give f as the part in the curly braces v(validation, errormsg){/*todo when there is no problem*/}.
I can't do formatting in comments so I'll post a new answer.
def badName() = if ("name" == "") Some("bad name") else None
def badEmail() = if ("email" == "") Some("bad email") else None
val verifications = List[() => Option[String]](badName, badEmail)
val failed = verifications.flatMap(_())
if (failed.nonEmpty) {
// handle failed
} else {
// your custom logic here
}
if (badName) S.notice
else if (badEmail) S.notice
else if (badDay) S.notice
else { // everything OK...
// return a JsCmd or what else do you wanted here
}
An alternative solution can be written using Option and flatMap, without these all "if"-s hardcoded. If you're interested in that -- ask..

Lift Framework - problems with passing url param to Snippet class

I am trying to do a simple case of /author/ and get the Lift to build a Person object based on the id passed in.
Currently i have an Author snippet
class Author(item: Person) {
def render = {
val s = item match { case Full(item) => "Name"; case _ => "not found" }
" *" #> s;
}
}
object Author{
val menu = Menu.param[Person]("Author", "Author", authorId => findPersonById(authorId), person => getIdForPerson(person)) / "author"
def findPersonById(id:String) : Box[Person] = {
//if(id == "bob"){
val p = new Person()
p.name="Bobby"
p.age = 32
println("findPersonById() id = " +id)
Full(p)
//}else{
//return Empty
//}
}
def getIdForPerson(person:Person) : String = {
return "1234"
}
}
What i am attempting to do is get the code to build a boxed person object and pass it in to the Author class's constructor. In the render method i want determine if the box is full or not and proceed as appropriate.
If i change
class Author(item: Person) {
to
class Author(item: Box[Person]) {
It no longer works but if i leave it as is it is no longer valid as Full(item) is incorrect. If i remove the val s line it works (and replace the s with item.name). So how do i do this. Thanks
The Box returned from findPersonById(id:String) : Box[Person] is evaluated and if the Box is Full, the unboxed value is passed into your function. If the Box is Empty or Failure the application will present a 404 or appropriate error page instead.
You can try double boxing your return if you want to handle this error checking yourself (so that the result of this method is always a Full Box).
def findPersonById(id:String) : Box[Box[Person]] = {
if(id == "bob"){
val p = new Person()
p.name="Bobby"
p.age = 32
println("findPersonById() id = " +id)
Full(Full(p))
}else{
return Full(Empty)
}
}
and then this should work:
class Author(item: Box[Person])