package orm import ( "fmt" "github.com/stretchr/testify/assert" "math/rand/v2" "os" "slices" "strings" "testing" "time" "github.com/go-loremipsum/loremipsum" ) type chapter struct { ChapterID int64 `json:"chapterID" d:"pk:t;"` Title string `json:"chapterTitle" form:"chapterTitle"` Index int `json:"index" form:"index"` Words int `json:"words"` Notes string `json:"notes" form:"notes"` Genre []string `json:"genre" form:"genre" d:"type:text[]"` Bands []band `json:"bands" ref:"band,bands"` Characters []string `json:"characters" form:"characters" d:"type:text[]"` Relationships [][]string `json:"relationships" form:"relationships" d:"type:jsonb"` Adult bool `json:"adult" form:"adult"` Summary string `json:"summary" form:"summary"` Hidden bool `json:"hidden" form:"hidden"` LoggedInOnly bool `json:"loggedInOnly" form:"loggedInOnly"` Posted time.Time `json:"datePosted"` FileName string `json:"fileName" d:"-"` Text string `json:"text" d:"column:content" gridfs:"story_text,/stories/{{.ChapterID}}.txt"` } type band struct { Document `json:",inline" d:"table:bands"` ID int64 `json:"_id" d:"pk;"` Name string `json:"name" form:"name"` Locked bool `json:"locked" form:"locked"` Characters []string `json:"characters" form:"characters" d:"type:text[]"` } type user struct { Document `json:",inline" d:"table:users"` ID int64 `json:"_id" d:"pk;"` Username string `json:"username"` Favs favs `json:"favs" ref:"user"` Roles []role `d:"m2m:user_roles"` } type role struct { ID int64 `d:"pk"` Name string Users []user `d:"m2m:user_roles"` } type favs struct { ID int64 `d:"pk"` Stories []story Authors []user } type story struct { Document `json:",inline" d:"table:stories"` ID int64 `json:"_id" d:"pk;"` Title string `json:"title" form:"title"` Author user `json:"author" ref:"user"` CoAuthor *user `json:"coAuthor" ref:"user"` Chapters []chapter `json:"chapters"` Recs int `json:"recs"` Favs int `json:"favs"` Views int `json:"views"` Completed bool `json:"completed" form:"completed"` Downloads int `json:"downloads"` } type somethingWithNestedChapters struct { ID int64 `json:"_id"` Document `json:",inline" coll:"nested_stuff"` Chapters []chapter `json:"chapters"` NestedText string `json:"text" gridfs:"nested_text,/nested/{{.ID}}.txt"` } func friend() user { return user{ Username: "DarQuiel7", ID: 83378, } } func author() user { return user{ Username: "tablet.exe", ID: 85783, } } func genChaps(single bool, aceil int) []chapter { var ret []chapter var ceil int if single { ceil = 1 } else { ceil = aceil } relMap := make([][][]string, 0) bands := make([][]band, 0) charMap := make([][]string, 0) for i := range ceil { curChars := make([]string, 0) curBands := make([]band, 0) curBands = append(curBands, diamondHead) curChars = append(curChars, diamondHead.Characters...) { randMin := max(i+1, 1) randMax := min(i+1, randMin+1) mod1 := max(rand.IntN(randMin), 1) mod2 := max(rand.IntN(randMax+1), 1) if (mod1%mod2 == 0 || (mod1%mod2) == 2) && i > 0 { curBands = append(curBands, bodom) curChars = append(curChars, bodom.Characters...) } } crel := make([][]string, 0) numRels := rand.IntN(3) seenRels := make(map[string]bool) for len(crel) <= numRels { arel := make([]string, 0) randRelChars := rand.IntN(3) numRelChars := 0 if randRelChars == 1 { numRelChars = 3 } else if randRelChars == 2 { numRelChars = 2 } if numRelChars == 0 { continue } seen := make(map[string]bool) for len(arel) < numRelChars { char := diamondHead.Characters[rand.IntN(len(diamondHead.Characters))] if !seen[char] { arel = append(arel, char) seen[char] = true } } slices.Sort(arel) maybeSeen := strings.Join(arel, "/") if maybeSeen != "" && !seenRels[maybeSeen] { seenRels[maybeSeen] = true crel = append(crel, arel) } } { numChars := rand.IntN(len(curChars)-1) + 1 seen := make(map[string]bool) cchars := make([]string, 0) for len(cchars) <= numChars { char := curChars[rand.IntN(len(curChars))] if !seen[char] { cchars = append(cchars, char) seen[char] = true } } charMap = append(charMap, cchars) } relMap = append(relMap, crel) bands = append(bands, curBands) } l := loremipsum.New() for i := range ceil { spf := fmt.Sprintf("%d.md", i+1) c := chapter{ Title: fmt.Sprintf("-%d-", i+1), Index: i + 1, Words: 50, Notes: "notenotenote !!!", Genre: []string{"Slash"}, Bands: bands[i], Characters: charMap[i], Relationships: relMap[i], Adult: true, Summary: l.Paragraph(), Hidden: false, LoggedInOnly: true, FileName: spf, Text: strings.Join(l.ParagraphList(10), "\n\n"), Posted: time.Now().Add(time.Hour * time.Duration(int64(24*7*i))), } ret = append(ret, c) } return ret } func doSomethingWithNested() somethingWithNestedChapters { l := loremipsum.New() swnc := somethingWithNestedChapters{ Chapters: genChaps(false, 7), NestedText: strings.Join(l.ParagraphList(15), "\n\n"), } return swnc } func iti_single(a user) *story { return &story{ Title: "title", Completed: true, Author: a, Chapters: genChaps(true, 1), } } func iti_multi(a user) *story { return &story{ Title: "Brian Tatler Fucked and Abused Sean Harris", Completed: false, Author: a, Chapters: genChaps(false, 5), } } func iti_blank(a user) *story { t := iti_single(a) t.Chapters = make([]chapter, 0) return t } var metallica = band{ ID: 1, Name: "Metallica", Characters: []string{ "James Hetfield", "Lars Ulrich", "Kirk Hammett", "Cliff Burton", }, Locked: false, } var diamondHead = band{ ID: 503, Name: "Diamond Head", Locked: false, Characters: []string{ "Brian Tatler", "Sean Harris", "Duncan Scott", "Colin Kimberley", }, } var bodom = band{ ID: 74, Name: "Children of Bodom", Locked: false, Characters: []string{ "Janne Wirman", "Alexi Laiho", "Jaska Raatikainen", "Henkka T. Blacksmith", "Roope Latvala", "Daniel Freyberg", "Alexander Kuoppala", }, } func initTest(t *testing.T) *Engine { e, err := Open("postgres://testbed_user:123@localhost/real_test_db", &Config{ LogLevel: LevelQuery, LogTo: os.Stderr, }) assert.Nil(t, err) e.Models(user{}, story{}, band{}, role{}) err = e.MigrateDropping() assert.Nil(t, err) return e } func insertBands(t *testing.T, e *Engine) { err := e.Model(&band{}).Create(&bodom) assert.Nil(t, err) err = e.Model(&band{}).Create(&diamondHead) assert.Nil(t, err) } func checkChapters(t *testing.T, s *story) { for _, c := range s.Chapters { assert.NotZero(t, c.ChapterID) assert.NotZero(t, c.Text) assert.NotZero(t, c.Posted) } }