Week 02

public class Person {
	String name;
	double weight;
	double height;

	public Person(String name, double weight, double height) {
		this.name = name;
		this.weight = weight;
		this.height = height;
	}

	public String getName() {
		return name;
	}

	public double getWeight() {
		return weight;
	}

	public double getHeight() {
		return height;
	}

	public static void main(String[] args) {
		Person jeff = new Person("Jeff", 72.4, 2.2);
		Person jim = new Person("Jim", 65, 1.7);
		System.out.println("Jeff is " + jeff.getHeight() + "m tall.");
		System.out.println("Jim is " + jim.getHeight() + "m tall.");
	}
}
public class BMICalculator {
	Person person;

	public BMICalculator(Person p) {
		this.person = p;
	}

	public double calculateBMI() {
		double bmi = person.getWeight() / (person.getHeight() * person.getHeight());
		return bmi;
	}

	public static void main(String[] args) {
		Person jeff = new Person("Jeff", 85.4, 1.9);
		BMICalculator calculator = new BMICalculator(jeff);
		System.out.println("Jeff's BMI is: " + calculator.calculateBMI());
	}
}
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

class BMICalculatorTest {
	/*
	 * BMI should be somewhere between 20 and 30.
	 */
	@Test
	void testPersonInNormalCategory() {
		Person jeff = new Person("Jeff", 85.4, 1.9);
		BMICalculator calculator = new BMICalculator(jeff);
		double result = calculator.calculateBMI();
		assertTrue(result > 20);
		assertTrue(result < 30);
	}

	/*
	 * BMI should be zero
	 */
	@Test
	void testWeightlessPerson() {
		Person jeff = new Person("Jeff", 0, 1.9);
		BMICalculator calculator = new BMICalculator(jeff);
		double result = calculator.calculateBMI();
		assertEquals(result, 0D);
	}

	/*
	 * BMI should be infinite
	 */
	@Test
	void testHeightlessPerson() {
		Person jeff = new Person("Jeff", 85.4, 0);
		BMICalculator calculator = new BMICalculator(jeff);
		double result = calculator.calculateBMI();
		assertTrue(Double.isInfinite(result));
	}
}

Week 07

Diamond Gate

package diamond;

import java.util.Collection;
import java.util.HashSet;

class DiamondGate {

	private DiamondGateState state;
	private Collection<String> registered;
	private int visitors;
	private Collection<String> overdue, bookList;

	DiamondGate(Collection<String> registered, Collection<String> overdue) {
		this.registered = registered;
		this.overdue = overdue;
		this.bookList = new HashSet<>();
		this.visitors = 0;
		this.state = new Idle(this);
	}

	// State Machine operations

	void entry_scan(String key) {
		state.entry_scan(key);
	}

	void exit_scan(String key) {
		state.exit_scan(key);
	}

	void entry_sensor_activated() {
		state.entry_sensor_activated();
	}

	void exit_sensor_activated() {
		state.exit_sensor_activated();
	}

	void time_out() {
		state.time_out();
	}

	void pay_fine(String key) {
		state.pay_fine(key);
	}

	void return_book(String key) {
		state.return_book(key);
	}

	// Context operations

	DiamondGateState.State getState() {
		return state.getState();
	}

	void setState(DiamondGateState state) {
		this.state = state;
	}

	boolean isRegistered(String s) {
		return registered.contains(s);
	}

	void incrementVisitors() {
		visitors++;
	}

	void decrementVisitors() {
		visitors--;
	}

	int getVisitors() {
		return visitors;
	}

	boolean isOverdue(String key) {
		return overdue.contains(key);
	}

	void paid_fine(String key) {
		if (overdue.contains(key)) {
			overdue.remove(key);
			bookList.add(key);
		}
	}

	void returned_book(String key) {
		if (bookList.contains(key)) {
			bookList.remove(key);
		}
	}
}
package diamond;

abstract class DiamondGateState {

	protected enum State {IDLE, OPENEXIT, OPENENTRY, PAIDFINE}

	DiamondGate context;

	DiamondGateState(DiamondGate context) {
		this.context = context;
	}

	abstract void entry_scan(String key);

	abstract void exit_scan(String key);

	abstract void entry_sensor_activated();

	abstract void exit_sensor_activated();

	abstract void time_out();

	abstract void pay_fine(String key);

	abstract void return_book(String key);

	abstract State getState();
}
package diamond;

import org.junit.jupiter.api.Test;

import java.util.Collection;
import java.util.HashSet;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;

class DiamondGateTest {
	@Test
	void testSimpleEntry() {
		// Create our set of registered students / staff.
		Collection<String> registered = new HashSet<>();
		registered.add("ac1nw");

		Collection<String> overdue = new HashSet<>();

		// Pass this when constructing our system under test (diamondGate);
		DiamondGate diamondGate = new DiamondGate(registered, overdue);

		assertEquals(0, diamondGate.getVisitors());

		// Now for the actual test sequence:
		diamondGate.entry_scan("ac1nw");

		// We know that ac1nw is registered.
		diamondGate.entry_sensor_activated();
		diamondGate.time_out();

		// We'd expect the number of visitors in the Diamond to be 1.
		assertEquals(1, diamondGate.getVisitors());
	}

	@Test
	void testSimpleExit() {
		Collection<String> registered = new HashSet<>();
		registered.add("acs18by");

		Collection<String> overdue = new HashSet<>();

		DiamondGate diamondGate = new DiamondGate(registered, overdue);

		assertEquals(0, diamondGate.getVisitors());

		diamondGate.exit_scan("acs18by");

		diamondGate.exit_sensor_activated();
		diamondGate.time_out();

		assertEquals(-1, diamondGate.getVisitors());
	}

	@Test
	void testEntryTimeout() {
		Collection<String> registered = new HashSet<>();
		registered.add("acs18by");

		Collection<String> overdue = new HashSet<>();

		DiamondGate diamondGate = new DiamondGate(registered, overdue);

		assertEquals(0, diamondGate.getVisitors());

		diamondGate.entry_scan("acs18by");

//		diamondGate.entry_sensor_activated();
		diamondGate.time_out();

		assertEquals(0, diamondGate.getVisitors());
	}

	@Test
	void testExitTimeout() {
		Collection<String> registered = new HashSet<>();
		registered.add("acs18by");

		Collection<String> overdue = new HashSet<>();

		DiamondGate diamondGate = new DiamondGate(registered, overdue);

		assertEquals(0, diamondGate.getVisitors());

		diamondGate.exit_scan("acs18by");

//		diamondGate.exit_sensor_activated();
		diamondGate.time_out();

		assertEquals(0, diamondGate.getVisitors());
	}

	@Test
	void testOverdue() {
		Collection<String> registered = new HashSet<>();
		registered.add("acs18test");

		Collection<String> overdue = new HashSet<>();
		overdue.add("acs18test");

		DiamondGate diamondGate = new DiamondGate(registered, overdue);

		assertEquals(0, diamondGate.getVisitors());

		diamondGate.entry_scan("acs18test");

		diamondGate.entry_sensor_activated();
		diamondGate.time_out();

		assertEquals(1, diamondGate.getVisitors());

		assertTrue(diamondGate.isOverdue("acs18test"));

		diamondGate.exit_scan("acs18test");
		diamondGate.exit_sensor_activated();
		diamondGate.time_out();

		assertEquals(1, diamondGate.getVisitors());

		diamondGate.pay_fine("acs18test");

		assertFalse(diamondGate.isOverdue("acs18test"));

		assertEquals(DiamondGateState.State.PAIDFINE, diamondGate.getState());

		diamondGate.return_book("acs18test");

		assertEquals(DiamondGateState.State.IDLE, diamondGate.getState());

		diamondGate.exit_scan("acs18test");

		diamondGate.exit_sensor_activated();
		diamondGate.time_out();

		assertEquals(0, diamondGate.getVisitors());
	}

	@Test
	void testNotRegisteredEntry() {
		Collection<String> registered = new HashSet<>();
		registered.add("acs18by");

		Collection<String> overdue = new HashSet<>();

		DiamondGate diamondGate = new DiamondGate(registered, overdue);

		assertEquals(0, diamondGate.getVisitors());

		diamondGate.entry_scan("acs18test");

		diamondGate.entry_sensor_activated();
		diamondGate.time_out();

		assertEquals(0, diamondGate.getVisitors());
	}

	@Test
	void testMultiEntry() {
		Collection<String> registered = new HashSet<>();
		registered.add("acs18test1");
		registered.add("acs18test2");

		Collection<String> overdue = new HashSet<>();

		DiamondGate diamondGate = new DiamondGate(registered, overdue);

		assertEquals(0, diamondGate.getVisitors());

		diamondGate.entry_scan("acs18test1");

		diamondGate.entry_sensor_activated();
		diamondGate.time_out();

		assertEquals(1, diamondGate.getVisitors());

		diamondGate.entry_scan("acs18test2");

		diamondGate.entry_sensor_activated();
		diamondGate.time_out();

		assertEquals(2, diamondGate.getVisitors());
	}

	@Test
	void testEntryAndExit() {
		Collection<String> registered = new HashSet<>();
		registered.add("acs18test1");
		registered.add("acs18test2");

		Collection<String> overdue = new HashSet<>();

		DiamondGate diamondGate = new DiamondGate(registered, overdue);

		assertEquals(0, diamondGate.getVisitors());

		diamondGate.entry_scan("acs18test1");

		diamondGate.entry_sensor_activated();
		diamondGate.time_out();

		assertEquals(1, diamondGate.getVisitors());

		diamondGate.entry_scan("acs18test2");

		diamondGate.entry_sensor_activated();
		diamondGate.time_out();

		assertEquals(2, diamondGate.getVisitors());

		diamondGate.exit_scan("acs18test1");

		diamondGate.exit_sensor_activated();
		diamondGate.time_out();

		assertEquals(1, diamondGate.getVisitors());

		diamondGate.exit_scan("acs18test2");

		diamondGate.exit_sensor_activated();
		diamondGate.time_out();

		assertEquals(0, diamondGate.getVisitors());
	}

	@Test
	void testMultiExit() {
		Collection<String> registered = new HashSet<>();
		registered.add("acs18test1");
		registered.add("acs18test2");

		Collection<String> overdue = new HashSet<>();

		DiamondGate diamondGate = new DiamondGate(registered, overdue);

		assertEquals(0, diamondGate.getVisitors());

		diamondGate.exit_scan("acs18test1");

		diamondGate.exit_sensor_activated();
		diamondGate.time_out();

		assertEquals(-1, diamondGate.getVisitors());

		diamondGate.exit_scan("acs18test2");

		diamondGate.exit_sensor_activated();
		diamondGate.time_out();

		assertEquals(-2, diamondGate.getVisitors());
	}
}
package diamond;

