Adding unit test to a legacy Scala project in IntelliJ - scala

I have a legacy Scala project to work with using maven as build tool.
Initially there is core code only under folder structure src/main/scala/ with package x.y.z and a file Main.scala with code as:
object Main {
def cube(x: Int) = {
x * x * x
}
}
There are no tests for the code. So I manually added a folder structure as test/scala under src.
Then I copied the package as for core code, ie x.y.z and added MainTest.scala with test code as:
class MainTest extends FunSuite {
test("Main.cube") {
assert(Main.cube(3) === 27)
}
}
Running test gives error as:
Error:(8, 12) not found: value Main
assert(Main.cube(3) === 27)
Why do I get this error?

For below project structure MainTest.scala and Main.scala are in the same package x.y.z therefore no package import is required, However MainTempTest.scala and Main.scala are in different package therefore an explicit import has to be done import x.y.z.Main
src
-main
--scala
---x.y.z
----Main.scala
-test
--scala
---MainTempTest.scala
---x.y.z
----MainTest.scala

Related

VS Code and Metals: Run 'Build import' to enable code navigation

I have a Scala- / Mill-Project that I wan't to import into VSCode.
The Metals Doctor gives me the following warnings:
Is there something missing in my project?
Here is my Mill configuration (build.sc):
import mill._
import mill.define.Target
import scalalib._
trait MyModule extends ScalaModule {
def scalaVersion = "2.13.1"
object version {
val cats = "2.0.0"
..
}
object libs {
val cats = ivy"org.typelevel::cats-core:${version.cats}"
..
}
object test extends Tests {
...
}
}
object entity extends MyModule {
override def ivyDeps = {
Agg(
libs.cats,
..
)
}
}
object macros extends MyModule {
..
}
Here is the whole project: https://github.com/pme123/zio-examples
The console output shows no warnings, here is the end:
...
time: connected to build server in 0.33s
time: imported build in 0.41s
time: indexed workspace in 3.85s
no build target: /Users/mpa/dev/Github/pme123/zio-examples/build.sc
This error/help message is misleading, as it presumes you are using Bloop, in which case re-importing solves the isssue (from experience). When you are using Mill's built-in BSP server, this won't change much.
Mill's recent 0.10.0-M4 release got a major BSP revamp. Also Metals improved it's Mill support. So you should have a better overall experience.
Here is some documentation: https://com-lihaoyi.github.io/mill/mill/Intro_to_Mill.html#_build_server_protocol_bsp

Scalatest with eclipse shows errors while using Matchers

I have an eclipse scala project which uses maven. Eclipse plugins for ScalaIDE and Scalatest are installed. I have tests like:
import org.scalatest._
class ExampleSpec extends FlatSpec with Matchers {
feature("Feature A Test") {
scenario("Foo scenario 1") {
val a = FooClass().getResult()
a.count shouldBe 1 // IDE shows error: value shouldBe is not a member of Long
a(0).getString(0) shouldBe "FOO" // IDE shows error: value shouldBe is not a member of String
}
}
}
The maven compilation and the tests run fine, but in eclipse when I open this file, I see an error in eclipse wherever I am using a Matcher as mentioned in the comments above. Eg.
value shouldBe is not a member of Long
What am I missing? A scala test file shows hundreds of problems.
After adding the following dummy code:
case class Bar() {
def count = Array(Bar())
def getString(x: Int) = Array("aqq")
def apply[T](x: Int) = this
}
case class FooClass() {
def getResult() = Bar()
}
and changing FlatSpec to FeatureSpec as this is the syntax you are using in your ExampleSpec, the code compiles without any issues.
If it's still not the case for you I can suggest creating simple build.sbt and generating project with Eclipse sbt plugin.
I know this is old, but I had the same issue with eclipse (late 2018), and I was able to fix this by making sure the test was NOT in the default package. That is, add "package org.scalatest.examples.flatspec" to the beginning of your test, as an example, and move the test into that package.

How can I compile a Scala and LWJGL3 application?

