mirror of
https://github.com/smyalygames/kahoot-challenge-2025.git
synced 2025-12-03 09:17:57 +01:00
feat(build): add gradle build system
This commit is contained in:
43
app/build.gradle.kts
Normal file
43
app/build.gradle.kts
Normal file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* This file was generated by the Gradle 'init' task.
|
||||
*
|
||||
* This generated file contains a sample Java application project to get you started.
|
||||
* For more details on building Java & JVM projects, please refer to https://docs.gradle.org/8.10.2/userguide/building_java_projects.html in the Gradle documentation.
|
||||
*/
|
||||
|
||||
plugins {
|
||||
// Apply the application plugin to add support for building a CLI application in Java.
|
||||
application
|
||||
}
|
||||
|
||||
repositories {
|
||||
// Use Maven Central for resolving dependencies.
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
// Use JUnit Jupiter for testing.
|
||||
testImplementation(libs.junit.jupiter)
|
||||
|
||||
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
|
||||
|
||||
// This dependency is used by the application.
|
||||
implementation(libs.guava)
|
||||
}
|
||||
|
||||
// Apply a specific Java toolchain to ease working on different environments.
|
||||
java {
|
||||
toolchain {
|
||||
languageVersion = JavaLanguageVersion.of(21)
|
||||
}
|
||||
}
|
||||
|
||||
application {
|
||||
// Define the main class for the application.
|
||||
mainClass = "Main"
|
||||
}
|
||||
|
||||
tasks.named<Test>("test") {
|
||||
// Use JUnit Platform for unit tests.
|
||||
useJUnitPlatform()
|
||||
}
|
||||
32
app/src/main/java/EMail.java
Normal file
32
app/src/main/java/EMail.java
Normal file
@@ -0,0 +1,32 @@
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class EMail {
|
||||
/**
|
||||
* Checks if the email is in a valid format
|
||||
* @param email The email address being checked
|
||||
* @return <code>true</code> if the email is correctly formatted, otherwise <code>false</code>
|
||||
*/
|
||||
public static boolean validate(String email) {
|
||||
// Set up regex for email format
|
||||
String emailRegex = "[^@ \\t\\r\\n]+@[^@ \\t\\r\\n]+\\.[^@ \\t\\r\\n]+";
|
||||
Pattern pattern = Pattern.compile(emailRegex);
|
||||
|
||||
// Checks and returns if the email matches the regex pattern
|
||||
return pattern.matcher(email).matches();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the domain part of the email address
|
||||
* @param email A valid email address
|
||||
* @return The domain of the email address from the parameter
|
||||
*/
|
||||
public static String getDomain(String email) {
|
||||
// Checks that the email address is valid, otherwise throw exception
|
||||
if (!validate(email)) {
|
||||
throw new IllegalArgumentException("The email address provided is not valid");
|
||||
}
|
||||
|
||||
// Returns the domain of the email address
|
||||
return email.split("@")[1];
|
||||
}
|
||||
}
|
||||
87
app/src/main/java/Main.java
Normal file
87
app/src/main/java/Main.java
Normal file
@@ -0,0 +1,87 @@
|
||||
import java.util.*;
|
||||
|
||||
public class Main {
|
||||
public static void main(String[] args) {
|
||||
// Get the data from the file
|
||||
List<String> data = ReadFile.open("example.txt");
|
||||
|
||||
// Gets a map with the total occurrences for each domain
|
||||
Map<String, Integer> domains = getDomainTotal(data);
|
||||
|
||||
// Order the map by descending value of the value
|
||||
List<Map.Entry<String, Integer>> sortedDomains = sortDomainMapDesc(domains);
|
||||
|
||||
// Format the data to the format specified
|
||||
String output = domainListToString(sortedDomains);
|
||||
|
||||
System.out.println(output);
|
||||
}
|
||||
|
||||
/**
|
||||
* Totals up the amount of times an email domain occured in the list.
|
||||
* @param emails A list of emails
|
||||
* @return A map of email domains and the total amount of times they occured in the <code>emails</code> parameter
|
||||
*/
|
||||
private static Map<String, Integer> getDomainTotal(List<String> emails) {
|
||||
// Create a map of all email address domains and counting them
|
||||
Map<String, Integer> domains = new HashMap<>();
|
||||
for (String email : emails) {
|
||||
if (!EMail.validate(email)) {
|
||||
throw new IllegalArgumentException("There was an invalid email in the file!");
|
||||
}
|
||||
|
||||
String domain = EMail.getDomain(email);
|
||||
|
||||
// Add email domain to the list
|
||||
if (!domains.containsKey(domain)) {
|
||||
// Creates new entry in the map if the domain didn't exist before
|
||||
domains.put(domain, 1);
|
||||
} else {
|
||||
// Updates the map with the new total for the domain
|
||||
// Gets the old total and adds 1
|
||||
Integer newTotal = domains.get(domain) + 1;
|
||||
|
||||
// Update domain value with new total
|
||||
domains.replace(domain, newTotal);
|
||||
}
|
||||
}
|
||||
|
||||
return domains;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the domains in descending order, from most occurrences to the least occurrences of domains.
|
||||
* @param domains An unsorted map of domains with the amount that they occur
|
||||
* @return Sorted list of Map Entries, in descending order of occurrences
|
||||
*/
|
||||
private static List<Map.Entry<String, Integer>> sortDomainMapDesc(Map<String, Integer> domains) {
|
||||
// Create a list from the map entries
|
||||
List<Map.Entry<String, Integer>> sortedDomains = new ArrayList<>(domains.entrySet());
|
||||
|
||||
// Sort the list in descending order
|
||||
sortedDomains.sort(Map.Entry.comparingByValue(Comparator.reverseOrder()));
|
||||
|
||||
return sortedDomains;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a string in a format to display the data from a list of domains and their occurrences.
|
||||
* @param domains A list of all the domains and their occurrences
|
||||
* @return A string with a specific format
|
||||
*/
|
||||
private static String domainListToString(List<Map.Entry<String, Integer>> domains) {
|
||||
StringBuilder output = new StringBuilder();
|
||||
for (Map.Entry<String, Integer> entry : domains) {
|
||||
// Get the values of the entry
|
||||
String domain = entry.getKey();
|
||||
Integer occurrences = entry.getValue();
|
||||
|
||||
output.append(domain).append(" ").append(occurrences).append("\n");
|
||||
}
|
||||
|
||||
// Remove unnecessary \n at the end of the output
|
||||
output.deleteCharAt(output.length() - 1);
|
||||
|
||||
return output.toString();
|
||||
}
|
||||
}
|
||||
39
app/src/main/java/ReadFile.java
Normal file
39
app/src/main/java/ReadFile.java
Normal file
@@ -0,0 +1,39 @@
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Scanner;
|
||||
|
||||
public class ReadFile {
|
||||
/**
|
||||
* Opens a file and returns a list of all the lines in the file
|
||||
* @param filename the name of the file with, only allowing a .txt extension
|
||||
* @return The contents of the file
|
||||
*/
|
||||
public static List<String> open(String filename) {
|
||||
// Check that the filetype is correct, otherwise, throw IllegalArgumentException
|
||||
if (!filename.endsWith(".txt")) {
|
||||
throw new IllegalArgumentException("The filename is not a .txt format");
|
||||
}
|
||||
|
||||
File file = new File(filename);
|
||||
Scanner reader;
|
||||
try {
|
||||
// Open the file that was defined
|
||||
reader = new Scanner(file);
|
||||
} catch (FileNotFoundException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
// List for all the separate lines on the database
|
||||
List<String> data = new ArrayList<>();
|
||||
|
||||
// Go through all the lines in the file and append them to the list `data`
|
||||
while (reader.hasNextLine()) {
|
||||
String currentData = reader.nextLine();
|
||||
data.add(currentData);
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
}
|
||||
100
app/src/test/java/EMailTest.java
Normal file
100
app/src/test/java/EMailTest.java
Normal file
@@ -0,0 +1,100 @@
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
@DisplayName("EMail class functions tests")
|
||||
class EMailTest {
|
||||
|
||||
@Nested
|
||||
@DisplayName("Testing EMail `validate()` function")
|
||||
class ValidateTest {
|
||||
|
||||
@Test
|
||||
@DisplayName("Empty string")
|
||||
void emptyString() {
|
||||
assertFalse(EMail.validate(""));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Valid email")
|
||||
void validEmail() {
|
||||
assertTrue(EMail.validate("test@test.com"));
|
||||
assertTrue(EMail.validate("test123@test.com"));
|
||||
assertTrue(EMail.validate("123@123.com"));
|
||||
assertTrue(EMail.validate("abc123abc123@abc123abc123.com"));
|
||||
assertTrue(EMail.validate("123@test.no"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Invalid email")
|
||||
void invalidEmail() {
|
||||
assertFalse(EMail.validate("@test.com"));
|
||||
assertFalse(EMail.validate("test@.com"));
|
||||
assertFalse(EMail.validate("@test.com"));
|
||||
assertFalse(EMail.validate("test.com"));
|
||||
assertFalse(EMail.validate("test@test."));
|
||||
assertFalse(EMail.validate("test@test"));
|
||||
assertFalse(EMail.validate("test@testing@test.com"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Email alias with +")
|
||||
void aliasPlus() {
|
||||
assertTrue(EMail.validate("test+alias@test.com"));
|
||||
assertTrue(EMail.validate("test+123@test.com"));
|
||||
assertTrue(EMail.validate("test+alias123@test.com"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Email alias with .")
|
||||
void aliasDot() {
|
||||
assertTrue(EMail.validate("te.st@test.com"));
|
||||
assertTrue(EMail.validate("t.e.s.t@test.com"));
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("Testing EMail `getDomain()` function")
|
||||
class GetDomainTest {
|
||||
|
||||
@Test
|
||||
@DisplayName("Throws with empty string")
|
||||
void emptyString() {
|
||||
assertThrowsExactly(IllegalArgumentException.class, () -> EMail.getDomain(""));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Throws with invalid emails")
|
||||
void invalidEmail() {
|
||||
assertThrowsExactly(IllegalArgumentException.class, () -> EMail.getDomain("@test.com"));
|
||||
assertThrowsExactly(IllegalArgumentException.class, () -> EMail.getDomain("test@.com"));
|
||||
assertThrowsExactly(IllegalArgumentException.class, () -> EMail.getDomain("@test.com"));
|
||||
assertThrowsExactly(IllegalArgumentException.class, () -> EMail.getDomain("test.com"));
|
||||
assertThrowsExactly(IllegalArgumentException.class, () -> EMail.getDomain("test@test."));
|
||||
assertThrowsExactly(IllegalArgumentException.class, () -> EMail.getDomain("test@test"));
|
||||
assertThrowsExactly(IllegalArgumentException.class, () -> EMail.getDomain("test@testing@test.com"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Check the domain is correct for each email address")
|
||||
void validEmail() {
|
||||
assertEquals("test.com", EMail.getDomain("test@test.com"));
|
||||
assertEquals("test.com", EMail.getDomain("test123@test.com"));
|
||||
assertEquals("123.com", EMail.getDomain("123@123.com"));
|
||||
assertEquals("abc123abc123.com", EMail.getDomain("abc123abc123@abc123abc123.com"));
|
||||
assertEquals("gmail.com", EMail.getDomain("test@gmail.com"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Check the domains will not be affected by aliases")
|
||||
void aliasEmail() {
|
||||
assertEquals("test.com", EMail.getDomain("test+alias@test.com"));
|
||||
assertEquals("test.com", EMail.getDomain("test+123@test.com"));
|
||||
assertEquals("test.com", EMail.getDomain("test+alias123@test.com"));
|
||||
assertEquals("test.com", EMail.getDomain("te.st@test.com"));
|
||||
assertEquals("test.com", EMail.getDomain("t.e.s.t@test.com"));
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user