Skip to content

Commit

Permalink
updating code coverage
Browse files Browse the repository at this point in the history
  • Loading branch information
moaxcp committed Jun 27, 2018
1 parent 576a4fd commit 9919f1e
Show file tree
Hide file tree
Showing 13 changed files with 283 additions and 79 deletions.
13 changes: 7 additions & 6 deletions MakeImages.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -180,34 +180,35 @@ def exampleClassifyEdges() {
}
snapshot()
classifyEdges('A') {Object from, Object to, EdgeType type ->
vertex(from).fillcolor = 'green'
vertex(from).style = 'filled'
vertex(to).fillcolor = 'green'
vertex(to).style = 'filled'
edge(from, to) {
switch(type) {
case EdgeType.TREE_EDGE:
color = 'black'
color = 'green'
snapshot()
label = 'tree'
break
case EdgeType.BACK_EDGE:
color = 'red'
snapshot()
label = 'back'
break
case EdgeType.FORWARD_EDGE:
color = 'grey'
snapshot()
label = 'forward'
break
case EdgeType.CROSS_EDGE:
color = 'blue'
snapshot()
label = 'cross'
break
}
}
snapshot()
CONTINUE
}
gif 'images/edge-classification.gif'
snapshot(4)
gif 'images/edge-classification.gif', 500
}
}

Expand Down
108 changes: 56 additions & 52 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -215,54 +215,54 @@ arguments can be used to modify the graph. In this example the edges are colored
```groovy
type 'directed-graph'
type 'directed-graph'
plugin 'graphviz'
vertex('A') {
connectsTo('B') {
connectsTo 'C'
connectsTo('D') {
connectsTo 'A'
connectsFrom 'A'
connectsTo 'C'
connectsTo 'E'
}
}
}
vertex('F') {
connectsTo('G') {
connectsTo 'D'
}
plugin 'graphviz'
vertex('A') {
connectsTo('B') {
connectsTo 'C'
connectsTo('D') {
connectsTo 'A'
connectsFrom 'A'
connectsTo 'C'
connectsTo 'E'
}
snapshot()
classifyEdges('A') {Object from, Object to, EdgeType type ->
vertex(from).fillcolor = 'green'
vertex(from).style = 'filled'
vertex(to).fillcolor = 'green'
vertex(to).style = 'filled'
edge(from, to) {
switch(type) {
case EdgeType.TREE_EDGE:
color = 'black'
label = 'tree'
break
case EdgeType.BACK_EDGE:
color = 'red'
label = 'back'
break
case EdgeType.FORWARD_EDGE:
color = 'grey'
label = 'forward'
break
case EdgeType.CROSS_EDGE:
color = 'blue'
label = 'cross'
break
}
}
snapshot()
CONTINUE
}
}
vertex('F') {
connectsTo('G') {
connectsTo 'D'
}
}
snapshot()
classifyEdges('A') {Object from, Object to, EdgeType type ->
edge(from, to) {
switch(type) {
case EdgeType.TREE_EDGE:
color = 'green'
snapshot()
label = 'tree'
break
case EdgeType.BACK_EDGE:
color = 'red'
snapshot()
label = 'back'
break
case EdgeType.FORWARD_EDGE:
color = 'grey'
snapshot()
label = 'forward'
break
case EdgeType.CROSS_EDGE:
color = 'blue'
snapshot()
label = 'cross'
break
}
gif 'images/edge-classification.gif'
}
snapshot()
CONTINUE
}
snapshot(4)
gif 'images/edge-classification.gif', 500
```

![Image](images/edge-classification.gif?raw=true)
Expand All @@ -273,6 +273,7 @@ Connected component visits each vertex supplying the root vertex for the compone
root vertex key and the current vertex.

```groovy
plugin 'graphviz'
vertex('A') {
connectsTo('B') {
connectsTo 'C'
Expand All @@ -291,13 +292,14 @@ vertex('Z') {
vertex 'J'
def colors = ['A':'yellow', 'Z':'green', J:'blue']
snapshot()
connectedComponent('A') { root, vertex ->
vertex.fillcolor = colors[(root)]
vertex.style = 'filled'
TraversalState.CONTINUE
snapshot()
CONTINUE
}
plugin 'graphviz'
image 'images/connected-component-undirected.png'
gif 'images/connected-component-undirected.gif'
```

