fix NUMERIC/DECIMAL size for postgres
[dbsrgits/DBIx-Class-Schema-Loader.git] / t / 12pg_common.t
1 use strict;
2 use lib qw(t/lib);
3 use dbixcsl_common_tests;
4 use Test::More;
5 use List::MoreUtils 'apply';
6
7 my $dsn      = $ENV{DBICTEST_PG_DSN} || '';
8 my $user     = $ENV{DBICTEST_PG_USER} || '';
9 my $password = $ENV{DBICTEST_PG_PASS} || '';
10
11 my $tester = dbixcsl_common_tests->new(
12     vendor      => 'Pg',
13     auto_inc_pk => 'SERIAL NOT NULL PRIMARY KEY',
14     dsn         => $dsn,
15     user        => $user,
16     password    => $password,
17     extra       => {
18         create => [
19             q{
20                 CREATE TABLE pg_loader_test1 (
21                     id SERIAL NOT NULL PRIMARY KEY,
22                     value VARCHAR(100)
23                 )
24             },
25             q{
26                 COMMENT ON TABLE pg_loader_test1 IS 'The Table'
27             },
28             q{
29                 COMMENT ON COLUMN pg_loader_test1.value IS 'The Column'
30             },
31             # Test to make sure data_types that don't need a size => don't
32             # have one and check varying types have the correct size.
33             q{
34                 CREATE TABLE pg_loader_test2 (
35                     id SERIAL NOT NULL PRIMARY KEY,
36                     a_bigint BIGINT,
37                     an_int8 INT8,
38                     a_bigserial BIGSERIAL,
39                     a_serial8 SERIAL8,
40                     a_bit BIT,
41                     a_boolean BOOLEAN,
42                     a_bool BOOL,
43                     a_box BOX,
44                     a_bytea BYTEA,
45                     a_cidr CIDR,
46                     a_circle CIRCLE,
47                     a_date DATE,
48                     a_double_precision DOUBLE PRECISION,
49                     a_float8 FLOAT8,
50                     an_inet INET,
51                     an_integer INTEGER,
52                     an_int INT,
53                     an_int4 INT4,
54                     an_interval INTERVAL,
55                     an_interval_with_precision INTERVAL(2),
56                     a_line LINE,
57                     an_lseg LSEG,
58                     a_macaddr MACADDR,
59                     a_money MONEY,
60                     a_path PATH,
61                     a_point POINT,
62                     a_polygon POLYGON,
63                     a_real REAL,
64                     a_float4 FLOAT4,
65                     a_smallint SMALLINT,
66                     an_int2 INT2,
67                     a_serial SERIAL,
68                     a_serial4 SERIAL4,
69                     a_text TEXT,
70                     a_time TIME,
71                     a_time_with_precision TIME(2),
72                     a_time_without_time_zone TIME WITHOUT TIME ZONE,
73                     a_time_without_time_zone_with_precision TIME(2) WITHOUT TIME ZONE,
74                     a_time_with_time_zone TIME WITH TIME ZONE,
75                     a_time_with_time_zone_with_precision TIME(2) WITH TIME ZONE,
76                     a_timestamp TIMESTAMP,
77                     a_timestamp_with_precision TIMESTAMP(2),
78                     a_timestamp_without_time_zone TIMESTAMP WITHOUT TIME ZONE,
79                     a_timestamp_without_time_zone_with_precision TIMESTAMP(2) WITHOUT TIME ZONE,
80                     a_timestamp_with_time_zone TIMESTAMP WITH TIME ZONE,
81                     a_timestamp_with_time_zone_with_precision TIMESTAMP(2) WITH TIME ZONE,
82                     a_bit_varying_with_precision BIT VARYING(2),
83                     a_varbit_with_precision VARBIT(2),
84                     a_character_varying_with_precision CHARACTER VARYING(2),
85                     a_varchar_with_precision VARCHAR(2),
86                     a_character_with_precision CHARACTER(2),
87                     a_char_with_precision CHAR(2),
88                     the_numeric NUMERIC(6, 3),
89                     the_decimal DECIMAL(6, 3)
90                 )
91             },
92 # XXX figure out what to do with DECIMAL(precision, scale) aka
93 # NUMERIC(precision, scale)
94         ],
95         drop  => [ qw/ pg_loader_test1 pg_loader_test2 / ],
96         count => 56,
97         run   => sub {
98             my ($schema, $monikers, $classes) = @_;
99
100             my $class    = $classes->{pg_loader_test1};
101             my $filename = $schema->_loader->_get_dump_filename($class);
102
103             my $code = do {
104                 local ($/, @ARGV) = (undef, $filename);
105                 <>;
106             };
107
108             like $code, qr/^=head1 NAME\n\n^$class - The Table\n\n^=cut\n/m,
109                 'table comment';
110
111             like $code, qr/^=head2 value\n\n(.+:.+\n)+\nThe Column\n\n/m,
112                 'column comment and attrs';
113
114             my $rsrc = $schema->resultset('PgLoaderTest2')->result_source;
115             my @type_columns = grep /^a/, $rsrc->columns;
116             my @without_precision = grep !/_with_precision\z/, @type_columns;
117             my @with_precision    = grep  /_with_precision\z/, @type_columns;
118             my %with_precision;
119             @with_precision{
120                 apply { s/_with_precision\z// } @with_precision
121             } = ();
122
123             for my $col (@without_precision) {
124                 my ($data_type) = $col =~ /^an?_(.*)/;
125                 ($data_type = uc $data_type) =~ s/_/ /g;
126
127                 ok((not exists $rsrc->column_info($col)->{size}),
128                     "$data_type " .
129                     (exists $with_precision{$col} ? 'without precision ' : '') .
130                     "has no 'size' column_info");
131             }
132
133             for my $col (@with_precision) {
134                 my ($data_type) = $col =~ /^an?_(.*)_with_precision\z/;
135                 ($data_type = uc $data_type) =~ s/_/ /g;
136                 my $size = $rsrc->column_info($col)->{size};
137
138                 is $size, 2,
139                   "$data_type with precision has a correct 'size' column_info";
140             }
141
142             is_deeply $rsrc->column_info('the_numeric')->{size}, [6,3],
143                 'size for NUMERIC(precision, scale) is correct';
144
145             is_deeply $rsrc->column_info('the_decimal')->{size}, [6,3],
146                 'size for DECIMAL(precision, scale) is correct';
147         },
148     },
149 );
150
151 if( !$dsn || !$user ) {
152     $tester->skip_tests('You need to set the DBICTEST_PG_DSN, _USER, and _PASS environment variables');
153 }
154 else {
155     $tester->run_tests();
156 }