// package mock_env -- обеспечивает мок-окружение для тестов. package mock_env import ( "os" "strings" "gitp78su.ipnodns.ru/svi/kern/v4/lev0" "gitp78su.ipnodns.ru/svi/kern/v4/lev0/helpers" ) type IMockEnv interface { // Pwd -- возвращает текущий рабочий каталог процесса Pwd() *lev0.LTxt } // MockEnv -- объект мок-окружения. type MockEnv struct { dictEnv map[lev0.Txt]*lev0.LTxt // Словарь переменных окружения pwd *lev0.LTxt // Текущий путь процесса fileName *lev0.LTxt // Полный путь к .env файлу strEnv *lev0.LTxt // Фактическое содержимое .env файла } // MakeEnv -- возвращает новое мок-окружение. func MakeEnv() *MockEnv { sf := &MockEnv{ dictEnv: map[lev0.Txt]*lev0.LTxt{}, } sf.setPath() sf.readEnv() sf.parseEnv() sf.SetAll() return sf } // Парсит полученный текст .env для установки переменных окружения. func (sf *MockEnv) parseEnv() { lstStr := strings.SplitSeq(sf.strEnv.String(), "\n") for val := range lstStr { pair := strings.TrimSuffix(val, "\r") if pair == "" { continue } if strings.HasPrefix(val, "#") { continue } sf.parseEnvStr(lev0.LetTxt(pair)) } } // Парсит строку окружения. func (sf *MockEnv) parseEnvStr(pair *lev0.LTxt) { lstPair := strings.Split(pair.String(), "=") lev0.If(len(lstPair) < 2).Hassert("MockEnv.parseEnvStr(): pair(%v) not have =", []any{pair}) key := lstPair[0] lev0.If(key == "").Hassert("MockEnv.parseEnvStr(): in pair(%v) key is empty", []any{pair}) lstVal := lstPair[1:] val := "" for _, val_ := range lstVal { val += val_ + "=" } val = strings.TrimSuffix(val, "=") lev0.If(val == "").Hassert("MockEnv.parseEnvStr(): in pair(%v) val is empty", []any{pair}) sf.dictEnv[lev0.Txt(key)] = lev0.LetTxt(val) } // Читает файл переменных окружения. func (sf *MockEnv) readEnv() { binEnv, err := os.ReadFile(sf.fileName.String()) lev0.If(err != nil). Hassert("MockEnv.readEnv(): in read %v, err=\n\t%v", []any{sf.fileName, err}) sf.strEnv = lev0.LetTxt(lev0.Txt(binEnv)) } // Устанавливает текущий путь относительно проекта в dev. func (sf *MockEnv) setPath() { dir, err := os.Getwd() helpers.If(err != nil).Hassert("MockEnv.setPath(): in get PWD, err=\n\t%v", []any{err}) lstDir := strings.Split(dir, "/") var pwd strings.Builder fileName := "" isFind := lev0.Bool(false) for _, point := range lstDir { _, _ = pwd.WriteString(point + "/") fileName = pwd.String() + ".env" _, err := os.ReadFile(fileName) if err == nil { isFind = true break } } helpers.If(!isFind).Hassert("MockEnv.setPath(): not find file .env", []any{}) sf.pwd = lev0.LetTxt(pwd.String() + "/bin_dev") err = os.MkdirAll(sf.pwd.String(), 0750) helpers.If(err != nil).Hassert("MockEnv.setPath(): in create PWD, err=\n\t%v", []any{err}) err = os.Chdir(sf.pwd.String()) helpers.If(err != nil).Hassert("MockEnv.setPath(): in set cwd(%v), err=\n\t%v", []any{sf.pwd, err}) sf.fileName = lev0.LetTxt(fileName) } // Pwd -- возвращает текущий рабочий каталог процесса. func (sf *MockEnv) Pwd() *lev0.LTxt { return sf.pwd } // SetAll -- поднимает все переменные окружения. func (sf *MockEnv) SetAll() { sf.ResetAll() for key, val := range sf.dictEnv { sf.Reset(lev0.LetTxt("key")) err := os.Setenv(string(key), val.String()) lev0.If(err != nil). Hassert("MockEnv.SetAll(): in set env %v on key %v, err=\n\t%v", []any{key, val, err}) } } // ResetAll -- сбрасывает все переменные окружения. func (sf *MockEnv) ResetAll() { for key := range sf.dictEnv { sf.Reset(lev0.LetTxt(key)) } } // Reset -- сбрасывает конкретный ключ. func (sf *MockEnv) Reset(key *lev0.LTxt) { lev0.If(key.Get() == ""). Hassert("MockEnv.Reset(): key is empty", []any{}) err := os.Unsetenv(key.String()) lev0.If(err != nil). Hassert("MockEnv.Reset(): in reset env %v, err=\n\t%v", []any{key, err}) }