Rename year directories to allow natural ordering

This commit is contained in:
2023-12-20 03:57:27 +00:00
parent 0ab1f5ad3a
commit 1f7d812b98
1895 changed files with 0 additions and 7188 deletions

View File

@ -0,0 +1,38 @@
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
### IntelliJ IDEA ###
.idea/modules.xml
.idea/jarRepositories.xml
.idea/compiler.xml
.idea/libraries/
*.iws
*.iml
*.ipr
### Eclipse ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/
### Mac OS ###
.DS_Store

View File

@ -0,0 +1,3 @@
# Default ignored files
/shelf/
/workspace.xml

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding">
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" />
</component>
</project>

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="MavenProjectsManager">
<option name="originalFiles">
<list>
<option value="$PROJECT_DIR$/pom.xml" />
</list>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="17" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

View File

@ -0,0 +1,124 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Palette2">
<group name="Swing">
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
</item>
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
</item>
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.svg" removable="false" auto-create-binding="false" can-attach-label="true">
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
</item>
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
<initial-values>
<property name="text" value="Button" />
</initial-values>
</item>
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="RadioButton" />
</initial-values>
</item>
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="CheckBox" />
</initial-values>
</item>
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
<initial-values>
<property name="text" value="Label" />
</initial-values>
</item>
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
</item>
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
</item>
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
<preferred-size width="-1" height="20" />
</default-constraints>
</item>
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
</item>
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
</item>
</group>
</component>
</project>

View File

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>CT326-Assignment3</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.10.0</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,81 @@
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.time.LocalDate;
/**
* class representing a player's achievement
*/
public class Achievement {
private String achievementName;
private String description;
private LocalDate dateOfAward;
/**
* constructor for the Achievement class
* @param achievementName a String representation of the name of the Achievement
* @param description a String describing the Achievement
* @param dateOfAward a LocalDate representing the date that the Achievement was awarded
*/
public Achievement(String achievementName, String description, LocalDate dateOfAward) {
this.achievementName = achievementName;
this.description = description;
this.dateOfAward = dateOfAward;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof Achievement) {
Achievement toCompare = (Achievement) obj;
if (!achievementName.equals(toCompare.achievementName)) {
return false;
}
if (!description.equals(toCompare.description)) {
return false;
}
if (!dateOfAward.equals(toCompare.dateOfAward)) {
return false;
}
return true;
}
else { return false; }
}
/**
* getter method for the achievementName field
* @return a String representation of the name of the Achievement
*/
public String getAchievementName() { return achievementName; }
/**
* setter method for the achievementName field
* @param achievementName a String representation of the name of the Achievement
*/
public void setAchievementName(String achievementName) { this.achievementName = achievementName; }
/**
* getter method for the description field
* @return a String describing the Achievement
*/
public String getDescription() { return description; }
/**
* setter method for the description field
* @param description a String describing the Achievement
*/
public void setDescription(String description) { this.description = description; }
/**
* getter method for the dateOfAward field
* @return a LocalDate representing the date that the Achievement was awarded
*/
public LocalDate getDateOfAward() { return dateOfAward; }
/**
* setter method for the dateOfAward field
* @param dateOfAward a LocalDate representing the date that the Achievement was awarded
*/
public void setDateOfAward(LocalDate dateOfAward) { this.dateOfAward = dateOfAward; }
}

View File

