Skip to content

Commit 1dbec88

Browse files
committed
Merge branch 'feature-init'
2 parents a0970b7 + a1f677d commit 1dbec88

34 files changed

+4209
-1
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,5 @@
11
*.class
22
*.log
3+
target/
4+
.idea/
5+
test-output/

README.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,10 @@
1-
# scalatestplus-junit
1+
# ScalaTest + JUnit
22
ScalaTest + JUnit provides integration support between ScalaTest and JUnit.
3+
4+
**Publishing**
5+
6+
Please use the following commands to publish to Sonatype:
7+
8+
```
9+
$ sbt +publishSigned
10+
```

build.sbt

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
name := "scalatestplus-junit"
2+
3+
organization := "org.scalatestplus"
4+
5+
version := "1.0.0-SNAP4"
6+
7+
homepage := Some(url("https://github.com/scalatest/scalatestplus-junit"))
8+
9+
licenses := List("Apache-2.0" -> url("http://www.apache.org/licenses/LICENSE-2.0"))
10+
11+
developers := List(
12+
Developer(
13+
"bvenners",
14+
"Bill Venners",
15+
16+
url("https://github.com/bvenners")
17+
),
18+
Developer(
19+
"cheeseng",
20+
"Chua Chee Seng",
21+
22+
url("https://github.com/cheeseng")
23+
)
24+
)
25+
26+
crossScalaVersions := List("2.10.7", "2.11.12", "2.12.8", "2.13.0-M5")
27+
28+
libraryDependencies ++= Seq(
29+
"org.scalatest" %% "scalatest" % "3.1.0-SNAP8",
30+
"junit" % "junit" % "4.12"
31+
)
32+
33+
testOptions in Test :=
34+
Seq(
35+
Tests.Argument(TestFrameworks.ScalaTest,
36+
"-m", "org.scalatestplus.junit",
37+
))
38+
39+
enablePlugins(SbtOsgi)
40+
41+
osgiSettings
42+
43+
OsgiKeys.exportPackage := Seq(
44+
"org.scalatestplus.junit.*"
45+
)
46+
47+
OsgiKeys.importPackage := Seq(
48+
"org.scalatest.*",
49+
"org.scalactic.*",
50+
"scala.*;version=\"$<range;[==,=+);$<replace;"+scalaBinaryVersion.value+";-;.>>\"",
51+
"*;resolution:=optional"
52+
)
53+
54+
OsgiKeys.additionalHeaders:= Map(
55+
"Bundle-Name" -> "ScalaTestPlusJUnit",
56+
"Bundle-Description" -> "ScalaTest+JUnit is an open-source integration library between ScalaTest and JUnit for Scala projects.",
57+
"Bundle-DocURL" -> "http://www.scalatest.org/",
58+
"Bundle-Vendor" -> "Artima, Inc."
59+
)
60+
61+
publishTo := {
62+
val nexus = "https://oss.sonatype.org/"
63+
Some("publish-releases" at nexus + "service/local/staging/deploy/maven2")
64+
}
65+
66+
publishMavenStyle := true
67+
68+
publishArtifact in Test := false
69+
70+
pomIncludeRepository := { _ => false }
71+
72+
credentials += Credentials(Path.userHome / ".ivy2" / ".credentials")
73+
74+
pgpSecretRing := file((Path.userHome / ".gnupg" / "secring.gpg").getAbsolutePath)
75+
76+
pgpPassphrase := None

project/build.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
sbt.version=1.2.8

