The Artima Developer Community
Sponsored Link

Weblogs Forum
Introducing the ScalaTest Shell: a DSL for the Scala Interpreter

12 replies on 1 page. Most recent reply: May 11, 2011 7:57 AM by Lalit Pant

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 12 replies on 1 page
Bill Venners

Posts: 2284
Nickname: bv
Registered: Jan, 2002

Introducing the ScalaTest Shell: a DSL for the Scala Interpreter (View in Weblogs)
Posted: May 6, 2011 12:45 AM
Reply to this message Reply
Summary
The ScalaTest Shell is a new DSL coming in ScalaTest 1.5 that aims to make ScalaTest easier to use from the Scala interpreter. This post gives preview.
Advertisement

ScalaTest, like Scala, is designed to grow with the demands of its users. The main way that ScalaTest does that is by defining clearly specified extension points, such as the lifecycle methods in trait Suite: run, runNestedSuites, nestedSuites, runTests, testNames, tags, runTest, and withFixture. These methods are designed to be overridden by users to allow them to more easily build custom solutions for their own specific needs.

But Scala is "scalable" not only by allowing its users to morph it into a language suitable for specific tasks, but also because it is useful for small tasks as well as large ones. One area in which I had always wanted to make ScalaTest more useful was inside the Scala interpreter (also called "the REPL," for Read-Evaluate-Print-Loop), a tool used primarily to do "small tasks." In the early days of ScalaTest, I wasn't sure how people would want to use a test framework in the Scala interpreter, so I did nothing. I then waited to see what users tried to do with ScalaTest in the Scala interpreter, and what they said they wanted.

I finally got a spark of inspiration a few months ago from a post to the JUnit mailing list by Joakim Ohlrogge. Joakim had done some experimenting to see how he could make it easier to use JUnit from the Scala interpreter, which he released as poju4s. This user feedback pointed me in a design direction, and the ScalaTest Shell was born.

The main command of the ScalaTest shell is run, which you can use to run a suite of tests. The shell also provides several commands for configuring a call to run:

  • color - display results in color (green for success; red for failure; yellow for warning; blue for statistics)
  • nocolor - display results without color
  • durations - display durations of (i.e., how long it took to run) tests and suites
  • nodurations - do not display durations of tests and suites
  • shortstacks - display short (i.e., truncated to show just the most useful portion) stack traces for all exceptions
  • fullstacks - display full stack trackes for all exceptions
  • nostacks - display no stack trace for StackDepth exceptions and a short stack trace for non-StackDepth exceptions
  • stats - display statistics before and after the run, such as expected test count before the run and tests succeeded, failed, pending, etc., counts after the run
  • nostats do not display statistics before or after the run

The default configuration is color, nodurations, nostacks, and nostats.

All of these commands are methods of class org.scalatest.Shell. Each configuration command is a method that produces another Shell instance with every configuration parameter the same except for the one you've asked to change. For example, when you invoke durations, you'll get back a Shell instance that has every parameter configured the same way, except with durations enabled. When you invoke run on that, you get a run with durations enabled and every other configuration parameter at its default value.

Two other useful "commands" to know about, though not technically part of the shell, are the apply factory methods in the Suites and Specs singleton objects. These allow you to easily create composite suites out of nested suites, which you can then pass to run. This will be demonstrated later in this documentation.

Using the ScalaTest shell

The package object of the org.scalatest package extends Shell with all its parameters set to their default values. A good way to use the ScalaTest shell, therefore, is to import the members of package org.scalatest:

scala> import org.scalatest._
import org.scalatest._

One thing importing org.scalatest._ allows you to do is access any of ScalaTest's classes and traits by shorter names, for example:

scala> class ArithmeticSuite extends FunSuite with matchers.ShouldMatchers {
     |   test("addition works") { 
     |     1 + 1 should equal (2)
     |   } 
     |   ignore("subtraction works") {
     |     1 - 1 should equal (0)
     |   }
     |   test("multiplication works") {
     |     1 * 1 should equal (2) 
     |   }
     |   test("division works") (pending)
     | } 
defined class ArithmeticSuite