class Idle extends DiamondGateState {

	Idle(DiamondGate context) {
		super(context);
	}

	@Override
	void entry_scan(String key) {
		if (context.isRegistered(key)) {
			context.setState(new OpenEntry(context));
		}
	}

	@Override
	void exit_scan(String key) {
		if (context.isRegistered(key) && !context.isOverdue(key)) {
			context.setState(new OpenExit(context));
		}
	}

	@Override
	void entry_sensor_activated() {

	}

	@Override
	void exit_sensor_activated() {

	}

	@Override
	void time_out() {

	}

	@Override
	void pay_fine(String key) {
		if (context.isOverdue(key)) {
			context.paid_fine(key);
			context.setState(new PaidFine(context));
		}
	}

	@Override
	void return_book(String key) {

	}

	@Override
	State getState() {
		return State.IDLE;
	}
}
package diamond;

import java.util.Timer;
import java.util.TimerTask;

class OpenEntry extends DiamondGateState {

	OpenEntry(DiamondGate context) {
		super(context);
		TimerTask task = new TimerTask() {
			@Override
			public void run() {
				context.time_out();
			}
		};
		Timer timer = new Timer("Timer");

		long delay = 5000L;
		timer.schedule(task, delay);
	}

	@Override
	void entry_scan(String key) {

	}

	@Override
	void exit_scan(String key) {

	}

	@Override
	void entry_sensor_activated() {
		context.incrementVisitors();
	}

	@Override
	void exit_sensor_activated() {

	}

	@Override
	void time_out() {
		context.setState(new Idle(context));
	}

	@Override
	void pay_fine(String key) {

	}

	@Override
	void return_book(String key) {

	}

	@Override
	State getState() {
		return State.OPENENTRY;
	}
}
package diamond;

import java.util.Timer;
import java.util.TimerTask;

class OpenExit extends DiamondGateState {

	OpenExit(DiamondGate context) {
		super(context);
		TimerTask task = new TimerTask() {
			@Override
			public void run() {
				context.time_out();
			}
		};
		Timer timer = new Timer("Timer");

		long delay = 5000L;
		timer.schedule(task, delay);
	}

	@Override
	void entry_scan(String key) {

	}

	@Override
	void exit_scan(String key) {

	}

	@Override
	void entry_sensor_activated() {

	}

	@Override
	void exit_sensor_activated() {
		context.decrementVisitors();
	}

	@Override
	void time_out() {
		context.setState(new Idle(context));
	}

	@Override
	void pay_fine(String key) {

	}

	@Override
	void return_book(String key) {

	}

	@Override
	State getState() {
		return State.OPENEXIT;
	}
}
package diamond;

class PaidFine extends DiamondGateState {
	PaidFine(DiamondGate context) {
		super(context);
	}

	@Override
	void entry_scan(String key) {

	}

	@Override
	void exit_scan(String key) {

	}

	@Override
	void entry_sensor_activated() {

	}

	@Override
	void exit_sensor_activated() {

	}

	@Override
	void time_out() {

	}

	@Override
	void pay_fine(String key) {

	}

	@Override
	void return_book(String key) {
		context.returned_book(key);
		context.setState(new Idle(context));
	}

	@Override
	State getState() {
		return State.PAIDFINE;
	}
}

TCP Server

public class TCP {
	TCPState state;

	public TCP() {
		this.state = new CLOSED(this);
	}

	void passive_open() {
		state.passive_open();
	}

	void close() {
		state.close();
	}

	void receive_syn() {
		state.receive_syn();
	}

	void receive_syn_ack() {
		state.receive_syn_ack();
	}

	void receive_fin() {
		state.receive_fin();
	}

	void receive_ack() {
		state.receive_ack();
	}

	void receive_ack_fin() {
		state.receive_ack_fin();
	}

	void send_syn_ack() {
		state.send_syn_ack();
	}

	void send_syn() {
		state.send_syn();
	}

	void send_ack() {
		state.send_ack();
	}

	void send_fin() {
		state.send_fin();
	}

	void timeout() {
		state.timeout();
	}

	void setState(TCPState state) {
		this.state = state;
	}

	TCPState.State getState() {
		return state.getState();
	}
}
public abstract class TCPState {
	protected enum State {
		CLOSED, LISTEN, SYN_RCVD, SYN_SENT, ESTABLISHED, CLOSE_WAIT,
		LAST_ACK, FIN_WAIT_1, FIN_WAIT_2, CLOSING, TIME_WAIT
	}

	protected TCP context;

	public TCPState(TCP context) {
		this.context = context;
	}

	public abstract void passive_open();

	public abstract void close();

	public abstract void receive_syn();

	public abstract void receive_syn_ack();

	public abstract void receive_fin();

	public abstract void receive_ack();

	public abstract void receive_ack_fin();

	public abstract void send_syn_ack();

	public abstract void send_syn();

	public abstract void send_ack();

	public abstract void send_fin();

	public abstract void timeout();

	public abstract State getState();
}
public class CLOSED extends TCPState {
	public CLOSED(TCP context) {
		super(context);
	}

	@Override
	public void passive_open() {
		context.setState(new LISTEN(context));
	}

	@Override
	public void close() {

	}

	@Override
	public void receive_syn() {

	}

	@Override
	public void receive_syn_ack() {

	}

	@Override
	public void receive_fin() {

	}

	@Override
	public void receive_ack() {

	}

	@Override
	public void receive_ack_fin() {

	}

	@Override
	public void send_syn_ack() {

	}

	@Override
	public void send_syn() {

	}

	@Override
	public void send_ack() {

	}

	@Override
	public void send_fin() {

	}

	@Override
	public void timeout() {

	}

	@Override
	public State getState() {
		return State.CLOSED;
	}
}
public class CLOSE_WAIT extends TCPState {
	public CLOSE_WAIT(TCP context) {
		super(context);
	}

	@Override
	public void passive_open() {

	}

	@Override
	public void close() {
		context.setState(new LAST_ACK(context));
	}

	@Override
	public void receive_syn() {

	}

	@Override
	public void receive_syn_ack() {

	}

	@Override
	public void receive_fin() {

	}

	@Override
	public void receive_ack() {

	}

	@Override
	public void receive_ack_fin() {

	}

	@Override
	public void send_syn_ack() {

	}

	@Override
	public void send_syn() {

	}

	@Override
	public void send_ack() {

	}

	@Override
	public void send_fin() {

	}

	@Override
	public void timeout() {

	}

	@Override
	public State getState() {
		return State.CLOSE_WAIT;
	}
}
public class CLOSING extends TCPState {
	public CLOSING(TCP context) {
		super(context);
	}

	@Override
	public void passive_open() {

	}

	@Override
	public void close() {

	}

	@Override
	public void receive_syn() {

	}

	@Override
	public void receive_syn_ack() {

	}

	@Override
	public void receive_fin() {

	}

	@Override
	public void receive_ack() {
		context.setState(new TIME_WAIT(context));
	}

	@Override
	public void receive_ack_fin() {

	}

	@Override
	public void send_syn_ack() {

	}

	@Override
	public void send_syn() {

	}

	@Override
	public void send_ack() {

	}

	@Override
	public void send_fin() {

	}

	@Override
	public void timeout() {

	}

	@Override
	public State getState() {
		return State.CLOSING;
	}
}
public class ESTABLISHED extends TCPState {
	public ESTABLISHED(TCP context) {
		super(context);
	}

	@Override
	public void passive_open() {

	}

	@Override
	public void close() {
		context.setState(new FIN_WAIT_1(context));
	}

	@Override
	public void receive_syn() {

	}

	@Override
	public void receive_syn_ack() {

	}

	@Override
	public void receive_fin() {
		context.setState(new CLOSE_WAIT(context));
	}

	@Override
	public void receive_ack() {

	}

	@Override
	public void receive_ack_fin() {

	}

	@Override
	public void send_syn_ack() {

	}

	@Override
	public void send_syn() {

	}

	@Override
	public void send_ack() {

	}

	@Override
	public void send_fin() {

	}

	@Override
	public void timeout() {

	}

	@Override
	public State getState() {
		return State.ESTABLISHED;
	}
}
import java.util.Random;

public class FIN_WAIT_1 extends TCPState {
	public FIN_WAIT_1(TCP context) {
		super(context);
	}

	@Override
	public void passive_open() {

	}

	@Override
	public void close() {

	}

	@Override
	public void receive_syn() {

	}

	@Override
	public void receive_syn_ack() {

	}

	@Override
	public void receive_fin() {
		context.setState(new CLOSING(context));
	}

	@Override
	public void receive_ack() {

	}

	@Override
	public void receive_ack_fin() {
		context.setState(new TIME_WAIT(context));
	}

	@Override
	public void send_syn_ack() {

	}

	@Override
	public void send_syn() {

	}

	@Override
	public void send_ack() {
		context.setState(new FIN_WAIT_2(context));
	}

	@Override
	public void send_fin() {

	}

	@Override
	public void timeout() {

	}

	@Override
	public State getState() {
		return State.FIN_WAIT_1;
	}
}
public class FIN_WAIT_2 extends TCPState {
	public FIN_WAIT_2(TCP context) {
		super(context);
	}

	@Override
	public void passive_open() {

	}

	@Override
	public void close() {

	}

	@Override
	public void receive_syn() {

	}

	@Override
	public void receive_syn_ack() {

	}

	@Override
	public void receive_fin() {
		context.setState(new TIME_WAIT(context));
	}

	@Override
	public void receive_ack() {

	}

	@Override
	public void receive_ack_fin() {

	}

	@Override
	public void send_syn_ack() {

	}

	@Override
	public void send_syn() {

	}

	@Override
	public void send_ack() {

	}

	@Override
	public void send_fin() {

	}

	@Override
	public void timeout() {

	}

	@Override
	public State getState() {
		return State.FIN_WAIT_2;
	}
}
public class LAST_ACK extends TCPState {
	public LAST_ACK(TCP context) {
		super(context);
	}

	@Override
	public void passive_open() {

	}

	@Override
	public void close() {

	}

	@Override
	public void receive_syn() {

	}

	@Override
	public void receive_syn_ack() {

	}

