use strict;
use warnings;
use Test::More;
use DBIx::Fast;

# Regression tests for make_sen() named-parameter substitution (rank 16):
# it must not rewrite ':' inside string literals or Postgres '::' casts.

eval "use DBD::SQLite 1.74";
plan skip_all => "DBD::SQLite 1.74 required" if $@;

my $db = DBIx::Fast->new(
    dsn        => 'dbi:SQLite:dbname=:memory:',
    driver     => 'SQLite',
    RaiseError => 1,
    PrintError => 0,
);

subtest 'Postgres :: cast is not treated as a named parameter' => sub {
    $db->sql('SELECT id, created::text FROM t WHERE name = :name');
    $db->make_sen({ name => 'Alice' });
    is($db->sql, 'SELECT id, created::text FROM t WHERE name = ?',
       ':: cast preserved; only :name substituted');
    is_deeply($db->p, ['Alice'], 'one bind value');
};

subtest 'colon inside a string literal is preserved' => sub {
    $db->sql(q{SELECT * FROM t WHERE note = 'tag:value' AND x = :x});
    $db->make_sen({ x => 5 });
    is($db->sql, q{SELECT * FROM t WHERE note = 'tag:value' AND x = ?},
       'colon inside a quoted literal is not substituted');
    is_deeply($db->p, [5], 'one bind value');
};

subtest 'normal and duplicate named params still work' => sub {
    $db->sql('SELECT * FROM t WHERE a = :v AND b = :v');
    $db->make_sen({ v => 7 });
    is($db->sql, 'SELECT * FROM t WHERE a = ? AND b = ?', 'duplicates expanded');
    is_deeply($db->p, [7, 7], 'two bind values for the duplicated placeholder');
};

done_testing;