But importing org.scalatest._ also brings into scope the commands of the Shell, so you can, for example, invoke run without qualification:

scala> run(new ArithmeticSuite)
ArithmeticSuite:
- addition works
- subtraction works !!! IGNORED !!!
- multiplication works *** FAILED ***
  1 did not equal 2 (<console>:16)
- division works (pending)

Configuring a single run

To configure a single run, you can prefix run by one or more configuration commands, separated by dots. For example, to enable durations during a single run, you would write:

scala> durations.run(new ArithmeticSuite)
ArithmeticSuite:
- addition works (102 milliseconds)
- subtraction works !!! IGNORED !!!
- multiplication works *** FAILED *** (36 milliseconds)
  1 did not equal 2 (<console>:16)
- division works (pending)

To enable statistics during a single run, you would write:

scala> stats.run(new ArithmeticSuite)
Run starting. Expected test count is: 3
ArithmeticSuite:
- addition works
- subtraction works !!! IGNORED !!!
- multiplication works *** FAILED ***
  1 did not equal 2 (<console>:16)
- division works (pending)
Run completed in 386 milliseconds.
Total number of tests run: 2
Suites: completed 1, aborted 0
Tests: succeeded 1, failed 1, ignored 1, pending 1
*** 1 TEST FAILED ***

And to enable both durations and statistics during a single run, you could write:

scala> durations.stats.run(new ArithmeticSuite)
Run starting. Expected test count is: 3
ArithmeticSuite:
- addition works (102 milliseconds)
- subtraction works !!! IGNORED !!!
- multiplication works *** FAILED (36 milliseconds)***
  1 did not equal 2 (<console>:16)
- division works (pending)
Run completed in 386 milliseconds.
Total number of tests run: 2
Suites: completed 1, aborted 0
Tests: succeeded 1, failed 1, ignored 1, pending 1
*** 1 TEST FAILED ***

The order doesn't matter when you are chaining multiple configuration commands. You'll get the same result whether you write durations.stats.run or stats.durations.run.

To disable color, use nocolor:

scala> nocolor.run(new ArithmeticSuite)
ArithmeticSuite:
- addition works
- subtraction works !!! IGNORED !!!
- multiplication works *** FAILED ***
  1 did not equal 2 (<console>:16)
- division works (pending)

To enable short stack traces during a single run, use shortstacks:

scala> shortstacks.run(new ArithmeticSuite)
ArithmeticSuite:
- addition works (101 milliseconds)
- subtraction works !!! IGNORED !!!
- multiplication works *** FAILED *** (33 milliseconds)
  1 did not equal 2 (<console>:16)
  org.scalatest.TestFailedException:
  ...
  at line2$object$$iw$$iw$$iw$$iw$ArithmeticSuite$$anonfun$3.apply$mcV$sp(<console>:16)
  at line2$object$$iw$$iw$$iw$$iw$ArithmeticSuite$$anonfun$3.apply(<console>:16)
  at line2$object$$iw$$iw$$iw$$iw$ArithmeticSuite$$anonfun$3.apply(<console>:16)
  at org.scalatest.FunSuite$$anon$1.apply(FunSuite.scala:992)
  at org.scalatest.Suite$class.withFixture(Suite.scala:1661)
  at line2$object$$iw$$iw$$iw$$iw$ArithmeticSuite.withFixture(<console>:8)
  at org.scalatest.FunSuite$class.invokeWithFixture$1(FunSuite.scala:989)
  ...
- division works (pending)

Changing the default configuration

If you want to change the default for multiple runs, you can import the members of your favorite Shell configuration. For example, if you always like to run with durations and statistics enabled, you could write:

scala> import stats.durations._
import stats.durations._

Now anytime you simply call run, statistics and durations will be enabled:

scala> run(new ArithmeticSuite)
Run starting. Expected test count is: 3
ArithmeticSuite:
- addition works (9 milliseconds)
- subtraction works !!! IGNORED !!!
- multiplication works *** FAILED *** (10 milliseconds)
  1 did not equal 2 (<console>:18)
- division works (pending)
Run completed in 56 milliseconds.
Total number of tests run: 2
Suites: completed 1, aborted 0
Tests: succeeded 1, failed 1, ignored 1, pending 1
*** 1 TEST FAILED ***