	@Override
	public void receive_fin() {

	}

	@Override
	public void receive_ack() {
		context.setState(new CLOSED(context));
	}

	@Override
	public void receive_ack_fin() {

	}

	@Override
	public void send_syn_ack() {

	}

	@Override
	public void send_syn() {

	}

	@Override
	public void send_ack() {

	}

	@Override
	public void send_fin() {

	}

	@Override
	public void timeout() {

	}

	@Override
	public State getState() {
		return State.LAST_ACK;
	}
}
public class LISTEN extends TCPState {
	public LISTEN(TCP context) {
		super(context);
	}

	@Override
	public void passive_open() {

	}

	@Override
	public void close() {
		context.setState(new CLOSED(context));
	}

	@Override
	public void receive_syn() {
		context.setState(new SYN_RCVD(context));
	}

	@Override
	public void receive_syn_ack() {

	}

	@Override
	public void receive_fin() {

	}

	@Override
	public void receive_ack() {

	}

	@Override
	public void receive_ack_fin() {

	}

	@Override
	public void send_syn_ack() {

	}

	@Override
	public void send_syn() {
		context.setState(new SYN_SENT(context));
	}

	@Override
	public void send_ack() {

	}

	@Override
	public void send_fin() {

	}

	@Override
	public void timeout() {

	}

	@Override
	public State getState() {
		return State.LISTEN;
	}
}
public class SYN_RCVD extends TCPState {
	public SYN_RCVD(TCP context) {
		super(context);
	}

	@Override
	public void passive_open() {

	}

	@Override
	public void close() {
		context.setState(new FIN_WAIT_1(context));
	}

	@Override
	public void receive_syn() {

	}

	@Override
	public void receive_syn_ack() {

	}

	@Override
	public void receive_fin() {

	}

	@Override
	public void receive_ack() {

	}

	@Override
	public void receive_ack_fin() {

	}

	@Override
	public void send_syn_ack() {

	}

	@Override
	public void send_syn() {

	}

	@Override
	public void send_ack() {
		context.setState(new ESTABLISHED(context));
	}

	@Override
	public void send_fin() {

	}

	@Override
	public void timeout() {

	}

	@Override
	public State getState() {
		return State.SYN_RCVD;
	}
}
public class SYN_SENT extends TCPState {
	public SYN_SENT(TCP context) {
		super(context);
	}

	@Override
	public void passive_open() {

	}

	@Override
	public void close() {

	}

	@Override
	public void receive_syn() {
		context.setState(new SYN_RCVD(context));
	}

	@Override
	public void receive_syn_ack() {
		context.setState(new ESTABLISHED(context));
	}

	@Override
	public void receive_fin() {

	}

	@Override
	public void receive_ack() {

	}

	@Override
	public void receive_ack_fin() {

	}

	@Override
	public void send_syn_ack() {

	}

	@Override
	public void send_syn() {

	}

	@Override
	public void send_ack() {

	}

	@Override
	public void send_fin() {

	}

	@Override
	public void timeout() {

	}

	@Override
	public State getState() {
		return State.SYN_SENT;
	}
}
import java.util.Timer;
import java.util.TimerTask;

public class TIME_WAIT extends TCPState {
	public TIME_WAIT(TCP context) {
		super(context);
		TimerTask task = new TimerTask() {
			@Override
			public void run() {
				context.timeout();
			}
		};
		Timer timer = new Timer("Timer");

		long delay = 5000L;
		timer.schedule(task, delay);
	}

	@Override
	public void passive_open() {

	}

	@Override
	public void close() {

	}

	@Override
	public void receive_syn() {

	}

	@Override
	public void receive_syn_ack() {

	}

	@Override
	public void receive_fin() {

	}

	@Override
	public void receive_ack() {

	}

	@Override
	public void receive_ack_fin() {

	}

	@Override
	public void send_syn_ack() {

	}

	@Override
	public void send_syn() {

	}

	@Override
	public void send_ack() {

	}

	@Override
	public void send_fin() {

	}

	@Override
	public void timeout() {
		context.setState(new CLOSED(context));
	}

	@Override
	public State getState() {
		return State.TIME_WAIT;
	}
}
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;

class TCPTest {
	@Test
	void testTCP1() {
		TCP tcp = new TCP();
		System.out.print(tcp.getState());
		assertEquals(TCPState.State.CLOSED, tcp.getState());

		System.out.print("->");

		tcp.passive_open();
		System.out.print(tcp.getState());
		assertEquals(TCPState.State.LISTEN, tcp.getState());

		System.out.print("->");

		tcp.receive_syn();
		System.out.print(tcp.getState());
		assertEquals(TCPState.State.SYN_RCVD, tcp.getState());

		System.out.print("->");

		tcp.send_ack();
		System.out.print(tcp.getState());
		assertEquals(TCPState.State.ESTABLISHED, tcp.getState());

		System.out.print("->");

		tcp.receive_fin();
		System.out.print(tcp.getState());
		assertEquals(TCPState.State.CLOSE_WAIT, tcp.getState());

		System.out.print("->");

		tcp.close();
		System.out.print(tcp.getState());
		assertEquals(TCPState.State.LAST_ACK, tcp.getState());

		System.out.print("->");

		tcp.receive_ack();
		System.out.print(tcp.getState());
		assertEquals(TCPState.State.CLOSED, tcp.getState());

		System.out.println();
	}

	@Test
	void testTCP2() {
		TCP tcp = new TCP();
		System.out.print(tcp.getState());
		assertEquals(TCPState.State.CLOSED, tcp.getState());

		System.out.print("->");

		tcp.passive_open();
		System.out.print(tcp.getState());
		assertEquals(TCPState.State.LISTEN, tcp.getState());

		System.out.print("->");

		tcp.send_syn();
		System.out.print(tcp.getState());
		assertEquals(TCPState.State.SYN_SENT, tcp.getState());

		System.out.print("->");

		tcp.receive_syn_ack();
		System.out.print(tcp.getState());
		assertEquals(TCPState.State.ESTABLISHED, tcp.getState());

		System.out.print("->");

		tcp.close();
		System.out.print(tcp.getState());
		assertEquals(TCPState.State.FIN_WAIT_1, tcp.getState());

		System.out.print("->");

		tcp.receive_fin();
		System.out.print(tcp.getState());
		assertEquals(TCPState.State.CLOSING, tcp.getState());

		System.out.print("->");

		tcp.receive_ack();
		System.out.print(tcp.getState());
		assertEquals(TCPState.State.TIME_WAIT, tcp.getState());

		System.out.print("->");

		tcp.timeout();
		System.out.print(tcp.getState());
		assertEquals(TCPState.State.CLOSED, tcp.getState());

		System.out.println();
	}

	@Test
	void testTCP3() {
		TCP tcp = new TCP();
		System.out.print(tcp.getState());
		assertEquals(TCPState.State.CLOSED, tcp.getState());

		System.out.print("->");

		tcp.passive_open();
		System.out.print(tcp.getState());
		assertEquals(TCPState.State.LISTEN, tcp.getState());

		System.out.print("->");

		tcp.send_syn();
		System.out.print(tcp.getState());
		assertEquals(TCPState.State.SYN_SENT, tcp.getState());

		System.out.print("->");

		tcp.receive_syn();
		System.out.print(tcp.getState());
		assertEquals(TCPState.State.SYN_RCVD, tcp.getState());

		System.out.print("->");

		tcp.close();
		System.out.print(tcp.getState());
		assertEquals(TCPState.State.FIN_WAIT_1, tcp.getState());

		System.out.print("->");

		tcp.send_ack();
		System.out.print(tcp.getState());
		assertEquals(TCPState.State.FIN_WAIT_2, tcp.getState());

		System.out.print("->");

		tcp.receive_fin();
		System.out.print(tcp.getState());
		assertEquals(TCPState.State.TIME_WAIT, tcp.getState());

		System.out.print("->");

		tcp.timeout();
		System.out.print(tcp.getState());
		assertEquals(TCPState.State.CLOSED, tcp.getState());

		System.out.println();
	}

	@Test
	void testTCP4() {
		TCP tcp = new TCP();
		System.out.print(tcp.getState());
		assertEquals(TCPState.State.CLOSED, tcp.getState());

		System.out.print("->");

		tcp.passive_open();
		System.out.print(tcp.getState());
		assertEquals(TCPState.State.LISTEN, tcp.getState());

		System.out.print("->");

		tcp.receive_syn();
		System.out.print(tcp.getState());
		assertEquals(TCPState.State.SYN_RCVD, tcp.getState());

		System.out.print("->");

		tcp.close();
		System.out.print(tcp.getState());
		assertEquals(TCPState.State.FIN_WAIT_1, tcp.getState());

		System.out.print("->");

		tcp.receive_ack_fin();
		System.out.print(tcp.getState());
		assertEquals(TCPState.State.TIME_WAIT, tcp.getState());

		System.out.print("->");

		tcp.timeout();
		System.out.print(tcp.getState());
		assertEquals(TCPState.State.CLOSED, tcp.getState());

		System.out.println();
	}

	@Test
	void testTCP5() {
		TCP tcp = new TCP();
		System.out.print(tcp.getState());
		assertEquals(TCPState.State.CLOSED, tcp.getState());

		System.out.print("->");

		tcp.passive_open();
		System.out.print(tcp.getState());
		assertEquals(TCPState.State.LISTEN, tcp.getState());

		System.out.print("->");

		tcp.receive_syn();
		System.out.print(tcp.getState());
		assertEquals(TCPState.State.SYN_RCVD, tcp.getState());

		System.out.print("->");

		tcp.send_ack();
		System.out.print(tcp.getState());
		assertEquals(TCPState.State.ESTABLISHED, tcp.getState());

		System.out.print("->");

		tcp.close();
		System.out.print(tcp.getState());
		assertEquals(TCPState.State.FIN_WAIT_1, tcp.getState());

		System.out.print("->");

		tcp.receive_ack_fin();
		System.out.print(tcp.getState());
		assertEquals(TCPState.State.TIME_WAIT, tcp.getState());

		System.out.print("->");

		tcp.timeout();
		System.out.print(tcp.getState());
		assertEquals(TCPState.State.CLOSED, tcp.getState());

		System.out.println();
	}
}
package dateTests;

import org.junit.jupiter.api.Test;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

import static org.junit.jupiter.api.Assertions.assertEquals;

