This is a quick update to present the main differences with specs2 2.0-RC1. I have been fixing a few bugs but more importantly I have:
- made the
Tags
trait part of the standard specification - removed some arguments for reporting and made the formatting of specifications more granular
This all started with an issue on Github...
Formatting
Creating reports for specifications is a bit tricky. On one hand you hand different possible "styles" for the specifications: "old" acceptance style (with the ^
operator), "new" acceptance style (with interpolated strings), "unit" style... Then, on the other hand, you want to report the results in the console, where information is logged on a line-by-line base and in HTML files, where newlines, whitespace and indentation all needs great care.
I don't think I got it quite right yet, especially for HTML, but working on issue #162 forced me to make specs2 implementation and API a bit more flexible. In particular, in specs2 < 2.0, you could set some arguments to control the display of the specification in the console and/or HTML. For example noindent
is a Specification argument saying that you don't want the automatic indentation of text and examples. And markdown = false
means that you don't want text to be parsed as Markdown before being rendered to HTML.
However issue 162 shows that setting formatting properties at the level of the whole specification doesn't play well with other features like specification inclusion. I decided to fix this issue by using an existing specs2 feature: tags.
Tags and Specification
Tags in specs2 are different from tags you can find in other testing libraries. Not only you can tag single examples but you can also mark a full section of a specification with some tags. We can use this capability to select specific parts of a specification for execution but we can also use it to direct the formatting of the specification text. For example you can now write:
class MySpec extends Specification { def is = s2""" ${formatSection(verbatim = false)}
This text uses Markdown when printed to html, however if some text is indented with 4 spaces
it should *not* be rendered as a code block because `verbatim` is false.
"""
}
Given the versatile use of tags now, I decided to include the Tags
trait, by default, in the Specification
class. I resisted doing that in the past because I didn't want to encumber too much the Specification
namespace with something that was rarely used by some users. Which leads me to the following tip on how to use the Specification
class:
when starting a new project or prototyping some code, use the
Specification
class directly with all inherited featureswhen making your project more robust and production-like, create your own
Spec
trait, generally inheriting from theBaseSpecification
class for basic features, and mix in only the traits you think you will generally use
This should give you more flexibility and choice over which specs2 feature you want to use with a minimal cost in terms of namespace footprint and compile times (because each new implicit you bring in might have an impact in terms of performances)
API changes
The consequence of this evolution is yet another API break:
- the
Text
andExample
classes now use aFormattedString
class containing the necessary parameters to display that string as HTML or in the console - for implementation reasons I have actually changed the constructor parameters of all
Fragment
classes to avoid storing state as private variables - the
noindent
,markdown
arguments are now gone (you need to replace them with${formatSection(flow=true)}
and${formatSection(markdown=true)}
, see below) - the
Tags
trait is mixed in theSpecification
class so if you had methods likedef tag
you might get conflicts
And there are now 2 methods formatSection(flow: Boolean, markdown: Boolean, verbatim: Boolean)
and formatTag(flow: Boolean, markdown: Boolean, verbatim: Boolean)
to tag specification fragments with the following parameters:
flow
: the fragment (Text
orExample
) shouldn't be reported with automatic indenting (default =false
, set automatically totrue
when usings2
interpolated strings)markdown
: the fragment is using Markdown (default =true
)verbatim
: indented text with more than 4 spaces must be rendered as a code block (default =true
but can be set tofalse
to solve #162)
HTML reports
I'm currently thinking that I should try out a brand new way of translating an executed specification with interpolated text into HTML. My first attempts were not completely successful and I find it hard to preserve the original layout of the specification text, especially with the Markdown
translation in the middle. Yet, I must say a word on the Markdown library I'm using, Pegdown. I found this library extremely easy to adapt for my current needs (to implement the verbatim = false
option) and I send my kudos to Mathias for such a great job.
This is it. Download RC2, use it and provide feedback as usual, thanks!