Running multiple suites

If you want to run multiple suites, you can use the factory methods in either the Suites or Specs singleton objects. If you wrap a comma-separated list of suite instances inside Suites(...), for example, you'll get a suite instance that contains no tests, but whose nested suites includes the suite instances you placed between the parentheses. You can place Suites inside Suites to any level of depth, creating a tree of suites to pass to run. Here's a (contrived) example in which ArithmeticSuite is executed four times:

scala> run(Suites(new ArithmeticSuite, new ArithmeticSuite, Suites(new ArithmeticSuite, new ArithmeticSuite)))
Run starting. Expected test count is: 12
Suites:
ArithmeticSuite:
- addition works (0 milliseconds)
- subtraction works !!! IGNORED !!!
- multiplication works *** FAILED *** (1 millisecond)
  1 did not equal 2 (<console>:16)
- division works (pending)
ArithmeticSuite:
- addition works (1 millisecond)
- subtraction works !!! IGNORED !!!
- multiplication works *** FAILED *** (0 milliseconds)
  1 did not equal 2 (<console>:16)
- division works (pending)
Suites:
ArithmeticSuite:
- addition works (0 milliseconds)
- subtraction works !!! IGNORED !!!
- multiplication works *** FAILED *** (0 milliseconds)
  1 did not equal 2 (<console>:16)
- division works (pending)
ArithmeticSuite:
- addition works (0 milliseconds)
- subtraction works !!! IGNORED !!!
- multiplication works *** FAILED *** (0 milliseconds)
  1 did not equal 2 (<console>:16)
- division works (pending)
Run completed in 144 milliseconds.
Total number of tests run: 8
Suites: completed 6, aborted 0
Tests: succeeded 4, failed 4, ignored 4, pending 4
*** 4 TESTS FAILED ***

Running a single test

The run command also allows you to specify the name of a test to run and/or a config map. You can run a particular test in a suite, for example, by specifying the test name after the suite instance in your call to run, like this:

scala> run(new ArithmeticSuite, "addition works")
ArithmeticSuite:
- addition works

Give it a try

I released an updated ScalaTest-1.5-SNAPSHOT today that includes the new ScalaTest shell. The snapshot works with Scala 2.8. You can download the snapshot release via the scala-tools.org Maven repository with:

  • group id: org.scalatest
  • artifact id: scalatest_2.8.1
  • version: 1.5-SNAPSHOT

Or you can just grab the jar file from:

http://www.scala-tools.org/repo-snapshots/org/scalatest/scalatest_2.8.1/1.5-SNAPSHOT/scalatest_2.8.1-1.5-SNAPSHOT.jar

I put the Scaladoc for this snapshot release up here:

http://www.artima.com/docs-scalatest-1.5-SNAPSHOT-5-May-2011/

These enhancements will be released as part of ScalaTest 1.5 within the next few weeks. I'm posting this preview now because I want to get feedback in general on the API and find if there are any bugs to fix or any code-breakages. (I expect no source code to break with any of this enhancement, so let me know if you have a problem.) So please give it a try and either post feedback to the discussion forum for this blog post, or email the scalatest-users mailing list.


Lalit Pant

Posts: 51
Nickname: litan
Registered: Jun, 2007

Re: Introducing the ScalaTest Shell: a DSL for the Scala Interpreter Posted: May 7, 2011 8:03 AM
Reply to this message Reply
This looks very interesting.