class MetaMorphicTestingExample {
	/**
	 * Illustration of how one might test the Metamorphic relation MA,
	 * given as example in the assignment (that the day of the week can
	 * be optional.
	 */
	@Test
	void MA() {
		//Imagine that the following string had been in our CatPart tests:
		String originalInput = "Tue, 3 Jun 2008 11:05:30 GMT";
		//Now we compute the output from the original test case.
		LocalDateTime originalDateTime = LocalDateTime.parse(originalInput, DateTimeFormatter.RFC_1123_DATE_TIME);

		/*Now we generate a new test input to test the Metamorphic relation.
		 * For the relation MA, we remove the 'Tue' part of the input, and make
		 * the assumption that we should also remove the subsequent comma and space
		 * as well to avoid a parsing error:
		 */

		String metaMorphInput = "3 Jun 2008 11:05:30 GMT";
		LocalDateTime metaMorphDateTime = LocalDateTime.parse(metaMorphInput, DateTimeFormatter.RFC_1123_DATE_TIME);

		/*Our Metamorphic relation suggests that the resulting time should remain
		 * equal to the original time. Therefore we make this our test oracle:
		 */

		assertEquals(originalDateTime, metaMorphDateTime);
	}
}
package dateTests;

import org.junit.jupiter.api.Test;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

class CatPart {
	@Test
	void test0() {
		String originalInput = "Mon, 6 Jan 2020 10:05:04 GMT";
		LocalDateTime originalDateTime = LocalDateTime.parse(originalInput, DateTimeFormatter.RFC_1123_DATE_TIME);
		/*
		 * day-of-week: weekdays
		 * day-of-month: first third of month
		 * month-of-year: quarter 1
		 * year: leap year
		 * hour-of-day: am, even
		 * minute-of-hour: <10, odd
		 * second-of-minute: <10, even
		 * offset ID: GMT
		 */
	}

	@Test
	void test1() {
		String originalInput = "Tue, 17 Apr 2018 09:06:07 -0100";
		LocalDateTime originalDateTime = LocalDateTime.parse(originalInput, DateTimeFormatter.RFC_1123_DATE_TIME);
		/*
		 * day-of-week: weekdays
		 * day-of-month: middle third of month
		 * month-of-year: quarter 2
		 * year: common year
		 * hour-of-day: am, odd
		 * minute-of-hour: <10, even
		 * second-of-minute: <10, odd
		 * offset ID: -, is a multiple of an hour
		 */
	}

	@Test
	void test2() {
		String originalInput = "Wed, 22 Jul 2020 08:12:33 -0130";
		LocalDateTime originalDateTime = LocalDateTime.parse(originalInput, DateTimeFormatter.RFC_1123_DATE_TIME);
		/*
		 * day-of-week: weekdays
		 * day-of-month: last third of month
		 * month-of-year: quarter 3
		 * year: leap year
		 * hour-of-day: am, even
		 * minute-of-hour: >=10, even
		 * second-of-minute: >=10, odd
		 * offset ID: -, is not a multiple of an hour
		 */
	}

	@Test
	void test3() {
		String originalInput = "Thu, 4 Oct 2018 13:16:21 +0230";
		LocalDateTime originalDateTime = LocalDateTime.parse(originalInput, DateTimeFormatter.RFC_1123_DATE_TIME);
		/*
		 * day-of-week: weekdays
		 * day-of-month: first third of month
		 * month-of-year: quarter 4
		 * year: common year
		 * hour-of-day: pm, odd
		 * minute-of-hour: >=10, even
		 * second-of-minute: >=10, odd
		 * offset ID: +, is not a multiple of an hour
		 */
	}

	@Test
	void test4() {
		String originalInput = "Fri, 14 Feb 2020 14:05:30 +0330";
		LocalDateTime originalDateTime = LocalDateTime.parse(originalInput, DateTimeFormatter.RFC_1123_DATE_TIME);
		/*
		 * day-of-week: weekdays
		 * day-of-month: middle third of month
		 * month-of-year: quarter 1
		 * year: leap year
		 * hour-of-day: pm, even
		 * minute-of-hour: <10, odd
		 * second-of-minute: >=10, even
		 * offset ID: +, is not a multiple of an hour
		 */
	}

	@Test
	void test5() {
		String originalInput = "Sat, 26 May 2018 07:03:40 -0500";
		LocalDateTime originalDateTime = LocalDateTime.parse(originalInput, DateTimeFormatter.RFC_1123_DATE_TIME);
		/*
		 * day-of-week: weekends
		 * day-of-month: last third of month
		 * month-of-year: quarter 2
		 * year: common year
		 * hour-of-day: am, odd
		 * minute-of-hour: <10, odd
		 * second-of-minute: >=10, even
		 * offset ID: -, is a multiple of an hour
		 */
	}

	@Test
	void test6() {
		String originalInput = "Sat, 8 Aug 2020 06:35:07 GMT";
		LocalDateTime originalDateTime = LocalDateTime.parse(originalInput, DateTimeFormatter.RFC_1123_DATE_TIME);
		/*
		 * day-of-week: weekends
		 * day-of-month: first third of month
		 * month-of-year: quarter 3
		 * year: leap year
		 * hour-of-day: am, even
		 * minute-of-hour: >=10, odd
		 * second-of-minute: <10, odd
		 * offset ID: GMT
		 */
	}

	@Test
	void test7() {
		String originalInput = "Sat, 17 Nov 2018 15:08:02 +0630";
		LocalDateTime originalDateTime = LocalDateTime.parse(originalInput, DateTimeFormatter.RFC_1123_DATE_TIME);
		/*
		 * day-of-week: weekends
		 * day-of-month: middle third of month
		 * month-of-year: quarter 4
		 * year: common year
		 * hour-of-day: pm, odd
		 * minute-of-hour: >=10, even
		 * second-of-minute: <10, even
		 * offset ID: +, is not a multiple of an hour
		 */
	}

	@Test
	void test8() {
		String originalInput = "Sun, 22 Mar 2020 17:09:03 -0700";
		LocalDateTime originalDateTime = LocalDateTime.parse(originalInput, DateTimeFormatter.RFC_1123_DATE_TIME);
		/*
		 * day-of-week: weekends
		 * day-of-month: last third of month
		 * month-of-year: quarter 1
		 * year: leap year
		 * hour-of-day: pm, odd
		 * minute-of-hour: <10, odd
		 * second-of-minute: <10, odd
		 * offset ID: -, is a multiple of an hour
		 */
	}

	@Test
	void test9() {
		String originalInput = "Sun, 3 Jun 2018 18:50:20 +0800";
		LocalDateTime originalDateTime = LocalDateTime.parse(originalInput, DateTimeFormatter.RFC_1123_DATE_TIME);
		/*
		 * day-of-week: weekends
		 * day-of-month: first third of month
		 * month-of-year: quarter 2
		 * year: common year
		 * hour-of-day: pm, even
		 * minute-of-hour: >=10, even
		 * second-of-minute: >=10, even
		 * offset ID: +, is a multiple of an hour
		 */
	}
}
package dateTests;

import org.junit.jupiter.api.Test;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

import static org.junit.jupiter.api.Assertions.assertEquals;

class MA {
	/*
	 * The year plus 1 should equals to the day plus 365 or 366(when leap year).
	 */
	@Test
	void test0() {
		String originalInput = "Mon, 6 Jan 2020 10:05:04 GMT";
		LocalDateTime originalDateTime = LocalDateTime.parse(originalInput, DateTimeFormatter.RFC_1123_DATE_TIME);
		/*
		 * day-of-week: weekdays
		 * day-of-month: first third of month
		 * month-of-year: quarter 1
		 * year: leap year
		 * hour-of-day: am, even
		 * minute-of-hour: <10, odd
		 * second-of-minute: <10, even
		 * offset ID: GMT
		 */
		String metamorphicInput = "Wed, 6 Jan 2021 10:05:04 GMT";
		LocalDateTime metamorphicDateTime = LocalDateTime.parse(metamorphicInput, DateTimeFormatter.RFC_1123_DATE_TIME);

		assertEquals(originalDateTime, metamorphicDateTime.minusDays(366));
	}

	@Test
	void test1() {
		String originalInput = "Tue, 17 Apr 2018 09:06:07 -0100";
		LocalDateTime originalDateTime = LocalDateTime.parse(originalInput, DateTimeFormatter.RFC_1123_DATE_TIME);
		/*
		 * day-of-week: weekdays
		 * day-of-month: middle third of month
		 * month-of-year: quarter 2
		 * year: common year
		 * hour-of-day: am, odd
		 * minute-of-hour: <10, even
		 * second-of-minute: <10, odd
		 * offset ID: -, is a multiple of an hour
		 */
		String metamorphicInput = "Wed, 17 Apr 2019 09:06:07 -0100";
		LocalDateTime metamorphicDateTime = LocalDateTime.parse(metamorphicInput, DateTimeFormatter.RFC_1123_DATE_TIME);

		assertEquals(originalDateTime, metamorphicDateTime.minusDays(365));
	}

	@Test
	void test2() {
		String originalInput = "Wed, 22 Jul 2020 08:12:33 -0130";
		LocalDateTime originalDateTime = LocalDateTime.parse(originalInput, DateTimeFormatter.RFC_1123_DATE_TIME);
		/*
		 * day-of-week: weekdays
		 * day-of-month: last third of month
		 * month-of-year: quarter 3
		 * year: leap year
		 * hour-of-day: am, even
		 * minute-of-hour: >=10, even
		 * second-of-minute: >=10, odd
		 * offset ID: -, is not a multiple of an hour
		 */
		String metamorphicInput = "Thu, 22 Jul 2021 08:12:33 -0130";
		LocalDateTime metamorphicDateTime = LocalDateTime.parse(metamorphicInput, DateTimeFormatter.RFC_1123_DATE_TIME);

		assertEquals(originalDateTime, metamorphicDateTime.minusDays(365));
	}

	@Test
	void test3() {
		String originalInput = "Thu, 4 Oct 2018 13:16:21 +0230";
		LocalDateTime originalDateTime = LocalDateTime.parse(originalInput, DateTimeFormatter.RFC_1123_DATE_TIME);
		/*
		 * day-of-week: weekdays
		 * day-of-month: first third of month
		 * month-of-year: quarter 4
		 * year: common year
		 * hour-of-day: pm, odd
		 * minute-of-hour: >=10, even
		 * second-of-minute: >=10, odd
		 * offset ID: +, is not a multiple of an hour
		 */
		String metamorphicInput = "Fri, 4 Oct 2019 13:16:21 +0230";
		LocalDateTime metamorphicDateTime = LocalDateTime.parse(metamorphicInput, DateTimeFormatter.RFC_1123_DATE_TIME);

		assertEquals(originalDateTime, metamorphicDateTime.minusDays(365));
	}