@ -0,0 +1,260 @@
/**
* enum for each ISO 3166 Alpha-2 country Code
*/
public enum Country {
// Explanation of how this data was sourced:
// the following ISO 3166 Alpha-2 Codes were taken from the CSV file found here: https://pkgstore.datahub.io/core/country-list/data_csv/data/d7c9d7cfb42cb69f4422dec222dbbaa8/data_csv.csv
// the CSV file was cleaned to have UNIX line endings (as it had Windows line endings, and I am on GNU/Linux) with the command `tr -d '\r' < data_csv.csv > clean_data.csv `
// they were then parsed & read into this Java source file with the Vim / GNU AWK command `:read !awk -F',' '{gsub(/\"/, ""); print $NF ",\t// " $1}' clean_data.csv`
// finally, the block was indented in Vim and a `;` appended to the last value
AF, // Afghanistan
AX, // Åland Islands
AL, // Albania
DZ, // Algeria
AS, // American Samoa
AD, // Andorra
AO, // Angola
AI, // Anguilla
AQ, // Antarctica
AG, // Antigua and Barbuda
AR, // Argentina
AM, // Armenia
AW, // Aruba
AU, // Australia
AT, // Austria
AZ, // Azerbaijan
BS, // Bahamas
BH, // Bahrain
BD, // Bangladesh
BB, // Barbados
BY, // Belarus
BE, // Belgium
BZ, // Belize
BJ, // Benin
BM, // Bermuda
BT, // Bhutan
BO, // Bolivia
BQ, // Bonaire
BA, // Bosnia and Herzegovina
BW, // Botswana
BV, // Bouvet Island
BR, // Brazil
IO, // British Indian Ocean Territory
BN, // Brunei Darussalam
BG, // Bulgaria
BF, // Burkina Faso
BI, // Burundi
KH, // Cambodia
CM, // Cameroon
CA, // Canada
CV, // Cape Verde
KY, // Cayman Islands
CF, // Central African Republic
TD, // Chad
CL, // Chile
CN, // China
CX, // Christmas Island
CC, // Cocos (Keeling) Islands
CO, // Colombia
KM, // Comoros
CG, // Congo
CD, // Congo
CK, // Cook Islands
CR, // Costa Rica
CI, // Côte d'Ivoire
HR, // Croatia
CU, // Cuba
CW, // Curaçao
CY, // Cyprus
CZ, // Czech Republic
DK, // Denmark
DJ, // Djibouti
DM, // Dominica
DO, // Dominican Republic
EC, // Ecuador
EG, // Egypt
SV, // El Salvador
GQ, // Equatorial Guinea
ER, // Eritrea
EE, // Estonia
ET, // Ethiopia
FK, // Falkland Islands (Malvinas)
FO, // Faroe Islands
FJ, // Fiji
FI, // Finland
FR, // France
GF, // French Guiana
PF, // French Polynesia
TF, // French Southern Territories
GA, // Gabon
GM, // Gambia
GE, // Georgia
DE, // Germany
GH, // Ghana
GI, // Gibraltar
GR, // Greece
GL, // Greenland
GD, // Grenada
GP, // Guadeloupe
GU, // Guam
GT, // Guatemala
GG, // Guernsey
GN, // Guinea
GW, // Guinea-Bissau
GY, // Guyana
HT, // Haiti
HM, // Heard Island and McDonald Islands
VA, // Holy See (Vatican City State)
HN, // Honduras
HK, // Hong Kong
HU, // Hungary
IS, // Iceland
IN, // India
ID, // Indonesia
IR, // Iran
IQ, // Iraq
IE, // Ireland
IM, // Isle of Man
IL, // Israel
IT, // Italy
JM, // Jamaica
JP, // Japan
JE, // Jersey
JO, // Jordan
KZ, // Kazakhstan
KE, // Kenya
KI, // Kiribati
KP, // Korea
KR, // Korea
KW, // Kuwait
KG, // Kyrgyzstan
LA, // Lao People's Democratic Republic
LV, // Latvia
LB, // Lebanon
LS, // Lesotho
LR, // Liberia
LY, // Libya
LI, // Liechtenstein
LT, // Lithuania
LU, // Luxembourg
MO, // Macao
MK, // Macedonia
MG, // Madagascar
MW, // Malawi
MY, // Malaysia
MV, // Maldives
ML, // Mali
MT, // Malta
MH, // Marshall Islands
MQ, // Martinique
MR, // Mauritania
MU, // Mauritius
YT, // Mayotte
MX, // Mexico
FM, // Micronesia
MD, // Moldova
MC, // Monaco
MN, // Mongolia
ME, // Montenegro
MS, // Montserrat
MA, // Morocco
MZ, // Mozambique
MM, // Myanmar
NA, // Namibia
NR, // Nauru
NP, // Nepal
NL, // Netherlands
NC, // New Caledonia
NZ, // New Zealand
NI, // Nicaragua
NE, // Niger
NG, // Nigeria
NU, // Niue
NF, // Norfolk Island
MP, // Northern Mariana Islands
NO, // Norway
OM, // Oman
PK, // Pakistan
PW, // Palau
PS, // Palestine
PA, // Panama
PG, // Papua New Guinea
PY, // Paraguay
PE, // Peru
PH, // Philippines
PN, // Pitcairn
PL, // Poland
PT, // Portugal
PR, // Puerto Rico
QA, // Qatar
RE, // Réunion
RO, // Romania
RU, // Russian Federation
RW, // Rwanda
BL, // Saint Barthélemy
SH, // Saint Helena
KN, // Saint Kitts and Nevis
LC, // Saint Lucia
MF, // Saint Martin (French part)
PM, // Saint Pierre and Miquelon
VC, // Saint Vincent and the Grenadines
WS, // Samoa
SM, // San Marino
ST, // Sao Tome and Principe
SA, // Saudi Arabia
SN, // Senegal
RS, // Serbia
SC, // Seychelles
SL, // Sierra Leone
SG, // Singapore
SX, // Sint Maarten (Dutch part)
SK, // Slovakia
SI, // Slovenia
SB, // Solomon Islands
SO, // Somalia
ZA, // South Africa
GS, // South Georgia and the South Sandwich Islands
SS, // South Sudan
ES, // Spain
LK, // Sri Lanka
SD, // Sudan
SR, // Suriname
SJ, // Svalbard and Jan Mayen
SZ, // Swaziland
SE, // Sweden
CH, // Switzerland
SY, // Syrian Arab Republic
TW, // Taiwan
TJ, // Tajikistan
TZ, // Tanzania
TH, // Thailand
TL, // Timor-Leste
TG, // Togo
TK, // Tokelau
TO, // Tonga
TT, // Trinidad and Tobago
TN, // Tunisia
TR, // Turkey
TM, // Turkmenistan
TC, // Turks and Caicos Islands
TV, // Tuvalu
UG, // Uganda
UA, // Ukraine
AE, // United Arab Emirates
GB, // United Kingdom
US, // United States
UM, // United States Minor Outlying Islands
UY, // Uruguay
UZ, // Uzbekistan
VU, // Vanuatu
VE, // Venezuela
VN, // Viet Nam
VG, // Virgin Islands
VI, // Virgin Islands
WF, // Wallis and Futuna
EH, // Western Sahara
YE, // Yemen
ZM, // Zambia
ZW; // Zimbabwe
}