I'm having a lot of trouble compiling a Scala program with LWJGL3. I suspect that I either don't understand Scala's import statement correctly, or I don't understand Scala's classpath correctly. I've placed the LWJGL3 Nightly download in an org folder at my project root. This is the error scalac gives me:
Minimum.scala:1: error: object opengl is not a member of package org.lwjgl
import org.lwjgl.opengl._
^
Minimum.scala:3: error: object glfw is not a member of package org.lwjgl
import org.lwjgl.glfw.GLFW._
^
Minimum.scala:4: error: object opengl is not a member of package org.lwjgl
import org.lwjgl.opengl.GL11._
^
Minimum.scala:5: error: object system is not a member of package org.lwjgl
import org.lwjgl.system.MemoryUtil._
^
(Plus lots of error: not found: value _______ errors because it couldn't find the various functions.)
Here's my code (in Minimum.scala at the project root):
import org.lwjgl.opengl._
import org.lwjgl.glfw.GLFW._
import org.lwjgl.opengl.GL11._
import org.lwjgl.system.MemoryUtil._
object Minimum {
def main(args: Array[String]): Unit = {
glfwInit()
long windowHandle = glfwCreateWindow(500, 500, "Hello, World!", NULL, NULL)
glfwMakeContextCurrent(windowHandle)
GL.createCapabilities()
glClearColor(0.0f, 1.0f, 0.0f, 0.0f)
while (!glfwWindowShouldClose(windowHandle)) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glfwSwapBuffers(windowHandle)
glfwPollEvents()
}
glfwDestroyWindow(windowHandle)
}
}
I've also tried these import statements instead, which were suggested here:
import org.lwjgl._, glfw._, opengl._
import Callbacks._, GLFW._, GL11._
import org.lwjgl.system.MemoryUtil._
Finally, I'm compiling with this command:
scalac -classpath ".;org/lwjgl/*;org/lwjgl-egl/*;org/lwjgl-glfw/*;org/lwjgl-jawt/*;org/lwjgl-jemalloc/*;org/lwjgl-lmdb/*;org/lwjgl-nanovg/*;org/lwjgl-nfd/*;org/lwjgl-nuklear/*;org/lwjgl-openal/*;org/lwjgl-opencl/*;org/lwjgl-opengl/*;org/lwjgl-opengles/*;org/lwjgl-ovr/*;org/lwjgl-par/*;org/lwjgl-sse/*;org/lwjgl-stb/*;org/lwjgl-tinyfd/*;org/lwjgl-vulkan/*;org/lwjgl-xxhash/*" Minimum.scala
Which I've tried numerous variations on including omitting the *, adding *.jar, moving the lwjgl libraries to another folder, giving just the org/ directory rather than the complete list, and replacing the ; with :. This is essentially the command I used to compile a nearly identical Java application, which worked perfectly.
Does anyone know how I can get my program to compile?

Scala doesn't import from manually created package

I'm using Scala with Ubuntu.
There are two files
File a.scala:
package ptest { class A() { def p = println ("A") } }
File b.scala
package ptest { import ptest.A ; class B() { def p = {print("B"); A.p} }
}
Compiling b.scala delivers an error:.
$ scalac a.scala
$ scalac b.scala
b.scala:2: error: A is not a member of ptest
although A.class is stored correct in dictionary ptest.
What is wrong?
You must explicitly put A.class on the classpath:
scalac -classpath . b.scala
(Replace . with the directory that contains A.class if it isn't in the current directory)
The next issue you have is import ptest.A, which doesn't do anything useful and produces a warning. There is no need to import members of the package you are in.
A.p produces an error. A.p means to invoke p on the value A, but no value A exists at that point. There is a class A, but you can't access class members without first creating an instance of that class.

Excluding a ScalaTest test when calling my tests from within sbt

I want to write a test that calls a remote server and validates the response because the server may change (it's not under my control). To do this I figure I'd give it a tag (RemoteTest) and then exclude it when calling the runner:
sbt> test-only * -- -l RemoteTest
However, when doing this all my tests are run, including RemoteTest. How do I call the runner from within sbt so that it is excluded?
If you have the following:-
package com.test
import org.scalatest.FlatSpec
import org.scalatest.Tag
object SlowTest extends Tag("com.mycompany.tags.SlowTest")
object DbTest extends Tag("com.mycompany.tags.DbTest")
class TestSuite extends FlatSpec {
"The Scala language" must "add correctly" taggedAs(SlowTest) in {
val sum = 1 + 1
assert(sum === 2)
}
it must "subtract correctly" taggedAs(SlowTest, DbTest) in {
val diff = 4 - 1
assert(diff === 3)
}
}
To exclude DbTest tag, you would do:-
test-only * -- -l com.mycompany.tags.DbTest
Note that you'll need to include the full tag name. If it's still not working for you, would you mind sharing part of source code that's not working?