	@Test
	void test4() {
		String originalInput = "Fri, 14 Feb 2020 14:05:30 +0330";
		LocalDateTime originalDateTime = LocalDateTime.parse(originalInput, DateTimeFormatter.RFC_1123_DATE_TIME);
		/*
		 * day-of-week: weekdays
		 * day-of-month: middle third of month
		 * month-of-year: quarter 1
		 * year: leap year
		 * hour-of-day: pm, even
		 * minute-of-hour: <10, odd
		 * second-of-minute: >=10, even
		 * offset ID: +, is not a multiple of an hour
		 */
		String metamorphicInput = "Sun, 14 Feb 2021 14:05:30 +0330";
		LocalDateTime metamorphicDateTime = LocalDateTime.parse(metamorphicInput, DateTimeFormatter.RFC_1123_DATE_TIME);

		assertEquals(originalDateTime, metamorphicDateTime.minusDays(366));
	}

	@Test
	void test5() {
		String originalInput = "Sat, 26 May 2018 07:03:40 -0500";
		LocalDateTime originalDateTime = LocalDateTime.parse(originalInput, DateTimeFormatter.RFC_1123_DATE_TIME);
		/*
		 * day-of-week: weekends
		 * day-of-month: last third of month
		 * month-of-year: quarter 2
		 * year: common year
		 * hour-of-day: am, odd
		 * minute-of-hour: <10, odd
		 * second-of-minute: >=10, even
		 * offset ID: -, is a multiple of an hour
		 */
		String metamorphicInput = "Sun, 26 May 2019 07:03:40 -0500";
		LocalDateTime metamorphicDateTime = LocalDateTime.parse(metamorphicInput, DateTimeFormatter.RFC_1123_DATE_TIME);

		assertEquals(originalDateTime, metamorphicDateTime.minusDays(365));
	}

	@Test
	void test6() {
		String originalInput = "Sat, 8 Aug 2020 06:35:07 GMT";
		LocalDateTime originalDateTime = LocalDateTime.parse(originalInput, DateTimeFormatter.RFC_1123_DATE_TIME);
		/*
		 * day-of-week: weekends
		 * day-of-month: first third of month
		 * month-of-year: quarter 3
		 * year: leap year
		 * hour-of-day: am, even
		 * minute-of-hour: >=10, odd
		 * second-of-minute: <10, odd
		 * offset ID: GMT
		 */
		String metamorphicInput = "Sun, 8 Aug 2021 06:35:07 GMT";
		LocalDateTime metamorphicDateTime = LocalDateTime.parse(metamorphicInput, DateTimeFormatter.RFC_1123_DATE_TIME);

		assertEquals(originalDateTime, metamorphicDateTime.minusDays(365));
	}

	@Test
	void test7() {
		String originalInput = "Sat, 17 Nov 2018 15:08:02 +0630";
		LocalDateTime originalDateTime = LocalDateTime.parse(originalInput, DateTimeFormatter.RFC_1123_DATE_TIME);
		/*
		 * day-of-week: weekends
		 * day-of-month: middle third of month
		 * month-of-year: quarter 4
		 * year: common year
		 * hour-of-day: pm, odd
		 * minute-of-hour: >=10, even
		 * second-of-minute: <10, even
		 * offset ID: +, is not a multiple of an hour
		 */
		String metamorphicInput = "Sun, 17 Nov 2019 15:08:02 +0630";
		LocalDateTime metamorphicDateTime = LocalDateTime.parse(metamorphicInput, DateTimeFormatter.RFC_1123_DATE_TIME);

		assertEquals(originalDateTime, metamorphicDateTime.minusDays(365));
	}

	@Test
	void test8() {
		String originalInput = "Sun, 22 Mar 2020 17:09:03 -0700";
		LocalDateTime originalDateTime = LocalDateTime.parse(originalInput, DateTimeFormatter.RFC_1123_DATE_TIME);
		/*
		 * day-of-week: weekends
		 * day-of-month: last third of month
		 * month-of-year: quarter 1
		 * year: leap year
		 * hour-of-day: pm, odd
		 * minute-of-hour: <10, odd
		 * second-of-minute: <10, odd
		 * offset ID: -, is a multiple of an hour
		 */
		String metamorphicInput = "Mon, 22 Mar 2021 17:09:03 -0700";
		LocalDateTime metamorphicDateTime = LocalDateTime.parse(metamorphicInput, DateTimeFormatter.RFC_1123_DATE_TIME);

		assertEquals(originalDateTime, metamorphicDateTime.minusDays(365));
	}

	@Test
	void test9() {
		String originalInput = "Sun, 3 Jun 2018 18:50:20 +0800";
		LocalDateTime originalDateTime = LocalDateTime.parse(originalInput, DateTimeFormatter.RFC_1123_DATE_TIME);
		/*
		 * day-of-week: weekends
		 * day-of-month: first third of month
		 * month-of-year: quarter 2
		 * year: common year
		 * hour-of-day: pm, even
		 * minute-of-hour: >=10, even
		 * second-of-minute: >=10, even
		 * offset ID: +, is a multiple of an hour
		 */
		String metamorphicInput = "Mon, 3 Jun 2019 18:50:20 +0800";
		LocalDateTime metamorphicDateTime = LocalDateTime.parse(metamorphicInput, DateTimeFormatter.RFC_1123_DATE_TIME);

		assertEquals(originalDateTime, metamorphicDateTime.minusDays(365));
	}
}
package dateTests;

import org.junit.jupiter.api.Test;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

import static org.junit.jupiter.api.Assertions.assertEquals;

class MB {
	/*
	 * When year changes, the month of year of two time should be equal.
	 */
	@Test
	void test0() {
		String originalInput = "Mon, 6 Jan 2020 10:05:04 GMT";
		LocalDateTime originalDateTime = LocalDateTime.parse(originalInput, DateTimeFormatter.RFC_1123_DATE_TIME);
		/*
		 * day-of-week: weekdays
		 * day-of-month: first third of month
		 * month-of-year: quarter 1
		 * year: leap year
		 * hour-of-day: am, even
		 * minute-of-hour: <10, odd
		 * second-of-minute: <10, even
		 * offset ID: GMT
		 */
		String metamorphicInput = "Mon, 6 Jan 2025 10:05:04 GMT";
		LocalDateTime metamorphicDateTime = LocalDateTime.parse(metamorphicInput, DateTimeFormatter.RFC_1123_DATE_TIME);

		assertEquals(originalDateTime.getMonth(), metamorphicDateTime.getMonth());
	}

	@Test
	void test1() {
		String originalInput = "Tue, 17 Apr 2018 09:06:07 -0100";
		LocalDateTime originalDateTime = LocalDateTime.parse(originalInput, DateTimeFormatter.RFC_1123_DATE_TIME);
		/*
		 * day-of-week: weekdays
		 * day-of-month: middle third of month
		 * month-of-year: quarter 2
		 * year: common year
		 * hour-of-day: am, odd
		 * minute-of-hour: <10, even
		 * second-of-minute: <10, odd
		 * offset ID: -, is a multiple of an hour
		 */
		String metamorphicInput = "Mon, 17 Apr 2017 09:06:07 -0100";
		LocalDateTime metamorphicDateTime = LocalDateTime.parse(metamorphicInput, DateTimeFormatter.RFC_1123_DATE_TIME);

		assertEquals(originalDateTime.getMonth(), metamorphicDateTime.getMonth());
	}

	@Test
	void test2() {
		String originalInput = "Wed, 22 Jul 2020 08:12:33 -0130";
		LocalDateTime originalDateTime = LocalDateTime.parse(originalInput, DateTimeFormatter.RFC_1123_DATE_TIME);
		/*
		 * day-of-week: weekdays
		 * day-of-month: last third of month
		 * month-of-year: quarter 3
		 * year: leap year
		 * hour-of-day: am, even
		 * minute-of-hour: >=10, even
		 * second-of-minute: >=10, odd
		 * offset ID: -, is not a multiple of an hour
		 */
		String metamorphicInput = "Sat, 22 Jul 2028 08:12:33 -0130";
		LocalDateTime metamorphicDateTime = LocalDateTime.parse(metamorphicInput, DateTimeFormatter.RFC_1123_DATE_TIME);

		assertEquals(originalDateTime.getMonth(), metamorphicDateTime.getMonth());
	}

	@Test
	void test3() {
		String originalInput = "Thu, 4 Oct 2018 13:16:21 +0230";
		LocalDateTime originalDateTime = LocalDateTime.parse(originalInput, DateTimeFormatter.RFC_1123_DATE_TIME);
		/*
		 * day-of-week: weekdays
		 * day-of-month: first third of month
		 * month-of-year: quarter 4
		 * year: common year
		 * hour-of-day: pm, odd
		 * minute-of-hour: >=10, even
		 * second-of-minute: >=10, odd
		 * offset ID: +, is not a multiple of an hour
		 */
		String metamorphicInput = "Sat, 4 Oct 2008 13:16:21 +0230";
		LocalDateTime metamorphicDateTime = LocalDateTime.parse(metamorphicInput, DateTimeFormatter.RFC_1123_DATE_TIME);

		assertEquals(originalDateTime.getMonth(), metamorphicDateTime.getMonth());
	}

	@Test
	void test4() {
		String originalInput = "Fri, 14 Feb 2020 14:05:30 +0330";
		LocalDateTime originalDateTime = LocalDateTime.parse(originalInput, DateTimeFormatter.RFC_1123_DATE_TIME);
		/*
		 * day-of-week: weekdays
		 * day-of-month: middle third of month
		 * month-of-year: quarter 1
		 * year: leap year
		 * hour-of-day: pm, even
		 * minute-of-hour: <10, odd
		 * second-of-minute: >=10, even
		 * offset ID: +, is not a multiple of an hour
		 */
		String metamorphicInput = "Tue, 14 Feb 2012 14:05:30 +0330";
		LocalDateTime metamorphicDateTime = LocalDateTime.parse(metamorphicInput, DateTimeFormatter.RFC_1123_DATE_TIME);

		assertEquals(originalDateTime.getMonth(), metamorphicDateTime.getMonth());
	}

