Commit ea3b85f26e6c9c47e4989bfdf16ee0c929fd1706

Authored by eishchuk
0 parents

Initial commit

.gitignore 0 → 100644
  1 +++ a/.gitignore
@@ -0,0 +1,73 @@ @@ -0,0 +1,73 @@
  1 +.classpath
  2 +.project
  3 +.settings
  4 +.idea
  5 +.metadata
  6 +*.iml
  7 +*.ipr
  8 +kong-stack.retry
  9 +target
  10 +.factorypath
  11 +
  12 +#
  13 +# NodeJS
  14 +#
  15 +
  16 +# Logs
  17 +logs
  18 +*.log
  19 +npm-debug.log*
  20 +yarn-debug.log*
  21 +yarn-error.log*
  22 +
  23 +# Runtime data
  24 +pids
  25 +*.pid
  26 +*.seed
  27 +*.pid.lock
  28 +
  29 +# Directory for instrumented libs generated by jscoverage/JSCover
  30 +lib-cov
  31 +
  32 +# Coverage directory used by tools like istanbul
  33 +coverage
  34 +
  35 +# nyc test coverage
  36 +.nyc_output
  37 +
  38 +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
  39 +.grunt
  40 +
  41 +# Bower dependency directory (https://bower.io/)
  42 +bower_components
  43 +
  44 +# node-waf configuration
  45 +.lock-wscript
  46 +
  47 +# Compiled binary addons (http://nodejs.org/api/addons.html)
  48 +build/Release
  49 +
  50 +# Dependency directories
  51 +node_modules/
  52 +jspm_packages/
  53 +
  54 +# Typescript v1 declaration files
  55 +typings/
  56 +
  57 +# Optional npm cache directory
  58 +.npm
  59 +
  60 +# Optional eslint cache
  61 +.eslintcache
  62 +
  63 +# Optional REPL history
  64 +.node_repl_history
  65 +
  66 +# Output of 'npm pack'
  67 +*.tgz
  68 +
  69 +# Yarn Integrity file
  70 +.yarn-integrity
  71 +
  72 +# dotenv environment variables file
  73 +.env
0 \ No newline at end of file 74 \ No newline at end of file
pom.xml 0 → 100644
  1 +++ a/pom.xml
@@ -0,0 +1,70 @@ @@ -0,0 +1,70 @@
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<project xmlns="http://maven.apache.org/POM/4.0.0"
  3 + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4 + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5 + <modelVersion>4.0.0</modelVersion>
  6 +
  7 + <groupId>com.ishchuk</groupId>
  8 + <artifactId>converter</artifactId>
  9 + <version>1.0-SNAPSHOT</version>
  10 +
  11 + <dependencies>
  12 + <dependency>
  13 + <groupId>org.antlr</groupId>
  14 + <artifactId>antlr4-runtime</artifactId>
  15 + <version>4.7.2</version>
  16 + </dependency>
  17 +
  18 + <dependency>
  19 + <groupId>junit</groupId>
  20 + <artifactId>junit</artifactId>
  21 + <version>4.12</version>
  22 + <scope>test</scope>
  23 + </dependency>
  24 +
  25 + </dependencies>
  26 +
  27 + <build>
  28 + <plugins>
  29 + <plugin>
  30 + <groupId>org.antlr</groupId>
  31 + <artifactId>antlr4-maven-plugin</artifactId>
  32 + <version>4.7.2</version>
  33 + <executions>
  34 + <execution>
  35 + <goals>
  36 + <goal>antlr4</goal>
  37 + </goals>
  38 + </execution>
  39 + </executions>
  40 + </plugin>
  41 + <plugin>
  42 + <groupId>org.codehaus.mojo</groupId>
  43 + <artifactId>build-helper-maven-plugin</artifactId>
  44 + <version>3.0.0</version>
  45 + <executions>
  46 + <execution>
  47 + <phase>generate-sources</phase>
  48 + <goals>
  49 + <goal>add-source</goal>
  50 + </goals>
  51 + <configuration>
  52 + <sources>
  53 + <source>${basedir}/target/generated-sources/antlr4</source>
  54 + </sources>
  55 + </configuration>
  56 + </execution>
  57 + </executions>
  58 + </plugin>
  59 + <plugin>
  60 + <groupId>org.apache.maven.plugins</groupId>
  61 + <artifactId>maven-compiler-plugin</artifactId>
  62 + <configuration>
  63 + <source>1.8</source>
  64 + <target>1.8</target>
  65 + </configuration>
  66 + </plugin>
  67 + </plugins>
  68 + </build>
  69 +
  70 +</project>
