diff --git a/README.md b/README.md index 3053d30..231d565 100644 --- a/README.md +++ b/README.md @@ -19,11 +19,20 @@ To start developing, set the `OPENAI_API_KEY` environment variable to your [ChatGPT secret key](https://platform.openai.com/account/api-keys). Follow these steps for running tests and building the application: -1. Run the unit tests using the following script: +1. Run the tests using the following scripts: +For unit tests, run: ```shell ./scripts/unit.sh ``` +For integration tests, run: +```shell +./scripts/integration.sh +``` +To run all tests, use: +```shell +./scripts/all-tests.sh +``` 2. Build the app using the installation script: diff --git a/cmd/chatgpt/main.go b/cmd/chatgpt/main.go index 2beb35b..c16673d 100644 --- a/cmd/chatgpt/main.go +++ b/cmd/chatgpt/main.go @@ -38,7 +38,7 @@ func main() { func run(cmd *cobra.Command, args []string) error { if clearHistory { - historyHandler := history.New() + historyHandler := history.NewDefault() err := historyHandler.Delete() if err != nil { return err @@ -58,7 +58,7 @@ func run(cmd *cobra.Command, args []string) error { if secret == "" { return errors.New("missing environment variable: " + secretEnv) } - client := client.New(http.New().WithSecret(secret), history.New()) + client := client.New(http.New().WithSecret(secret), history.NewDefault()) if queryMode { result, err := client.Query(strings.Join(args, " ")) diff --git a/history/store.go b/history/store.go index 190d880..cb532df 100644 --- a/history/store.go +++ b/history/store.go @@ -18,46 +18,41 @@ type Store interface { var _ Store = &FileIO{} type FileIO struct { + historyFilePath string } -func New() *FileIO { - return &FileIO{} +func NewDefault() *FileIO { + path, _ := getPath() + return &FileIO{ + historyFilePath: path, + } } -func (f *FileIO) Delete() error { - historyFilePath, err := getPath() - if err != nil { - return err +func New(historyFilePath string) *FileIO { + return &FileIO{ + historyFilePath: historyFilePath, } +} - if _, err := os.Stat(historyFilePath); err == nil { - return os.Remove(historyFilePath) +func (f *FileIO) Delete() error { + if _, err := os.Stat(f.historyFilePath); err == nil { + return os.Remove(f.historyFilePath) } return nil } func (f *FileIO) Read() ([]types.Message, error) { - historyFilePath, err := getPath() - if err != nil { - return nil, err - } - - return parseFile(historyFilePath) + return parseFile(f.historyFilePath) } func (f *FileIO) Write(messages []types.Message) error { - historyFilePath, err := getPath() - if err != nil { - return err - } - data, err := json.Marshal(messages) if err != nil { return err } - return ioutil.WriteFile(historyFilePath, data, 0644) + return ioutil.WriteFile(f.historyFilePath, data, 0644) } func getPath() (string, error) { diff --git a/integration/integration_test.go b/integration/integration_test.go new file mode 100644 index 0000000..701c67a --- /dev/null +++ b/integration/integration_test.go @@ -0,0 +1,82 @@ +package integration_test + +import ( + "github.com/kardolus/chatgpt-cli/history" + "github.com/kardolus/chatgpt-cli/types" + "github.com/sclevine/spec" + "github.com/sclevine/spec/report" + "io/ioutil" + "os" + "testing" + + . "github.com/onsi/gomega" +) + +func TestIntegration(t *testing.T) { + spec.Run(t, "Integration Tests", testIntegration, spec.Report(report.Terminal{})) +} + +func testIntegration(t *testing.T, when spec.G, it spec.S) { + it.Before(func() { + RegisterTestingT(t) + }) + + when("Read, Write and Delete", func() { + var ( + tmpDir string + tmpFile *os.File + fileIO *history.FileIO + messages []types.Message + err error + ) + + it.Before(func() { + tmpDir, err = ioutil.TempDir("", "chatgpt-cli-test") + Expect(err).NotTo(HaveOccurred()) + + tmpFile, err = ioutil.TempFile(tmpDir, "history.json") + Expect(err).NotTo(HaveOccurred()) + + tmpFile.Close() + + fileIO = history.New(tmpFile.Name()) + + messages = []types.Message{ + { + Role: "user", + Content: "Test message 1", + }, + { + Role: "assistant", + Content: "Test message 2", + }, + } + }) + + it.After(func() { + os.RemoveAll(tmpDir) + }) + + it("writes the messages to the file", func() { + err = fileIO.Write(messages) + Expect(err).NotTo(HaveOccurred()) + }) + + it("reads the messages from the file", func() { + err = fileIO.Write(messages) // need to write before reading + Expect(err).NotTo(HaveOccurred()) + + readMessages, err := fileIO.Read() + Expect(err).NotTo(HaveOccurred()) + Expect(readMessages).To(Equal(messages)) + }) + + it("deletes the file", func() { + err = fileIO.Delete() + Expect(err).NotTo(HaveOccurred()) + + _, err = os.Stat(tmpFile.Name()) + Expect(os.IsNotExist(err)).To(BeTrue()) + }) + }) +}