Dagens kata
This commit is contained in:
@@ -0,0 +1,10 @@
|
||||
package data;
|
||||
|
||||
/**
|
||||
* Implementation omitted, we use test doubles for testing
|
||||
*/
|
||||
public abstract class ColumnStorage implements Storage {
|
||||
|
||||
abstract public void dump();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package data;
|
||||
|
||||
import tree.Visitor;
|
||||
|
||||
public class LoadVisitor implements Visitor {
|
||||
|
||||
@Override
|
||||
public void handle(Session session) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(Partition partition) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(Storage storage) {
|
||||
storage.load();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package data;
|
||||
|
||||
import java.io.PrintStream;
|
||||
|
||||
public class Logging {
|
||||
|
||||
public static PrintStream out;
|
||||
|
||||
}
|
||||
107
RefactorToVisitorPatternKata/src/main/java/data/Partition.java
Normal file
107
RefactorToVisitorPatternKata/src/main/java/data/Partition.java
Normal file
@@ -0,0 +1,107 @@
|
||||
package data;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import tree.Visitable;
|
||||
import tree.Visitor;
|
||||
|
||||
public class Partition implements Visitable {
|
||||
|
||||
private String name;
|
||||
private List<Storage> storages;
|
||||
private List<Partition> partitions;
|
||||
|
||||
public Partition(String name, List<Partition> partitions,
|
||||
List<Storage> storages) {
|
||||
this.partitions = partitions;
|
||||
this.storages = storages;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Partition(String name) {
|
||||
this(name, new ArrayList<Partition>(), new ArrayList<Storage>());
|
||||
}
|
||||
|
||||
public void addPartition(Partition partition) {
|
||||
partitions.add(partition);
|
||||
}
|
||||
|
||||
public void addStorage(Storage storage) {
|
||||
storages.add(storage);
|
||||
}
|
||||
|
||||
public void printInfo() {
|
||||
Logging.out.println("Partition: " + name);
|
||||
for (Partition p : partitions) {
|
||||
p.printInfo();
|
||||
}
|
||||
for (Storage s : storages) {
|
||||
if (s instanceof TableStorage) {
|
||||
((TableStorage) s).printout();
|
||||
}
|
||||
if (s instanceof ColumnStorage) {
|
||||
((ColumnStorage) s).dump();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void load() { // Visitor
|
||||
// Visitor visitor = new LoadVisitor();
|
||||
// accept(visitor);
|
||||
// return visitor;
|
||||
}
|
||||
|
||||
public void refresh() {
|
||||
for (Partition p : partitions) {
|
||||
p.refresh();
|
||||
}
|
||||
for (Storage s : storages) {
|
||||
if (s instanceof TableStorage) {
|
||||
((TableStorage) s).refresh();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int getSize() {
|
||||
int total_size = 0;
|
||||
for (Partition p : partitions) {
|
||||
total_size += p.getSize();
|
||||
}
|
||||
for (Storage s : storages) {
|
||||
total_size += s.getSize();
|
||||
}
|
||||
return total_size;
|
||||
}
|
||||
|
||||
public int getLatestCommitId() {
|
||||
int latestCommitId = 0;
|
||||
for (Partition p : partitions) {
|
||||
int partitionCommitId = p.getLatestCommitId();
|
||||
if (partitionCommitId > latestCommitId) {
|
||||
latestCommitId = partitionCommitId;
|
||||
}
|
||||
}
|
||||
for (Storage s : storages) {
|
||||
if (s instanceof TableStorage) {
|
||||
int storageCommitId = ((TableStorage) s).getLatestCommitId();
|
||||
if (storageCommitId > latestCommitId) {
|
||||
latestCommitId = storageCommitId;
|
||||
}
|
||||
}
|
||||
}
|
||||
return latestCommitId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(Visitor visitor) {
|
||||
visitor.handle(this);
|
||||
|
||||
for (Partition p : partitions) {
|
||||
p.accept(visitor);
|
||||
}
|
||||
for (Storage s : storages) {
|
||||
s.accept(visitor);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package data;
|
||||
|
||||
import tree.Visitor;
|
||||
|
||||
public class RefreshVisitor implements Visitor {
|
||||
|
||||
@Override
|
||||
public void handle(Session session) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(Partition partition) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new RuntimeException();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(Storage storage) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new RuntimeException();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
65
RefactorToVisitorPatternKata/src/main/java/data/Session.java
Normal file
65
RefactorToVisitorPatternKata/src/main/java/data/Session.java
Normal file
@@ -0,0 +1,65 @@
|
||||
package data;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import tree.Visitable;
|
||||
import tree.Visitor;
|
||||
|
||||
public class Session implements Visitable {
|
||||
|
||||
private List<Partition> partitions = new ArrayList<>();
|
||||
|
||||
public void addPartition(Partition partition) {
|
||||
partitions.add(partition);
|
||||
}
|
||||
|
||||
public void printInfo() {
|
||||
Logging.out.println("Session:");
|
||||
for (Partition p : partitions) {
|
||||
p.printInfo();
|
||||
}
|
||||
}
|
||||
|
||||
public Session load() {
|
||||
Visitor visitor = new LoadVisitor();
|
||||
accept(visitor);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Session refresh() {
|
||||
// for (Partition p : partitions) {
|
||||
// p.refresh();
|
||||
// }
|
||||
Visitor visitor = new RefreshVisitor();
|
||||
return this;
|
||||
}
|
||||
|
||||
public int getLatestCommitId() {
|
||||
int latestCommitId = 0;
|
||||
for (Partition p : partitions) {
|
||||
int partitionCommitId = p.getLatestCommitId();
|
||||
if (partitionCommitId > latestCommitId) {
|
||||
latestCommitId = partitionCommitId;
|
||||
}
|
||||
}
|
||||
return latestCommitId;
|
||||
}
|
||||
|
||||
public int getSize() {
|
||||
int totalSize = 0;
|
||||
for (Partition p : partitions) {
|
||||
totalSize += p.getSize();
|
||||
}
|
||||
return totalSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(Visitor visitor) {
|
||||
visitor.handle(this);
|
||||
|
||||
for (Partition p : partitions) {
|
||||
p.accept(visitor);
|
||||
}
|
||||
}
|
||||
}
|
||||
11
RefactorToVisitorPatternKata/src/main/java/data/Storage.java
Normal file
11
RefactorToVisitorPatternKata/src/main/java/data/Storage.java
Normal file
@@ -0,0 +1,11 @@
|
||||
package data;
|
||||
|
||||
import tree.Visitable;
|
||||
|
||||
public interface Storage extends Visitable {
|
||||
|
||||
int getSize();
|
||||
|
||||
void load();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package data;
|
||||
|
||||
/**
|
||||
* Implementation omitted, we use test doubles for testing
|
||||
*/
|
||||
public abstract class TableStorage implements Storage {
|
||||
|
||||
abstract public int getSize();
|
||||
|
||||
abstract public int getLatestCommitId();
|
||||
|
||||
abstract public void printout();
|
||||
|
||||
abstract public void load();
|
||||
|
||||
abstract public void refresh();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package tree;
|
||||
|
||||
public interface Visitable {
|
||||
void accept (Visitor visitor);
|
||||
|
||||
}
|
||||
13
RefactorToVisitorPatternKata/src/main/java/tree/Visitor.java
Normal file
13
RefactorToVisitorPatternKata/src/main/java/tree/Visitor.java
Normal file
@@ -0,0 +1,13 @@
|
||||
package tree;
|
||||
|
||||
import data.Partition;
|
||||
import data.Session;
|
||||
import data.Storage;
|
||||
|
||||
public interface Visitor {
|
||||
void handle (Session session);
|
||||
|
||||
void handle (Partition partition);
|
||||
|
||||
void handle (Storage storage);
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package data;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import tree.Visitor;
|
||||
|
||||
public class ColumnStorageFake extends ColumnStorage {
|
||||
|
||||
private String name;
|
||||
private int size = 0;
|
||||
private static final Map<String, Integer> _mock_data;
|
||||
|
||||
static {
|
||||
_mock_data = new HashMap<>();
|
||||
_mock_data.put("JSON storage 1", 6645);
|
||||
_mock_data.put("JSON storage 2", 321);
|
||||
_mock_data.put("JSON storage 3", 566);
|
||||
}
|
||||
|
||||
public ColumnStorageFake(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public void dump() {
|
||||
Logging.out.println("ColumnStorage: " + name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load() {
|
||||
if (_mock_data.containsKey(name)) {
|
||||
size = _mock_data.get(name);
|
||||
} else {
|
||||
size = -1;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(Visitor visitor) {
|
||||
visitor.handle(this);
|
||||
}
|
||||
|
||||
}
|
||||
27
RefactorToVisitorPatternKata/src/test/java/data/FakeOut.java
Normal file
27
RefactorToVisitorPatternKata/src/test/java/data/FakeOut.java
Normal file
@@ -0,0 +1,27 @@
|
||||
package data;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
public class FakeOut extends PrintStream {
|
||||
|
||||
private StringBuffer sb = new StringBuffer();
|
||||
|
||||
public FakeOut(OutputStream out) {
|
||||
super(out);
|
||||
}
|
||||
|
||||
public FakeOut() throws FileNotFoundException, IOException {
|
||||
super((OutputStream) new FileOutputStream(File.createTempFile("fake", "out")));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void println(String x) {
|
||||
sb.append(x);
|
||||
sb.append("\n");
|
||||
}
|
||||
|
||||
public String getOut() {
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package data;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class FakeOutTest {
|
||||
|
||||
@Test
|
||||
public void simpleFlow() throws Exception {
|
||||
FakeOut f = new FakeOut();
|
||||
f.println("Hello");
|
||||
f.println("World");
|
||||
assertEquals("Hello\nWorld\n", f.getOut());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
package data;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class FullSystemTest {
|
||||
|
||||
private Session session;
|
||||
private static final int size_after_load = 46544 + 344 + 465 + 6645 + 321 + 566;
|
||||
private static final int size_after_refreshes = 51345 + 545 + 513 + 6645 + 321 + 566;
|
||||
|
||||
@Before
|
||||
public void setup() throws Exception {
|
||||
Logging.out = new FakeOut();
|
||||
|
||||
this.session = new Session();
|
||||
Partition p1 = new Partition("partition 1");
|
||||
p1.addStorage(new TableStorageFake("SQL storage 1"));
|
||||
p1.addStorage(new ColumnStorageFake("JSON storage 1"));
|
||||
session.addPartition(p1);
|
||||
|
||||
Partition p2 = new Partition("partition 2");
|
||||
p2.addStorage(new TableStorageFake("SQL storage 2"));
|
||||
session.addPartition(p2);
|
||||
|
||||
Partition p3 = new Partition("partition 3");
|
||||
p3.addStorage(new TableStorageFake("SQL storage 3"));
|
||||
p3.addStorage(new ColumnStorageFake("JSON storage 2"));
|
||||
p3.addStorage(new ColumnStorageFake("JSON storage 3"));
|
||||
p2.addPartition(p3);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initialCommitIdIsZero() throws Exception {
|
||||
assertEquals(0, session.getLatestCommitId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void commitIdIs125AfterLoad() throws Exception {
|
||||
session.load();
|
||||
assertEquals(125, session.getLatestCommitId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void commitIdAfterTwoRefreshesIs137() throws Exception {
|
||||
session.load();
|
||||
session.refresh();
|
||||
session.refresh();
|
||||
assertEquals(137, session.getLatestCommitId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initialSizeIsZero() throws Exception {
|
||||
assertEquals(0, session.getSize());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sizeAfterLoadIs_MagicNumber() throws Exception {
|
||||
session.load();
|
||||
assertEquals(size_after_load, session.getSize());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sizeAfterTwoRefreshesIs_MagicNumber() throws Exception {
|
||||
session.load().refresh().refresh();
|
||||
assertEquals(size_after_refreshes, session.getSize());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void printSession() throws Exception {
|
||||
session.printInfo();
|
||||
String actual = ((FakeOut) Logging.out).getOut();
|
||||
String expected = "Session:\n" +
|
||||
"Partition: partition 1\n" +
|
||||
"TableStorage: SQL storage 1\n" +
|
||||
"ColumnStorage: JSON storage 1\n" +
|
||||
"Partition: partition 2\n" +
|
||||
"Partition: partition 3\n" +
|
||||
"TableStorage: SQL storage 3\n" +
|
||||
"ColumnStorage: JSON storage 2\n" +
|
||||
"ColumnStorage: JSON storage 3\n" +
|
||||
"TableStorage: SQL storage 2\n";
|
||||
assertEquals(expected, actual);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
package data;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import tree.Visitable;
|
||||
import tree.Visitor;
|
||||
|
||||
public class TableStorageFake extends TableStorage implements Visitable {
|
||||
|
||||
private static final Map<String, Map<String, List<Integer>>> _mock_data;
|
||||
|
||||
static {
|
||||
_mock_data = new HashMap<>();
|
||||
_mock_data.put("SQL storage 1",
|
||||
m("cids", "0, 123, 126, 134, 156, 158",
|
||||
"sizes", "0, 46544, 50444, 51345, 52333, 55991"));
|
||||
_mock_data.put("SQL storage 2",
|
||||
m("cids", "0, 125, 133, 134, 143, 155",
|
||||
"sizes", "0, 344, 544, 545, 633, 791"));
|
||||
_mock_data.put("SQL storage 3",
|
||||
m("cids", "0, 124, 127, 137, 177, 199",
|
||||
"sizes", "0, 465, 504, 513, 523, 559"));
|
||||
}
|
||||
|
||||
private String name;
|
||||
private int mockDataIndex = 0;
|
||||
|
||||
public TableStorageFake(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void printout() {
|
||||
Logging.out.println("TableStorage: " + name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSize() {
|
||||
// return DaveStorageMock._mock_data[name]["sizes"][index]
|
||||
return _mock_data.get(name).get("sizes").get(mockDataIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLatestCommitId() {
|
||||
// return DaveStorageMock._mock_data[name]["cids"][index]
|
||||
return _mock_data.get(name).get("cids").get(mockDataIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load() {
|
||||
this.mockDataIndex = 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refresh() {
|
||||
this.mockDataIndex++;
|
||||
if (this.mockDataIndex > _mock_data.get(name).get("cids").size()) {
|
||||
throw new IllegalStateException("out of mock data!");
|
||||
}
|
||||
}
|
||||
|
||||
// this is soo ugly
|
||||
private static Map<String, List<Integer>> m(Object... args) {
|
||||
Map<String, List<Integer>> map = new HashMap<>();
|
||||
for (int index = 0; index < args.length; index = index + 2) {
|
||||
String key = (String) args[index];
|
||||
List<Integer> values = new ArrayList<Integer>();
|
||||
for (String n : ((String) args[index + 1]).split(",")) {
|
||||
values.add(new Integer(n.trim()));
|
||||
}
|
||||
map.put(key, values);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept (Visitor visitor) {
|
||||
visitor.handle(this);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user