replace ClassName with custom string to display in IntelliJ scalatest window - scala

For a specific use case, we are trying to replace
ClassName with Verifying ClassName
in IntelliJ scala test case window.
For that, we overridden toString method in spec class as below :-
override def toString: String = s"Verifying ${getClass.getSimpleName}"
Still in IntelliJ test class, we can see only test ClassName name.
Kindly suggest, how to implement it.

Related

How come "println" without being enclosed in a method, allowed inside a scala class?

I'm new to Scala and in Scala I found that one can write println directly inside a class despite it not being a variable or method, how is this possible?
Even if println is a method then why aren't we defining it in the class as required generally for methods? Why despite being a method it is not allowed directly in Java class but allowed in Scala?
E.g.
class Hero {
println("running fine...") // Why is this println allowed in scala when its not inside a function?
}
object MainObject{
def main(args: Array[String]){
new Hero()
}
}
Basically, it runs inside the Class constructor. Any code inside the Class besides the variable and function declarations is constructor's code.
You can write any statement directly inside a class and it will be run whenever the class is instantiated.
When you open up an editor and start typing code, you will find, that some things are already available and some need to be imported. So all of these things which are available without importing are present in the scala.Predef package.
println is one of the methods made available by the scala compiler in the scala.Predef package.
def println() = Console.println()
If you check the scala docs, println method internally calls the Console object to print the contents on the screen.
I'm new to Scala and in Scala I found that one can write println directly inside a class despite it not being a variable or method, how is this possible?
You are wrong: println is a method, that's why this is possible. Here is the documentation for scala.Predef.println.

Scala 'this' and 'self' not working in simple App

New to scala (using version 2.12.1) obviously from the title. I'm writing my first app in IntelliJ. I've read about the Scala equivalent in Java to this. I've tried this, self, classOf[] and IntelliJ is complaining and the code is not compiling even if I ignore IntelliJ. Here's what I have:
import ch.qos.logback.classic.Logger
object Main extends App {
val logger = Logger[Main]
}
Logger package is importing correctly in SBT. However it cannot resolve the symbol Main. I tried sticking it in a package to make it less ubiquitous and then doing something like Logger[me.justin.Main] but that also doesn't work.
I also thought maybe extending App was causing some problems but I think that's fixed in the scala version I'm using? Maybe it's not even applicable?
I'm all Googled out. Help please!
You're getting tripped up by how Scala's objects work. Let's say we had a class Foo and a companion object for same:
class Foo
object Foo
If we wanted a logger for the class, we'd do the obvious thing:
val logger = Logger[Foo] // `Foo` here is the type of the class.
But what if we wanted to refer to the type of the object? We have to disambiguate from the type of the class. The answer is to use the special type member on the object:
val logger = Logger[Foo.type] // `Foo.type` here is the type of the object.
So in your case:
val logger = Logger[Main.type]

How to suppress intellij IDEA error in editor when using Binding.scala macro annotation?

Despite it compiles and runs in sbt console.
Intellij complains that I should have Binding[Node] instead of Elem in editor.
#dom def renderDiv: Binding[Div] = <div>...</div>
From intellij IDEA's perspective, this method returns a Elem which is a subtype of scala.xml.Node,
but when rendering:
dom.render(document.getElementById("root"),renderDiv)
it requires a org.scalajs.dom.raw.Node.
Is there any workaround to this?
Could put an implicit conversion def in scope:
package object xxx {
implicit def makeIntellijHappy[T<:org.scalajs.dom.raw.Node](x: scala.xml.Node): Binding[T] =
throw new AssertionError("This should never execute.")
}
define method above in the package object, thus it covers the whole package. This method will never be executed, actually.

Generating constructor in Scala in IntelliJ IDEA

In Java it's possible to just select "create constructor matching super" (or something pretty similar) and it automatically creates constructor. Is something like that available for Scala?
Example:
class Foo(a:Int, b:Int)
class Bar extends Foo
I'd just hit some hotkey on Bar and it would generate this:
class Bar(a:Int, b:Int) extends Foo(a:Int, b:Int)
As per the IntelliJ IDEA scala plugin version 0.22.302 nothing has changed in code generation functionality. It has only got override & implement methods, companion object and toString options under code generation and no construction generation support yet.

How to create annotations and get them in scala

I want to define some annotations and use them in Scala.
I looked into the source of Scala, found in scala.annotation package, there are some annotations like tailrec, switch, elidable, and so on. So I defined some annotations as them do:
class A extends StaticAnnotation
#A
class X {
#A
def aa() {}
}
Then I write a test:
object Main {
def main(args: Array[String]) {
val x = new X
println(x.getClass.getAnnotations.length)
x.getClass.getAnnotations map { println }
}
}
It prints some strange messages:
1
#scala.reflect.ScalaSignature(bytes=u1" !1* 1!AbCaE
9"a!Q!! 1gn!!.<b iBPE*,7
Ii#)1oY1mC&1'G.Y(cUGCa#=S:LGO/AA!A 1mI!)
Seems I can't get the annotation aaa.A.
How can I create annotations in Scala correctly? And how to use and get them?
FWIW, you can now define scala annotation in scala 2.10 and use reflection to read them back.
Here are some examples:
Reflecting Annotations in Scala 2.10
Could it have something to do with retention? I bet #tailrec is not included in the bytecode getting generated.
If I try to extend ClassfileAnnotation (in order to have runtime retention), Scala tells me that it can't be done, and it has to be done in Java:
./test.scala:1: warning: implementation restriction: subclassing Classfile does not
make your annotation visible at runtime. If that is what
you want, you must write the annotation class in Java.
class A extends ClassfileAnnotation
^
I think you can only define annotations in Java now.
http://www.scala-lang.org/node/106
You can find a nice description of how annotations are to be used in Scala in Programming Scala.
So you can define or use annotations in scala. However there is at least one limitation:
Runtime retention is not quite possible. In theory you should subclass ClassFileAnnotation to achieve this, but currently scalac reports the following warning if you do it:
"implementation restriction: subclassing Classfile does not make your annotation visible at runtime. If that is what you want, you must write the annotation class in Java."
It also means that your code is fine as it is (at least as fine as it is currently possible in Scala), but the annotation is on the class only during compile time. So you could use it e.g. in compiler plugins, but you will not be able to access it runtime.
With scala 2.11.6, this works to extract values of a annotation:
case class MyAnnotationClass(id: String) extends scala.annotation.StaticAnnotation
val myAnnotatedClass: ClassSymbol = u.runtimeMirror(Thread.currentThread().getContextClassLoader).staticClass("MyAnnotatedClass")
val annotation: Option[Annotation] = myAnnotatedClass.annotations.find(_.tree.tpe =:= u.typeOf[MyAnnotationClass])
val result = annotation.flatMap { a =>
a.tree.children.tail.collect({ case Literal(Constant(id: String)) => doSomething(id) }).headOption
}