Skip to content

Commit

Permalink
Add types_are().
Browse files Browse the repository at this point in the history
  • Loading branch information
theory committed Nov 20, 2009
1 parent 54f5904 commit 2edd599
Show file tree
Hide file tree
Showing 6 changed files with 256 additions and 7 deletions.
2 changes: 1 addition & 1 deletion Changes
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Revision history for pgTAP
* Added `throws_like()`, `throws_ilike()`, `throws_matching()`, and
`throws_imatching()` to test that an SQL statement throws an error message
matching a `LIKE` pattern or a regular expression.
* Added `roles_are()`.
* Added `roles_are()` and `types_are()`.

0.22 2009-07-31T00:26:16
-------------------------
Expand Down
33 changes: 29 additions & 4 deletions README.pgtap
Original file line number Diff line number Diff line change
Expand Up @@ -1567,9 +1567,9 @@ missing opclasses, like so:

This function tests that all of the rules on the named relation are only the
rules that *should* be on that relation (a table or a view). If the `:schema`
argument is omitted, the relation must be visible in the search path,
excluding `pg_catalog`. If the description is omitted, a generally useful
default description will be generated.
argument is omitted, the rules must be visible in the search path, excluding
`pg_catalog`. If the description is omitted, a generally useful default
description will be generated.

In the event of a failure, you'll see diagnostics listing the extra and/or
missing rules, like so:
Expand All @@ -1580,6 +1580,32 @@ missing rules, like so:
# Missing rules:
# on_delete

### `types_are( schema, types[], description )` ###
### `types_are( schema, types[] )` ###
### `types_are( types[], description )` ###
### `types_are( types[] )` ###

SELECT types_are(
'myschema',
ARRAY[ 'timezone', 'state' ],
'Should have the correct types in myschema'
);

Tests that all of the types in the named schema are the only types in that
schema. If the `:schema` argument is omitted, the types must be visible in the
search path, excluding `pg_catalog` and `information_schema`. If the
description is omitted, a generally useful default description will be
generated.

In the event of a failure, you'll see diagnostics listing the extra and/or
missing types, like so:

# Failed test 307: "Schema someschema should have the correct types"
# Extra types:
# sometype
# Missing types:
# timezone

To Have or Have Not
-------------------

Expand Down Expand Up @@ -3959,7 +3985,6 @@ To Do
+ `sequence_increments_by()`
+ `sequence_starts_at()`
+ `sequence_cycles()`
+ `types_are()`
+ `domains_are()`
+ `enums_are()`
+ `triggers_are()`
Expand Down
28 changes: 27 additions & 1 deletion expected/aretap.out
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
\unset ECHO
1..280
1..306
ok 1 - tablespaces_are(schemas, desc) should pass
ok 2 - tablespaces_are(schemas, desc) should have the proper description
ok 3 - tablespaces_are(schemas, desc) should have the proper diagnostics
Expand Down Expand Up @@ -280,3 +280,29 @@ ok 277 - rules_are(table, rules) + missing should have the proper diagnostics
ok 278 - rules_are(table, rules) + extra & missing should fail
ok 279 - rules_are(table, rules) + extra & missing should have the proper description
ok 280 - rules_are(table, rules) + extra & missing should have the proper diagnostics
ok 281 - types_are(schema, types, desc) should pass
ok 282 - types_are(schema, types, desc) should have the proper description
ok 283 - types_are(schema, types, desc) should have the proper diagnostics
ok 284 - types_are(schema, types) should pass
ok 285 - types_are(schema, types) should have the proper description
ok 286 - types_are(schema, types, desc) + missing should fail
ok 287 - types_are(schema, types, desc) + missing should have the proper description
ok 288 - types_are(schema, types, desc) + missing should have the proper diagnostics
ok 289 - types_are(schema, types, desc) + extra should fail
ok 290 - types_are(schema, types, desc) + extra should have the proper description
ok 291 - types_are(schema, types, desc) + extra should have the proper diagnostics
ok 292 - types_are(schema, types, desc) + extra & missing should fail
ok 293 - types_are(schema, types, desc) + extra & missing should have the proper description
ok 294 - types_are(schema, types, desc) + extra & missing should have the proper diagnostics
ok 295 - types_are(types) should pass
ok 296 - types_are(types) should have the proper description
ok 297 - types_are(types) should have the proper diagnostics
ok 298 - types_are(types, desc) + missing should fail
ok 299 - types_are(types, desc) + missing should have the proper description
ok 300 - types_are(types, desc) + missing should have the proper diagnostics
ok 301 - types_are(types, desc) + extra should fail
ok 302 - types_are(types, desc) + extra should have the proper description
ok 303 - types_are(types, desc) + extra should have the proper diagnostics
ok 304 - types_are(types, desc) + extra & missing should fail
ok 305 - types_are(types, desc) + extra & missing should have the proper description
ok 306 - types_are(types, desc) + extra & missing should have the proper diagnostics
88 changes: 88 additions & 0 deletions pgtap.sql.in
Original file line number Diff line number Diff line change
Expand Up @@ -6587,3 +6587,91 @@ RETURNS TEXT AS $$
SELECT roles_are( $1, 'There should be the correct roles' );
$$ LANGUAGE SQL;

