237 lines
7.1 KiB
Prolog
237 lines
7.1 KiB
Prolog
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% HELPERS
|
|
|
|
% plunit is a Prolog unit-test framework initially developed for SWI-Prolog
|
|
:- use_module(library(plunit)).
|
|
:- discontiguous test/2.
|
|
|
|
% Run the tests.
|
|
test :-
|
|
run_tests(sql).
|
|
|
|
% 'clean' drop: call drop/1 and swallow any thrown exceptions
|
|
cdrop(Table) :-
|
|
catch(drop(Table), _, true).
|
|
|
|
% Checks that two lists have the same content.
|
|
same_content(L1, L2) :-
|
|
msort(L1, S),
|
|
msort(L2, S).
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% TESTS
|
|
|
|
:- begin_tests(sql).
|
|
|
|
% Test if create/1 works.
|
|
test(create_table, cleanup(cdrop(foo))) :-
|
|
create_table(foo, [bar, baz]),
|
|
tables(Tables),
|
|
member(foo, Tables), !.
|
|
|
|
% Test if create/1 throws an error on dup table name.
|
|
test(create_redundant, [throws(_), cleanup(cdrop(foo))]) :-
|
|
create_table(foo, [bar, baz]),
|
|
create_table(foo, [bab, bac]).
|
|
|
|
% Test if the columns are properly recorded.
|
|
test(cols, cleanup(cdrop(foo))) :-
|
|
create_table(foo, [baru, bazu]),
|
|
cols(foo, Cols),
|
|
assertion(Cols == [baru, bazu]).
|
|
|
|
% Test if drop/1 works.
|
|
test(drop) :-
|
|
create_table(foo, [bar, baz]),
|
|
drop(foo), !,
|
|
tables(Tables),
|
|
\+ member(foo, Tables).
|
|
|
|
% Test if drop/1 throws an error on unknown table name.
|
|
test(drop_inexistant, throws(_)) :-
|
|
drop(foobar).
|
|
|
|
% Test if row/2 returns the different rows of a given table.
|
|
test(rows, cleanup(cdrop(foo))) :-
|
|
create_table(foo, [bar, baz]),
|
|
insert(foo, [1, 2]),
|
|
insert(foo, [3, 4]),
|
|
rows(foo, Rows),
|
|
assertion(length(Rows,2)).
|
|
|
|
% Test if row/2 fails on an unknown table name.
|
|
test(row_inexistant, throws(_)) :-
|
|
rows(foo, _Row).
|
|
|
|
% Test if rows/1 works when called for a given table name.
|
|
test(rows, cleanup(cdrop(foo))) :-
|
|
create_table(foo, [bar, baz]),
|
|
insert(foo, [1, 2]),
|
|
insert(foo, [3, 4]),
|
|
rows(foo).
|
|
|
|
% Test if rows/1 throws an error on unknown table name.
|
|
test(rows_inexistant, throws(_)) :-
|
|
rows(foo).
|
|
|
|
% Simple insert/2 & selec/4 test.
|
|
test(insert2, cleanup(cdrop(foo))) :-
|
|
create_table(foo, [bar, baz]),
|
|
insert(foo, [1, 2]),
|
|
%selec(foo, *, [], X/Y), !,
|
|
selec(foo, *, X/Y), !,
|
|
assertion(X == [+bar, +baz]),
|
|
assertion(Y == [1, 2]),
|
|
insert(foo, [3, 4]),
|
|
findall(Z, selec(foo, *, [], _/Z), Zs), !,
|
|
assertion(Zs == [[1,2],[3,4]]).
|
|
|
|
% Test if insert/2 throws an error on unknown table name.
|
|
test(insert_inexistant, throws(_)) :-
|
|
insert(foo, [1, 2]).
|
|
|
|
% Simple delete/1 test.
|
|
test(delete1, cleanup(cdrop(foo))) :-
|
|
create_table(foo, [bar, baz]),
|
|
insert(foo, [1, 2]),
|
|
insert(foo, [3, 4]),
|
|
delete(foo),
|
|
findall(Z, selec(foo, *, [], _/Z), Zs),
|
|
assertion(Zs == []),
|
|
tables(Tables),
|
|
member(foo, Tables).
|
|
|
|
% Simple delete/2 test.
|
|
test(delete2, cleanup(cdrop(foo))) :-
|
|
create_table(foo, [bar, baz]),
|
|
insert(foo, [1, 2]),
|
|
insert(foo, [3, 4]),
|
|
delete(foo, [+bar = 1]),
|
|
findall(Z, selec(foo, *, [], _/Z), Zs),
|
|
assertion(Zs == [[3, 4]]).
|
|
|
|
% Another simple delete/2 test.
|
|
test(delete2bis, cleanup(cdrop(foo))) :-
|
|
create_table(foo, [bar, baz]),
|
|
insert(foo, [1, 2]),
|
|
insert(foo, [3, 4]),
|
|
delete(foo, [+bar >= 1]),
|
|
findall(Z, selec(foo, *, [], _/Z), Zs),
|
|
assertion(Zs == []).
|
|
|
|
% Test delete/2 using multiple conditions.
|
|
test(delete2_mult, cleanup(cdrop(foo))) :-
|
|
create_table(foo, [bar, baz]),
|
|
insert(foo, [1, 2]),
|
|
insert(foo, [3, 4]),
|
|
delete(foo, [+bar = 1, +baz = 2]),
|
|
findall(Z, selec(foo, *, [], _/Z), Zs),
|
|
assertion(Zs == [[3, 4]]).
|
|
|
|
% Another test of delete/2 using multiple conditions.
|
|
test(delete2_mult_bis, cleanup(cdrop(foo))) :-
|
|
create_table(foo, [bar, baz]),
|
|
insert(foo, [1, 2]),
|
|
insert(foo, [3, 4]),
|
|
delete(foo, [+bar > 1, +baz < 2]),
|
|
findall(Z, selec(foo, *, [], _/Z), Zs),
|
|
assertion(Zs == [[1, 2],[3,4]]).
|
|
|
|
% Test selec/4 with a single condition +col condition.
|
|
test(selec_cond1) :-
|
|
selec(persons, *, [+id = 0], _/Row1), !,
|
|
assertion(Row1 == [0, "Jeffrey", "Bowman", 30, "Daytona Beach"]),
|
|
selec(persons, *, [+first = "Lorena"], _/Row2), !,
|
|
assertion(Row2 == [1, "Lorena", "Michaels", 50, "Boardman"]).
|
|
|
|
|
|
% Test selec/4 with two +col conditions.
|
|
test(selec_cond_mult1) :-
|
|
selec(persons, *, [+age = 47, +city = "Atlanta"], _/Row), !,
|
|
assertion(Row == [11, "Betty", "Strickland", 47, "Atlanta"]).
|
|
|
|
% Test selec/4 with a single projection and no conditions.
|
|
test(selec_proj) :-
|
|
findall(Row, selec(persons, [+first], [], _/Row), Rows0),
|
|
flatten(Rows0, Rows),
|
|
assertion(Rows == ["Jeffrey", "Lorena", "Joseph", "Stewart", "Thomas",
|
|
"Tameka", "Annette", "David", "Anthony", "Lindsay", "Claudette", "Betty",
|
|
"Richard", "Robert", "Candace", "Sandra"]).
|
|
|
|
% Test selec/4 with projections and a condition.
|
|
test(selec_mult_proj) :-
|
|
findall(Row, selec(persons, [+first, +last], [+age >= 70], _/Row), Rows),
|
|
same_content(Rows, [
|
|
["Stewart", "Sullivan"],
|
|
["Thomas", "Marshall"],
|
|
["Lindsay", "Faught"]]).
|
|
|
|
% Test that drop/1 correctly removes rows.
|
|
test(drop_implem, cleanup(cdrop(foo))) :-
|
|
create_table(foo, [bar, baz]),
|
|
insert(foo, [1, 2]),
|
|
drop(foo),
|
|
create_table(foo, [bar, baz]),
|
|
findall(Z, selec(foo, *, [], _/Z), Zs), !,
|
|
assertion(Zs == []).
|
|
|
|
% Test that tables/1 works.
|
|
test(tables, cleanup((cdrop(foo), cdrop(bar), cdrop(baz)))) :-
|
|
create_table(foo, []),
|
|
create_table(bar, []),
|
|
create_table(baz, []),
|
|
drop(bar),
|
|
tables(Tables),
|
|
member(foo, Tables), !,
|
|
member(baz, Tables), !,
|
|
\+ member(bar, Tables), !.
|
|
|
|
% Test that insert/2 throws an error on unknown table name.
|
|
test(insert_inexistant, throws(_)) :-
|
|
insert(foobar, [1, 2]).
|
|
|
|
% Test that insert/2 throws an error if it is supplied too few values.
|
|
test(insert_count1, [throws(_), cleanup(drop(foo))]) :-
|
|
create_table(foo, [bar, baz]),
|
|
insert(foo, [1]).
|
|
|
|
% Test that insert/2 throws an error if it is supplied too many values.
|
|
test(insert_count2, [throws(_), cleanup(drop(foo))]) :-
|
|
create_table(foo, [bar, baz]),
|
|
insert(foo, [1, 2, 3]).
|
|
|
|
% Tests that delete/1 throws an error on unknown table name.
|
|
test(delete_inexistant1, throws(_)) :-
|
|
delete(foobar).
|
|
|
|
% Tests that delete/2 throws an error on unknown table name.
|
|
test(delete_inexistant2, throws(_)) :-
|
|
delete(foobar, []).
|
|
|
|
% Simple delete/2 test using the +<column>.
|
|
test(delete2_1, cleanup(drop(foo))) :-
|
|
create_table(foo, [bar, baz]),
|
|
insert(foo, [1, 2]),
|
|
insert(foo, [3, 4]),
|
|
delete(foo, [+baz = 4]),
|
|
findall(Z, selec(foo, *, [], _/Z), Zs),
|
|
assertion(Zs == [[1, 2]]).
|
|
|
|
% delete/2 test using mixed notations.
|
|
test(delete2_2, cleanup(drop(foo))) :-
|
|
create_table(foo, [bar, baz]),
|
|
insert(foo, [1, 2]),
|
|
insert(foo, [3, 4]),
|
|
insert(foo, [3, 5]),
|
|
delete(foo, [+bar = 3, +baz = 4]),
|
|
findall(Z, selec(foo, *, [], _/Z), Zs),
|
|
assertion(Zs == [[1, 2], [3, 5]]).
|
|
|
|
% Test selec/4 with a projection and multiple conditions.
|
|
test(selec_mult_cond) :-
|
|
findall(Row, selec(persons, [+first, +last],
|
|
[+age >= 60, +city = "Atlanta"], _/Row), Rows),
|
|
same_content(Rows, [["Robert", "Evans"]]).
|
|
|
|
% ==============================================================================
|