	@Test
	void test5() {
		String originalInput = "Sat, 26 May 2018 07:03:40 -0500";
		LocalDateTime originalDateTime = LocalDateTime.parse(originalInput, DateTimeFormatter.RFC_1123_DATE_TIME);
		/*
		 * day-of-week: weekends
		 * day-of-month: last third of month
		 * month-of-year: quarter 2
		 * year: common year
		 * hour-of-day: am, odd
		 * minute-of-hour: <10, odd
		 * second-of-minute: >=10, even
		 * offset ID: -, is a multiple of an hour
		 */
		String metamorphicInput = "Tue, 26 May 2218 07:03:40 -0500";
		LocalDateTime metamorphicDateTime = LocalDateTime.parse(metamorphicInput, DateTimeFormatter.RFC_1123_DATE_TIME);

		assertEquals(originalDateTime.getMonth(), metamorphicDateTime.getMonth());
	}

	@Test
	void test6() {
		String originalInput = "Sat, 8 Aug 2020 06:35:07 GMT";
		LocalDateTime originalDateTime = LocalDateTime.parse(originalInput, DateTimeFormatter.RFC_1123_DATE_TIME);
		/*
		 * day-of-week: weekends
		 * day-of-month: first third of month
		 * month-of-year: quarter 3
		 * year: leap year
		 * hour-of-day: am, even
		 * minute-of-hour: >=10, odd
		 * second-of-minute: <10, odd
		 * offset ID: GMT
		 */
		String metamorphicInput = "Thu, 8 Aug 2120 06:35:07 GMT";
		LocalDateTime metamorphicDateTime = LocalDateTime.parse(metamorphicInput, DateTimeFormatter.RFC_1123_DATE_TIME);

		assertEquals(originalDateTime.getMonth(), metamorphicDateTime.getMonth());
	}

	@Test
	void test7() {
		String originalInput = "Sat, 17 Nov 2018 15:08:02 +0630";
		LocalDateTime originalDateTime = LocalDateTime.parse(originalInput, DateTimeFormatter.RFC_1123_DATE_TIME);
		/*
		 * day-of-week: weekends
		 * day-of-month: middle third of month
		 * month-of-year: quarter 4
		 * year: common year
		 * hour-of-day: pm, odd
		 * minute-of-hour: >=10, even
		 * second-of-minute: <10, even
		 * offset ID: +, is not a multiple of an hour
		 */
		String metamorphicInput = "Sun, 17 Nov 1996 15:08:02 +0630";
		LocalDateTime metamorphicDateTime = LocalDateTime.parse(metamorphicInput, DateTimeFormatter.RFC_1123_DATE_TIME);

		assertEquals(originalDateTime.getMonth(), metamorphicDateTime.getMonth());
	}

	@Test
	void test8() {
		String originalInput = "Sun, 22 Mar 2020 17:09:03 -0700";
		LocalDateTime originalDateTime = LocalDateTime.parse(originalInput, DateTimeFormatter.RFC_1123_DATE_TIME);
		/*
		 * day-of-week: weekends
		 * day-of-month: last third of month
		 * month-of-year: quarter 1
		 * year: leap year
		 * hour-of-day: pm, odd
		 * minute-of-hour: <10, odd
		 * second-of-minute: <10, odd
		 * offset ID: -, is a multiple of an hour
		 */
		String metamorphicInput = "Mon, 22 Mar 1920 17:09:03 -0700";
		LocalDateTime metamorphicDateTime = LocalDateTime.parse(metamorphicInput, DateTimeFormatter.RFC_1123_DATE_TIME);

		assertEquals(originalDateTime.getMonth(), metamorphicDateTime.getMonth());
	}

	@Test
	void test9() {
		String originalInput = "Sun, 3 Jun 2018 18:50:20 +0800";
		LocalDateTime originalDateTime = LocalDateTime.parse(originalInput, DateTimeFormatter.RFC_1123_DATE_TIME);
		/*
		 * day-of-week: weekends
		 * day-of-month: first third of month
		 * month-of-year: quarter 2
		 * year: common year
		 * hour-of-day: pm, even
		 * minute-of-hour: >=10, even
		 * second-of-minute: >=10, even
		 * offset ID: +, is a multiple of an hour
		 */
		String metamorphicInput = "Sat, 3 Jun 2000 18:50:20 +0800";
		LocalDateTime metamorphicDateTime = LocalDateTime.parse(metamorphicInput, DateTimeFormatter.RFC_1123_DATE_TIME);

		assertEquals(originalDateTime.getMonth(), metamorphicDateTime.getMonth());
	}
}
package dateTests;

import org.junit.jupiter.api.Test;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

import static org.junit.jupiter.api.Assertions.assertNotEquals;

class MC {
	/*
	 * The second of minute is optional.
	 * Missing out this value should affect the time where second is not zero.
	 */
	@Test
	void test0() {
		String originalInput = "Mon, 6 Jan 2020 10:05:04 GMT";
		LocalDateTime originalDateTime = LocalDateTime.parse(originalInput, DateTimeFormatter.RFC_1123_DATE_TIME);
		/*
		 * day-of-week: weekdays
		 * day-of-month: first third of month
		 * month-of-year: quarter 1
		 * year: leap year
		 * hour-of-day: am, even
		 * minute-of-hour: <10, odd
		 * second-of-minute: <10, even
		 * offset ID: GMT
		 */
		String metamorphicInput = "Mon, 6 Jan 2020 10:05 GMT";
		LocalDateTime metamorphicDateTime = LocalDateTime.parse(metamorphicInput, DateTimeFormatter.RFC_1123_DATE_TIME);

		assertNotEquals(originalDateTime, metamorphicDateTime);
	}

	@Test
	void test1() {
		String originalInput = "Tue, 17 Apr 2018 09:06:07 -0100";
		LocalDateTime originalDateTime = LocalDateTime.parse(originalInput, DateTimeFormatter.RFC_1123_DATE_TIME);
		/*
		 * day-of-week: weekdays
		 * day-of-month: middle third of month
		 * month-of-year: quarter 2
		 * year: common year
		 * hour-of-day: am, odd
		 * minute-of-hour: <10, even
		 * second-of-minute: <10, odd
		 * offset ID: -, is a multiple of an hour
		 */
		String metamorphicInput = "Tue, 17 Apr 2018 09:06 -0100";
		LocalDateTime metamorphicDateTime = LocalDateTime.parse(metamorphicInput, DateTimeFormatter.RFC_1123_DATE_TIME);

		assertNotEquals(originalDateTime, metamorphicDateTime);
	}

	@Test
	void test2() {
		String originalInput = "Wed, 22 Jul 2020 08:12:33 -0130";
		LocalDateTime originalDateTime = LocalDateTime.parse(originalInput, DateTimeFormatter.RFC_1123_DATE_TIME);
		/*
		 * day-of-week: weekdays
		 * day-of-month: last third of month
		 * month-of-year: quarter 3
		 * year: leap year
		 * hour-of-day: am, even
		 * minute-of-hour: >=10, even
		 * second-of-minute: >=10, odd
		 * offset ID: -, is not a multiple of an hour
		 */
		String metamorphicInput = "Wed, 22 Jul 2020 08:12 -0130";
		LocalDateTime metamorphicDateTime = LocalDateTime.parse(metamorphicInput, DateTimeFormatter.RFC_1123_DATE_TIME);

		assertNotEquals(originalDateTime, metamorphicDateTime);
	}

	@Test
	void test3() {
		String originalInput = "Thu, 4 Oct 2018 13:16:21 +0230";
		LocalDateTime originalDateTime = LocalDateTime.parse(originalInput, DateTimeFormatter.RFC_1123_DATE_TIME);
		/*
		 * day-of-week: weekdays
		 * day-of-month: first third of month
		 * month-of-year: quarter 4
		 * year: common year
		 * hour-of-day: pm, odd
		 * minute-of-hour: >=10, even
		 * second-of-minute: >=10, odd
		 * offset ID: +, is not a multiple of an hour
		 */
		String metamorphicInput = "Thu, 4 Oct 2018 13:16 +0230";
		LocalDateTime metamorphicDateTime = LocalDateTime.parse(metamorphicInput, DateTimeFormatter.RFC_1123_DATE_TIME);

		assertNotEquals(originalDateTime, metamorphicDateTime);
	}

	@Test
	void test4() {
		String originalInput = "Fri, 14 Feb 2020 14:05:30 +0330";
		LocalDateTime originalDateTime = LocalDateTime.parse(originalInput, DateTimeFormatter.RFC_1123_DATE_TIME);
		/*
		 * day-of-week: weekdays
		 * day-of-month: middle third of month
		 * month-of-year: quarter 1
		 * year: leap year
		 * hour-of-day: pm, even
		 * minute-of-hour: <10, odd
		 * second-of-minute: >=10, even
		 * offset ID: +, is not a multiple of an hour
		 */
		String metamorphicInput = "Fri, 14 Feb 2020 14:05 +0330";
		LocalDateTime metamorphicDateTime = LocalDateTime.parse(metamorphicInput, DateTimeFormatter.RFC_1123_DATE_TIME);

		assertNotEquals(originalDateTime, metamorphicDateTime);
	}

	@Test
	void test5() {
		String originalInput = "Sat, 26 May 2018 07:03:40 -0500";
		LocalDateTime originalDateTime = LocalDateTime.parse(originalInput, DateTimeFormatter.RFC_1123_DATE_TIME);
		/*
		 * day-of-week: weekends
		 * day-of-month: last third of month
		 * month-of-year: quarter 2
		 * year: common year
		 * hour-of-day: am, odd
		 * minute-of-hour: <10, odd
		 * second-of-minute: >=10, even
		 * offset ID: -, is a multiple of an hour
		 */
		String metamorphicInput = "Sat, 26 May 2018 07:03 -0500";
		LocalDateTime metamorphicDateTime = LocalDateTime.parse(metamorphicInput, DateTimeFormatter.RFC_1123_DATE_TIME);

		assertNotEquals(originalDateTime, metamorphicDateTime);
	}

	@Test
	void test6() {
		String originalInput = "Sat, 8 Aug 2020 06:35:07 GMT";
		LocalDateTime originalDateTime = LocalDateTime.parse(originalInput, DateTimeFormatter.RFC_1123_DATE_TIME);
		/*
		 * day-of-week: weekends
		 * day-of-month: first third of month
		 * month-of-year: quarter 3
		 * year: leap year
		 * hour-of-day: am, even
		 * minute-of-hour: >=10, odd
		 * second-of-minute: <10, odd
		 * offset ID: GMT
		 */
		String metamorphicInput = "Sat, 8 Aug 2020 06:35 GMT";
		LocalDateTime metamorphicDateTime = LocalDateTime.parse(metamorphicInput, DateTimeFormatter.RFC_1123_DATE_TIME);

		assertNotEquals(originalDateTime, metamorphicDateTime);
	}

