From 56382d23a1b6be2ec13c468a38e9fed43dd73d0f Mon Sep 17 00:00:00 2001 From: Nathan Baulch Date: Tue, 1 Oct 2024 10:36:38 +1000 Subject: [PATCH 1/4] fix: typos --- CHANGELOG.md | 12 ++++++------ bun.go | 2 +- dialect/mssqldialect/dialect.go | 2 +- driver/pgdriver/column.go | 2 +- example/fixture/fixture.yml | 2 +- example/opentelemetry/uptrace.yml | 2 +- extra/bunbig/README.md | 2 +- internal/dbtest/db_test.go | 6 +++--- model_table_struct.go | 2 +- relation_join.go | 4 ++-- 10 files changed, 18 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e15e4bd7e..56420dedf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,7 +33,7 @@ ### Features -* Allow overiding of Warn and Deprecated loggers ([#952](https://github.com/uptrace/bun/issues/952)) ([0e9d737](https://github.com/uptrace/bun/commit/0e9d737e4ca2deb86930237ee32a39cf3f7e8157)) +* Allow overriding of Warn and Deprecated loggers ([#952](https://github.com/uptrace/bun/issues/952)) ([0e9d737](https://github.com/uptrace/bun/commit/0e9d737e4ca2deb86930237ee32a39cf3f7e8157)) * enable SNI ([#953](https://github.com/uptrace/bun/issues/953)) ([4071ffb](https://github.com/uptrace/bun/commit/4071ffb5bcb1b233cda239c92504d8139dcf1d2f)) * **idb:** add NewMerge method to IDB ([#966](https://github.com/uptrace/bun/issues/966)) ([664e2f1](https://github.com/uptrace/bun/commit/664e2f154f1153d2a80cd062a5074f1692edaee7)) @@ -119,7 +119,7 @@ ### Bug Fixes -* add support for inserting values with unicode encoding for mssql dialect ([e98c6c0](https://github.com/uptrace/bun/commit/e98c6c0f033b553bea3bbc783aa56c2eaa17718f)) +* add support for inserting values with Unicode encoding for mssql dialect ([e98c6c0](https://github.com/uptrace/bun/commit/e98c6c0f033b553bea3bbc783aa56c2eaa17718f)) * fix relation tag ([a3eedff](https://github.com/uptrace/bun/commit/a3eedff49700490d4998dcdcdc04f554d8f17166)) @@ -155,7 +155,7 @@ ### Bug Fixes -* addng dialect override for append-bool ([#695](https://github.com/uptrace/bun/issues/695)) ([338f2f0](https://github.com/uptrace/bun/commit/338f2f04105ad89e64530db86aeb387e2ad4789e)) +* adding dialect override for append-bool ([#695](https://github.com/uptrace/bun/issues/695)) ([338f2f0](https://github.com/uptrace/bun/commit/338f2f04105ad89e64530db86aeb387e2ad4789e)) * don't call hooks twice for whereExists ([9057857](https://github.com/uptrace/bun/commit/90578578e717f248e4b6eb114c5b495fd8d4ed41)) * don't lock migrations when running Migrate and Rollback ([69a7354](https://github.com/uptrace/bun/commit/69a7354d987ff2ed5338c9ef5f4ce320724299ab)) * **query:** make WhereDeleted compatible with ForceDelete ([299c3fd](https://github.com/uptrace/bun/commit/299c3fd57866aaecd127a8f219c95332898475db)), closes [#673](https://github.com/uptrace/bun/issues/673) @@ -323,7 +323,7 @@ recommended to upgrade to v1.0.24 before upgrading to v1.1.x. - append slice values ([4a65129](https://github.com/uptrace/bun/commit/4a651294fb0f1e73079553024810c3ead9777311)) -- check for nils when appeding driver.Value +- check for nils when appending driver.Value ([7bb1640](https://github.com/uptrace/bun/commit/7bb1640a00fceca1e1075fe6544b9a4842ab2b26)) - cleanup soft deletes for mssql ([e72e2c5](https://github.com/uptrace/bun/commit/e72e2c5d0a85f3d26c3fa22c7284c2de1dcfda8e)) @@ -342,7 +342,7 @@ recommended to upgrade to v1.0.24 before upgrading to v1.1.x. ### Deprecated -In the comming v1.1.x release, Bun will stop automatically adding `,pk,autoincrement` options on +In the coming v1.1.x release, Bun will stop automatically adding `,pk,autoincrement` options on `ID int64/int32` fields. This version (v1.0.23) only prints a warning when it encounters such fields, but the code will continue working as before. @@ -460,7 +460,7 @@ In v1.1.x, such options as `,nopk` and `,allowzero` will not be necessary and wi ([693f1e1](https://github.com/uptrace/bun/commit/693f1e135999fc31cf83b99a2530a695b20f4e1b)) - add model embedding via embed:prefix\_ ([9a2cedc](https://github.com/uptrace/bun/commit/9a2cedc8b08fa8585d4bfced338bd0a40d736b1d)) -- change the default logoutput to stderr +- change the default log output to stderr ([4bf5773](https://github.com/uptrace/bun/commit/4bf577382f19c64457cbf0d64490401450954654)), closes [#349](https://github.com/uptrace/bun/issues/349) diff --git a/bun.go b/bun.go index e382c9056..626f0bf4b 100644 --- a/bun.go +++ b/bun.go @@ -74,7 +74,7 @@ type AfterDropTableHook interface { AfterDropTable(ctx context.Context, query *DropTableQuery) error } -// SetLogger overwriters default Bun logger. +// SetLogger overwrites default Bun logger. func SetLogger(logger internal.Logging) { internal.SetLogger(logger) } diff --git a/dialect/mssqldialect/dialect.go b/dialect/mssqldialect/dialect.go index 353417af7..a5c99a274 100755 --- a/dialect/mssqldialect/dialect.go +++ b/dialect/mssqldialect/dialect.go @@ -128,7 +128,7 @@ func (*Dialect) AppendBool(b []byte, v bool) []byte { } func (d *Dialect) AppendString(b []byte, s string) []byte { - // 'N' prefix means the string uses unicode encoding. + // 'N' prefix means the string uses Unicode encoding. b = append(b, 'N') return d.BaseDialect.AppendString(b, s) } diff --git a/driver/pgdriver/column.go b/driver/pgdriver/column.go index 710d707aa..6bbc39d21 100644 --- a/driver/pgdriver/column.go +++ b/driver/pgdriver/column.go @@ -51,7 +51,7 @@ func readColumnValue(rd *reader, dataType int32, dataLen int) (interface{}, erro case pgTimestamptz: return readTimeCol(rd, dataLen) case pgDate: - // Return a string and let the scanner to convert string to time.Time if necessary. + // Return a string and let the scanner convert the string to time.Time if necessary. return readStringCol(rd, dataLen) case pgText, pgVarchar: return readStringCol(rd, dataLen) diff --git a/example/fixture/fixture.yml b/example/fixture/fixture.yml index a8b45edb8..3bb6723a8 100644 --- a/example/fixture/fixture.yml +++ b/example/fixture/fixture.yml @@ -7,7 +7,7 @@ created_at: '{{ now }}' updated_at: '{{ now }}' - _id: doe - name: Jonh Doe + name: John Doe email: john@doe.com created_at: '{{ now }}' diff --git a/example/opentelemetry/uptrace.yml b/example/opentelemetry/uptrace.yml index dea8d5967..a781fe6a1 100644 --- a/example/opentelemetry/uptrace.yml +++ b/example/opentelemetry/uptrace.yml @@ -207,7 +207,7 @@ smtp_mailer: password: mailhog # Uncomment to disable opportunistic TLS. #tls: { disabled: true } - # Emails will be send from this address. + # Emails will be sent from this address. from: 'uptrace@localhost' ## diff --git a/extra/bunbig/README.md b/extra/bunbig/README.md index 224eec01a..0d283ed80 100644 --- a/extra/bunbig/README.md +++ b/extra/bunbig/README.md @@ -66,7 +66,7 @@ let we have x , y as two bigint.Bigint numbers in buntypes. y:= bunbig.FromInt64(90) ``` -For comparing the above numbers, we can do as follow: +For comparing the above numbers, we can do as follows: ``` cmp:=x.Cmp(y) diff --git a/internal/dbtest/db_test.go b/internal/dbtest/db_test.go index 4f103be52..8055d6e4f 100644 --- a/internal/dbtest/db_test.go +++ b/internal/dbtest/db_test.go @@ -876,7 +876,7 @@ func testFKViolation(t *testing.T, db *bun.DB) { _, err = db.NewInsert().Model(new(Deck)).Exec(ctx) require.Error(t, err) - // Create a deck that violates the user_id FK contraint + // Create a deck that violates the user_id FK constraint deck := &Deck{UserID: 42} _, err = db.NewInsert().Model(deck).Exec(ctx) @@ -927,7 +927,7 @@ func testWithForeignKeysAndRules(t *testing.T, db *bun.DB) { _, err = db.NewInsert().Model(new(Deck)).Exec(ctx) require.Error(t, err) - // Create a deck that violates the user_id FK contraint + // Create a deck that violates the user_id FK constraint deck := &Deck{UserID: 42} _, err = db.NewInsert().Model(deck).Exec(ctx) @@ -1012,7 +1012,7 @@ func testWithForeignKeys(t *testing.T, db *bun.DB) { _, err = db.NewInsert().Model(new(Deck)).Exec(ctx) require.Error(t, err) - // Create a deck that violates the user_id FK contraint + // Create a deck that violates the user_id FK constraint deck := &Deck{UserID: 42} _, err = db.NewInsert().Model(deck).Exec(ctx) diff --git a/model_table_struct.go b/model_table_struct.go index a5c9a7bc3..a8860908e 100644 --- a/model_table_struct.go +++ b/model_table_struct.go @@ -242,7 +242,7 @@ func (m *structTableModel) ScanRows(ctx context.Context, rows *sql.Rows) (int, e n++ // And discard the rest. This is especially important for SQLite3, which can return - // a row like it was inserted sucessfully and then return an actual error for the next row. + // a row like it was inserted successfully and then return an actual error for the next row. // See issues/100. for rows.Next() { n++ diff --git a/relation_join.go b/relation_join.go index ba542666d..0ec2aa82d 100644 --- a/relation_join.go +++ b/relation_join.go @@ -367,13 +367,13 @@ func appendChildValues( } // appendMultiValues is an alternative to appendChildValues that doesn't use the sql keyword ID -// but instead use a old style ((k1=v1) AND (k2=v2)) OR (...) of conditions. +// but instead uses old style ((k1=v1) AND (k2=v2)) OR (...) conditions. func appendMultiValues( fmter schema.Formatter, b []byte, v reflect.Value, index []int, baseFields, joinFields []*schema.Field, joinTable schema.Safe, ) []byte { // This is based on a mix of appendChildValues and query_base.appendColumns - // These should never missmatch in length but nice to know if it does + // These should never mismatch in length but nice to know if it does if len(joinFields) != len(baseFields) { panic("not reached") } From 2a8a3a27a1427b932b254c126b837555d4943400 Mon Sep 17 00:00:00 2001 From: Nathan Baulch Date: Tue, 8 Oct 2024 09:31:21 +1100 Subject: [PATCH 2/4] fix: parser unit tests --- internal/parser/parser_test.go | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/internal/parser/parser_test.go b/internal/parser/parser_test.go index 6a8b4a82f..2747436d5 100644 --- a/internal/parser/parser_test.go +++ b/internal/parser/parser_test.go @@ -1,6 +1,7 @@ package parser import ( + "errors" "testing" "github.com/stretchr/testify/require" @@ -140,7 +141,7 @@ func TestParser_Skip(t *testing.T) { name string fields fields args args - want bool + want error idAfterSkip int }{ { @@ -152,7 +153,7 @@ func TestParser_Skip(t *testing.T) { args: args{ skip: '?', }, - want: true, + want: nil, idAfterSkip: 1, }, { @@ -164,7 +165,7 @@ func TestParser_Skip(t *testing.T) { args: args{ skip: '!', }, - want: false, + want: errors.New("got '?', wanted '!'"), idAfterSkip: 0, }, } @@ -179,7 +180,7 @@ func TestParser_Skip(t *testing.T) { } } -func TestParser_SkipBytes(t *testing.T) { +func TestParser_SkipPrefix(t *testing.T) { type fields struct { b []byte i int @@ -191,7 +192,7 @@ func TestParser_SkipBytes(t *testing.T) { name string fields fields args args - want bool + want error idAfterSkip int }{ { @@ -203,7 +204,7 @@ func TestParser_SkipBytes(t *testing.T) { args: args{ skip: []byte("? = "), }, - want: true, + want: nil, idAfterSkip: 4, }, { @@ -215,11 +216,11 @@ func TestParser_SkipBytes(t *testing.T) { args: args{ skip: []byte("hoge"), }, - want: false, + want: errors.New(`got "? = ?", wanted prefix "hoge"`), idAfterSkip: 0, }, { - name: "return false when argument is longer than the remaining bytes", + name: "return error when argument is longer than the remaining bytes", fields: fields{ b: []byte("? = ?"), i: 0, @@ -227,7 +228,7 @@ func TestParser_SkipBytes(t *testing.T) { args: args{ skip: []byte("? = ? hoge"), }, - want: false, + want: errors.New(`got "? = ?", wanted prefix "? = ? hoge"`), idAfterSkip: 0, }, } @@ -237,7 +238,7 @@ func TestParser_SkipBytes(t *testing.T) { b: tt.fields.b, i: tt.fields.i, } - require.Equal(t, tt.want, p.SkipBytes(tt.args.skip)) + require.Equal(t, tt.want, p.SkipPrefix(tt.args.skip)) require.Equal(t, tt.idAfterSkip, p.i) }) } From e3ccc6c4b61ca3428ca4d73f1a95299df04fc112 Mon Sep 17 00:00:00 2001 From: Nathan Baulch Date: Tue, 8 Oct 2024 09:39:07 +1100 Subject: [PATCH 3/4] chore: consistent line endings --- internal/parser/parser_test.go | 1028 ++++++++++++++++---------------- 1 file changed, 514 insertions(+), 514 deletions(-) diff --git a/internal/parser/parser_test.go b/internal/parser/parser_test.go index 2747436d5..21ec14e0a 100644 --- a/internal/parser/parser_test.go +++ b/internal/parser/parser_test.go @@ -1,514 +1,514 @@ -package parser - -import ( - "errors" - "testing" - - "github.com/stretchr/testify/require" -) - -func TestParser_Valid(t *testing.T) { - type fields struct { - b []byte - i int - } - tests := []struct { - name string - fields fields - want bool - }{ - { - name: "return true", - fields: fields{ - b: []byte("users AS u"), - i: 0, - }, - want: true, - }, - { - name: "return false", - fields: fields{ - b: []byte("users AS u"), - i: 10, - }, - want: false, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - p := &Parser{ - b: tt.fields.b, - i: tt.fields.i, - } - require.Equal(t, tt.want, p.Valid()) - }) - } -} - -func TestParser_Read(t *testing.T) { - type fields struct { - b []byte - i int - } - tests := []struct { - name string - fields fields - want byte - idAfterRead int - }{ - { - name: "success to read first byte", - fields: fields{ - b: []byte("users AS u"), - i: 0, - }, - want: 'u', - idAfterRead: 1, - }, - { - name: "fail to read when parser is invalid", - fields: fields{ - b: []byte("users AS u"), - i: 10, - }, - want: 0, - idAfterRead: 10, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - p := &Parser{ - b: tt.fields.b, - i: tt.fields.i, - } - require.Equal(t, tt.want, p.Read()) - require.Equal(t, tt.idAfterRead, p.i) - }) - } -} - -func TestParser_Peek(t *testing.T) { - type fields struct { - b []byte - i int - } - tests := []struct { - name string - fields fields - want byte - idAfterPeek int - }{ - { - name: "success to peek first byte", - fields: fields{ - b: []byte("users AS u"), - i: 0, - }, - want: 'u', - idAfterPeek: 0, - }, - { - name: "fail to peek when parser is invalid", - fields: fields{ - b: []byte("users AS u"), - i: 10, - }, - want: 0, - idAfterPeek: 10, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - p := &Parser{ - b: tt.fields.b, - i: tt.fields.i, - } - require.Equal(t, tt.want, p.Peek()) - require.Equal(t, tt.idAfterPeek, p.i) - }) - } -} - -func TestParser_Skip(t *testing.T) { - type fields struct { - b []byte - i int - } - type args struct { - skip byte - } - tests := []struct { - name string - fields fields - args args - want error - idAfterSkip int - }{ - { - name: "when to skip", - fields: fields{ - b: []byte("? = ?"), - i: 0, - }, - args: args{ - skip: '?', - }, - want: nil, - idAfterSkip: 1, - }, - { - name: "when not to skip", - fields: fields{ - b: []byte("? = ?"), - i: 0, - }, - args: args{ - skip: '!', - }, - want: errors.New("got '?', wanted '!'"), - idAfterSkip: 0, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - p := &Parser{ - b: tt.fields.b, - i: tt.fields.i, - } - require.Equal(t, tt.want, p.Skip(tt.args.skip)) - }) - } -} - -func TestParser_SkipPrefix(t *testing.T) { - type fields struct { - b []byte - i int - } - type args struct { - skip []byte - } - tests := []struct { - name string - fields fields - args args - want error - idAfterSkip int - }{ - { - name: "when to skip", - fields: fields{ - b: []byte("? = ?"), - i: 0, - }, - args: args{ - skip: []byte("? = "), - }, - want: nil, - idAfterSkip: 4, - }, - { - name: "when not to skip", - fields: fields{ - b: []byte("? = ?"), - i: 0, - }, - args: args{ - skip: []byte("hoge"), - }, - want: errors.New(`got "? = ?", wanted prefix "hoge"`), - idAfterSkip: 0, - }, - { - name: "return error when argument is longer than the remaining bytes", - fields: fields{ - b: []byte("? = ?"), - i: 0, - }, - args: args{ - skip: []byte("? = ? hoge"), - }, - want: errors.New(`got "? = ?", wanted prefix "? = ? hoge"`), - idAfterSkip: 0, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - p := &Parser{ - b: tt.fields.b, - i: tt.fields.i, - } - require.Equal(t, tt.want, p.SkipPrefix(tt.args.skip)) - require.Equal(t, tt.idAfterSkip, p.i) - }) - } -} - -func TestParser_ReadSep(t *testing.T) { - type fields struct { - b []byte - i int - } - type args struct { - sep byte - } - tests := []struct { - name string - fields fields - args args - want []byte - wantOk bool - }{ - { - name: "when there are no separators", - fields: fields{ - b: []byte("foo"), - i: 0, - }, - args: args{ - sep: '?', - }, - want: []byte("foo"), - wantOk: false, - }, - { - name: "single question mark", - fields: fields{ - b: []byte("(?) AS foo"), - i: 0, - }, - args: args{ - sep: '?', - }, - want: []byte("("), - wantOk: true, - }, - { - name: "look at first question mark when there are two", - fields: fields{ - b: []byte("? = ?"), - i: 0, - }, - args: args{ - sep: '?', - }, - want: []byte(""), - wantOk: true, - }, - { - name: "look at second question mark when there are two", - fields: fields{ - b: []byte("? = ?"), - i: 1, - }, - args: args{ - sep: '?', - }, - want: []byte(" = "), - wantOk: true, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - p := &Parser{ - b: tt.fields.b, - i: tt.fields.i, - } - got, gotOk := p.ReadSep(tt.args.sep) - require.Equal(t, tt.want, got) - require.Equal(t, tt.wantOk, gotOk) - }) - } -} - -func TestParser_ReadIdentifier(t *testing.T) { - type fields struct { - b []byte - i int - } - tests := []struct { - name string - fields fields - want string - numeric bool - }{ - { - name: "read identifier closed by parenthesis", - fields: fields{ - b: []byte("(?)"), - i: 0, - }, - want: "?", - numeric: false, - }, - { - name: "read space after question mark", - fields: fields{ - b: []byte("? = ?"), - i: 1, - }, - want: "", - numeric: false, - }, - { - name: "read number after question mark", - fields: fields{ - b: []byte("?0, ?1"), - i: 1, - }, - want: "0", - numeric: true, - }, - { - name: "read supported identifier `TableName`", - fields: fields{ - b: []byte("?TableName"), - i: 1, - }, - want: "TableName", - numeric: false, - }, - { - name: "read supported identifier `TableAlias`", - fields: fields{ - b: []byte("?TableAlias"), - i: 1, - }, - want: "TableAlias", - numeric: false, - }, - { - name: "read supported identifier `PKs`", - fields: fields{ - b: []byte("?PKs"), - i: 1, - }, - want: "PKs", - numeric: false, - }, - { - name: "read supported identifier `TablePKs`", - fields: fields{ - b: []byte("?TablePKs"), - i: 1, - }, - want: "TablePKs", - numeric: false, - }, - { - name: "read supported identifier `Columns`", - fields: fields{ - b: []byte("?Columns"), - i: 1, - }, - want: "Columns", - numeric: false, - }, - { - name: "read supported identifier `TableColumns`", - fields: fields{ - b: []byte("?TableColumns"), - i: 1, - }, - want: "TableColumns", - numeric: false, - }, - { - name: "read first identifier", - fields: fields{ - b: []byte("?TableName AS ?TableAlias"), - i: 1, - }, - want: "TableName", - numeric: false, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - p := &Parser{ - b: tt.fields.b, - i: tt.fields.i, - } - got, gotNumeric := p.ReadIdentifier() - require.Equal(t, tt.want, got) - require.Equal(t, tt.numeric, gotNumeric) - }) - } -} - -func TestParser_ReadNumber(t *testing.T) { - type fields struct { - b []byte - i int - } - tests := []struct { - name string - fields fields - want int - }{ - { - name: "read single digit number", - fields: fields{ - b: []byte("?0"), - i: 1, - }, - want: 0, - }, - { - name: "read double digit number", - fields: fields{ - b: []byte("?10"), - i: 1, - }, - want: 10, - }, - { - name: "return 0 when there is no number", - fields: fields{ - b: []byte("?TableName"), - i: 1, - }, - want: 0, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - p := &Parser{ - b: tt.fields.b, - i: tt.fields.i, - } - require.Equal(t, tt.want, p.ReadNumber()) - }) - } - -} - -func Test_isNum(t *testing.T) { - numbers := "0123456789" - for i := 0; i < len(numbers); i++ { - require.True(t, isNum(numbers[i])) - } - alphabet := "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" - for i := 0; i < len(alphabet); i++ { - require.False(t, isNum(alphabet[i])) - } - symbols := "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~" - for i := 0; i < len(symbols); i++ { - require.False(t, isNum(symbols[i])) - } -} - -func Test_isAlpha(t *testing.T) { - numbers := "0123456789" - for i := 0; i < len(numbers); i++ { - require.False(t, isAlpha(numbers[i])) - } - alphabet := "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" - for i := 0; i < len(alphabet); i++ { - require.True(t, isAlpha(alphabet[i])) - } - symbols := "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~" - for i := 0; i < len(symbols); i++ { - require.False(t, isNum(symbols[i])) - } -} +package parser + +import ( + "errors" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestParser_Valid(t *testing.T) { + type fields struct { + b []byte + i int + } + tests := []struct { + name string + fields fields + want bool + }{ + { + name: "return true", + fields: fields{ + b: []byte("users AS u"), + i: 0, + }, + want: true, + }, + { + name: "return false", + fields: fields{ + b: []byte("users AS u"), + i: 10, + }, + want: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &Parser{ + b: tt.fields.b, + i: tt.fields.i, + } + require.Equal(t, tt.want, p.Valid()) + }) + } +} + +func TestParser_Read(t *testing.T) { + type fields struct { + b []byte + i int + } + tests := []struct { + name string + fields fields + want byte + idAfterRead int + }{ + { + name: "success to read first byte", + fields: fields{ + b: []byte("users AS u"), + i: 0, + }, + want: 'u', + idAfterRead: 1, + }, + { + name: "fail to read when parser is invalid", + fields: fields{ + b: []byte("users AS u"), + i: 10, + }, + want: 0, + idAfterRead: 10, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &Parser{ + b: tt.fields.b, + i: tt.fields.i, + } + require.Equal(t, tt.want, p.Read()) + require.Equal(t, tt.idAfterRead, p.i) + }) + } +} + +func TestParser_Peek(t *testing.T) { + type fields struct { + b []byte + i int + } + tests := []struct { + name string + fields fields + want byte + idAfterPeek int + }{ + { + name: "success to peek first byte", + fields: fields{ + b: []byte("users AS u"), + i: 0, + }, + want: 'u', + idAfterPeek: 0, + }, + { + name: "fail to peek when parser is invalid", + fields: fields{ + b: []byte("users AS u"), + i: 10, + }, + want: 0, + idAfterPeek: 10, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &Parser{ + b: tt.fields.b, + i: tt.fields.i, + } + require.Equal(t, tt.want, p.Peek()) + require.Equal(t, tt.idAfterPeek, p.i) + }) + } +} + +func TestParser_Skip(t *testing.T) { + type fields struct { + b []byte + i int + } + type args struct { + skip byte + } + tests := []struct { + name string + fields fields + args args + want error + idAfterSkip int + }{ + { + name: "when to skip", + fields: fields{ + b: []byte("? = ?"), + i: 0, + }, + args: args{ + skip: '?', + }, + want: nil, + idAfterSkip: 1, + }, + { + name: "when not to skip", + fields: fields{ + b: []byte("? = ?"), + i: 0, + }, + args: args{ + skip: '!', + }, + want: errors.New("got '?', wanted '!'"), + idAfterSkip: 0, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &Parser{ + b: tt.fields.b, + i: tt.fields.i, + } + require.Equal(t, tt.want, p.Skip(tt.args.skip)) + }) + } +} + +func TestParser_SkipPrefix(t *testing.T) { + type fields struct { + b []byte + i int + } + type args struct { + skip []byte + } + tests := []struct { + name string + fields fields + args args + want error + idAfterSkip int + }{ + { + name: "when to skip", + fields: fields{ + b: []byte("? = ?"), + i: 0, + }, + args: args{ + skip: []byte("? = "), + }, + want: nil, + idAfterSkip: 4, + }, + { + name: "when not to skip", + fields: fields{ + b: []byte("? = ?"), + i: 0, + }, + args: args{ + skip: []byte("hoge"), + }, + want: errors.New(`got "? = ?", wanted prefix "hoge"`), + idAfterSkip: 0, + }, + { + name: "return error when argument is longer than the remaining bytes", + fields: fields{ + b: []byte("? = ?"), + i: 0, + }, + args: args{ + skip: []byte("? = ? hoge"), + }, + want: errors.New(`got "? = ?", wanted prefix "? = ? hoge"`), + idAfterSkip: 0, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &Parser{ + b: tt.fields.b, + i: tt.fields.i, + } + require.Equal(t, tt.want, p.SkipPrefix(tt.args.skip)) + require.Equal(t, tt.idAfterSkip, p.i) + }) + } +} + +func TestParser_ReadSep(t *testing.T) { + type fields struct { + b []byte + i int + } + type args struct { + sep byte + } + tests := []struct { + name string + fields fields + args args + want []byte + wantOk bool + }{ + { + name: "when there are no separators", + fields: fields{ + b: []byte("foo"), + i: 0, + }, + args: args{ + sep: '?', + }, + want: []byte("foo"), + wantOk: false, + }, + { + name: "single question mark", + fields: fields{ + b: []byte("(?) AS foo"), + i: 0, + }, + args: args{ + sep: '?', + }, + want: []byte("("), + wantOk: true, + }, + { + name: "look at first question mark when there are two", + fields: fields{ + b: []byte("? = ?"), + i: 0, + }, + args: args{ + sep: '?', + }, + want: []byte(""), + wantOk: true, + }, + { + name: "look at second question mark when there are two", + fields: fields{ + b: []byte("? = ?"), + i: 1, + }, + args: args{ + sep: '?', + }, + want: []byte(" = "), + wantOk: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &Parser{ + b: tt.fields.b, + i: tt.fields.i, + } + got, gotOk := p.ReadSep(tt.args.sep) + require.Equal(t, tt.want, got) + require.Equal(t, tt.wantOk, gotOk) + }) + } +} + +func TestParser_ReadIdentifier(t *testing.T) { + type fields struct { + b []byte + i int + } + tests := []struct { + name string + fields fields + want string + numeric bool + }{ + { + name: "read identifier closed by parenthesis", + fields: fields{ + b: []byte("(?)"), + i: 0, + }, + want: "?", + numeric: false, + }, + { + name: "read space after question mark", + fields: fields{ + b: []byte("? = ?"), + i: 1, + }, + want: "", + numeric: false, + }, + { + name: "read number after question mark", + fields: fields{ + b: []byte("?0, ?1"), + i: 1, + }, + want: "0", + numeric: true, + }, + { + name: "read supported identifier `TableName`", + fields: fields{ + b: []byte("?TableName"), + i: 1, + }, + want: "TableName", + numeric: false, + }, + { + name: "read supported identifier `TableAlias`", + fields: fields{ + b: []byte("?TableAlias"), + i: 1, + }, + want: "TableAlias", + numeric: false, + }, + { + name: "read supported identifier `PKs`", + fields: fields{ + b: []byte("?PKs"), + i: 1, + }, + want: "PKs", + numeric: false, + }, + { + name: "read supported identifier `TablePKs`", + fields: fields{ + b: []byte("?TablePKs"), + i: 1, + }, + want: "TablePKs", + numeric: false, + }, + { + name: "read supported identifier `Columns`", + fields: fields{ + b: []byte("?Columns"), + i: 1, + }, + want: "Columns", + numeric: false, + }, + { + name: "read supported identifier `TableColumns`", + fields: fields{ + b: []byte("?TableColumns"), + i: 1, + }, + want: "TableColumns", + numeric: false, + }, + { + name: "read first identifier", + fields: fields{ + b: []byte("?TableName AS ?TableAlias"), + i: 1, + }, + want: "TableName", + numeric: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &Parser{ + b: tt.fields.b, + i: tt.fields.i, + } + got, gotNumeric := p.ReadIdentifier() + require.Equal(t, tt.want, got) + require.Equal(t, tt.numeric, gotNumeric) + }) + } +} + +func TestParser_ReadNumber(t *testing.T) { + type fields struct { + b []byte + i int + } + tests := []struct { + name string + fields fields + want int + }{ + { + name: "read single digit number", + fields: fields{ + b: []byte("?0"), + i: 1, + }, + want: 0, + }, + { + name: "read double digit number", + fields: fields{ + b: []byte("?10"), + i: 1, + }, + want: 10, + }, + { + name: "return 0 when there is no number", + fields: fields{ + b: []byte("?TableName"), + i: 1, + }, + want: 0, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &Parser{ + b: tt.fields.b, + i: tt.fields.i, + } + require.Equal(t, tt.want, p.ReadNumber()) + }) + } + +} + +func Test_isNum(t *testing.T) { + numbers := "0123456789" + for i := 0; i < len(numbers); i++ { + require.True(t, isNum(numbers[i])) + } + alphabet := "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" + for i := 0; i < len(alphabet); i++ { + require.False(t, isNum(alphabet[i])) + } + symbols := "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~" + for i := 0; i < len(symbols); i++ { + require.False(t, isNum(symbols[i])) + } +} + +func Test_isAlpha(t *testing.T) { + numbers := "0123456789" + for i := 0; i < len(numbers); i++ { + require.False(t, isAlpha(numbers[i])) + } + alphabet := "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" + for i := 0; i < len(alphabet); i++ { + require.True(t, isAlpha(alphabet[i])) + } + symbols := "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~" + for i := 0; i < len(symbols); i++ { + require.False(t, isNum(symbols[i])) + } +} From f14731d73ea72df664fda64c286af802fa2c12ae Mon Sep 17 00:00:00 2001 From: Nathan Baulch Date: Tue, 8 Oct 2024 09:39:45 +1100 Subject: [PATCH 4/4] chore: migrate deprecated function --- schema/append_value.go | 4 ++-- schema/scan.go | 2 +- schema/table.go | 2 +- schema/zerochecker.go | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/schema/append_value.go b/schema/append_value.go index 1457aab65..48a0761be 100644 --- a/schema/append_value.go +++ b/schema/append_value.go @@ -67,7 +67,7 @@ func FieldAppender(dialect Dialect, field *Field) AppenderFunc { } if fieldType.Kind() != reflect.Ptr { - if reflect.PtrTo(fieldType).Implements(driverValuerType) { + if reflect.PointerTo(fieldType).Implements(driverValuerType) { return addrAppender(appendDriverValue) } } @@ -123,7 +123,7 @@ func appender(dialect Dialect, typ reflect.Type) AppenderFunc { } if kind != reflect.Ptr { - ptr := reflect.PtrTo(typ) + ptr := reflect.PointerTo(typ) if ptr.Implements(queryAppenderType) { return addrAppender(appendQueryAppenderValue) } diff --git a/schema/scan.go b/schema/scan.go index 485748006..4da160daf 100644 --- a/schema/scan.go +++ b/schema/scan.go @@ -111,7 +111,7 @@ func scanner(typ reflect.Type) ScannerFunc { } if kind != reflect.Ptr { - ptr := reflect.PtrTo(typ) + ptr := reflect.PointerTo(typ) if ptr.Implements(scannerType) { return addrScanner(scanScanner) } diff --git a/schema/table.go b/schema/table.go index 9806c9998..79388fb1c 100644 --- a/schema/table.go +++ b/schema/table.go @@ -100,7 +100,7 @@ func (table *Table) init(dialect Dialect, typ reflect.Type, canAddr bool) { {afterScanRowHookType, afterScanRowHookFlag}, } - typ = reflect.PtrTo(table.Type) + typ = reflect.PointerTo(table.Type) for _, hook := range hooks { if typ.Implements(hook.typ) { table.flags = table.flags.Set(hook.flag) diff --git a/schema/zerochecker.go b/schema/zerochecker.go index f24e51d30..7c1f088c1 100644 --- a/schema/zerochecker.go +++ b/schema/zerochecker.go @@ -60,7 +60,7 @@ func zeroChecker(typ reflect.Type) IsZeroerFunc { kind := typ.Kind() if kind != reflect.Ptr { - ptr := reflect.PtrTo(typ) + ptr := reflect.PointerTo(typ) if ptr.Implements(isZeroerType) { return addrChecker(isZeroInterface) }