diff --git a/concepts/enums/.meta/config.json b/concepts/enums/.meta/config.json new file mode 100644 index 000000000..1fb16845f --- /dev/null +++ b/concepts/enums/.meta/config.json @@ -0,0 +1,5 @@ +{ + "blurb": "Enums are useful to create a predefined set of constants.", + "authors": ["sanderploegsma"], + "contributors": [] +} diff --git a/concepts/enums/about.md b/concepts/enums/about.md new file mode 100644 index 000000000..c259d9262 --- /dev/null +++ b/concepts/enums/about.md @@ -0,0 +1,120 @@ +# About + +An _enum type_ is a special data type that enables for a variable to be a set of predefined constants. +The variable must be equal to one of the values that have been predefined for it. +Common examples include compass directions (values of `NORTH`, `SOUTH`, `EAST`, and `WEST`) and the days of the week. + +Because they are constants, the names of an enum type's fields are in uppercase letters. + +## Defining an enum type + +In the Java programming language, you define an enum type by using the `enum` keyword. +For example, you would specify a days-of-the-week enum type as: + +```java +public enum DayOfWeek { + SUNDAY, + MONDAY, + TUESDAY, + WEDNESDAY, + THURSDAY, + FRIDAY, + SATURDAY +} +``` + +You should use enum types any time you need to represent a fixed set of constants. +That includes natural enum types such as the planets in our solar system and data sets where you know all possible values at compile time - for example, the choices on a menu, command line flags, and so on. + +## Using an enum type + +Here is some code that shows you how to use the `DayOfWeek` enum defined above: + +```java +public class Shop { + public String getOpeningHours(DayOfWeek dayOfWeek) { + switch (dayOfWeek) { + case MONDAY: + case TUESDAY: + case WEDNESDAY: + case THURSDAY: + case FRIDAY: + return "9am - 5pm"; + case SATURDAY: + return "10am - 4pm" + case SUNDAY: + return "Closed."; + } + } +} +``` + +```java +var shop = new Shop(); +shop.getOpeningHours(DayOfWeek.WEDNESDAY); +// => "9am - 5pm" +``` + +## Adding methods and fields + +Java programming language enum types are much more powerful than their counterparts in other languages. +The `enum` declaration defines a _class_ (called an _enum type_). +The enum class body can include methods and other fields: + +```java +public enum Rating { + GREAT(5), + GOOD(4), + OK(3), + BAD(2), + TERRIBLE(1); + + private final int numberOfStars; + + Rating(int numberOfStars) { + this.numberOfStars = numberOfStars; + } + + public int getNumberOfStars() { + return this.numberOfStars; + } +} +``` + +Calling the `getNumberOfStars` method on a member of the `Rating` enum type: + +```java +Rating.GOOD.getNumberOfStars(); +// => 4 +``` + +## Built-in methods + +The compiler automatically adds some special methods when it creates an enum. + +For example, they have a static `values` method that returns an array containing all of the values of the enum in the order they are declared: + +```java +for (DayOfWeek dayOfWeek : DayOfWeek.values()) { + System.out.println(dayOfWeek.toString()); +} +``` + +The snippet above would print the following: + +```text +SUNDAY +MONDAY +TUESDAY +WEDNESDAY +THURSDAY +FRIDAY +SATURDAY +``` + +The compiler also adds a static `valueOf` method that returns an enum member based on its name: + +```java +DayOfWeek.valueOf("SUNDAY"); +// => DayOfWeek.SUNDAY +``` diff --git a/concepts/enums/introduction.md b/concepts/enums/introduction.md new file mode 100644 index 000000000..61b1786a2 --- /dev/null +++ b/concepts/enums/introduction.md @@ -0,0 +1,89 @@ +# Introduction + +An _enum type_ is a special data type that enables for a variable to be a set of predefined constants. +The variable must be equal to one of the values that have been predefined for it. +Common examples include compass directions (values of `NORTH`, `SOUTH`, `EAST`, and `WEST`) and the days of the week. + +Because they are constants, the names of an enum type's fields are in uppercase letters. + +## Defining an enum type + +In the Java programming language, you define an enum type by using the `enum` keyword. +For example, you would specify a days-of-the-week enum type as: + +```java +public enum DayOfWeek { + SUNDAY, + MONDAY, + TUESDAY, + WEDNESDAY, + THURSDAY, + FRIDAY, + SATURDAY +} +``` + +You should use enum types any time you need to represent a fixed set of constants. +That includes natural enum types such as the planets in our solar system and data sets where you know all possible values at compile time - for example, the choices on a menu, command line flags, and so on. + +## Using an enum type + +Here is some code that shows you how to use the `DayOfWeek` enum defined above: + +```java +public class Shop { + public String getOpeningHours(DayOfWeek dayOfWeek) { + switch (dayOfWeek) { + case MONDAY: + case TUESDAY: + case WEDNESDAY: + case THURSDAY: + case FRIDAY: + return "9am - 5pm"; + case SATURDAY: + return "10am - 4pm" + case SUNDAY: + return "Closed."; + } + } +} +``` + +```java +var shop = new Shop(); +shop.getOpeningHours(DayOfWeek.WEDNESDAY); +// => "9am - 5pm" +``` + +## Adding methods and fields + +Java programming language enum types are much more powerful than their counterparts in other languages. +The `enum` declaration defines a _class_ (called an _enum type_). +The enum class body can include methods and other fields: + +```java +public enum Rating { + GREAT(5), + GOOD(4), + OK(3), + BAD(2), + TERRIBLE(1); + + private final int numberOfStars; + + Rating(int numberOfStars) { + this.numberOfStars = numberOfStars; + } + + public int getNumberOfStars() { + return this.numberOfStars; + } +} +``` + +Calling the `getNumberOfStars` method on a member of the `Rating` enum type: + +```java +Rating.GOOD.getNumberOfStars(); +// => 4 +``` diff --git a/concepts/enums/links.json b/concepts/enums/links.json new file mode 100644 index 000000000..55f1e75ad --- /dev/null +++ b/concepts/enums/links.json @@ -0,0 +1,6 @@ +[ + { + "url": "https://docs.oracle.com/javase/tutorial/java/javaOO/enum.html", + "description": "Java Tuturial on Enum Types" + } +] diff --git a/config.json b/config.json index c430efb43..9e2c17231 100644 --- a/config.json +++ b/config.json @@ -224,6 +224,13 @@ "booleans" ], "status": "active" + }, + { + "slug": "logs-logs-logs", + "name": "Logs, Logs, Logs!", + "uuid": "f33927f7-676f-4045-b1fc-34e719453c61", + "concepts": ["enums"], + "prerequisites": ["strings", "switch-statement", "constructors"] } ], "practice": [ @@ -307,9 +314,11 @@ "name": "Secret Handshake", "uuid": "71c7c174-7e2c-43c2-bdd6-7515fcb12a91", "practices": [ - "lists" + "lists", + "enums" ], "prerequisites": [ + "enums", "numbers", "for-loops" ], @@ -592,10 +601,11 @@ "name": "Resistor Color Duo", "uuid": "0ae1989d-df46-414d-ad1f-4bd0f0f78421", "practices": [ - "arrays" + "arrays", + "enums" ], "prerequisites": [ - "basics" + "enums" ], "difficulty": 2 }, @@ -826,11 +836,14 @@ "name": "Allergies", "uuid": "6a617ddb-04e3-451c-bb30-27ccd0be9125", "practices": [ + "classes", + "enums", + "for-loops", "lists" ], "prerequisites": [ "for-loops", - "classes" + "enums" ], "difficulty": 5 }, @@ -839,11 +852,11 @@ "name": "Meetup", "uuid": "602511d5-7e89-4def-b072-4dd311816810", "practices": [ + "enums", "for-loops" ], "prerequisites": [ - "conditionals-if", - "classes" + "enums" ], "difficulty": 7 }, @@ -852,11 +865,12 @@ "name": "Yacht", "uuid": "0cb45688-9598-49aa-accc-ed48c5d6962d", "practices": [ - "arrays" + "arrays", + "enums", + "switch-statement" ], "prerequisites": [ - "switch-statement", - "classes" + "enums" ], "difficulty": 4 }, @@ -921,15 +935,15 @@ "slug": "go-counting", "name": "Go Counting", "uuid": "2e760ae2-fadd-4d31-9639-c4554e2826e9", - "practices": [], - "prerequisites": [], - "difficulty": 7, - "topics": [ - "algorithms", + "practices": [ "conditionals-if", - "games", - "loops" - ] + "for-loops", + "enums" + ], + "prerequisites": [ + "enums" + ], + "difficulty": 7 }, { "slug": "markdown", @@ -978,16 +992,16 @@ "slug": "perfect-numbers", "name": "Perfect Numbers", "uuid": "d0dcc898-ec38-4822-9e3c-1a1829c9b2d9", - "practices": [], - "prerequisites": [], - "difficulty": 3, - "topics": [ - "enumerations", - "exception_handling", - "filtering", - "integers", - "math" - ] + "practices": [ + "enums", + "exceptions", + "numbers" + ], + "prerequisites": [ + "enums", + "exceptions" + ], + "difficulty": 3 }, { "slug": "say", @@ -1062,15 +1076,15 @@ "slug": "robot-simulator", "name": "Robot Simulator", "uuid": "993bde9d-7774-4e7a-a381-9eee75f28ecb", - "practices": [], - "prerequisites": [], - "difficulty": 6, - "topics": [ + "practices": [ "classes", - "enumerations", - "logic", - "loops" - ] + "enums", + "for-loops" + ], + "prerequisites": [ + "enums" + ], + "difficulty": 6 }, { "slug": "wordy", @@ -1110,18 +1124,18 @@ "slug": "kindergarten-garden", "name": "Kindergarten Garden", "uuid": "df41c70c-daa1-4380-9729-638c17b4105d", - "practices": [], - "prerequisites": [], - "difficulty": 4, - "topics": [ + "practices": [ "arrays", - "enumerations", + "enums", + "for-loops", "lists", - "logic", - "loops", - "pattern_recognition", "strings" - ] + ], + "prerequisites": [ + "enums", + "lists" + ], + "difficulty": 4 }, { "slug": "pascals-triangle", @@ -1623,16 +1637,16 @@ "slug": "sublist", "name": "Sublist", "uuid": "d2aedbd7-092a-43d0-8a5e-ae3ebd5b9c7f", - "practices": [], - "prerequisites": [], - "difficulty": 7, - "topics": [ - "enumerations", - "generics", - "lists", - "loops", - "searching" - ] + "practices": [ + "enums", + "generic-types", + "lists" + ], + "prerequisites": [ + "enums", + "generic-types" + ], + "difficulty": 7 }, { "slug": "tree-building", @@ -1688,14 +1702,14 @@ "slug": "hangman", "name": "Hangman", "uuid": "ab3f8bf4-cfae-4f7a-b134-bb0fa4fafa63", - "practices": [], - "prerequisites": [], - "difficulty": 8, - "topics": [ - "strings", - "reactive_programming", - "functional_programming" - ] + "practices": [ + "enums", + "strings" + ], + "prerequisites": [ + "enums" + ], + "difficulty": 8 }, { "slug": "list-ops", @@ -1878,12 +1892,12 @@ "slug": "connect", "name": "Connect", "uuid": "1532b9a8-7e0d-479f-ad55-636e01e9d19f", - "practices": ["switch-statement"], + "practices": [ + "enums", + "switch-statement" + ], "prerequisites": [ - "strings", - "chars", - "arrays", - "conditionals-if" + "enums" ], "difficulty": 8 }, @@ -1977,6 +1991,11 @@ "slug": "constructors", "name": "Constructors" }, + { + "uuid": "cb753863-b7c1-4ff6-adeb-ae9a1f39deca", + "slug": "enums", + "name": "Enums" + }, { "uuid": "b7f8e129-303c-45b8-ac07-297bfd5a9906", "slug": "exceptions", diff --git a/exercises/concept/logs-logs-logs/.docs/hints.md b/exercises/concept/logs-logs-logs/.docs/hints.md new file mode 100644 index 000000000..a3463a1be --- /dev/null +++ b/exercises/concept/logs-logs-logs/.docs/hints.md @@ -0,0 +1,22 @@ +# Hints + +## General + +- [Tutorial on working with enums][java-tutorial-enum-types]. + +## 1. Parse log level + +- There is a [method to get a part of a string][java-docs-substring]. +- You can use a [`switch` statement][java-tutorial-switch-statement] to elegantly handle the various log levels. + +## 2. Support unknown log level + +- There is a special switch case called `default` that can be used to catch unspecified cases. + +## 3. Convert log line to short format + +- You can add fields and methods to an enum type, see the [tutorial on working with enums][java-tutorial-enum-types]. + +[java-tutorial-enum-types]: https://docs.oracle.com/javase/tutorial/java/javaOO/enum.html +[java-tutorial-switch-statement]: https://docs.oracle.com/javase/tutorial/java/nutsandbolts/switch.html +[java-docs-substring]: https://docs.oracle.com/javase/8/docs/api/java/lang/String.html#substring-int-int- diff --git a/exercises/concept/logs-logs-logs/.docs/instructions.md b/exercises/concept/logs-logs-logs/.docs/instructions.md new file mode 100644 index 000000000..b699efa0b --- /dev/null +++ b/exercises/concept/logs-logs-logs/.docs/instructions.md @@ -0,0 +1,69 @@ +# Instructions + +In this exercise you'll be processing log-lines. + +Each log line is a string formatted as follows: `"[]: "`. + +These are the different log levels: + +- `TRC` (trace) +- `DBG` (debug) +- `INF` (info) +- `WRN` (warning) +- `ERR` (error) +- `FTL` (fatal) + +You have three tasks. + +## 1. Parse log level + +Define a `LogLevel` enum that has six elements corresponding to the above log levels. + +- `TRACE` +- `DEBUG` +- `INFO` +- `WARNING` +- `ERROR` +- `FATAL` + +Next, implement the `LogLine.getLogLevel()` method that returns the parsed the log level of a log line: + +```java +var logLine = new LogLine("[INF]: File deleted"); +logLine.getLogLevel(); +// => LogLevel.INFO +``` + +## 2. Support unknown log level + +Unfortunately, occasionally some log lines have an unknown log level. +To gracefully handle these log lines, add an `UNKNOWN` element to the `LogLevel` enum which should be returned when parsing an unknown log level: + +```java +var logLine = new LogLine("[XYZ]: Overly specific, out of context message"); +logLine.getLogLevel(); +// => LogLevel.UNKNOWN +``` + +## 3. Convert log line to short format + +The log level of a log line is quite verbose. +To reduce the disk space needed to store the log lines, a short format is developed: `"[]:"`. + +The encoded log level is a simple mapping of a log level to a number: + +- `UNKNOWN` - `0` +- `TRACE` - `1` +- `DEBUG` - `2` +- `INFO` - `4` +- `WARNING` - `5` +- `ERROR` - `6` +- `FATAL` - `42` + +Implement the `LogLine.getOutputForShortLog()` method that can output the shortened log line format: + +```java +var logLine = new LogLine("[ERR]: Stack Overflow"); +logLine.getOutputForShortLog(); +// => "6:Stack overflow" +``` diff --git a/exercises/concept/logs-logs-logs/.docs/introduction.md b/exercises/concept/logs-logs-logs/.docs/introduction.md new file mode 100644 index 000000000..8b53d6c25 --- /dev/null +++ b/exercises/concept/logs-logs-logs/.docs/introduction.md @@ -0,0 +1,91 @@ +# Introduction + +## Enums + +An _enum type_ is a special data type that enables for a variable to be a set of predefined constants. +The variable must be equal to one of the values that have been predefined for it. +Common examples include compass directions (values of `NORTH`, `SOUTH`, `EAST`, and `WEST`) and the days of the week. + +Because they are constants, the names of an enum type's fields are in uppercase letters. + +### Defining an enum type + +In the Java programming language, you define an enum type by using the `enum` keyword. +For example, you would specify a days-of-the-week enum type as: + +```java +public enum DayOfWeek { + SUNDAY, + MONDAY, + TUESDAY, + WEDNESDAY, + THURSDAY, + FRIDAY, + SATURDAY +} +``` + +You should use enum types any time you need to represent a fixed set of constants. +That includes natural enum types such as the planets in our solar system and data sets where you know all possible values at compile time - for example, the choices on a menu, command line flags, and so on. + +### Using an enum type + +Here is some code that shows you how to use the `DayOfWeek` enum defined above: + +```java +public class Shop { + public String getOpeningHours(DayOfWeek dayOfWeek) { + switch (dayOfWeek) { + case MONDAY: + case TUESDAY: + case WEDNESDAY: + case THURSDAY: + case FRIDAY: + return "9am - 5pm"; + case SATURDAY: + return "10am - 4pm" + case SUNDAY: + return "Closed."; + } + } +} +``` + +```java +var shop = new Shop(); +shop.getOpeningHours(DayOfWeek.WEDNESDAY); +// => "9am - 5pm" +``` + +### Adding methods and fields + +Java programming language enum types are much more powerful than their counterparts in other languages. +The `enum` declaration defines a _class_ (called an _enum type_). +The enum class body can include methods and other fields: + +```java +public enum Rating { + GREAT(5), + GOOD(4), + OK(3), + BAD(2), + TERRIBLE(1); + + private final int numberOfStars; + + Rating(int numberOfStars) { + this.numberOfStars = numberOfStars; + } + + public int getNumberOfStars() { + return this.numberOfStars; + } +} +``` + +Calling the `getNumberOfStars` method on a member of the `Rating` enum type: + +```java +Rating.GOOD.getNumberOfStars(); +// => 4 +``` diff --git a/exercises/concept/logs-logs-logs/.docs/introduction.md.tpl b/exercises/concept/logs-logs-logs/.docs/introduction.md.tpl new file mode 100644 index 000000000..00708a387 --- /dev/null +++ b/exercises/concept/logs-logs-logs/.docs/introduction.md.tpl @@ -0,0 +1,3 @@ +# Introduction + +%{concept:enums} diff --git a/exercises/concept/logs-logs-logs/.meta/config.json b/exercises/concept/logs-logs-logs/.meta/config.json new file mode 100644 index 000000000..0d8458a89 --- /dev/null +++ b/exercises/concept/logs-logs-logs/.meta/config.json @@ -0,0 +1,15 @@ +{ + "authors": ["sanderploegsma"], + "contributors": [], + "files": { + "solution": ["src/main/java/LogLevel.java", "src/main/java/LogLine.java"], + "test": ["src/test/java/LogsLogsLogsTest.java"], + "exemplar": [ + ".meta/src/reference/java/LogLevel.java", + ".meta/src/reference/java/LogLine.java" + ], + "invalidator": ["build.gradle"] + }, + "forked_from": ["csharp/logs-logs-logs"], + "blurb": "Learn about enums by parsing logs." +} diff --git a/exercises/concept/logs-logs-logs/.meta/design.md b/exercises/concept/logs-logs-logs/.meta/design.md new file mode 100644 index 000000000..df78aa422 --- /dev/null +++ b/exercises/concept/logs-logs-logs/.meta/design.md @@ -0,0 +1,22 @@ +# Design + +## Learning objectives + +After completing this exercise, the student should: + +- Know of the existence of the `enum` keyword. +- Know how to define enum members. +- Know how to add fields to enum types. +- Know how to add methods to enum types. + +## Concepts + +- `enums`: know of the existence of the `enum` keyword; know how to define enum members; know how to assign values to enum members. + +## Prerequisites + +This exercise's prerequisites Concepts are: + +- `strings` +- `switch-statement` +- `constructors` diff --git a/exercises/concept/logs-logs-logs/.meta/src/reference/java/LogLevel.java b/exercises/concept/logs-logs-logs/.meta/src/reference/java/LogLevel.java new file mode 100644 index 000000000..0d61767e1 --- /dev/null +++ b/exercises/concept/logs-logs-logs/.meta/src/reference/java/LogLevel.java @@ -0,0 +1,19 @@ +public enum LogLevel { + UNKNOWN(0), + TRACE(1), + DEBUG(2), + INFO(4), + WARNING(5), + ERROR(6), + FATAL(42); + + private final int encodedLevel; + + LogLevel(int encodedLevel) { + this.encodedLevel = encodedLevel; + } + + public int getEncodedLevel() { + return this.encodedLevel; + } +} diff --git a/exercises/concept/logs-logs-logs/.meta/src/reference/java/LogLine.java b/exercises/concept/logs-logs-logs/.meta/src/reference/java/LogLine.java new file mode 100644 index 000000000..dceabeffa --- /dev/null +++ b/exercises/concept/logs-logs-logs/.meta/src/reference/java/LogLine.java @@ -0,0 +1,26 @@ +public class LogLine { + private final LogLevel level; + private final String message; + + public LogLine(String logLine) { + this.level = switch (logLine.substring(1, 4)) { + case "TRC" -> LogLevel.TRACE; + case "DBG" -> LogLevel.DEBUG; + case "INF" -> LogLevel.INFO; + case "WRN" -> LogLevel.WARNING; + case "ERR" -> LogLevel.ERROR; + case "FTL" -> LogLevel.FATAL; + default -> LogLevel.UNKNOWN; + }; + + this.message = logLine.substring(7); + } + + public LogLevel getLogLevel() { + return this.level; + } + + public String getOutputForShortLog() { + return String.format("%d:%s", this.level.getEncodedLevel(), this.message); + } +} diff --git a/exercises/concept/logs-logs-logs/build.gradle b/exercises/concept/logs-logs-logs/build.gradle new file mode 100644 index 000000000..b00a93663 --- /dev/null +++ b/exercises/concept/logs-logs-logs/build.gradle @@ -0,0 +1,23 @@ +plugins { + id "java" +} + +repositories { + mavenCentral() +} + +dependencies { + testImplementation platform("org.junit:junit-bom:5.10.0") + testImplementation "org.junit.jupiter:junit-jupiter" + testImplementation "org.assertj:assertj-core:3.15.0" +} + +test { + useJUnitPlatform() + + testLogging { + exceptionFormat = "full" + showStandardStreams = true + events = ["passed", "failed", "skipped"] + } +} \ No newline at end of file diff --git a/exercises/concept/logs-logs-logs/src/main/java/LogLevel.java b/exercises/concept/logs-logs-logs/src/main/java/LogLevel.java new file mode 100644 index 000000000..17fb02207 --- /dev/null +++ b/exercises/concept/logs-logs-logs/src/main/java/LogLevel.java @@ -0,0 +1,3 @@ +public enum LogLevel { + // TODO: define members for each log level +} diff --git a/exercises/concept/logs-logs-logs/src/main/java/LogLine.java b/exercises/concept/logs-logs-logs/src/main/java/LogLine.java new file mode 100644 index 000000000..49b5c5b21 --- /dev/null +++ b/exercises/concept/logs-logs-logs/src/main/java/LogLine.java @@ -0,0 +1,13 @@ +public class LogLine { + + public LogLine(String logLine) { + } + + public LogLevel getLogLevel() { + throw new UnsupportedOperationException("Please implement the getLogLevel() method"); + } + + public String getOutputForShortLog() { + throw new UnsupportedOperationException("Please implement the getOutputForShortLog() method"); + } +} diff --git a/exercises/concept/logs-logs-logs/src/test/java/LogsLogsLogsTest.java b/exercises/concept/logs-logs-logs/src/test/java/LogsLogsLogsTest.java new file mode 100644 index 000000000..ce796efb8 --- /dev/null +++ b/exercises/concept/logs-logs-logs/src/test/java/LogsLogsLogsTest.java @@ -0,0 +1,127 @@ +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +public class LogsLogsLogsTest { + @Test + @Tag("task:1") + @DisplayName("Parsing log level TRC") + public void getLogLevelTrace() { + var logLine = new LogLine("[TRC]: Line 84 - System.out.println(\"Hello World\");"); + assertThat(logLine.getLogLevel()).isEqualTo(LogLevel.valueOf("TRACE")); + } + + @Test + @Tag("task:1") + @DisplayName("Parsing log level DBG") + public void parseLogLevelDbg() { + var logLine = new LogLine("[DBG]: ; expected"); + assertThat(logLine.getLogLevel()).isEqualTo(LogLevel.valueOf("DEBUG")); + } + + @Test + @Tag("task:1") + @DisplayName("Parsing log level INF") + public void parseLogLevelInf() { + var logLine = new LogLine("[INF]: Timezone changed"); + assertThat(logLine.getLogLevel()).isEqualTo(LogLevel.valueOf("INFO")); + } + + @Test + @Tag("task:1") + @DisplayName("Parsing log level WRN") + public void parseLogLevelWrn() { + var logLine = new LogLine("[WRN]: Timezone not set"); + assertThat(logLine.getLogLevel()).isEqualTo(LogLevel.valueOf("WARNING")); + } + + @Test + @Tag("task:1") + @DisplayName("Parsing log level ERR") + public void parseLogLevelErr() { + var logLine = new LogLine("[ERR]: Disk full"); + assertThat(logLine.getLogLevel()).isEqualTo(LogLevel.valueOf("ERROR")); + } + + @Test + @Tag("task:1") + @DisplayName("Parsing log level FTL") + public void parseLogLevelFtl() { + var logLine = new LogLine("[FTL]: Not enough memory"); + assertThat(logLine.getLogLevel()).isEqualTo(LogLevel.valueOf("FATAL")); + } + + @Test + @Tag("task:2") + @DisplayName("Parsing unknown log level XYZ") + public void parseLogLevelXyz() { + var logLine = new LogLine("[XYZ]: Gibberish message.. beep boop.."); + assertThat(logLine.getLogLevel()).isEqualTo(LogLevel.valueOf("UNKNOWN")); + } + + @Test + @Tag("task:2") + @DisplayName("Parsing unknown log level ABC") + public void parseLogLevelAbc() { + var logLine = new LogLine("[ABC]: Gibberish message.. beep boop.."); + assertThat(logLine.getLogLevel()).isEqualTo(LogLevel.valueOf("UNKNOWN")); + } + + @Test + @Tag("task:3") + @DisplayName("Get short log output for log level UNKNOWN") + public void getShortLogOutputUnknown() { + var logLine = new LogLine("[ABC]: We're no strangers to love"); + assertThat(logLine.getOutputForShortLog()).isEqualTo("0:We're no strangers to love"); + } + + @Test + @Tag("task:3") + @DisplayName("Get short log output for log level TRACE") + public void getShortLogOutputTrace() { + var logLine = new LogLine("[TRC]: You know the rules and so do I"); + assertThat(logLine.getOutputForShortLog()).isEqualTo("1:You know the rules and so do I"); + } + + @Test + @Tag("task:3") + @DisplayName("Get short log output for log level DEBUG") + public void getShortLogOutputDebug() { + var logLine = new LogLine("[DBG]: A full commitment's what I'm thinking of"); + assertThat(logLine.getOutputForShortLog()).isEqualTo("2:A full commitment's what I'm thinking of"); + } + + @Test + @Tag("task:3") + @DisplayName("Get short log output for log level INFO") + public void getShortLogOutputInfo() { + var logLine = new LogLine("[INF]: You wouldn't get this from any other guy"); + assertThat(logLine.getOutputForShortLog()).isEqualTo("4:You wouldn't get this from any other guy"); + } + + @Test + @Tag("task:3") + @DisplayName("Get short log output for log level WARNING") + public void getShortLogOutputWarning() { + var logLine = new LogLine("[WRN]: I just wanna tell you how I'm feeling"); + assertThat(logLine.getOutputForShortLog()).isEqualTo("5:I just wanna tell you how I'm feeling"); + } + + @Test + @Tag("task:3") + @DisplayName("Get short log output for log level ERROR") + public void getShortLogOutputError() { + var logLine = new LogLine("[ERR]: Gotta make you understand"); + assertThat(logLine.getOutputForShortLog()).isEqualTo("6:Gotta make you understand"); + } + + @Test + @Tag("task:3") + @DisplayName("Get short log output for log level FATAL") + public void getShortLogOutputFatal() { + var logLine = new LogLine("[FTL]: Never gonna give you up"); + assertThat(logLine.getOutputForShortLog()).isEqualTo("42:Never gonna give you up"); + } +} diff --git a/exercises/settings.gradle b/exercises/settings.gradle index 37a4f5b88..33425c055 100644 --- a/exercises/settings.gradle +++ b/exercises/settings.gradle @@ -16,6 +16,7 @@ include 'concept:remote-control-competition' include 'concept:football-match-reports' include 'concept:wizards-and-warriors' include 'concept:calculator-conundrum' +include 'concept:logs-logs-logs' // practice exercises include 'practice:accumulate'