-- types_are( schema, types[], description )
CREATE OR REPLACE FUNCTION types_are ( NAME, NAME[], TEXT )
RETURNS TEXT AS $$
SELECT _are(
'types',
ARRAY(
SELECT t.typname
FROM pg_catalog.pg_type t
LEFT JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace
WHERE (
t.typrelid = 0
OR (SELECT c.relkind = 'c' FROM pg_catalog.pg_class c WHERE c.oid = t.typrelid)
)
AND NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type el WHERE el.oid = t.typelem AND el.typarray = t.oid)
AND n.nspname = $1
EXCEPT
SELECT $2[i]
FROM generate_series(1, array_upper($2, 1)) s(i)
),
ARRAY(
SELECT $2[i]
FROM generate_series(1, array_upper($2, 1)) s(i)
EXCEPT
SELECT t.typname
FROM pg_catalog.pg_type t
LEFT JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace
WHERE (
t.typrelid = 0
OR (SELECT c.relkind = 'c' FROM pg_catalog.pg_class c WHERE c.oid = t.typrelid)
)
AND NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type el WHERE el.oid = t.typelem AND el.typarray = t.oid)
AND n.nspname = $1
),
$3
);
$$ LANGUAGE SQL;

-- types_are( schema, types[] )
CREATE OR REPLACE FUNCTION types_are ( NAME, NAME[] )
RETURNS TEXT AS $$
SELECT types_are( $1, $2, 'Schema ' || quote_ident($1) || ' should have the correct types' );
$$ LANGUAGE SQL;

-- types_are( types[], description )
CREATE OR REPLACE FUNCTION types_are ( NAME[], TEXT )
RETURNS TEXT AS $$
SELECT _are(
'types',
ARRAY(
SELECT t.typname
FROM pg_catalog.pg_type t
LEFT JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace
WHERE (
t.typrelid = 0
OR (SELECT c.relkind = 'c' FROM pg_catalog.pg_class c WHERE c.oid = t.typrelid)
)
AND NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type el WHERE el.oid = t.typelem AND el.typarray = t.oid)
AND n.nspname NOT IN('pg_catalog', 'information_schema')
AND pg_catalog.pg_type_is_visible(t.oid)
EXCEPT
SELECT $1[i]
FROM generate_series(1, array_upper($1, 1)) s(i)
),
ARRAY(
SELECT $1[i]
FROM generate_series(1, array_upper($1, 1)) s(i)
EXCEPT
SELECT t.typname
FROM pg_catalog.pg_type t
LEFT JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace
WHERE (
t.typrelid = 0
OR (SELECT c.relkind = 'c' FROM pg_catalog.pg_class c WHERE c.oid = t.typrelid)
)
AND NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type el WHERE el.oid = t.typelem AND el.typarray = t.oid)
AND n.nspname NOT IN('pg_catalog', 'information_schema')
AND pg_catalog.pg_type_is_visible(t.oid)
),
$2
);
$$ LANGUAGE SQL;

-- types_are( types[] )
CREATE OR REPLACE FUNCTION types_are ( NAME[] )
RETURNS TEXT AS $$
SELECT types_are( $1, 'Search path ' || pg_catalog.current_setting('search_path') || ' should have the correct types' );
$$ LANGUAGE SQL;

