first commit
This commit is contained in:
commit
de2fc4afe0
Binary file not shown.
|
@ -0,0 +1,33 @@
|
|||
:- dynamic tabl/2.
|
||||
|
||||
tabl(persons, [id, first, last, age, city]).
|
||||
tabl(cities, [name, state, temp]).
|
||||
|
||||
:- dynamic persons/5.
|
||||
persons( 0, "Jeffrey", "Bowman", 30, "Daytona Beach").
|
||||
persons( 1, "Lorena", "Michaels", 50, "Boardman").
|
||||
persons( 2, "Joseph", "Mixson", 37, "Washington").
|
||||
persons( 3, "Stewart", "Sullivan", 83, "Grand Island").
|
||||
persons( 4, "Thomas", "Marshall", 75, "Houston").
|
||||
persons( 5, "Tameka", "Escobedo", 25, "Orlando").
|
||||
persons( 6, "Annette", "Marcy", 40, "Pittsburgh").
|
||||
persons( 7, "David", "Smith", 36, "Orlando").
|
||||
persons( 8, "Anthony", "Garcia", 20, "Daytona Beach").
|
||||
persons( 9, "Lindsay", "Faught", 70, "Boardman").
|
||||
persons(10, "Claudette", "Neil", 32, "Washington").
|
||||
persons(11, "Betty", "Strickland", 47, "Atlanta").
|
||||
persons(12, "Richard", "Gordon", 47, "Dallas").
|
||||
persons(13, "Robert", "Evans", 69, "Atlanta").
|
||||
persons(14, "Candace", "Griffin", 61, "Pittsburgh").
|
||||
persons(15, "Sandra", "Smith", 67, "Dallas").
|
||||
|
||||
:- dynamic cities/3.
|
||||
cities("Daytona Beach", "Florida", 22).
|
||||
cities("Boardman", "Oregon", 12).
|
||||
cities("Washington", "District of Columbia", 11).
|
||||
cities("Grand Island", "New York", 10).
|
||||
cities("Houston", "Texas", 20).
|
||||
cities("Orlando", "Florida", 23).
|
||||
cities("Dallas", "Texas", 17).
|
||||
cities("Pittsburgh", "Pennsylvania", 11).
|
||||
cities("Atlanta", "Georgia", 16).
|
|
@ -0,0 +1,236 @@
|
|||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% 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"]]).
|
||||
|
||||
% ==============================================================================
|
|
@ -0,0 +1,98 @@
|
|||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% HELPERS
|
||||
|
||||
% plunit is a Prolog unit-test framework initially developed for SWI-Prolog
|
||||
:- use_module(library(plunit)).
|
||||
:- discontiguous test/2.
|
||||
|
||||
% Run the tests.
|
||||
test_dcg :-
|
||||
run_tests(dcg).
|
||||
|
||||
% '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).
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
:- begin_tests(dcg).
|
||||
|
||||
%%not tested because not specified.
|
||||
%%test(query3) :-
|
||||
%% query("SELECT +id FROM cities;", _/Z), !,
|
||||
%% assertion(Z == []).
|
||||
|
||||
test(selec_with_selectors) :-
|
||||
findall(Z,
|
||||
query("SELECT +first, +age FROM persons;",
|
||||
_/Z), Zs),
|
||||
same_content(Zs, [
|
||||
["Jeffrey",30],
|
||||
["Lorena",50],
|
||||
["Joseph",37],
|
||||
["Stewart",83],
|
||||
["Thomas",75],
|
||||
["Tameka",25],
|
||||
["Annette",40],
|
||||
["David",36],
|
||||
["Anthony",20],
|
||||
["Lindsay",70],
|
||||
["Claudette",32],
|
||||
["Betty",47],
|
||||
["Richard",47],
|
||||
["Robert",69],
|
||||
["Candace",61],
|
||||
["Sandra",67]]).
|
||||
|
||||
test(selec_selectors_conditions) :-
|
||||
findall(Z,
|
||||
query("SELECT +state, +name FROM cities WHERE +temp>=20;",
|
||||
_/Z), Zs),
|
||||
same_content(Zs, [
|
||||
["Florida", "Daytona Beach"],
|
||||
["Texas", "Houston"],
|
||||
["Florida", "Orlando"]]).
|
||||
|
||||
test(selec_multi_conditions) :-
|
||||
findall(Z,
|
||||
query(`SELECT +last FROM persons WHERE +city="Orlando", +age>30;`,
|
||||
_/Z), Zs),
|
||||
same_content(Zs, [["Smith"]]).
|
||||
|
||||
test(selec_all) :-
|
||||
findall(Z,
|
||||
query("SELECT * FROM cities;"
|
||||
, _/Z), Zs),
|
||||
same_content(Zs, [["Daytona Beach", "Florida", 22],
|
||||
["Boardman", "Oregon", 12],
|
||||
["Washington", "District of Columbia", 11],
|
||||
["Grand Island", "New York", 10],
|
||||
["Houston", "Texas", 20],
|
||||
["Orlando", "Florida", 23],
|
||||
["Dallas", "Texas", 17],
|
||||
["Pittsburgh", "Pennsylvania", 11],
|
||||
["Atlanta", "Georgia", 16]]).
|
||||
|
||||
test(selec_after_insert, cleanup(delete(cities, [+name="Tempa"]))) :-
|
||||
query(`INSERT INTO cities (+name, +state) VALUES ("Tempa", "Florida");`),
|
||||
findall(Z,
|
||||
query("SELECT * FROM cities;"
|
||||
, _/Z), Zs),
|
||||
same_content(Zs, [["Daytona Beach", "Florida", 22],
|
||||
["Boardman", "Oregon", 12],
|
||||
["Washington", "District of Columbia", 11],
|
||||
["Grand Island", "New York", 10],
|
||||
["Houston", "Texas", 20],
|
||||
["Orlando", "Florida", 23],
|
||||
["Dallas", "Texas", 17],
|
||||
["Pittsburgh", "Pennsylvania", 11],
|
||||
["Atlanta", "Georgia", 16],
|
||||
["Tempa", "Florida", _]]).
|
||||
|
||||
:- end_tests(dcg).
|
||||
|
Loading…
Reference in New Issue