My first thought on seeing this post was that I want to be able to use the ScalaTest Shell within Kojo (http://www.kogics.net/sf:kojo).

A little browsing through the ScalaTest source code revealed the seemingly perfect method for me to override:

private[scalatest] abstract class StringReporter(...) {
protected def printPossiblyInColor(text: String, ansiColor: String)
}


Alas, StringReporter is private[scalatest].

Any thoughts on the best way for me to proceed?

Bill Venners

Posts: 2284
Nickname: bv
Registered: Jan, 2002

Re: Introducing the ScalaTest Shell: a DSL for the Scala Interpreter Posted: May 7, 2011 8:23 PM
Reply to this message Reply
> This looks very interesting.
>
> My first thought on seeing this post was that I want to be
> able to use the ScalaTest Shell within Kojo
> (http://www.kogics.net/sf:kojo).
>
> A little browsing through the ScalaTest source code
> revealed the seemingly perfect method for me to override:
>

> private[scalatest] abstract class StringReporter(...) {
> protected def printPossiblyInColor(text: String,
> ing, ansiColor: String)
> }
>

>
> Alas, StringReporter is
> private[scalatest].
>
> Any thoughts on the best way for me to proceed?
>
I need to take a look at kojo, but I suspect the answer to your question is most likely that you probably want to make a custom reporter. ScalaTest is designed to let users make custom Reporters that do custom things with the events fired during testing. StringReporter is an internal class I use to implement several of the built-in reporters. If it looks like something you'd like to use, what you can do is simply make a copy of it (it's open source, free as in free beer as well as free speech), make whatever changes you want to do for your application, then tell ScalaTest to use your Reporter class. Info is here:

http://www.artima.com/docs-scalatest-1.5-SNAPSHOT-5-May-2011/#org.scalatest.Reporter

There are typos in the Extensibility section of that page that I just now noticed and fixed in the trunk. There's nothing called ReportFunction. I was thinking of calling it that at one point I believe. The apply method is abstract in Reporter, and that's all you need to implement. To tell the Runner to use a customer reporter, you use -r, as explained in the "Specifying reporters" section on this page:

http://www.artima.com/docs-scalatest-1.5-SNAPSHOT-5-May-2011/#org.scalatest.tools.Runner$

Can you tell me more about how you'd imagine using ScalaTest in kojo?

Lalit Pant

Posts: 51
Nickname: litan
Registered: Jun, 2007

Re: Introducing the ScalaTest Shell: a DSL for the Scala Interpreter Posted: May 7, 2011 9:21 PM
Reply to this message Reply
> StringReporter is an internal
> class I use to implement several of the built-in
> reporters. If it looks like something you'd like to use,
> what you can do is simply make a copy of it

That's the first thing I tried, but after running into dependencies on other private code within that package, I figured I'd just ask you before moving any further. I'll now go ahead and do what you're suggesting.

> Can you tell me more about how you'd imagine using
> ScalaTest in kojo?

- Kids would use it to write simple tests for their code. This would be especially useful for Math related code (e.g. - a function to determine the prime factors of a number, and a ScalaTest test for that)
- Programmers using Kojo as a REPL would have a quick and easy way to write tests for their experimental code. These tests could then easily migrate to the production version of their code.

I'm very new to ScalaTest, but based on your post, I imagine that people (in both the above scenarios) would just write a Suite, and then run it with the run method (like you described).

> To tell the Runner to use a customer reporter,
> you use -r, as explained in the "Specifying reporters"
> section on this page:
> http://www.artima.com/docs-scalatest-1.5-SNAPSHOT-5-May-2011/#org.scalatest.tools.Runner$

I will need to tell the ScalaTest shell to use my custom reporter. Can I do this by putting something into the config map when I call the shell run method?

Thanks,
- Lalit

Bill Venners

Posts: 2284
Nickname: bv
Registered: Jan, 2002

Re: Introducing the ScalaTest Shell: a DSL for the Scala Interpreter Posted: May 7, 2011 11:43 PM
Reply to this message Reply
> > StringReporter is an internal
> > class I use to implement several of the built-in
> > reporters. If it looks like something you'd like to
> use,
> > what you can do is simply make a copy of it
>
> That's the first thing I tried, but after running into
> dependencies on other private code within that package, I
> figured I'd just ask you before moving any further. I'll
> now go ahead and do what you're suggesting.
>
> > Can you tell me more about how you'd imagine using
> > ScalaTest in kojo?
>
> - Kids would use it to write simple tests for their code.
> This would be especially useful for Math related code
> (e.g. - a function to determine the prime factors of a
> number, and a ScalaTest test for that)
> - Programmers using Kojo as a REPL would have a quick and
> easy way to write tests for their experimental code. These
> tests could then easily migrate to the production version
> of their code.
>
Sounds cool. I'll download kojo this week and try it.

> I'm very new to ScalaTest, but based on your post, I
> imagine that people (in both the above scenarios) would
> just write a Suite, and then run it with the
> run method (like you described).
>
A Suite or maybe a FunSuite might be good for starters.

> > To tell the Runner to use a customer reporter,
> > you use -r, as explained in the "Specifying reporters"
> > section on this page:
> >
> http://www.artima.com/docs-scalatest-1.5-SNAPSHOT-5-May-201
> 1/#org.scalatest.tools.Runner$
>
> I will need to tell the ScalaTest shell to use my custom
> reporter. Can I do this by putting something into the
> config map when I call the shell run method?
>
The Shell doesn't currently allow you to specify a different Reporter, because Suite.execute doesn't (simply because I didn't imagine someone would want to do that). But that wouldn't be difficult to add at all. Can you give me more details about what you really need to do in your custom reporter?

Lalit Pant

Posts: 51
Nickname: litan
Registered: Jun, 2007

Re: Introducing the ScalaTest Shell: a DSL for the Scala Interpreter Posted: May 8, 2011 12:09 AM
Reply to this message Reply
> Sounds cool. I'll download kojo this week and try it.

Cool. Lemme know if you have any questions about anything when you try it.

> Can you give me more details about what you really need to
> do in your custom reporter?

I just need to redirect the message coming in from ScalaTest - to Kojo's output window, with the appropriate color.

Which is why I'm thinking that I'll take the StringReporter, and override:

protected def printPossiblyInColor(text: String, ansiColor: String)

...to do the right thing.

Then I'll need to get the Shell to use my custom reporter.

Lalit Pant

Posts: 51
Nickname: litan
Registered: Jun, 2007

Re: Introducing the ScalaTest Shell: a DSL for the Scala Interpreter Posted: May 8, 2011 6:41 AM
Reply to this message Reply
> Can you give me more details about what you really need to
> do in your custom reporter?

To make my previous reply more concrete, here's some Kojo code that uses the ScalaTest Shell:

import org.scalatest._

class KojoReporter extends Reporter {
def apply(event: events.Event) {
println(event) // Kojo's println, which sends stuff to the output window
println("--------------------")
}
}

class ArithmeticSuite extends FunSuite with matchers.ShouldMatchers {

val kreporter = new KojoReporter

override def runTest(testName: String, reporter: Reporter, stopper: Stopper, configMap: Map[String, Any], tracker: Tracker) {
super.runTest(testName, kreporter, stopper, configMap, tracker)
}


test("addition works") {
1 + 1 should equal (2)
}
ignore("subtraction works") {
1 - 1 should equal (0)
}
test("multiplication works") {
1 * 1 should equal (2)
}
test("division works") (pending)
}

run(new ArithmeticSuite)


To run this code within Kojo:
- Download the latest version of Kojo (Version 080511-1 or later), install, and launch Kojo.
- Go into Help->About, and locate your Userdir (this shows up right at the bottom of the dialog)
- Create a dir called libk under your Userdir, and copy the ScalaTest jar in there.
- Restart Kojo
- Paste the code above into the Kojo Script Editor.
- Run the code, to see raw ScalaTest output in the Kojo Output Window.

As you can see in the code above, I have plugged into the FunSuite to get ScalaTest to use my reporter. Telling the Shell to use the custom reporter would, of course, be a much better solution.

Bill Venners

Posts: 2284
Nickname: bv
Registered: Jan, 2002

Re: Introducing the ScalaTest Shell: a DSL for the Scala Interpreter Posted: May 8, 2011 10:57 AM
Reply to this message Reply
> To run this code within Kojo:
> - Download the latest version of Kojo (Version 080511-1 or
> later), install, and launch Kojo.
> - Go into Help->About, and locate your Userdir (this shows
> up right at the bottom of the dialog)
> - Create a dir called libk under your Userdir, and copy
> the ScalaTest jar in there.
> - Restart Kojo
> - Paste the code above into the Kojo Script Editor.
> - Run the code, to see raw ScalaTest output in the Kojo
> Output Window.
>
> As you can see in the code above, I have plugged into the
> FunSuite to get ScalaTest to use my reporter. Telling the
> Shell to use the custom reporter would, of course, be a
> much better solution.
>
I tried this. Kojo is really nice. It looks like what you'd like to do is call your own println and possibly put an extra dashed line. That's definitely the realm of a custom reporter. I'll add that to execute and the Shell prior to the 1.5 release. Have a guest this weekend so can't do it today, but I'll try and release that as a snapshot Monday if possible.

Also, do you have an output stream handy as well? I see you have your own println, but is there an output stream or a reader you could pass into a reporter? What might make things easier for people in your kind of situation is an OutputStreamReporter or WriterReporter that takes an output stream or Writer and then just prints StringReporter's output to that stream or writer. If so, would you prefer an OutputStream or a Writer? I think a Writer is probably better if you have no preference.

Lalit Pant

Posts: 51
Nickname: litan
Registered: Jun, 2007

Re: Introducing the ScalaTest Shell: a DSL for the Scala Interpreter Posted: May 8, 2011 11:39 AM
Reply to this message Reply
> It looks like what you'd like to do is call your own
> println

Right. I'll maybe have another version of println where you can specify a text color, to allow for green/red etc test output.

> custom reporter. I'll add that to execute and the Shell prior to the 1.5 release.

That sounds great.

> If so, would you prefer an OutputStream or a Writer?

Yes, I have a Writer in there.
A WriterReporter would be great, although I'm not sure how we would handle colors with that (the output would probably come in interspersed with the color information)?

Thanks!
- Lalit

Bill Venners

Posts: 2284
Nickname: bv
Registered: Jan, 2002

Re: Introducing the ScalaTest Shell: a DSL for the Scala Interpreter Posted: May 9, 2011 9:10 AM
Reply to this message Reply
> > It looks like what you'd like to do is call your own
> > println
>
> Right. I'll maybe have another version of println where
> you can specify a text color, to allow for green/red etc
> test output.
>
> > custom reporter. I'll add that to execute and the Shell
> prior to the 1.5 release.
>
> That sounds great.
>
> > If so, would you prefer an OutputStream or a Writer?
>
> Yes, I have a Writer in there.
> A WriterReporter would be great, although I'm not sure how
> we would handle colors with that (the output would
> probably come in interspersed with the color
> information)?
>
Hi Lalit,

I've been thinking about this. One way that's possible is to define a KojoShell that is identical to org.scalatest.Shell, except instead of calling execute on Suite, which writes to the standard output, it calls run directly. Alternatively I could add a PrintWriter parameter to execute whose default value wraps java.io.System.out. The trouble is that they'd have to do a second import.

import org.scalatest._
import kojoshell._

Another way I considered is to have run take an implicit parameter that holds onto a PrintWriter, but in that case I'd have to define that implicit parameter in the org.scalatest package object, and they'd have to do another import again. I also would really like to not have an implicit.

Another way is to define a krun command or something, but that's ugly. And it would again require another import, unless you included ScalaTest as part of Kojo. If you think that might be possible, there are lots of ways to do it. Is that something you would consider?

Lalit Pant

Posts: 51
Nickname: litan
Registered: Jun, 2007

Re: Introducing the ScalaTest Shell: a DSL for the Scala Interpreter Posted: May 9, 2011 11:25 AM
Reply to this message Reply
> unless you included ScalaTest as part of Kojo. If you think that might be possible, there are lots of ways to do it. Is that something you would consider?

I almost have to, to make this work out of the box at schools. The problem, if I can call it that, is ScalaTest's size (~2.5 Megs). Bundling it would result in a ~20% increase in Kojo's size. I'm hoping that I can bundle in a stripped down version of ScalaTest, with the possibility that those who know what they are doing - can download the full version and plop it into the libk dir to get full ScalaTest functionality.

Is ScalaTest amenable to this kind of splitting (into a core portion, and the bells and whistles)?

In terms of how this might work out, I really like your WriterReporter idea. So if:

- Suite.execute (and Shell.run) took a Reporter (which could default to a StandardOutputReporter)
- and we had a WriterReporter available within ScalaTest

...Kojo could just call Shell.run with a Writer (pointing to its output window) inside a WriterReporter.

Would that work from a ScalaTest perspective?

I also checked and saw that the Kojo Output Window, which is a Netbeans Platform Output Window, is able to handle ansi color codes - so the Writer idea also works fine with colors.

Bill Venners

Posts: 2284
Nickname: bv
Registered: Jan, 2002

Re: Introducing the ScalaTest Shell: a DSL for the Scala Interpreter Posted: May 9, 2011 5:39 PM
Reply to this message Reply
> > unless you included ScalaTest as part of Kojo. If you
> think that might be possible, there are lots of ways to do
> it. Is that something you would consider?
>
> I almost have to, to make this work out of the box at
> schools. The problem, if I can call it that, is
> ScalaTest's size (~2.5 Megs). Bundling it would result in
> a ~20% increase in Kojo's size. I'm hoping that I can
> bundle in a stripped down version of ScalaTest, with the
> possibility that those who know what they are doing - can
> download the full version and plop it into the libk dir to
> get full ScalaTest functionality.
>
> Is ScalaTest amenable to this kind of splitting (into a
> core portion, and the bells and whistles)?
>
Yes. What I think would make sense is to pick and chose what you think belongs in Kojo, fork ScalaTest, get rid of everything else, and then probably make a KojoSuite trait that mixes in everything you think they should have. For example if you define KojoSuite like this:

trait KojoSuite extends FunSuite with BeforeAndAfterEachFunctions

your users could just write:

class MySuite extends KojoSuite {
beforeEach {
// ...
}
test("something") {}
test("something else") {}
}

One thing Dick Wall and I do in our Scala courses is mix in a trait that stops the run after the first test fails. Dick calls these Koans after a similar concept in the Ruby community. We basically pass out problems in the form of tests that fail one at a time, leading the students through the exercises. Everybody seems to really like that. Not sure if you're providing a learning Scala path in there, but that might be something to think about as well.

> In terms of how this might work out, I really like your
> WriterReporter idea. So if:
>
> - Suite.execute (and Shell.run) took a Reporter (which
> could default to a StandardOutputReporter)
> - and we had a WriterReporter available within ScalaTest
>
> ...Kojo could just call Shell.run with a Writer (pointing
> to its output window) inside a WriterReporter.
>
> Would that work from a ScalaTest perspective?
>
> I also checked and saw that the Kojo Output Window, which
> is a Netbeans Platform Output Window, is able to handle
> ansi color codes - so the Writer idea also works fine with
> colors.
>
That's good news on color. I'm wondering if you do anything with setting the Console output stream at this point. That's probably one way to get the existing snapshot's Shell output right into your console window. If not, is there a reason you couldn't do that?

Lalit Pant

Posts: 51
Nickname: litan
Registered: Jun, 2007

Re: Introducing the ScalaTest Shell: a DSL for the Scala Interpreter Posted: May 11, 2011 7:57 AM
Reply to this message Reply
> I'm wondering if you do anything with setting the Console output stream at this point. That's probably one way to get the existing snapshot's Shell output right into your console window.

I tried redirecting stdout, and it works pretty well.

I have just put out a new version of Kojo (which can be downloaded from http://www.kogics.net/sf:kojo-download) which supports ScalaTest based on this approach.

There's a story within Kojo (available via the Stories -> Tools -> Setup ScalaTest menuitem) that guides users through the process of setting up ScalaTest for Kojo (this involves downloading ScalaTest, putting it in the right location for Kojo, and then defining some helper functions).

After ScalaTest is setup for use within Kojo, you can start writing simple tests like this:

def sum(n1: Int, n2: Int) = {
    n1 + n2
}
 
test("sum of positives") {
    sum(1,1) should equal(2)
}
 
// ignore test for now
notest("sum of negatives") {
    sum(-1,-1) should equal(-2)
}


You can also, of course, do all of the things that you would do with ScalaTest in an IDE environment.

Thanks for all the input on this, Bill.

Flat View: This topic has 12 replies on 1 page
Topic: Programming Summer Camp: July 25-29 2011, Crested Butte, Colorado Previous Topic   Next Topic Topic: Language Design Is Not Just Solving Puzzles

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use