/* Execute as:
swipl -s unittest.pl -g main -q
*/

:- ensure_loaded(database).
:- ensure_loaded(travel).

main :-
	test(N, minutes(time(13,45), N), [825]);
	test(N, minutes(time(0,0), N), [0]);
	test(as_early(time(5,30), time(8,45)), true);
	test(as_early(time(5,30), time(5,30)), true);
	test(as_early(time(23,58), time(0,05)), false);
	test(between(time(5,30), time(7,13), time(8,45)), true);
	test(between(time(5,30), time(8,45), time(8,45)), true);
	test(between(time(5,30), time(5,30), time(8,45)), true);
	test(between(time(5,30), time(11,30), time(8,45)), false);
	test(between(time(5,30), time(5,30), time(5,30)), true);
	test(between(time(5,30), time(5,29), time(5,30)), false);
	test(between(time(22,15), time(23,49), time(1,23)), true);
	test(between(time(22,15), time(1,15), time(1,23)), true);
	test(between(time(22,15), time(5,05), time(1,23)), false);
	test(M, elapsed(time(5,30), time(8,45), M), [195]);
	test(M, elapsed(time(23,58), time(0,05), M), [7]);
	test(G, gmt(stl, time(11,30), G), [time(17,30)]);
	test(L, gmt(stl, L, time(17,30)), [time(11,30)]);
	test(T, flight_time(flight(aa,1040), stl, ord, T), [75]);
	test(T, flight_time(flight(dl,2088), stl, slc, T), [197]);
	test(flies(as,stl), true);
	test(flies(ha,stl), false);
	test(A, flies(A,pvd), [b6, dl, e9, ev, ua, us, wn, yv]);
	test(nonstop(stl,den), true);
	test(nonstop(stl,cos), false);
	test(nonstop(stl,den,wn), true);
	test(nonstop(stl,den,aa), false);
	test(D, nonstop(stl,D,dl), [atl,dtw,msp,slc]);
	testList(L, arrivals(stl, time(10,00), time(10,10), L),
	         [flight(e9,3360), flight(e9,4102), flight(wn,4)]);
	testList(L, arrivals(stl, time(9,25), time(9,25), L),
		 [flight(wn, 2425), flight(wn, 340), flight(wn, 3482),
	flight(wn, 3861), flight(wn, 683), flight(wn, 749)]);
	testList(L, arrivals(lax, time(23,50), time(0,45), L),
		 [flight(aa, 1035), flight(aa, 2497), flight(b6, 677),
	flight(dl, 2363), flight(ua, 1445)]);
	test(W, wait(flight(wn,369), mdw, flight(wn,369), W), [50]);
	test(W, wait(flight(wn,2766), mdw, flight(wn,2766), W), [40]);
	test(F, connecting(flight(wn,1359), stl, F, 20, 40),
	     [flight(fl,544), flight(wn, 1281), flight(wn, 2319), flight(wn, 1359)]);
	test(F, connecting(F, stl, flight(wn,1359), 20, 40),
	     [flight(e9,3360), flight(e9,4102), flight(aa,1266),
	      flight(wn,1359),flight(wn,2319),flight(wn,4)]);
        test(F, connecting_airline(flight(wn,1359), stl, F, 20, 40),
	     [flight(wn,1281), flight(wn,1359), flight(wn,2319)]);
        test(F, connecting_airline(F, stl, flight(wn,1359), 20, 40),
	     [flight(wn,1359), flight(wn,2319), flight(wn,4)]);
	test(T, travel_time([pwm, flight(b6,609), jfk], T), [83]);
	test(T, travel_time([pwm, flight(b6,609), jfk, flight(dl,1394), pdx], T), [520]);
	test(T, travel_time([pwm, flight(ev, 4091), ewr, flight(wn, 369), mdw,
			     flight(wn, 2766), pdx], T), [594]);

        test(T, travel_time([ppg, flight(ha,466), hnl, flight(ua,106), lax, flight(dl,1406),
			     dtw, flight(e9,3489), phl, flight(aa,1007), mia, flight(aa,1165),
			     stx], T), [2280]);
        test(I, plan(pwm,pdx,30,3,600,I),
	     [[pwm, flight(b6, 609), jfk, flight(dl, 1394), pdx],
	      [pwm, flight(ev, 6046), iad, flight(ua, 1671), pdx],
	      [pwm, flight(ev, 6046), iad, flight(ua, 72), den, flight(ua, 745), pdx],
	      [pwm, flight(ev, 4091), ewr, flight(wn, 369), mdw, flight(wn, 2766), pdx]]);
	halt.


/* 2-argument version tests whether goal was true or false. */
test(Goal, true) :-
	write('Test...'),ttyflush,
	not(Goal),!,
	write('ERROR.  '), write(Goal), write(' was false'),nl,
	fail.

test(Goal, false) :-
	write('Test...'),ttyflush,
	Goal,!,
	write('ERROR.  '), write(Goal), write(' was true'),nl,
	fail.

test(_,_) :- write('success'),nl,fail.


/* 3-argument version tests binding of Var to Exepcted list of results */
test(Var,Goal,Expected) :-
	write('Test...'),ttyflush,
	not(setof(Var,Goal,_)), !,
	write('ERROR.'),nl,
	write('  '),write(Goal),nl,
	write('  failed'),nl,
	write('  expected '), write(Expected),nl,
	fail.

test(Var,Goal,Expected) :-
	setof(Var, Goal, Ans),
	sort(Ans,Ans2),
	sort(Expected,Expected2),
	Ans2 \= Expected2,!,
	write('ERROR.'),nl,
	write('  '),write(Goal),nl,
	write('  reported '),write(Ans),nl,
	write('  expected '), write(Expected),nl,
	fail.

test(_,_,_) :- write('success'),nl,fail.

/* non-deterministic version with Var being a single list */
testList(Var,Goal,Expected) :-
	write('Test...'),ttyflush,
	setof(Var, Goal, Ans),
	Ans = [ L ],
	sort(L,L2),
	sort(Expected,Expected2),
	L2 \= Expected2,!,
	write('ERROR.'),nl,
	write('  '),write(Goal),nl,
	write('  reported '),write(Ans),nl,
	write('  expected '), write(Expected),nl,
	fail.
testList(_,_,_) :- write('success'),nl,fail.
