Reputation: 879
I am taking the Coursera course Functional Programming in Scala. If you have qualms about providing the solutions to problems, this does not pertain directly to the assignment.
I am finding myself frequently unclear about what is happening. So, I use tests to gain insight. In the assignment for the current week a set of tests are included. In the suite of tests a couple functions are defined - size and asSet, the latter of which converts a TweetSet to Set[Tweet]. I created tests for both. The size tests work just fine. The asSet works for the empty set, but it fails with a set of one element. The output message sure makes it seem like what I have done is correct, so I have no idea at present what is wrong.
The result message is:
org.scalatest.exceptions.TestFailedException: Set(User: a
Text: a body [20]) did not equal Set(User: a
Text: a body [20])
As you can see, it states that the result is equal to the expect. Here is the failing test:
test("asSet: on singleton set") {
new TestSets {
assert(asSet(set2) === Set[Tweet](new Tweet("a", "a body", 20)))
}
}
The function is defined as follows (this was provided in the course materials):
def asSet(tweets: TweetSet): Set[Tweet] = {
var res = Set[Tweet]()
tweets.foreach(res += _)
res
}
The definition of set2 as follows (again, provided):
val set1 = new Empty
val set2 = set1.incl(new Tweet("a", "a body", 20))
Tweet is defined as follows:
class Tweet(val user: String, val text: String, val retweets: Int) {
override def toString: String =
"User: " + user + "\n" +
"Text: " + text + " [" + retweets + "]"
}
What am I missing such that this test is failing though looks like it should be passing?
Upvotes: 2
Views: 1702
Reputation: 22206
I believe your problem is that in the assignment you are manually developing an implementation of Set
, whereas on the other hand you used Scala's internal Set
type to compare it to; i.e. you are comparing two instances of different types.
I believe the right-hand side of this line creates a scala.collection.immutable.Set
assert(asSet(set2) === Set[Tweet](new Tweet("a", "a body", 20)))
Upvotes: 0
Reputation: 10904
Your test fails because of the way hashCode is implemented.
The basic source of your error As you have implemented Tweet every instance is different, even if it contains the same information.
scala> val x= Set(new Tweet( "me", "test message", 1),new Tweet( "me", "test message", 1) )
x: scala.collection.immutable.Set[Tweet] =
Set(User: me
Text: test message [1 ],
User: me
Text: test message [1 ])
scala> x.size
res3: Int = 2
How this methods are implemented differs with classes and case classes.
Example
with normal class
class Tweet(val user: String, val text: String, val retweets: Int) {
override def toString: String =
s"""User: $user
|Text: $text [$retweets ]""".stripMargin
}
scala> val x = new Tweet( "me", "test message", 1)
x: Tweet =
User: me
Text: test message [1 ]
scala> x == x
res0: Boolean = true
scala> x == new Tweet( "me", "test message", 1)
res1: Boolean = false
with case class
case class Tweet(val user: String, val text: String, val retweets: Int) {
override def toString: String =
s"""User: $user
|Text: $text [$retweets ]""".stripMargin
}
scala> val x = new Tweet( "me", "test message", 1)
x: Tweet =
User: me
Text: test message [1 ]
scala> x == x
res2: Boolean = true
scala> x == new Tweet( "me", "test message", 1)
res3: Boolean = true
scala> (new Tweet( "me", "test message", 1)).hashCode
res6: Int = -1967705983
scala> (new Tweet( "me", "test message", 1)).hashCode
res7: Int = -1967705983
Upvotes: 1