![Image](images/connected-component-undirected.gif?raw=true)
Expand All @@ -306,6 +308,7 @@ image 'images/connected-component-undirected.png'

```groovy
type 'directed-graph'
plugin 'graphviz'
vertex('A') {
connectsTo('B') {
connectsTo 'C'
Expand All @@ -323,13 +326,14 @@ vertex('Z') {
}
vertex 'J'
def colors = ['A': 'yellow', 'Z': 'green', J: 'blue']
snapshot()
connectedComponent('A') { root, vertex ->
vertex.fillcolor = colors[(root)]
vertex.style = 'filled'
TraversalState.CONTINUE
snapshot()
CONTINUE
}
plugin 'graphviz'
image 'images/connected-component-directed.png'
gif 'images/connected-component-directed.gif'
```

![Image](images/connected-component-directed.gif?raw=true)
Expand Down
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -194,5 +194,5 @@ dependencies {
testCompile "org.codehaus.groovy:groovy-all:$groovyVersion"
testCompile 'cglib:cglib-nodep:3.2.6'

testCompile 'org.hamcrest:hamcrest-all:1.3'
testCompile 'org.hamcrest:java-hamcrest:2.0.0.0'
}
Binary file modified images/breadth-first-traversal.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified images/connected-component-directed.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified images/connected-component-undirected.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified images/edge-classification.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified images/post-order-traversal.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified images/pre-order-traversal.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified images/reverse-post-order-traversal.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
68 changes: 48 additions & 20 deletions src/main/groovy/graph/plugin/GraphViz.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -115,38 +115,66 @@ class GraphViz implements Plugin {
return [image:image, error:err.toString()]
}