project/plugins.sbt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
addSbtPlugin("com.jsuereth" % "sbt-pgp" % "1.1.1")
2+
3+
addSbtPlugin("com.geirsson" % "sbt-ci-release" % "1.2.2")
4+
5+
addSbtPlugin("com.typesafe.sbt" % "sbt-osgi" % "0.9.4")
Lines changed: 246 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,246 @@
1+
/*
2+
* Copyright 2001-2013 Artima, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.scalatestplus.junit
17+
18+
import org.scalatest._
19+
import _root_.junit.framework.AssertionFailedError
20+
import org.scalactic._
21+
import org.scalactic.exceptions.NullArgumentException
22+
import org.scalatest.exceptions.{StackDepthException, TestCanceledException}
23+
24+
/**
25+
* Trait that contains ScalaTest's basic assertion methods, suitable for use with JUnit.
26+
*
27+
* <p>
28+
* The assertion methods provided in this trait look and behave exactly like the ones in
29+
* <a href="../Assertions.html"><code>Assertions</code></a>, except instead of throwing
30+
* <a href="../exceptions/TestFailedException.html"><code>TestFailedException</code></a> they throw
31+
* <a href="JUnitTestFailedError.html"><code>JUnitTestFailedError</code></a>,
32+
* which extends <code>junit.framework.AssertionFailedError</code>.
33+
*
34+
* <p>
35+
* JUnit 3 (release 3.8 and earlier) distinguishes between <em>failures</em> and <em>errors</em>.
36+
* If a test fails because of a failed assertion, that is considered a <em>failure</em>. If a test
37+
* fails for any other reason, either the test code or the application being tested threw an unexpected
38+
* exception, that is considered an <em>error</em>. The way JUnit 3 decides whether an exception represents
39+
* a failure or error is that only thrown <code>junit.framework.AssertionFailedError</code>s are considered
40+
* failures. Any other exception type is considered an error. The exception type thrown by the JUnit 3
41+
* assertion methods declared in <code>junit.framework.Assert</code> (such as <code>assertEquals</code>,
42+
* <code>assertTrue</code>, and <code>fail</code>) is, therefore, <code>AssertionFailedError</code>.
43+
* </p>
44+
*
45+
* <p>
46+
* In JUnit 4, <code>AssertionFailedError</code> was made to extend <code>java.lang.AssertionError</code>,
47+
* and the distinction between failures and errors was essentially dropped. However, some tools that integrate
48+
* with JUnit carry on this distinction, so even if you are using JUnit 4 you may want to use this
49+
* <code>AssertionsForJUnit</code> trait instead of plain-old ScalaTest
50+
* <a href="../Assertions.html"><code>Assertions</code></a>.
51+
* </p>
52+
*
53+
* <p>
54+
* To use this trait in a JUnit 3 <code>TestCase</code>, you can mix it into your <code>TestCase</code> class, like this:
55+
* </p>
56+
*
57+
* <pre class="stHighlight">
58+
* import junit.framework.TestCase
59+
* import org.scalatest.junit.AssertionsForJUnit
60+
*
61+
* class MyTestCase extends TestCase with AssertionsForJUnit {
62+
*
63+
* def testSomething() {
64+
* assert("hi".charAt(1) === 'i')
65+
* }
66+
*
67+
* // ...
68+
* }
69+
* </pre>
70+
*
71+
* <p>
72+
* You can alternatively import the methods defined in this trait.
73+
* </p>
74+
*
75+
* <pre class="stHighlight">
76+
* import junit.framework.TestCase
77+
* import org.scalatest.junit.AssertionsForJUnit._
78+
*
79+
* class MyTestCase extends TestCase {
80+
*
81+
* def testSomething() {
82+
* assert("hi".charAt(1) === 'i')
83+
* }
84+
*
85+
* // ...
86+
* }
87+
* </pre>
88+
*
89+
* <p>
90+
* For details on the importing approach, see the documentation
91+
* for the <a href="AssertionsForJUnit$.html"><code>AssertionsForJUnit</code> companion object</a>.
92+
* For the details on the <code>AssertionsForJUnit</code> syntax, see the Scaladoc documentation for
93+
* <a href="../Assertions.html"><code>org.scalatest.Assertions</code></a>
94+
* </p>
95+
*
96+
* @author Bill Venners
97+
*/
98+
trait AssertionsForJUnit extends Assertions {
99+
100+
private[org] override def newAssertionFailedException(optionalMessage: Option[String], optionalCause: Option[Throwable], pos: source.Position, differences: scala.collection.immutable.IndexedSeq[String]): Throwable = {
101+
new JUnitTestFailedError(optionalMessage, optionalCause, pos, None)
102+
}
103+
104+
private[org] override def newTestCanceledException(optionalMessage: Option[String], optionalCause: Option[Throwable], pos: source.Position): Throwable =
105+
new TestCanceledException(toExceptionFunction(optionalMessage), optionalCause, pos, None)
106+
107+
/**
108+
* If message or message contents are null, throw a null exception, otherwise
109+
* create a function that returns the option.
110+
*/
111+
def toExceptionFunction(message: Option[String]): StackDepthException => Option[String] = {
112+
message match {
113+
case null => throw new NullArgumentException("message was null")
114+
case Some(null) => throw new NullArgumentException("message was a Some(null)")
115+
case _ => { e => message }
116+
}
117+
}
118+
119+
import scala.language.experimental.macros
120+
121+
override def assert(condition: Boolean)(implicit prettifier: Prettifier, pos: source.Position): Assertion = macro AssertionsForJUnitMacro.assert
122+
123+
override def assert(condition: Boolean, clue: Any)(implicit prettifier: Prettifier, pos: source.Position): Assertion = macro AssertionsForJUnitMacro.assertWithClue
124+
125+
override def assume(condition: Boolean)(implicit prettifier: Prettifier, pos: source.Position): Assertion = macro AssertionsForJUnitMacro.assume
126+
127+
override def assume(condition: Boolean, clue: Any)(implicit prettifier: Prettifier, pos: source.Position): Assertion = macro AssertionsForJUnitMacro.assumeWithClue
128+
129+
/*
130+
private[scalatest] override def newAssertionFailedException(optionalMessage: Option[Any], optionalCause: Option[Throwable], stackDepth: Int): Throwable = {
131+
132+
val assertionFailedError =
133+
optionalMessage match {
134+
case None => new AssertionFailedError
135+
case Some(message) => new AssertionFailedError(message.toString)
136+
}
137+
138+
for (cause <- optionalCause)
139+
assertionFailedError.initCause(cause)
140+
141+
assertionFailedError
142+
} */
143+
}
144+
145+
/**
146+
* Companion object that facilitates the importing of <code>AssertionsForJUnit</code> members as
147+
* an alternative to mixing it in. One use case is to import <code>AssertionsForJUnit</code> members so you can use
148+
* them in the Scala interpreter:
149+
*
150+
* <pre>
151+
* $ scala -cp junit3.8.2/junit.jar:../target/jar_contents
152+
* Welcome to Scala version 2.7.5.final (Java HotSpot(TM) Client VM, Java 1.5.0_16).
153+
* Type in expressions to have them evaluated.
154+
* Type :help for more information.
155+
*
156+
* scala> import org.scalatest.junit.AssertionsForJUnit._
157+
* import org.scalatest.junit.AssertionsForJUnit._
158+
*
159+
* scala> assert(1 === 2)
160+
* junit.framework.AssertionFailedError: 1 did not equal 2
161+
* at org.scalatest.junit.AssertionsForJUnit$class.assert(AssertionsForJUnit.scala:353)
162+
* at org.scalatest.junit.AssertionsForJUnit$.assert(AssertionsForJUnit.scala:672)
163+
* at .<init>(<console>:7)
164+
* at .<clinit>(<console>)
165+
* at RequestResult$.<init>(<console>:3)
166+
* at RequestResult$.<clinit>(<console>)
167+
* at RequestResult$result(<consol...
168+
* scala> expect(3) { 1 + 3 }
169+
* junit.framework.AssertionFailedError: Expected 3, but got 4
170+
* at org.scalatest.junit.AssertionsForJUnit$class.expect(AssertionsForJUnit.scala:563)
171+
* at org.scalatest.junit.AssertionsForJUnit$.expect(AssertionsForJUnit.scala:672)
172+
* at .<init>(<console>:7)
173+
* at .<clinit>(<console>)
174+
* at RequestResult$.<init>(<console>:3)
175+
* at RequestResult$.<clinit>(<console>)
176+
* at RequestResult$result(<co...
177+
* scala> val caught = intercept[StringIndexOutOfBoundsException] { "hi".charAt(-1) }
178+
* caught: StringIndexOutOfBoundsException = java.lang.StringIndexOutOfBoundsException: String index out of range: -1
179+
* </pre>
180+
*
181+
* @author Bill Venners
182+
*/
183+
object AssertionsForJUnit extends AssertionsForJUnit {
184+
185+
import Requirements._
186+
187+
/**
188+
* Helper class used by code generated by the <code>assert</code> macro.
189+
*/
190+
class AssertionsHelper {
191+
192+
private def append(currentMessage: Option[String], clue: Any) = {
193+
val clueStr = clue.toString
194+
if (clueStr.isEmpty)
195+
currentMessage
196+
else {
197+
currentMessage match {
198+
case Some(msg) =>
199+
// clue.toString.head is guaranteed to work, because the previous if check that clue.toString != ""
200+
val firstChar = clueStr.head
201+
if (firstChar.isWhitespace || firstChar == '.' || firstChar == ',' || firstChar == ';')
202+
Some(msg + clueStr)
203+
else
204+
Some(msg + " " + clueStr)
205+
case None => Some(clueStr)
206+
}
207+
}
208+
}
209+
210+
/**
211+
* Assert that the passed in <code>Bool</code> is <code>true</code>, else fail with <code>TestFailedException</code>.
212+
*
213+
* @param bool the <code>Bool</code> to assert for
214+
* @param clue optional clue to be included in <code>TestFailedException</code>'s error message when assertion failed
215+
*/
216+
def macroAssert(bool: Bool, clue: Any, prettifier: Prettifier, pos: source.Position): Assertion = {
217+
requireNonNull(clue)(prettifier, pos)
218+
if (!bool.value) {
219+
val failureMessage = if (Bool.isSimpleWithoutExpressionText(bool)) None else Some(bool.failureMessage)
220+
throw newAssertionFailedException(append(failureMessage, clue), None, pos, bool.analysis)
221+
}
222+
Succeeded
223+
}
224+
225+
/**
226+
* Assume that the passed in <code>Bool</code> is <code>true</code>, else throw <code>TestCanceledException</code>.
227+
*
228+
* @param bool the <code>Bool</code> to assume for
229+
* @param clue optional clue to be included in <code>TestCanceledException</code>'s error message when assertion failed
230+
*/
231+
def macroAssume(bool: Bool, clue: Any, prettifier: Prettifier, pos: source.Position): Assertion = {
232+
requireNonNull(clue)(prettifier, pos)
233+
if (!bool.value) {
234+
val failureMessage = if (Bool.isSimpleWithoutExpressionText(bool)) None else Some(bool.failureMessage)
235+
throw newTestCanceledException(append(failureMessage, clue), None, pos)
236+
}
237+
Succeeded
238+
}
239+
}
240+
241+
/**
242+
* Helper instance used by code generated by macro assertion.
243+
*/
244+
val assertionsHelper = new AssertionsHelper
245+
246+
}

0 commit comments

Comments
 (0)