View File

@ -0,0 +1,184 @@
import java.io.*;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* class to represent a player
*/
public class Player implements Serializable {
private String id;
private String username;
private Country country;
private LocalDate joinDate;
private List<Achievement> achievements;
private static final String serializeAchievementsTo = "achievements.csv";
/**
* constructor for the Player class
* @param id a String representing the player's ID
* @param username a String representing the player's username
* @param country a Country object representing the country to which the player belongs
* @param joinDate a LocalDate object representing the date that the player joined the team
* @param achievements a List of Achievement objects awarded to the player
*/
public Player(String id, String username, Country country, LocalDate joinDate, List<Achievement> achievements) {
this.id = id;
this.username = username;
this.country = country;
this.joinDate = joinDate;
this.achievements = achievements;
}
/**
* overridden method to compare two objects for equality
* @param obj the object to be compared
* @return boolean - true if the objects have all the same fields equals, false otherwise
*/
@Override
public boolean equals(Object obj) {
if (obj instanceof Player) {
Player toCompare = (Player) obj;
if (!id.equals(toCompare.id)) {
return false;
}
if (!username.equals(toCompare.username)) {
return false;
}
if (!country.equals(toCompare.country)) {
return false;
}
if (!joinDate.equals(toCompare.joinDate)) {
return false;
}
if (!achievements.equals(toCompare.achievements)) {
return false;
} // note that if the lists are in different orders, this will return false
return true;
}
else { return false; }
}
/**
* method to deserialize the Player object and to read in its achievements from a CSV file
* @param out ObjectOutputStream
* @throws IOException
*/
@Serial
private void writeObject(ObjectOutputStream out) throws IOException {
// would be inappropriate to catch IOExceptions here - should be caught in the code attempting to serialize the object
out.writeObject(id);
out.writeObject(username);
out.writeObject(country);
out.writeObject(joinDate);
// deliberate design choice here to not use the writeObject method of the Achievement class
// serializing Achievements in the context of a Player's list of Achievements should be treated differently to serializing, say, a single, isolated Achievement
// there may be times when we want to serialize an Achievement without reference to a Player, without a CSV file
// writing out Achievements to CSV file
FileWriter writer = new FileWriter(serializeAchievementsTo, true); // append set to true
for (Achievement achievement : achievements) {
writer.write(id + "," + achievement.getAchievementName() + "," + achievement.getDescription() + "," + achievement.getDateOfAward().toString() + "\n");
}
writer.close();
}
/**
* method to serialize the Player object and to write out its achievements to a CSV file
* @param in ObjectInputStream
* @throws IOException
* @throws ClassNotFoundException
*/
@Serial
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
// would be inappropriate to catch exceptions here - should be caught in the code attempting to de-serialize the object
id = (String) in.readObject();
username = (String) in.readObject();
country = (Country) in.readObject();
joinDate = (LocalDate) in.readObject();
achievements = new ArrayList<>();
FileReader fileReader = new FileReader(serializeAchievementsTo);
BufferedReader bufferedReader = new BufferedReader(fileReader);
String line;
while ((line = bufferedReader.readLine()) != null) {
String[] cols = line.split(",");
// only adding to list of achievements if the player ids match
if (cols[0].equals(id)) {
achievements.add(new Achievement(cols[1], cols[2], LocalDate.parse(cols[3], DateTimeFormatter.ofPattern("yyyy-MM-dd"))));
}
}
bufferedReader.close();
}
/**
* getter method for the ID field
* @return a String representing the player's ID
*/
public String getId() { return id; }
/**
* setter method for the id field
* @param id String representing the player's ID
*/
public void setId(String id) { this.id = id; }
/**
* getter method for the username field
* @return a String representing the player's username
*/
public String getUsername() { return username; }
/**
* setter method for the username field
* @param username String representing the player's username
*/
public void setUsername(String username) { this.username = username; }
/**
* getter method for the country field
* @return a Country object
*/
public Country getCountry() { return country; }
/**
* setter method for the country field
* @param country a Country object
*/
public void setCountry(Country country) { this.country = country; }
/**
* getter method for the joinDate field
* @return a LocalDate representing the date when the player joined the team
*/
public LocalDate getJoinDate() { return joinDate; }
/**
* setter method for the joinDate field
* @param joinDate LocalDate representing the date when the player joined the team
*/
public void setJoinDate(LocalDate joinDate) { this.joinDate = joinDate; }
/**
* getter method for the achievements field
* @return a list of Achievement objects
*/
public List<Achievement> getAchievements() { return achievements; }
/**
* setter method for the achievements field
* @param achievements a list of Achievement objects
*/
public void setAchievements(List<Achievement> achievements) { this.achievements = achievements; }
}