	@Test
	void test7() {
		String originalInput = "Sat, 17 Nov 2018 15:08:02 +0630";
		LocalDateTime originalDateTime = LocalDateTime.parse(originalInput, DateTimeFormatter.RFC_1123_DATE_TIME);
		/*
		 * day-of-week: weekends
		 * day-of-month: middle third of month
		 * month-of-year: quarter 4
		 * year: common year
		 * hour-of-day: pm, odd
		 * minute-of-hour: >=10, even
		 * second-of-minute: <10, even
		 * offset ID: +, is not a multiple of an hour
		 */
		String metamorphicInput = "Sat, 17 Nov 2018 15:08 +0630";
		LocalDateTime metamorphicDateTime = LocalDateTime.parse(metamorphicInput, DateTimeFormatter.RFC_1123_DATE_TIME);

		assertNotEquals(originalDateTime, metamorphicDateTime);
	}

	@Test
	void test8() {
		String originalInput = "Sun, 22 Mar 2020 17:09:03 -0700";
		LocalDateTime originalDateTime = LocalDateTime.parse(originalInput, DateTimeFormatter.RFC_1123_DATE_TIME);
		/*
		 * day-of-week: weekends
		 * day-of-month: last third of month
		 * month-of-year: quarter 1
		 * year: leap year
		 * hour-of-day: pm, odd
		 * minute-of-hour: <10, odd
		 * second-of-minute: <10, odd
		 * offset ID: -, is a multiple of an hour
		 */
		String metamorphicInput = "Sun, 22 Mar 2020 17:09 -0700";
		LocalDateTime metamorphicDateTime = LocalDateTime.parse(metamorphicInput, DateTimeFormatter.RFC_1123_DATE_TIME);

		assertNotEquals(originalDateTime, metamorphicDateTime);
	}

	@Test
	void test9() {
		String originalInput = "Sun, 3 Jun 2018 18:50:20 +0800";
		LocalDateTime originalDateTime = LocalDateTime.parse(originalInput, DateTimeFormatter.RFC_1123_DATE_TIME);
		/*
		 * day-of-week: weekends
		 * day-of-month: first third of month
		 * month-of-year: quarter 2
		 * year: common year
		 * hour-of-day: pm, even
		 * minute-of-hour: >=10, even
		 * second-of-minute: >=10, even
		 * offset ID: +, is a multiple of an hour
		 */
		String metamorphicInput = "Sun, 3 Jun 2018 18:50 +0800";
		LocalDateTime metamorphicDateTime = LocalDateTime.parse(metamorphicInput, DateTimeFormatter.RFC_1123_DATE_TIME);

		assertNotEquals(originalDateTime, metamorphicDateTime);
	}
}
package dateTests;

import org.junit.jupiter.api.Test;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

import static org.junit.jupiter.api.Assertions.assertEquals;

class MD {
	/*
	 * Case insensitive.
	 */
	@Test
	void test0() {
		String originalInput = "Mon, 6 Jan 2020 10:05:04 GMT";
		LocalDateTime originalDateTime = LocalDateTime.parse(originalInput, DateTimeFormatter.RFC_1123_DATE_TIME);
		/*
		 * day-of-week: weekdays
		 * day-of-month: first third of month
		 * month-of-year: quarter 1
		 * year: leap year
		 * hour-of-day: am, even
		 * minute-of-hour: <10, odd
		 * second-of-minute: <10, even
		 * offset ID: GMT
		 */
		String metamorphicInput = "mon, 6 jan 2020 10:05:04 gmt";
		LocalDateTime metamorphicDateTime = LocalDateTime.parse(metamorphicInput, DateTimeFormatter.RFC_1123_DATE_TIME);

		assertEquals(originalDateTime, metamorphicDateTime);
	}

	@Test
	void test1() {
		String originalInput = "Tue, 17 Apr 2018 09:06:07 -0100";
		LocalDateTime originalDateTime = LocalDateTime.parse(originalInput, DateTimeFormatter.RFC_1123_DATE_TIME);
		/*
		 * day-of-week: weekdays
		 * day-of-month: middle third of month
		 * month-of-year: quarter 2
		 * year: common year
		 * hour-of-day: am, odd
		 * minute-of-hour: <10, even
		 * second-of-minute: <10, odd
		 * offset ID: -, is a multiple of an hour
		 */
		String metamorphicInput = "tue, 17 apr 2018 09:06:07 -0100";
		LocalDateTime metamorphicDateTime = LocalDateTime.parse(metamorphicInput, DateTimeFormatter.RFC_1123_DATE_TIME);

		assertEquals(originalDateTime, metamorphicDateTime);
	}

	@Test
	void test2() {
		String originalInput = "Wed, 22 Jul 2020 08:12:33 -0130";
		LocalDateTime originalDateTime = LocalDateTime.parse(originalInput, DateTimeFormatter.RFC_1123_DATE_TIME);
		/*
		 * day-of-week: weekdays
		 * day-of-month: last third of month
		 * month-of-year: quarter 3
		 * year: leap year
		 * hour-of-day: am, even
		 * minute-of-hour: >=10, even
		 * second-of-minute: >=10, odd
		 * offset ID: -, is not a multiple of an hour
		 */
		String metamorphicInput = "wed, 22 jul 2020 08:12:33 -0130";
		LocalDateTime metamorphicDateTime = LocalDateTime.parse(metamorphicInput, DateTimeFormatter.RFC_1123_DATE_TIME);

		assertEquals(originalDateTime, metamorphicDateTime);
	}

	@Test
	void test3() {
		String originalInput = "Thu, 4 Oct 2018 13:16:21 +0230";
		LocalDateTime originalDateTime = LocalDateTime.parse(originalInput, DateTimeFormatter.RFC_1123_DATE_TIME);
		/*
		 * day-of-week: weekdays
		 * day-of-month: first third of month
		 * month-of-year: quarter 4
		 * year: common year
		 * hour-of-day: pm, odd
		 * minute-of-hour: >=10, even
		 * second-of-minute: >=10, odd
		 * offset ID: +, is not a multiple of an hour
		 */
		String metamorphicInput = "thu, 4 oct 2018 13:16:21 +0230";
		LocalDateTime metamorphicDateTime = LocalDateTime.parse(metamorphicInput, DateTimeFormatter.RFC_1123_DATE_TIME);

		assertEquals(originalDateTime, metamorphicDateTime);
	}

	@Test
	void test4() {
		String originalInput = "Fri, 14 Feb 2020 14:05:30 +0330";
		LocalDateTime originalDateTime = LocalDateTime.parse(originalInput, DateTimeFormatter.RFC_1123_DATE_TIME);
		/*
		 * day-of-week: weekdays
		 * day-of-month: middle third of month
		 * month-of-year: quarter 1
		 * year: leap year
		 * hour-of-day: pm, even
		 * minute-of-hour: <10, odd
		 * second-of-minute: >=10, even
		 * offset ID: +, is not a multiple of an hour
		 */
		String metamorphicInput = "fri, 14 feb 2020 14:05:30 +0330";
		LocalDateTime metamorphicDateTime = LocalDateTime.parse(metamorphicInput, DateTimeFormatter.RFC_1123_DATE_TIME);

		assertEquals(originalDateTime, metamorphicDateTime);
	}

	@Test
	void test5() {
		String originalInput = "Sat, 26 May 2018 07:03:40 -0500";
		LocalDateTime originalDateTime = LocalDateTime.parse(originalInput, DateTimeFormatter.RFC_1123_DATE_TIME);
		/*
		 * day-of-week: weekends
		 * day-of-month: last third of month
		 * month-of-year: quarter 2
		 * year: common year
		 * hour-of-day: am, odd
		 * minute-of-hour: <10, odd
		 * second-of-minute: >=10, even
		 * offset ID: -, is a multiple of an hour
		 */
		String metamorphicInput = "sAt, 26 mAy 2018 07:03:40 -0500";
		LocalDateTime metamorphicDateTime = LocalDateTime.parse(metamorphicInput, DateTimeFormatter.RFC_1123_DATE_TIME);

		assertEquals(originalDateTime, metamorphicDateTime);
	}

	@Test
	void test6() {
		String originalInput = "Sat, 8 Aug 2020 06:35:07 GMT";
		LocalDateTime originalDateTime = LocalDateTime.parse(originalInput, DateTimeFormatter.RFC_1123_DATE_TIME);
		/*
		 * day-of-week: weekends
		 * day-of-month: first third of month
		 * month-of-year: quarter 3
		 * year: leap year
		 * hour-of-day: am, even
		 * minute-of-hour: >=10, odd
		 * second-of-minute: <10, odd
		 * offset ID: GMT
		 */
		String metamorphicInput = "saT, 8 auG 2020 06:35:07 gmT";
		LocalDateTime metamorphicDateTime = LocalDateTime.parse(metamorphicInput, DateTimeFormatter.RFC_1123_DATE_TIME);

		assertEquals(originalDateTime, metamorphicDateTime);
	}

	@Test
	void test7() {
		String originalInput = "Sat, 17 Nov 2018 15:08:02 +0630";
		LocalDateTime originalDateTime = LocalDateTime.parse(originalInput, DateTimeFormatter.RFC_1123_DATE_TIME);
		/*
		 * day-of-week: weekends
		 * day-of-month: middle third of month
		 * month-of-year: quarter 4
		 * year: common year
		 * hour-of-day: pm, odd
		 * minute-of-hour: >=10, even
		 * second-of-minute: <10, even
		 * offset ID: +, is not a multiple of an hour
		 */
		String metamorphicInput = "SAT, 17 NOV 2018 15:08:02 +0630";
		LocalDateTime metamorphicDateTime = LocalDateTime.parse(metamorphicInput, DateTimeFormatter.RFC_1123_DATE_TIME);

		assertEquals(originalDateTime, metamorphicDateTime);
	}