void snapshot() {
snapshots.add(image().image)
void snapshot(int count = 1) {
(0..count).each {
snapshots.add(image().image)
}
}

void gif(String file, int delay = 1000, boolean loop = true) throws IOException {
int width = 0
int height = 0
snapshots.each {
width = it.width > width ? it.width : width
height = it.height > height ? it.height : height
}
Map<String, Integer> max = findMaxWidthHeight()
List<BufferedImage> resized = snapshots.collect {
int x = (width - it.width) / 2
int y = (height - it.height) / 2
BufferedImage out = new BufferedImage(width, height, it.type)
Graphics2D g2d = out.createGraphics()
def b = it.getRGB(0, 0)
g2d.setBackground(new Color(b))
g2d.clearRect(0, 0, width, height)
g2d.drawImage(it, x, y, it.width, it.height, null)
g2d.dispose()
out
int b = guessBackgroundColor(it)
BufferedImage out = createOutputImage(b, max.width, max.height, it.type)
centerOnOutput(out, it)
}
new FileImageOutputStream(new File(file)).withCloseable { out ->
writeImagesToFileAsGif(new File(file), resized, delay, loop)
}

void writeImagesToFileAsGif(File file, List<BufferedImage> images, int delay, boolean loop) {
new FileImageOutputStream(file).withCloseable { out ->
GifSequenceWriter writer = new GifSequenceWriter(out, BufferedImage.TYPE_3BYTE_BGR, delay, loop)
resized.each {
images.each {
writer.writeToSequence(it)
}
writer.close()
}
}

BufferedImage centerOnOutput(BufferedImage output, BufferedImage image) {
int x = (output.width - image.width) / 2
int y = (output.height - image.height) / 2
Graphics2D g2d = output.createGraphics()
g2d.drawImage(image, x, y, image.width, image.height, null)
g2d.dispose()
output
}

BufferedImage createOutputImage(int background, int width, int height, int type) {
BufferedImage out = new BufferedImage(width, height, type)
Graphics2D g2d = out.createGraphics()
g2d.setBackground(new Color(background))
g2d.clearRect(0, 0, width, height)
g2d.dispose()
out

}

int guessBackgroundColor(BufferedImage image) {
image.getRGB(0, 0)
}

Map<String, Integer> findMaxWidthHeight() {
Map<String, Integer> max = [:]
max.width = 0
max.height = 0
snapshots.each {
max.width = it.width > max.width ? it.width : max.width
max.height = it.height > max.height ? it.height : max.height
}
max
}

void image(String file) {
new File(file).withOutputStream { out ->
ImageIO.write(image().image, 'PNG', out)
Expand Down
88 changes: 88 additions & 0 deletions src/test/groovy/api/graphviz/GraphVizSpec.groovy
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
package api.graphviz

import graph.Graph
import graph.plugin.GraphViz
import spock.lang.Specification

import java.awt.Color
import java.awt.Graphics2D
import java.awt.image.BufferedImage
import java.nio.file.Files
import java.nio.file.Path
import static org.junit.Assert.*
import static graph.ImageMatcher.*

class GraphVizSpec extends Specification {
Graph graph = new Graph()
Expand Down Expand Up @@ -134,4 +140,86 @@ class GraphVizSpec extends Specification {
'''.stripIndent().trim() == file.text
Files.delete(file)
}

def 'centerOnOutput centers the image'() {
given: '200x200 black out image'
BufferedImage output = new BufferedImage(200, 200, BufferedImage.TYPE_4BYTE_ABGR)
Graphics2D outg = output.createGraphics()
outg.setColor(Color.BLACK)
outg.fillRect(0, 0, output.width, output.height)
outg.dispose()

and: '150x75 white image'
BufferedImage image = new BufferedImage(150, 100, BufferedImage.TYPE_4BYTE_ABGR)
Graphics2D imageg = image.createGraphics()
imageg.setColor(Color.WHITE)
imageg.fillRect(0, 0, image.width, image.height)
imageg.dispose()

when: 'image is centered on out image'
GraphViz plugin = new GraphViz()
BufferedImage result = plugin.centerOnOutput(output, image)

then: 'result shows image centered'
BufferedImage expected = new BufferedImage( 200, 200, BufferedImage.TYPE_4BYTE_ABGR)
Graphics2D expectedg = expected.createGraphics()
expectedg.setColor(Color.BLACK)
expectedg.fillRect(0, 0, 200, 200)
expectedg.setColor(Color.WHITE)
int x = (output.width - image.width) / 2
int y = (output.height - image.height) / 2
expectedg.fillRect(x, y, 150, 100)
expectedg.dispose()

assertThat(result, contentEqualTo(expected))
}

def 'guess background color'() {
given: '200x200 black image'
BufferedImage image = new BufferedImage(200, 200, BufferedImage.TYPE_4BYTE_ABGR)
Graphics2D g = image.createGraphics()
g.setColor(Color.BLACK)
g.fillRect(0, 0, image.width, image.height)
g.dispose()

when: 'background color is guessed'
GraphViz plugin = new GraphViz()
int color = plugin.guessBackgroundColor(image)

then: 'background was black'
color == Color.BLACK.getRGB()
}

def 'can create output image'() {
given: 'specification for a 200x200 black image'
int background = Color.BLACK.getRGB()
int width = 200
int height = 200
int type = BufferedImage.TYPE_4BYTE_ABGR

when: 'image is created'
GraphViz plugin = new GraphViz()
BufferedImage image = plugin.createOutputImage(background, width, height, type)

then: 'image matches specification'
width == image.width
height == image.height
type == image.type
background == image.getRGB(0, 0)
}

def 'can find max width and height of snapshots'() {
given: 'snapshots of different sizes'
GraphViz plugin = new GraphViz()
plugin.snapshots.add(new BufferedImage(200, 220, BufferedImage.TYPE_4BYTE_ABGR))
plugin.snapshots.add(new BufferedImage(210, 300, BufferedImage.TYPE_4BYTE_ABGR))
plugin.snapshots.add(new BufferedImage(150, 200, BufferedImage.TYPE_4BYTE_ABGR))

when: 'plugin finds max width and height'
Map<String, Integer> result = plugin.findMaxWidthHeight()

then: 'expected width and height is returned'
result.width == 210
result.height == 300
}
}
Loading

0 comments on commit 9919f1e

Please sign in to comment.