108 changes: 107 additions & 1 deletion sql/aretap.sql
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
\unset ECHO
\i test_setup.sql

SELECT plan(280);
SELECT plan(306);
--SELECT * FROM no_plan();

-- This will be rolled back. :-)
Expand Down Expand Up @@ -55,6 +55,11 @@ DEFAULT FOR TYPE goofy USING BTREE AS
FUNCTION 1 goofy_cmp(goofy,goofy)
;

CREATE TYPE someschema.sometype AS (
id INT,
name TEXT
);

RESET client_min_messages;

/****************************************************************************/
Expand Down Expand Up @@ -1008,6 +1013,107 @@ SELECT * FROM check_test(
del_me'
);

/****************************************************************************/
-- Test types_are().

SELECT * FROM check_test(
types_are( 'someschema', ARRAY['sometype'], 'whatever' ),
true,
'types_are(schema, types, desc)',
'whatever',
''
);

SELECT * FROM check_test(
types_are( 'someschema', ARRAY['sometype'] ),
true,
'types_are(schema, types)',
'Schema someschema should have the correct types'
''
);

SELECT * FROM check_test(
types_are( 'someschema', ARRAY['sometype', 'typo'], 'whatever' ),
false,
'types_are(schema, types, desc) + missing',
'whatever',
' Missing types:
typo'
);

SELECT * FROM check_test(
types_are( 'someschema', '{}'::name[], 'whatever' ),
false,
'types_are(schema, types, desc) + extra',
'whatever',
' Extra types:
sometype'
);

SELECT * FROM check_test(
types_are( 'someschema', ARRAY['typo'], 'whatever' ),
false,
'types_are(schema, types, desc) + extra & missing',
'whatever',
' Extra types:
sometype
Missing types:
typo'
);

CREATE FUNCTION ___mytype(ex text) RETURNS NAME[] AS $$
SELECT COALESCE(ARRAY(
SELECT t.typname
FROM pg_catalog.pg_type t
LEFT JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace
WHERE (
t.typrelid = 0
OR (SELECT c.relkind = 'c' FROM pg_catalog.pg_class c WHERE c.oid = t.typrelid)
)
AND NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type el WHERE el.oid = t.typelem AND el.typarray = t.oid)
AND n.nspname NOT IN('pg_catalog', 'information_schema')
AND t.typname <> $1
AND pg_catalog.pg_type_is_visible(t.oid)
), '{}'::name[]);;
$$ LANGUAGE SQL;

SELECT * FROM check_test(
types_are( ___mytype('') ),
true,
'types_are(types)',
'Search path ' || pg_catalog.current_setting('search_path') || ' should have the correct types',
''
);

SELECT * FROM check_test(
types_are( array_append(___mytype(''), 'silltypo'), 'whatever' ),
false,
'types_are(types, desc) + missing',
'whatever',
' Missing types:
silltypo'
);

SELECT * FROM check_test(
types_are( ___mytype('goofy'), 'whatever' ),
false,
'types_are(types, desc) + extra',
'whatever',
' Extra types:
goofy'
);

SELECT * FROM check_test(
types_are( array_append(___mytype('goofy'), 'silltypo'), 'whatever' ),
false,
'types_are(types, desc) + extra & missing',
'whatever',
' Extra types:
goofy
Missing types:
silltypo'
);

/****************************************************************************/
-- Finish the tests and clean up.
SELECT * FROM finish();
Expand Down
4 changes: 4 additions & 0 deletions uninstall_pgtap.sql.in
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
-- ## SET search_path TO TAPSCHEMA, public;
DROP FUNCTION types_are ( NAME[] );
DROP FUNCTION types_are ( NAME[], TEXT );
DROP FUNCTION types_are ( NAME, NAME[] );
DROP FUNCTION types_are ( NAME, NAME[], TEXT );
DROP FUNCTION roles_are( NAME[] );
DROP FUNCTION roles_are( NAME[], TEXT );
DROP FUNCTION throws_imatching ( TEXT, TEXT );
Expand Down

0 comments on commit 2edd599

Please sign in to comment.