	@Test
	void test8() {
		String originalInput = "Sun, 22 Mar 2020 17:09:03 -0700";
		LocalDateTime originalDateTime = LocalDateTime.parse(originalInput, DateTimeFormatter.RFC_1123_DATE_TIME);
		/*
		 * day-of-week: weekends
		 * day-of-month: last third of month
		 * month-of-year: quarter 1
		 * year: leap year
		 * hour-of-day: pm, odd
		 * minute-of-hour: <10, odd
		 * second-of-minute: <10, odd
		 * offset ID: -, is a multiple of an hour
		 */
		String metamorphicInput = "SUn, 22 MAr 2020 17:09:03 -0700";
		LocalDateTime metamorphicDateTime = LocalDateTime.parse(metamorphicInput, DateTimeFormatter.RFC_1123_DATE_TIME);

		assertEquals(originalDateTime, metamorphicDateTime);
	}

	@Test
	void test9() {
		String originalInput = "Sun, 3 Jun 2018 18:50:20 +0800";
		LocalDateTime originalDateTime = LocalDateTime.parse(originalInput, DateTimeFormatter.RFC_1123_DATE_TIME);
		/*
		 * day-of-week: weekends
		 * day-of-month: first third of month
		 * month-of-year: quarter 2
		 * year: common year
		 * hour-of-day: pm, even
		 * minute-of-hour: >=10, even
		 * second-of-minute: >=10, even
		 * offset ID: +, is a multiple of an hour
		 */
		String metamorphicInput = "SuN, 3 JuN 2018 18:50:20 +0800";
		LocalDateTime metamorphicDateTime = LocalDateTime.parse(metamorphicInput, DateTimeFormatter.RFC_1123_DATE_TIME);

		assertEquals(originalDateTime, metamorphicDateTime);
	}
}
package dateTests;

import org.junit.jupiter.api.Test;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

import static org.junit.jupiter.api.Assertions.assertEquals;

class ME {
	/*
	 * The month of year can be number or words.
	 */
	@Test
	void test0() {
		String originalInput = "Mon, 6 Jan 2020 0010:05:04 GMT";
		LocalDateTime originalDateTime = LocalDateTime.parse(originalInput, DateTimeFormatter.RFC_1123_DATE_TIME);
		/*
		 * day-of-week: weekdays
		 * day-of-month: first third of month
		 * month-of-year: quarter 1
		 * year: leap year
		 * hour-of-day: am, even
		 * minute-of-hour: <10, odd
		 * second-of-minute: <10, even
		 * offset ID: GMT
		 */
		String metamorphicInput = "Mon, 6 1 2020 0010:05:04 GMT";
		LocalDateTime metamorphicDateTime = LocalDateTime.parse(metamorphicInput, DateTimeFormatter.RFC_1123_DATE_TIME);

		assertEquals(originalDateTime, metamorphicDateTime);
	}

	@Test
	void test1() {
		String originalInput = "Tue, 17 Apr 2018 09:06:07 -0100";
		LocalDateTime originalDateTime = LocalDateTime.parse(originalInput, DateTimeFormatter.RFC_1123_DATE_TIME);
		/*
		 * day-of-week: weekdays
		 * day-of-month: middle third of month
		 * month-of-year: quarter 2
		 * year: common year
		 * hour-of-day: am, odd
		 * minute-of-hour: <10, even
		 * second-of-minute: <10, odd
		 * offset ID: -, is a multiple of an hour
		 */
		String metamorphicInput = "Tue, 17 4 2018 09:06:07 -0100";
		LocalDateTime metamorphicDateTime = LocalDateTime.parse(metamorphicInput, DateTimeFormatter.RFC_1123_DATE_TIME);

		assertEquals(originalDateTime, metamorphicDateTime);
	}

	@Test
	void test2() {
		String originalInput = "Wed, 22 Jul 2020 08:12:33 -0130";
		LocalDateTime originalDateTime = LocalDateTime.parse(originalInput, DateTimeFormatter.RFC_1123_DATE_TIME);
		/*
		 * day-of-week: weekdays
		 * day-of-month: last third of month
		 * month-of-year: quarter 3
		 * year: leap year
		 * hour-of-day: am, even
		 * minute-of-hour: >=10, even
		 * second-of-minute: >=10, odd
		 * offset ID: -, is not a multiple of an hour
		 */
		String metamorphicInput = "Wed, 22 7 2020 08:12:33 -0130";
		LocalDateTime metamorphicDateTime = LocalDateTime.parse(metamorphicInput, DateTimeFormatter.RFC_1123_DATE_TIME);

		assertEquals(originalDateTime, metamorphicDateTime);
	}

	@Test
	void test3() {
		String originalInput = "Thu, 4 Oct 2018 13:16:21 +0230";
		LocalDateTime originalDateTime = LocalDateTime.parse(originalInput, DateTimeFormatter.RFC_1123_DATE_TIME);
		/*
		 * day-of-week: weekdays
		 * day-of-month: first third of month
		 * month-of-year: quarter 4
		 * year: common year
		 * hour-of-day: pm, odd
		 * minute-of-hour: >=10, even
		 * second-of-minute: >=10, odd
		 * offset ID: +, is not a multiple of an hour
		 */
		String metamorphicInput = "Thu, 4 10 2018 13:16:21 +0230";
		LocalDateTime metamorphicDateTime = LocalDateTime.parse(metamorphicInput, DateTimeFormatter.RFC_1123_DATE_TIME);

		assertEquals(originalDateTime, metamorphicDateTime);
	}

	@Test
	void test4() {
		String originalInput = "Fri, 14 Feb 2020 14:05:30 +0330";
		LocalDateTime originalDateTime = LocalDateTime.parse(originalInput, DateTimeFormatter.RFC_1123_DATE_TIME);
		/*
		 * day-of-week: weekdays
		 * day-of-month: middle third of month
		 * month-of-year: quarter 1
		 * year: leap year
		 * hour-of-day: pm, even
		 * minute-of-hour: <10, odd
		 * second-of-minute: >=10, even
		 * offset ID: +, is not a multiple of an hour
		 */
		String metamorphicInput = "Fri, 14 2 2020 14:05:30 +0330";
		LocalDateTime metamorphicDateTime = LocalDateTime.parse(metamorphicInput, DateTimeFormatter.RFC_1123_DATE_TIME);

		assertEquals(originalDateTime, metamorphicDateTime);
	}

	@Test
	void test5() {
		String originalInput = "Sat, 26 May 2018 07:03:40 -0500";
		LocalDateTime originalDateTime = LocalDateTime.parse(originalInput, DateTimeFormatter.RFC_1123_DATE_TIME);
		/*
		 * day-of-week: weekends
		 * day-of-month: last third of month
		 * month-of-year: quarter 2
		 * year: common year
		 * hour-of-day: am, odd
		 * minute-of-hour: <10, odd
		 * second-of-minute: >=10, even
		 * offset ID: -, is a multiple of an hour
		 */
		String metamorphicInput = "Sat, 26 5 2018 07:03:40 -0500";
		LocalDateTime metamorphicDateTime = LocalDateTime.parse(metamorphicInput, DateTimeFormatter.RFC_1123_DATE_TIME);

		assertEquals(originalDateTime, metamorphicDateTime);
	}

	@Test
	void test6() {
		String originalInput = "Sat, 8 Aug 2020 06:35:07 GMT";
		LocalDateTime originalDateTime = LocalDateTime.parse(originalInput, DateTimeFormatter.RFC_1123_DATE_TIME);
		/*
		 * day-of-week: weekends
		 * day-of-month: first third of month
		 * month-of-year: quarter 3
		 * year: leap year
		 * hour-of-day: am, even
		 * minute-of-hour: >=10, odd
		 * second-of-minute: <10, odd
		 * offset ID: GMT
		 */
		String metamorphicInput = "Sat, 8 8 2020 06:35:07 GMT";
		LocalDateTime metamorphicDateTime = LocalDateTime.parse(metamorphicInput, DateTimeFormatter.RFC_1123_DATE_TIME);

		assertEquals(originalDateTime, metamorphicDateTime);
	}

	@Test
	void test7() {
		String originalInput = "Sat, 17 Nov 2018 15:08:02 +0630";
		LocalDateTime originalDateTime = LocalDateTime.parse(originalInput, DateTimeFormatter.RFC_1123_DATE_TIME);
		/*
		 * day-of-week: weekends
		 * day-of-month: middle third of month
		 * month-of-year: quarter 4
		 * year: common year
		 * hour-of-day: pm, odd
		 * minute-of-hour: >=10, even
		 * second-of-minute: <10, even
		 * offset ID: +, is not a multiple of an hour
		 */
		String metamorphicInput = "Sat, 17 11 2018 15:08:02 +0630";
		LocalDateTime metamorphicDateTime = LocalDateTime.parse(metamorphicInput, DateTimeFormatter.RFC_1123_DATE_TIME);

		assertEquals(originalDateTime, metamorphicDateTime);
	}

	@Test
	void test8() {
		String originalInput = "Sun, 22 Mar 2020 17:09:03 -0700";
		LocalDateTime originalDateTime = LocalDateTime.parse(originalInput, DateTimeFormatter.RFC_1123_DATE_TIME);
		/*
		 * day-of-week: weekends
		 * day-of-month: last third of month
		 * month-of-year: quarter 1
		 * year: leap year
		 * hour-of-day: pm, odd
		 * minute-of-hour: <10, odd
		 * second-of-minute: <10, odd
		 * offset ID: -, is a multiple of an hour
		 */
		String metamorphicInput = "Sun, 22 3 2020 17:09:03 -0700";
		LocalDateTime metamorphicDateTime = LocalDateTime.parse(metamorphicInput, DateTimeFormatter.RFC_1123_DATE_TIME);

		assertEquals(originalDateTime, metamorphicDateTime);
	}

	@Test
	void test9() {
		String originalInput = "Sun, 3 Jun 2018 18:50:20 +0800";
		LocalDateTime originalDateTime = LocalDateTime.parse(originalInput, DateTimeFormatter.RFC_1123_DATE_TIME);
		/*
		 * day-of-week: weekends
		 * day-of-month: first third of month
		 * month-of-year: quarter 2
		 * year: common year
		 * hour-of-day: pm, even
		 * minute-of-hour: >=10, even
		 * second-of-minute: >=10, even
		 * offset ID: +, is a multiple of an hour
		 */
		String metamorphicInput = "Sun, 3 6 2018 18:50:20 +0800";
		LocalDateTime metamorphicDateTime = LocalDateTime.parse(metamorphicInput, DateTimeFormatter.RFC_1123_DATE_TIME);

		assertEquals(originalDateTime, metamorphicDateTime);
	}
}