You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: hooks_test.go
    path of file: ./repos/gorm/tests
    
    the code of the file until where you have to start completion: package tests_test

import (
	"errors"
	"reflect"
	"strings"
	"testing"

	"gorm.io/gorm"
	. "gorm.io/gorm/utils/tests"
)

type Product struct {
	gorm.Model
	Name                  string
	Code                  string
	Price                 float64
	AfterFindCallTimes    int64
	BeforeCreateCallTimes int64
	AfterCreateCallTimes  int64
	BeforeUpdateCallTimes int64
	AfterUpdateCallTimes  int64
	BeforeSaveCallTimes   int64
	AfterSaveCallTimes    int64
	BeforeDeleteCallTimes int64
	AfterDeleteCallTimes  int64
}

func (s *Product) BeforeCreate(tx *gorm.DB) (err error) {
	if s.Code == "Invalid" {
		err = errors.New("invalid product")
	}
	s.BeforeCreateCallTimes = s.BeforeCreateCallTimes + 1
	return
}

func (s *Product) BeforeUpdate(tx *gorm.DB) (err error) {
	if s.Code == "dont_update" {
		err = errors.New("can't update")
	}
	s.BeforeUpdateCallTimes = s.BeforeUpdateCallTimes + 1
	return
}

func (s *Product) BeforeSave(tx *gorm.DB) (err error) {
	if s.Code == "dont_save" {
		err = errors.New("can't save")
	}
	s.BeforeSaveCallTimes = s.BeforeSaveCallTimes + 1
	return
}

func (s *Product) AfterFind(tx *gorm.DB) (err error) {
	s.AfterFindCallTimes = s.AfterFindCallTimes + 1
	return
}

func (s *Product) AfterCreate(tx *gorm.DB) (err error) {
	return tx.Model(s).UpdateColumn("AfterCreateCallTimes", s.AfterCreateCallTimes+1).Error
}

func (s *Product) AfterUpdate(tx *gorm.DB) (err error) {
	s.AfterUpdateCallTimes = s.AfterUpdateCallTimes + 1
	return
}

func (s *Product) AfterSave(tx *gorm.DB) (err error) {
	if s.Code == "after_save_erro
    
func TestSetColumn(t *testing.T) {
	DB.Migrator().DropTable(&Product3{})
	DB.AutoMigrate(&Product3{})

	product := Product3{Name: "Product", Price: 0}
	DB.Create(&product)

	if product.Price != 100 {
		t.Errorf("invalid price after create, got %+v", product)
	}

	DB.Model(&product).Select("code", "price").Updates(map[string]interface{}{"code": "L1212"})

	if product.Price != 150 || product.Code != "L1212" {
		t.Errorf("invalid data after update, got %+v", product)
	}

	// Code not changed, price should not change
	DB.Model(&product).Updates(map[string]interface{}{"Name": "Product New"})

	if product.Name != "Product New" || product.Price != 160 || product.Code != "L1212" {
		t.Errorf("invalid data after update, got %+v", product)
	}

	// Code changed, but not selected, price should not change
	DB.Model(&product).Select("Name", "Price").Updates(map[string]interface{}{"Name": "Product New2", "code": "L1213"})

	if product.Name != "Product New2" || product.Price != 170 || product.Code != "L1212" {
		t.Errorf("invalid data after update, got %+v", product)
	}

	// Code changed, price should changed
	DB.Model(&product).Select("Name", "Code", "Price").Updates(map[string]interface{}{"Name": "Product New3", "code": "L1213"})

	if product.Name != "Product New3" || product.Price != 220 || product.Code != "L1213" {
		t.Errorf("invalid data after update, got %+v", product)
	}

	var result Product3
	DB.First(&result, product.ID)

	AssertEqual(t, result, product)

	// Select to change Code, but nothing updated, price should not change
	DB.Model(&product).Select("code").Updates(Product3{Name: "L1214", Code: "L1213"})

	if product.Price != 220 || product.Code != "L1213" || product.Name != "Product New3" {
		t.Errorf("invalid data after update, got %+v", product)
	}

	DB.Model(&product).Updates(Product3{Code: "L1214"})
	if product.Price != 270 || product.Code != "L1214" {
		t.Errorf("invalid data after update, got %+v", product)
	}

	// Code changed, price should changed
	DB.Model(&product).Select("Name", "Code", "Price").Updates(Product3{Name: "Product New4", Code: ""})
	if product.Name != "Product New4" || product.Price != 320 || product.Code != "" {
		t.Errorf("invalid data after update, got %+v", product)
	}

	DB.Model(&product).UpdateColumns(Product3{Code: "L1215"})
	if product.Price != 320 || product.Code != "L1215" {
		t.Errorf("invalid data after update, got %+v", product)
	}

	DB.Model(&product).Session(&gorm.Session{SkipHooks: true}).Updates(Product3{Code: "L1216"})
	if product.Price != 320 || product.Code != "L1216" {
		t.Errorf("invalid data after update, got %+v", product)
	}

	var result2 Product3
	DB.First(&result2, product.ID)

	AssertEqual(t, result2, product)

	product2 := Product3{Name: "Product", Price: 0}
	DB.Session(&gorm.Session{SkipHooks: true}).Create(&product2)

	if product2.Price != 0 {
		t.Errorf("invalid price after create without hooks, got %+v", product2)
	}
}