Skip to content

Commit 05fdac1

Browse files
committed
Merge pull request #8 from xdotai/chris
1.0.1
2 parents 59718e3 + dddd74b commit 05fdac1

File tree

5 files changed

+67
-15
lines changed

5 files changed

+67
-15
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@ Be aware: Collections (List, Seq, etc.) are compared like sets, i.e. ignoring or
88

99
### SBT Dependency
1010

11-
`"ai.x" %% "diff" % "1.0"`
11+
`"ai.x" %% "diff" % "1.0.1"`
1212

1313
### Usage
1414

1515
```scala
16-
println( ai.x.diff.DiffShow.diff( before, after ).string )
16+
println( ai.x.diff.DiffShow.diff[Foo]( before, after ).string )
1717
```
1818

1919
#### Output

TODO.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
21
Loose TODO:
32

3+
- remove fallback implicit and make sure tests pass
4+
- allow to always show certain fields for selected types even if unchanged in order to see relevant context
45
- replace many of the manual type classes with shapeless type class derivation
56
- introduce intermediate representation to allow alternative String renderings and allow easy testability of added/removed
67
- split Show and Diff

build/build.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import scala.collection.immutable.Seq
77
class Build(context: cbt.Context) extends cbt.PublishBuild(context){
88
override def defaultScalaVersion = "2.11.8"
99

10-
override def defaultVersion = "1.0"
10+
override def defaultVersion = "1.0.1"
1111
override def artifactId = "diff"
1212
override def groupId = "ai.x"
1313

diff.scala

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,6 @@ object `package` {
1010
def arrow( l: String, r: String ) = l + " -> " + r
1111
def showChange( l: String, r: String ) = red( l ) + " -> " + green( r )
1212
}
13-
/*
14-
Loose TODO:
15-
- replace many of the manual type classes with shapeless type class derivation
16-
- introduce intermediate representation to allow alternative String renderings and allow easy testability of added/removed
17-
- split Show and Diff
18-
*/
1913

2014
abstract class Comparison {
2115
def string: String
@@ -25,15 +19,18 @@ abstract class Comparison {
2519
case Identical( s ) => create( s )
2620
case c: Different => c
2721
}
22+
def isIdentical: Boolean
2823
}
2924
case class Identical( string: String ) extends Comparison {
3025
def create( s: String ) = Identical( s )
26+
override def isIdentical = true
3127
}
3228
object Identical {
3329
def apply[T: DiffShow]( value: T ): Identical = Identical( DiffShow.show( value ) )
3430
}
3531
case class Different( string: String ) extends Comparison {
3632
def create( s: String ) = Different( s )
33+
override def isIdentical = false
3734
}
3835
object Different {
3936
def apply[T: DiffShow]( left: T, right: T ): Different = Different( DiffShow.show( left ), DiffShow.show( right ) )
@@ -43,7 +40,7 @@ object Different {
4340
abstract class DiffShow[-T] { // contra-variant to allow Seq type class for List
4441
def show( t: T ): String
4542
def diff( left: T, right: T ): Comparison
46-
def diffable( left: T, right: T ) = show( left ) == show( right )
43+
def diffable( left: T, right: T ) = diff(left, right).isIdentical
4744
}
4845
object DiffShow extends DiffShowInstances {
4946
def apply[T]( implicit diffShow: DiffShow[T] ) = diffShow
@@ -54,7 +51,6 @@ object DiffShow extends DiffShowInstances {
5451
abstract class DiffShowFields[-T] { // contra-variant to allow Seq type class for List
5552
def show( t: T ): Map[String, String]
5653
def diff( left: T, right: T ): Map[String, Comparison]
57-
def diffable( left: T, right: T ) = show( left ) == show( right )
5854
}
5955

6056
abstract class DiffShowFieldsLowPriority {

test/Main.scala

Lines changed: 58 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,64 @@
11
import ai.x.diff._
22
import scala.collection.immutable.SortedMap
3+
sealed trait Parent
4+
case class Bar( s: String, i: Int ) extends Parent
5+
case class Foo( bar: Bar, b: List[Int], parent: Option[Parent] ) extends Parent
6+
7+
case class Id(int: Int)
8+
case class Row(id: Id, value: String)
39
object Main extends App {
4-
sealed trait Parent
5-
case class Bar( s: String, i: Int ) extends Parent
6-
case class Foo( bar: Bar, b: List[Int], parent: Option[Parent] ) extends Parent
10+
val bar = Bar("test",1)
11+
val barAsParent: Parent = bar
12+
val foo = Foo( bar, Nil, None )
13+
val fooAsParent: Parent = foo
14+
15+
assert( DiffShow.diff( bar, bar ).isIdentical )
16+
assert( DiffShow.diff( barAsParent, barAsParent ).isIdentical )
17+
assert( DiffShow.diff( bar, barAsParent ).isIdentical )
18+
assert( DiffShow.diff( barAsParent, bar ).isIdentical )
19+
assert( DiffShow.diff( foo, foo ).isIdentical )
20+
assert( DiffShow.diff( foo, fooAsParent ).isIdentical )
21+
assert( DiffShow.diff( fooAsParent, foo ).isIdentical )
22+
assert( DiffShow.diff( fooAsParent, fooAsParent ).isIdentical )
23+
24+
assert( !DiffShow.diff[Parent]( bar, foo ).isIdentical )
25+
assert( !DiffShow.diff( bar, fooAsParent ).isIdentical )
26+
assert( !DiffShow.diff( barAsParent, foo ).isIdentical )
27+
assert( !DiffShow.diff( barAsParent, fooAsParent ).isIdentical )
28+
29+
assert( DiffShow.diff( Seq(bar), Seq(bar) ).isIdentical )
30+
// Seqs are compared as Sets
31+
assert( DiffShow.diff( Seq(bar), Seq(bar,bar) ).isIdentical )
732

33+
assert( !DiffShow.diff[Seq[Parent]]( Seq(foo,bar), Seq(bar) ).isIdentical )
34+
assert( !DiffShow.diff[Seq[Parent]]( Seq(foo), Seq(bar) ).isIdentical )
35+
36+
def ignore[T] = new DiffShow[T] {
37+
def show( t: T ) = t.toString
38+
def diff( left: T, right: T ) = Identical( "<not compared>" )
39+
override def diffable( left: T, right: T ) = true
40+
}
41+
42+
{
43+
implicit val ignoreId = ignore[Id]
44+
assert( DiffShow.diff( Id(1), Id(1) ).isIdentical )
45+
assert( DiffShow.diff( Id(1), Id(2) ).isIdentical )
46+
47+
val rowA = Row(Id(1),"foo")
48+
val rowB = Row(Id(2),"foo")
49+
assert( DiffShow.diff( rowA, rowB ).isIdentical )
50+
assert( DiffShow.diff( Seq(rowA), Seq(rowB) ).isIdentical )
51+
}
52+
53+
assert( DiffShow.diff( Id(1), Id(1) ).isIdentical )
54+
assert( !DiffShow.diff( Id(1), Id(2) ).isIdentical )
55+
56+
val rowA = Row(Id(1),"foo")
57+
val rowB = Row(Id(2),"foo")
58+
assert( !DiffShow.diff( rowA, rowB ).isIdentical )
59+
assert( !DiffShow.diff( Seq(rowA), Seq(rowB) ).isIdentical )
60+
61+
/*
862
val before: Foo = Foo(
963
Bar( "asdf", 5 ),
1064
List( 123, 1234 ),
@@ -19,6 +73,7 @@ object Main extends App {
1973
println(
2074
DiffShow.diff( before, after ).string
2175
)
76+
*/
2277

2378
{
2479
implicit def StringDiffShow = new DiffShow[String] {

0 commit comments

Comments
 (0)