github.com/amacneil/dbmate@v1.16.3-0.20230225174651-ca89b10d75d7/pkg/dbmate/migration_test.go (about)

     1  package dbmate
     2  
     3  import (
     4  	"testing"
     5  	"testing/fstest"
     6  
     7  	"github.com/stretchr/testify/require"
     8  )
     9  
    10  func TestParse(t *testing.T) {
    11  	fs := fstest.MapFS{
    12  		"bar/123_foo.sql": {
    13  			Data: []byte(`-- migrate:up
    14  create table users (id serial, name text);
    15  -- migrate:down
    16  drop table users;
    17  `),
    18  		},
    19  	}
    20  
    21  	migration := &Migration{
    22  		Applied:  false,
    23  		FileName: "123_foo.sql",
    24  		FilePath: "bar/123_foo.sql",
    25  		FS:       fs,
    26  		Version:  "123",
    27  	}
    28  
    29  	parsed, err := migration.Parse()
    30  	require.Nil(t, err)
    31  	require.Equal(t, "-- migrate:up\ncreate table users (id serial, name text);\n", parsed.Up)
    32  	require.True(t, parsed.UpOptions.Transaction())
    33  	require.Equal(t, "-- migrate:down\ndrop table users;\n", parsed.Down)
    34  	require.True(t, parsed.DownOptions.Transaction())
    35  }
    36  
    37  func TestParseMigrationContents(t *testing.T) {
    38  	// It supports the typical use case.
    39  	migration := `-- migrate:up
    40  create table users (id serial, name text);
    41  -- migrate:down
    42  drop table users;`
    43  
    44  	parsed, err := parseMigrationContents(migration)
    45  	require.Nil(t, err)
    46  
    47  	require.Equal(t, "-- migrate:up\ncreate table users (id serial, name text);\n", parsed.Up)
    48  	require.Equal(t, true, parsed.UpOptions.Transaction())
    49  
    50  	require.Equal(t, "-- migrate:down\ndrop table users;", parsed.Down)
    51  	require.Equal(t, true, parsed.DownOptions.Transaction())
    52  
    53  	// It does not require space between the '--' and 'migrate'
    54  	migration = `
    55  --migrate:up
    56  create table users (id serial, name text);
    57  
    58  --migrate:down
    59  drop table users;
    60  `
    61  
    62  	parsed, err = parseMigrationContents(migration)
    63  	require.Nil(t, err)
    64  
    65  	require.Equal(t, "--migrate:up\ncreate table users (id serial, name text);\n\n", parsed.Up)
    66  	require.Equal(t, true, parsed.UpOptions.Transaction())
    67  
    68  	require.Equal(t, "--migrate:down\ndrop table users;\n", parsed.Down)
    69  	require.Equal(t, true, parsed.DownOptions.Transaction())
    70  
    71  	// It is acceptable for down to be defined before up
    72  	migration = `-- migrate:down
    73  drop table users;
    74  -- migrate:up
    75  create table users (id serial, name text);
    76  `
    77  
    78  	parsed, err = parseMigrationContents(migration)
    79  	require.Nil(t, err)
    80  
    81  	require.Equal(t, "-- migrate:up\ncreate table users (id serial, name text);\n", parsed.Up)
    82  	require.Equal(t, true, parsed.UpOptions.Transaction())
    83  
    84  	require.Equal(t, "-- migrate:down\ndrop table users;\n", parsed.Down)
    85  	require.Equal(t, true, parsed.DownOptions.Transaction())
    86  
    87  	// It supports turning transactions off for a given migration block,
    88  	// e.g., the below would not work in Postgres inside a transaction.
    89  	// It also supports omitting the down block.
    90  	migration = `-- migrate:up transaction:false
    91  ALTER TYPE colors ADD VALUE 'orange' AFTER 'red';
    92  `
    93  
    94  	parsed, err = parseMigrationContents(migration)
    95  	require.Nil(t, err)
    96  
    97  	require.Equal(t, "-- migrate:up transaction:false\nALTER TYPE colors ADD VALUE 'orange' AFTER 'red';\n", parsed.Up)
    98  	require.Equal(t, false, parsed.UpOptions.Transaction())
    99  
   100  	require.Equal(t, "", parsed.Down)
   101  	require.Equal(t, true, parsed.DownOptions.Transaction())
   102  
   103  	// It does *not* support omitting the up block.
   104  	migration = `-- migrate:down
   105  drop table users;
   106  `
   107  
   108  	_, err = parseMigrationContents(migration)
   109  	require.NotNil(t, err)
   110  	require.Equal(t, "dbmate requires each migration to define an up block with '-- migrate:up'", err.Error())
   111  
   112  	// It allows leading comments and whitespace preceding the migrate blocks
   113  	migration = `
   114  -- This migration creates the users table.
   115  -- It'll drop it in the event of a rollback.
   116  
   117  -- migrate:up
   118  create table users (id serial, name text);
   119  
   120  -- migrate:down
   121  drop table users;
   122  `
   123  
   124  	parsed, err = parseMigrationContents(migration)
   125  	require.Nil(t, err)
   126  
   127  	require.Equal(t, "-- migrate:up\ncreate table users (id serial, name text);\n\n", parsed.Up)
   128  	require.Equal(t, true, parsed.UpOptions.Transaction())
   129  
   130  	require.Equal(t, "-- migrate:down\ndrop table users;\n", parsed.Down)
   131  	require.Equal(t, true, parsed.DownOptions.Transaction())
   132  
   133  	// It does *not* allow arbitrary statements preceding the migrate blocks
   134  	migration = `
   135  -- create status_type
   136  CREATE TYPE status_type AS ENUM ('active', 'inactive');
   137  
   138  -- migrate:up
   139  ALTER TABLE users
   140  ADD COLUMN status status_type DEFAULT 'active';
   141  
   142  -- migrate:down
   143  ALTER TABLE users
   144  DROP COLUMN status;
   145  `
   146  
   147  	_, err = parseMigrationContents(migration)
   148  	require.NotNil(t, err)
   149  	require.Equal(t, "dbmate does not support statements defined outside of the '-- migrate:up' or '-- migrate:down' blocks", err.Error())
   150  
   151  	// It requires an at least an up block
   152  	migration = `
   153  ALTER TABLE users
   154  ADD COLUMN status status_type DEFAULT 'active';
   155  `
   156  
   157  	_, err = parseMigrationContents(migration)
   158  	require.NotNil(t, err)
   159  	require.Equal(t, "dbmate requires each migration to define an up block with '-- migrate:up'", err.Error())
   160  }