0 \ No newline at end of file 71 \ No newline at end of file
src/main/antlr4/com/ishchuk/antlr4/JSONgram.g4 0 → 100644
  1 +++ a/src/main/antlr4/com/ishchuk/antlr4/JSONgram.g4
@@ -0,0 +1,20 @@ @@ -0,0 +1,20 @@
  1 +grammar JSONgram;
  2 +
  3 +json : content;
  4 +
  5 +object : '{' keyValue (',' keyValue)* '}' | '{' '}';
  6 +table : '[' content (',' content)* ']' | '[' ']';
  7 +keyValue : CHAINE ':' content;
  8 +
  9 +content: CHAINE | NUMBER | object | table | 'true' | 'false' | 'null';
  10 +
  11 +
  12 +fragment INT: '0' | [1-9] [0-9]*;
  13 +fragment EXP: [Ee] [+\-]? INT;
  14 +
  15 +CHAINE : '"' [a-zA-Z0-9_!@#$%^&*()\-+=/.,<>;':] [a-zA-Z0-9_!@#$%^&*()\-+=/.,<>;':]* '"' ;
  16 +NUMBER : '-'? INT ('.' [0-9] +)? EXP?;
  17 +
  18 +WS : [ \t\n\r] + -> skip;
  19 +
  20 +
src/main/antlr4/com/ishchuk/antlr4/Log.g4 0 → 100644
  1 +++ a/src/main/antlr4/com/ishchuk/antlr4/Log.g4
@@ -0,0 +1,16 @@ @@ -0,0 +1,16 @@
  1 +grammar Log;
  2 +
  3 +log : entry+;
  4 +entry : timestamp ' ' level ' ' message CRLF;
  5 +timestamp : DATE ' ' TIME;
  6 +level : 'ERROR' | 'INFO' | 'DEBUG';
  7 +message : (TEXT | ' ')+;
  8 +
  9 +fragment DIGIT : [0-9];
  10 +fragment TWODIGIT : DIGIT DIGIT;
  11 +fragment LETTER : [A-Za-z];
  12 +
  13 +DATE : TWODIGIT TWODIGIT '-' LETTER LETTER LETTER '-' TWODIGIT;
  14 +TIME : TWODIGIT ':' TWODIGIT ':' TWODIGIT;
  15 +TEXT : LETTER+;
  16 +CRLF : '\r'? '\n' | '\r';
0 \ No newline at end of file 17 \ No newline at end of file
src/main/java/com/ishchuk/antlr/json/JsonListener.java 0 → 100644
  1 +++ a/src/main/java/com/ishchuk/antlr/json/JsonListener.java
@@ -0,0 +1,123 @@ @@ -0,0 +1,123 @@
  1 +package com.ishchuk.antlr.json;
  2 +
  3 +import com.ishchuk.antlr.json.model.*;
  4 +import com.ishchuk.antlr4.JSONgramBaseListener;
  5 +import com.ishchuk.antlr4.JSONgramParser;
  6 +
  7 +import java.util.*;
  8 +
  9 +
  10 +public class JsonListener extends JSONgramBaseListener {
  11 +
  12 + private JsonModel jsonFile;
  13 + private Map<String, JsonElement> json;
  14 + private List<String> var;
  15 + private boolean read;
  16 +
  17 + @Override
  18 + public void enterJson(JSONgramParser.JsonContext ctx) {
  19 + this.jsonFile = new JsonModel();
  20 + this.json = new HashMap<>();
  21 + this.var = new ArrayList<>();
  22 + this.read = true;
  23 +
  24 +
  25 + }
  26 +
  27 + public JsonModel getJsonFile() {
  28 + return this.jsonFile;
  29 + }
  30 +
  31 + @Override
  32 + public void enterContent(JSONgramParser.ContentContext ctx) {
  33 +
  34 + if (read && Objects.nonNull(ctx.object())) {
  35 + ctx.object().keyValue().forEach(kv -> {
  36 + JsonElement elem = new JsonElement();
  37 + elem.setContent(kv.content());
  38 + json.put(kv.CHAINE().getSymbol().getText(), elem);
  39 + });
  40 + read = false;
  41 + } else {
  42 + System.out.println("content: " + ctx.getText());
  43 + String parent = getParent(ctx);
  44 + System.out.println("parent: " + parent);
  45 +
  46 +
  47 + if (json.containsKey(parent)) {
  48 + System.out.println("parent in json");
  49 + searchMap(json, parent);
  50 +
  51 + } else {
  52 + System.out.println("NOT in json");
  53 +
  54 + json.values().forEach(kv -> {
  55 + if (kv instanceof JsonObject) {
  56 + searchMap(((JsonObject) kv).getMap(), parent);
  57 + } else if (kv instanceof JsonArray) {
  58 + ((JsonArray) kv).getArray().forEach(obj -> {
  59 + searchMap(obj.getMap(), parent);
  60 + });
  61 + }
  62 + });
  63 + }
  64 + }
  65 + }
  66 +
  67 + private void searchMap(Map<String, JsonElement> json, final String parent) {
  68 + if (json.containsKey(parent)) {
  69 + System.out.println("parent in json");
  70 + if (json.get(parent).getContent() instanceof JSONgramParser.ContentContext) {
  71 + JSONgramParser.ContentContext content =
  72 + (JSONgramParser.ContentContext) json.get(parent).getContent();
  73 + if (Objects.nonNull(content.object())) {
  74 + json.replace(parent, prepareJsonObject(content));
  75 + } else if (Objects.nonNull(content.table())) {
  76 + JsonArray arr = new JsonArray();
  77 + content.table().content().forEach(cont -> {
  78 + JsonObject obj = prepareJsonObject(cont);
  79 + arr.getArray().add(obj);
  80 + });
  81 + arr.getArray().forEach(temp -> {
  82 + searchMap(temp.getMap(), parent);
  83 + });
  84 + json.replace(parent, arr);
  85 + } else {
  86 + JsonPrimitive prim = new JsonPrimitive();
  87 + prim.setValue(content.getText());
  88 + json.replace(parent, prim);
  89 + }
  90 + }
  91 + }
  92 + }
  93 +
  94 + private JsonObject prepareJsonObject(JSONgramParser.ContentContext cont) {
  95 + JsonObject obj = new JsonObject();
  96 + cont.object().keyValue().forEach(kv -> {
  97 + JsonElement elem = new JsonElement();
  98 + elem.setContent(kv.content());
  99 + obj.getMap().put(kv.CHAINE().getSymbol().getText(), elem);
  100 + });
  101 + return obj;
  102 + }
  103 +
  104 +
  105 + private String getParent(JSONgramParser.ContentContext ctx) {
  106 + String parent;
  107 + if (Objects.nonNull(ctx.table()) || Objects.nonNull(ctx.object())) {
  108 + if (ctx.getParent().children.get(0).getText().equals("[")) {
  109 + parent = ctx.getParent().getParent().getParent().children.get(0).getText();
  110 + } else {
  111 + parent = ctx.getParent().children.get(0).getText();
  112 + }
  113 + } else {
  114 + parent = ctx.getParent().children.get(0).getText();
  115 + }
  116 + return parent;
  117 + }
  118 +
  119 +
  120 +
  121 +
  122 +
  123 +}
src/main/java/com/ishchuk/antlr/json/model/JsonArray.java 0 → 100644
  1 +++ a/src/main/java/com/ishchuk/antlr/json/model/JsonArray.java
@@ -0,0 +1,21 @@ @@ -0,0 +1,21 @@
  1 +package com.ishchuk.antlr.json.model;
  2 +
  3 +import java.util.ArrayList;
  4 +import java.util.List;
  5 +
  6 +public class JsonArray extends JsonElement {
  7 +
  8 + private List<JsonObject> array;
  9 +
  10 + public List<JsonObject> getArray() {
  11 + return array;
  12 + }
  13 +
  14 + public void setArray(List<JsonObject> array) {
  15 + this.array = array;
  16 + }
  17 +
  18 + public JsonArray() {
  19 + this.array = new ArrayList<>();
  20 + }
  21 +}
src/main/java/com/ishchuk/antlr/json/model/JsonElement.java 0 → 100644
  1 +++ a/src/main/java/com/ishchuk/antlr/json/model/JsonElement.java
@@ -0,0 +1,13 @@ @@ -0,0 +1,13 @@
  1 +package com.ishchuk.antlr.json.model;
  2 +
  3 +public class JsonElement {
  4 + private Object content;
  5 +
  6 + public Object getContent() {
  7 + return content;
  8 + }
  9 +
  10 + public void setContent(Object content) {
  11 + this.content = content;
  12 + }
  13 +}
src/main/java/com/ishchuk/antlr/json/model/JsonModel.java 0 → 100644
  1 +++ a/src/main/java/com/ishchuk/antlr/json/model/JsonModel.java
@@ -0,0 +1,22 @@ @@ -0,0 +1,22 @@
  1 +package com.ishchuk.antlr.json.model;
  2 +
  3 +import java.util.ArrayList;
  4 +import java.util.List;
  5 +
  6 +public class JsonModel {
  7 +
  8 + private List<Object> list;
  9 +
  10 + public List<Object> getList() {
  11 + return list;
  12 + }
  13 +
  14 + public void setList(List<Object> list) {
  15 + this.list = list;
  16 + }
  17 +
  18 + public JsonModel() {
  19 + this.list = new ArrayList<>();
  20 + }
  21 +
  22 +}
src/main/java/com/ishchuk/antlr/json/model/JsonObject.java 0 → 100644
  1 +++ a/src/main/java/com/ishchuk/antlr/json/model/JsonObject.java
@@ -0,0 +1,20 @@ @@ -0,0 +1,20 @@
  1 +package com.ishchuk.antlr.json.model;
  2 +
  3 +import java.util.HashMap;
  4 +import java.util.Map;
  5 +
  6 +public class JsonObject extends JsonElement {
  7 + private Map<String, JsonElement> map;
  8 +
  9 + public Map<String, JsonElement> getMap() {
  10 + return map;
  11 + }
  12 +
  13 + public void setMap(Map<String, JsonElement> map) {
  14 + this.map = map;
  15 + }
  16 +
  17 + public JsonObject() {
  18 + this.map = new HashMap<>();
  19 + }
  20 +}
src/main/java/com/ishchuk/antlr/json/model/JsonPrimitive.java 0 → 100644
  1 +++ a/src/main/java/com/ishchuk/antlr/json/model/JsonPrimitive.java
@@ -0,0 +1,15 @@ @@ -0,0 +1,15 @@
  1 +package com.ishchuk.antlr.json.model;
  2 +
  3 +public class JsonPrimitive extends JsonElement {
  4 +
  5 + private String value;
  6 +
  7 + public String getValue() {
  8 + return value;
  9 + }
  10 +
  11 + public void setValue(String value) {
  12 + this.value = value;
  13 + }
  14 +
  15 +}
src/main/java/com/ishchuk/antlr/json/model/intermediate/Intermediate.java 0 → 100644
  1 +++ a/src/main/java/com/ishchuk/antlr/json/model/intermediate/Intermediate.java
@@ -0,0 +1,23 @@ @@ -0,0 +1,23 @@
  1 +package com.ishchuk.antlr.json.model.intermediate;
  2 +
  3 +public class Intermediate {
  4 + private boolean wait;
  5 + private String name;
  6 +
  7 + public boolean isWait() {
  8 + return wait;
  9 + }
  10 +
  11 + public void setWait(boolean wait) {
  12 + this.wait = wait;
  13 + }
  14 +
  15 + public String getName() {
  16 + return name;
  17 + }
  18 +
  19 + public void setName(String name) {
  20 + this.name = name;
  21 + }
  22 +}
  23 +
src/main/java/com/ishchuk/antlr/log/LogListener.java 0 → 100644
  1 +++ a/src/main/java/com/ishchuk/antlr/log/LogListener.java
@@ -0,0 +1,51 @@ @@ -0,0 +1,51 @@
  1 +package com.ishchuk.antlr.log;
  2 +
  3 +import com.ishchuk.antlr4.LogBaseListener;
  4 +import com.ishchuk.antlr4.LogParser;
  5 +import com.ishchuk.antlr.log.model.LogLevel;
  6 +import com.ishchuk.antlr.log.model.LogEntry;
  7 +
  8 +import java.time.LocalDateTime;
  9 +import java.time.format.DateTimeFormatter;
  10 +import java.util.ArrayList;
  11 +import java.util.Collections;
  12 +import java.util.List;
  13 +import java.util.Locale;
  14 +
  15 +public class LogListener extends LogBaseListener {
  16 +
  17 + private static final DateTimeFormatter DEFAULT_DATETIME_FORMATTER
  18 + = DateTimeFormatter.ofPattern("yyyy-MMM-dd HH:mm:ss", Locale.ENGLISH);
  19 +
  20 + private List<LogEntry> entries = new ArrayList<>();
  21 + private LogEntry currentLogEntry;
  22 +
  23 + @Override
  24 + public void enterEntry(LogParser.EntryContext ctx) {
  25 + this.currentLogEntry = new LogEntry();
  26 + }
  27 +
  28 + @Override
  29 + public void exitEntry(LogParser.EntryContext ctx) {
  30 + entries.add(currentLogEntry);
  31 + }
  32 +
  33 + @Override
  34 + public void enterTimestamp(LogParser.TimestampContext ctx) {
  35 + currentLogEntry.setTimestamp(LocalDateTime.parse(ctx.getText(), DEFAULT_DATETIME_FORMATTER));
  36 + }
  37 +
  38 + @Override
  39 + public void enterMessage(LogParser.MessageContext ctx) {
  40 + currentLogEntry.setMessage(ctx.getText());
  41 + }
  42 +
  43 + @Override
  44 + public void enterLevel(LogParser.LevelContext ctx) {
  45 + currentLogEntry.setLevel(LogLevel.valueOf(ctx.getText()));
  46 + }
  47 +
  48 + public List<LogEntry> getEntries() {
  49 + return Collections.unmodifiableList(entries);
  50 + }
  51 +}
0 \ No newline at end of file 52 \ No newline at end of file
src/main/java/com/ishchuk/antlr/log/model/LogEntry.java 0 → 100644
  1 +++ a/src/main/java/com/ishchuk/antlr/log/model/LogEntry.java
@@ -0,0 +1,35 @@ @@ -0,0 +1,35 @@
  1 +package com.ishchuk.antlr.log.model;
  2 +
  3 +import java.time.LocalDateTime;
  4 +
  5 +
  6 +public class LogEntry {
  7 +
  8 + private LogLevel level;
  9 + private String message;
  10 + private LocalDateTime timestamp;
  11 +
  12 + public LogLevel getLevel() {
  13 + return level;
  14 + }
  15 +
  16 + public void setLevel(LogLevel level) {
  17 + this.level = level;
  18 + }
  19 +
  20 + public String getMessage() {
  21 + return message;
  22 + }
  23 +
  24 + public void setMessage(String message) {
  25 + this.message = message;
  26 + }
  27 +
  28 + public LocalDateTime getTimestamp() {
  29 + return timestamp;
  30 + }
  31 +
  32 + public void setTimestamp(LocalDateTime timestamp) {
  33 + this.timestamp = timestamp;
  34 + }
  35 +}
src/main/java/com/ishchuk/antlr/log/model/LogLevel.java 0 → 100644
  1 +++ a/src/main/java/com/ishchuk/antlr/log/model/LogLevel.java
@@ -0,0 +1,5 @@ @@ -0,0 +1,5 @@
  1 +package com.ishchuk.antlr.log.model;
  2 +
  3 +public enum LogLevel {
  4 + DEBUG, INFO, ERROR
  5 +}
src/test/java/com/ishchuk/antlr/JsonParserUnitTest.java 0 → 100644
  1 +++ a/src/test/java/com/ishchuk/antlr/JsonParserUnitTest.java
@@ -0,0 +1,49 @@ @@ -0,0 +1,49 @@
  1 +package com.ishchuk.antlr;
  2 +
  3 +
  4 +import com.ishchuk.antlr.json.JsonListener;
  5 +import com.ishchuk.antlr4.JSONgramLexer;
  6 +import com.ishchuk.antlr4.JSONgramParser;
  7 +
  8 +import org.antlr.v4.runtime.CharStreams;
  9 +import org.antlr.v4.runtime.CommonTokenStream;
  10 +import org.antlr.v4.runtime.tree.ParseTreeWalker;
  11 +import org.junit.Test;
  12 +
  13 +
  14 +
  15 +import static org.hamcrest.CoreMatchers.is;
  16 +import static org.hamcrest.MatcherAssert.assertThat;
  17 +
  18 +public class JsonParserUnitTest {
  19 +
  20 + @Test
  21 + public void whenJsonObjectWithString_thenStringIsDetected() throws Exception {
  22 + // String line = "{\"menu\": \"light134-()%4praer---'$\"}";
  23 + String line = "{\n" + "\"line\": \"contentLine\"," +
  24 + "\"table\":[{\"lineInTable\":\"contentLineIntTable\"},{}]," +
  25 + " \"menu\": {\n" +
  26 + " \"id\": \"file\",\n" +
  27 + " \"value\": \"File\",\n" +
  28 + " \"popup\": {\n" +
  29 + " \"menuitem\": [\n" +
  30 + " { \"value\": \"New\", \"onclick\": \"CreateNewDoc()\" },\n" +
  31 + " { \"value\": \"Open\", \"onclick\": \"OpenDoc()\" },\n" +
  32 + " { \"value\": \"Close\", \"onclick\": \"CloseDoc()\" }\n" +
  33 + " ]\n" +
  34 + " }\n" +
  35 + " }\n" +
  36 + "}";
  37 + JSONgramLexer serverJSONgramLexer = new JSONgramLexer(CharStreams.fromString(line));
  38 + CommonTokenStream tokens = new CommonTokenStream( serverJSONgramLexer );
  39 + JSONgramParser JSONgramParser = new JSONgramParser(tokens);
  40 + ParseTreeWalker walker = new ParseTreeWalker();
  41 + JsonListener jsonWalker = new JsonListener();
  42 + walker.walk(jsonWalker, JSONgramParser.json());
  43 +
  44 + System.out.println(jsonWalker.getJsonFile().getList().size());
  45 + jsonWalker.getJsonFile().getList().forEach(System.out::println);
  46 + assertThat(jsonWalker.getJsonFile(), is(line));
  47 +
  48 + }
  49 +}
src/test/java/com/ishchuk/antlr/LogParserUnitTest.java 0 → 100644
  1 +++ a/src/test/java/com/ishchuk/antlr/LogParserUnitTest.java
@@ -0,0 +1,38 @@ @@ -0,0 +1,38 @@
  1 +package com.ishchuk.antlr;
  2 +
  3 +import static org.hamcrest.CoreMatchers.is;
  4 +import static org.hamcrest.MatcherAssert.assertThat;
  5 +
  6 +import com.ishchuk.antlr.log.LogListener;
  7 +import com.ishchuk.antlr.log.model.LogLevel;
  8 +import com.ishchuk.antlr.log.model.LogEntry;
  9 +import com.ishchuk.antlr4.LogLexer;
  10 +import com.ishchuk.antlr4.LogParser;
  11 +import org.antlr.v4.runtime.CharStreams;
  12 +import org.antlr.v4.runtime.CommonTokenStream;
  13 +import org.antlr.v4.runtime.tree.ParseTreeWalker;
  14 +import org.junit.Test;
  15 +
  16 +import java.time.LocalDateTime;
  17 +
  18 +
  19 +public class LogParserUnitTest {
  20 +
  21 + @Test
  22 + public void whenLogContainsOneErrorLogEntry_thenOneErrorIsReturned() throws Exception {
  23 + String logLines = "2018-May-05 14:20:21 DEBUG entering awesome method\r\n" +
  24 + "2018-May-05 14:20:24 ERROR Bad thing happened\r\n";
  25 + LogLexer serverLogLexer = new LogLexer(CharStreams.fromString(logLines));
  26 + CommonTokenStream tokens = new CommonTokenStream( serverLogLexer );
  27 + LogParser logParser = new LogParser(tokens);
  28 + ParseTreeWalker walker = new ParseTreeWalker();
  29 + LogListener logWalker = new LogListener();
  30 + walker.walk(logWalker, logParser.log());
  31 +
  32 + assertThat(logWalker.getEntries().size(), is(2));
  33 + LogEntry error = logWalker.getEntries().get(1);
  34 + assertThat(error.getLevel(), is(LogLevel.ERROR));
  35 + assertThat(error.getMessage(), is("Bad thing happened"));
  36 + assertThat(error.getTimestamp(), is(LocalDateTime.of(2018,5,5,14,20,24)));
  37 + }
  38 +}