View File

@ -0,0 +1,155 @@
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.*;
import java.io.*;
import java.time.LocalDate;
import java.util.ArrayList;
/**
* JUnit tests to test the serialization ability of the Player class
*/
public class TestSerialization {
// assuming that the instruction "Use a test-driven development approach to implement the serialization of Player objects" only applies to the serialization, and not the other functionality
/**
* method that runs after each test and deletes the achievements.csv and players.ser files
*/
@AfterEach
void deleteFiles() {
File achievementsFile = new File("achievements.csv");
achievementsFile.delete();
File playersFile = new File("player.ser");
playersFile.delete();
}
/**
* test that creates 5 player objects, serializes them, and compares them to the deserialized objects
* @throws IOException
* @throws ClassNotFoundException
*/
@Test
void serializeFivePlayers() throws IOException, ClassNotFoundException {
// deliberately not catching potential IOExceptions - we want the tests to fail if these are thrown
FileOutputStream players_file = new FileOutputStream("players.ser");
ObjectOutputStream players_out = new ObjectOutputStream(players_file);
ObjectInputStream players_in = new ObjectInputStream(new FileInputStream("players.ser"));
ArrayList<Player> players = new ArrayList<>(); // array of players to be serialized
// creating some unique players
// player 0
players.add(new Player("0", "player0", Country.IE, LocalDate.now(),
new ArrayList<>() {{
add(new Achievement("Something Award", "An award for something that was especially something", LocalDate.of(2004, 7, 6)));
}}
));
// player 1
players.add(new Player("1", "player1", Country.JP, LocalDate.now(),
new ArrayList<>() {{
add(new Achievement("Something Award", "An award for something that was especially something", LocalDate.of(2004, 7, 6)));
add(new Achievement("Another Award", "An award for something else", LocalDate.of(1996, 7, 6)));
}}
));
// player 2
players.add(new Player("2", "player2", Country.UA, LocalDate.now(),
new ArrayList<>() {{
add(new Achievement("Something Award", "An award for something that was especially something", LocalDate.of(2004, 7, 6)));
add(new Achievement("Another Award", "An award for something else", LocalDate.of(1996, 7, 6)));
add(new Achievement("Yet Another Award", "An award for something else entirely", LocalDate.of(2023, 8, 6)));
}}
));
// player 3
players.add(new Player("3", "player3", Country.AD, LocalDate.now(),
new ArrayList<>() {{
add(new Achievement("Something Award", "An award for something that was especially something", LocalDate.of(2004, 7, 6)));
add(new Achievement("Another Award", "An award for something else", LocalDate.of(1996, 7, 6)));
add(new Achievement("Yet Another Award", "An award for something else entirely", LocalDate.of(2023, 8, 6)));
add(new Achievement("A fourth award", "An award that comes after three previous awards", LocalDate.of(2022, 8, 3)));
}}
));
// player 4
players.add(new Player("4", "player4", Country.DE, LocalDate.now(),
new ArrayList<>() {{
add(new Achievement("Something Award", "An award for something that was especially something", LocalDate.of(2004, 7, 6)));
add(new Achievement("Another Award", "An award for something else", LocalDate.of(1996, 7, 6)));
add(new Achievement("Yet Another Award", "An award for something else entirely", LocalDate.of(2023, 8, 6)));
add(new Achievement("A fourth award", "An award that comes after three previous awards", LocalDate.of(2022, 8, 3)));
add(new Achievement("The final award", "The last award anyone will ever get", LocalDate.of(2030, 12, 25)));
}}
));
for (Player player : players) {
players_out.writeObject(player);
}
// looping over each player and comparing it to the de-serialized player
// doing this in a separate loop to separate writing and reading
for (Player player : players) {
// deliberately not catching exceptions here - we want the test to fail if exceptions are thrown
Player dplayer = (Player) players_in.readObject();
assertEquals(player, dplayer);
}
players_out.close();
players_file.close();
}
/**
* test the equals() method of the Player class
*/
@Test
void testPlayerDotEquals() {
// creating two identical players
Player player1 = new Player("0", "player0", Country.IE, LocalDate.now(),
new ArrayList<>(){{ add(new Achievement("Something Award", "An award for something that was especially something", LocalDate.of(2004, 7, 6))); }}
);
Player player2 = new Player("0", "player0", Country.IE, LocalDate.now(),
new ArrayList<>(){{ add(new Achievement("Something Award", "An award for something that was especially something", LocalDate.of(2004, 7, 6))); }}
);
// assertEquals uses the objects equals() method, so it suffices for this test
assertEquals(player1, player2);
}
/**
* test the equals() method of the Achievement class
*/
@Test
void testAchievementDotEquals() {
Achievement achievement1 = new Achievement("Something Award", "An award for something that was especially something", LocalDate.of(2004, 7, 6));
Achievement achievement2 = new Achievement("Something Award", "An award for something that was especially something", LocalDate.of(2004, 7, 6));
assertEquals(achievement1, achievement2);
}
/**
* test serializing & de-serializing just one player
* @throws IOException
* @throws ClassNotFoundException
*/
@Test
void testSerializePlayer() throws IOException, ClassNotFoundException {
// deliberately not catching potential IOExceptions - we want the tests to fail if these are thrown
FileOutputStream players_file = new FileOutputStream("players.ser");
ObjectOutputStream players_out = new ObjectOutputStream(players_file);
ObjectInputStream players_in = new ObjectInputStream(new FileInputStream("players.ser"));
Player player = new Player("0", "player0", Country.IE, LocalDate.now(),
new ArrayList<>(){{ add(new Achievement("Something Award", "An award for something that was especially something", LocalDate.of(2004, 7, 6))); }}
);
// serializing player object, de-serializing it, and comparing them
players_out.writeObject(player);
Player dplayer = (Player) players_in.readObject();
players_out.close();
players_file.close();
assertEquals(player, dplayer);
}
}