conn = new FakeMySQLPDO(); // 'threshold' is a nullable numeric column with no default. Declared 'double' // rather than 'int' because SQLite's pragma_table_info uppercases int/integer // ('INT'), which the case-sensitive str_contains($type, 'int') in sql_save() // would miss; float/double/decimal round-trip lowercase and hit the branch. $this->conn->exec('CREATE TABLE metric (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, threshold double)'); }); it('stores an empty string on a nullable numeric column as SQL NULL', function () { sql_save(['name' => 'a', 'threshold' => ''], 'metric', 'id', true, $this->conn); $row = $this->conn->query('SELECT threshold FROM metric WHERE name = \'a\'')->fetch(PDO::FETCH_ASSOC); expect($row['threshold'])->toBeNull(); }); it('preserves a numeric 0 on a nullable numeric column', function () { sql_save(['name' => 'b', 'threshold' => 0], 'metric', 'id', true, $this->conn); $row = $this->conn->query('SELECT threshold FROM metric WHERE name = \'b\'')->fetch(PDO::FETCH_ASSOC); expect($row['threshold'])->not->toBeNull() ->and((int) $row['threshold'])->toBe(0); }); it('preserves the string "0" on a nullable numeric column', function () { sql_save(['name' => 'c', 'threshold' => '0'], 'metric', 'id', true, $this->conn); $row = $this->conn->query('SELECT threshold FROM metric WHERE name = \'c\'')->fetch(PDO::FETCH_ASSOC); expect($row['threshold'])->not->toBeNull() ->and((int) $row['threshold'])->toBe(0); });