diff --git a/README.md b/README.md index 0645188..cbf0919 100644 --- a/README.md +++ b/README.md @@ -4,8 +4,6 @@ A generative AI-driven CLI for testing Jarvis is a powerful CLI tool that leverages advanced generative AI technologies (such as Google's Gemini Pro LLM and Gemini Vision Pro) to streamline and enhance various software testing activities. It aims to revolutionize how we approach test case generation and scenario creation. -## Features: - * **Effortless Test Scenario Generation**: Analyze provided API specs (OpenAPI v3.0 and potentially others) to automatically suggest comprehensive test scenarios, covering both positive and negative test cases. * **AI-Driven Test Case Writing**: Leverages the language model's capabilities to draft detailed test cases, ensuring clarity, accuracy, and consistency. * **Image/Document Analysis**: (Powered by Gemini Vision Pro) Extends analysis to screenshots, wireframes, or other visual representations of expected behavior, enhancing scenario generation and test case creation. diff --git a/docs/example.md b/docs/example.md index 76ec028..b3bcd8e 100644 --- a/docs/example.md +++ b/docs/example.md @@ -2,55 +2,78 @@ ```md ```sh go build -o ./dist -ldflags="-X 'github.com/dipjyotimetia/jarvis/cmd/cmd.version=0.0.2'" ./... -.\dist\jarvis.exe generate-scenarios --path="specs/openapi/v3.0" +.\dist\jarvis.exe generate-scenarios --path="specs/openapi/v3.0/mini_blog.yaml" ``` +**Test Scenario 1: Retrieve All Blog Posts** -**Positive Test Cases:** - -* **List all pets (GET /pets): -** - * Send a GET request to `/pets` without any query parameters. - * Expected response: Status code 200, a list - of pets in JSON format. -* **Create a pet (POST /pets):** - * Send a POST request to `/pets` with a valid pet object in the request body. - * Expected response: Status code 201, no response body. -* **Get pet by ID ( -GET /pets/{petId}):** - * Send a GET request to `/pets/{petId}` with a valid pet ID. - * Expected response: Status code 200, the pet object in JSON format. - -**Negative Test Cases:** - -* **List all pets with invalid limit (GET /pets):** - * Send a GET request to `/pets` with an invalid limit value (e.g., -10). - * Expected response: Status code 400 (Bad Request), an error message in JSON format. -* **Create a pet with invalid data (POST - /pets):** - * Send a POST request to `/pets` with an invalid pet object (e.g., missing required properties). - * Expected response: Status code 400 (Bad Request), an error message in JSON format. -* **Get pet by invalid ID (GET /pets/{petId}):** - * Send a GET request to `/pets/{petId}` with an invalid pet ID (e.g., "abc"). - * Expected response: Status code 404 (Not Found), an error message in JSON format. - -**Edge Cases:** - -* **List all pets with maximum limit (GET /pets):** - * Send a GET request to `/pets` with the maximum allowed limit value (100). - * Expected response: Status code 200, a list of 100 pets in JSON format. -* **Create a pet with empty name (POST /pets):** - * Send a POST request to `/pets` with a pet object with an empty name. - * Expected response: Status code 201, no response body. -* **Get pet with a non-existent ID (GET /pets/{petId -}):** - * Send a GET request to `/pets/{petId}` with a non-existent pet ID. - * Expected response: Status code 404 (Not Found), an error message in JSON format. +* Precondition: + The API server is up and running. +* Action: Send a GET request to the "/posts" endpoint. +* Expected Result: The server responds with + a status code of 200 and a list of all blog posts in JSON format. + +**Test Scenario 2: Create a New Blog Post** + +* Precondition: The API server is up and running. +* Action: Send a POST request to the "/posts" endpoint with a valid JSON payload + representing a new blog post. +* Expected Result: The server responds with a status code of 201 and the newly created blog post in JSON format. + +**Test Scenario 3: Retrieve a Specific Blog Post** + +* Precondition: The API server is up and running. +* Action: Send a GET request to the "/posts/{postId}" endpoint with a valid postId. +* Expected Result: The server responds with a status code of 200 and the details of the requested blog post in JSON format. + +**Test Scenario 4: Update a Blog Post** + +* Precondition: The API + server is up and running. +* Action: Send a PATCH request to the "/posts/{postId}" endpoint with a valid postId and a JSON payload containing the updated fields. +* Expected Result: The server responds with a status code of 200 and the updated blog post in JSON format. + +**Test Scenario 5: Delete a Blog Post** + +* Precondition: The API server is up and running. +* Action: Send a DELETE request to the "/posts/{postId}" endpoint with a valid postId. +* Expected Result: The server responds with a status code of 204 and no content in the response body. + +**Test Scenario 6: Retrieve Comments for a Blog Post** + +* Precondition: The API server is up and running. +* Action: Send a GET request to the "/posts/{postId}/comments" endpoint with a valid postId. +* Expected Result: The server responds with a status code of 200 and a list of comments for the specified blog post in JSON format. + +**Test Scenario 7: Add a New Comment** + +* Precondition: The API server is up and running. +* Action: Send a POST request to the "/posts/{postId}/comments" endpoint + with a valid postId and a JSON payload representing a new comment. +* Expected Result: The server responds with a status code of 201 and the newly created comment in JSON format. + +**Test Scenario 8: Retrieve User Profile** + +* Precondition: The API server is up and running. +* Action: Send a GET request to the "/users/{userId}" endpoint with a valid userId. +* Expected Result: The server responds with a status code of 200 and the user profile details in JSON format. + +**Test Scenario 9: Handle Invalid Input** + +* Precondition: The API server is up and running. +* Action: Send a request to an endpoint with invalid input (e.g., an invalid postId or userId). +* Expected Result: The server responds with a status code of 400 (Bad Request) and an error message in the response body. + +**Test Scenario 10: Handle Non-existent Resources** + +* Precondition: The API server is up and running. +* Action: Send a request to an endpoint with a non-existent resource (e.g., a postId or userId that does not exist). +* Expected Result: The server responds with a status code of 404 (Not Found) and an error message in the response body. ``` ```md ```sh - .\dist\jarvis.exe generate-test --path="specs/proto" --output="output" + jarvis generate-test --path="specs/proto" --output="output" ``` ```go import ( diff --git a/go.mod b/go.mod index f960a31..b581c2a 100644 --- a/go.mod +++ b/go.mod @@ -6,6 +6,7 @@ require ( github.com/Azure/azure-sdk-for-go/sdk/ai/azopenai v0.4.1 github.com/Azure/azure-sdk-for-go/sdk/azcore v1.9.2 github.com/briandowns/spinner v1.23.0 + github.com/ctreminiom/go-atlassian v1.5.1 github.com/fatih/color v1.16.0 github.com/google/generative-ai-go v0.8.0 github.com/google/go-github/v59 v59.0.0 @@ -31,10 +32,17 @@ require ( github.com/google/s2a-go v0.1.7 // indirect github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect github.com/googleapis/gax-go/v2 v2.12.1 // indirect + github.com/imdario/mergo v0.3.16 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/josharian/intern v1.0.0 // indirect + github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect + github.com/perimeterx/marshmallow v1.1.5 // indirect github.com/spf13/pflag v1.0.5 // indirect + github.com/tidwall/gjson v1.16.0 // indirect + github.com/tidwall/match v1.1.1 // indirect + github.com/tidwall/pretty v1.2.0 // indirect go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.48.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.48.0 // indirect diff --git a/go.sum b/go.sum index e11d193..b21a40d 100644 --- a/go.sum +++ b/go.sum @@ -35,6 +35,8 @@ github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGX github.com/cncf/xds/go v0.0.0-20231128003011-0fa0005c9caa h1:jQCWAUqqlij9Pgj2i/PB79y4KOPYVyFYdROxgaCwdTQ= github.com/cncf/xds/go v0.0.0-20231128003011-0fa0005c9caa/go.mod h1:x/1Gn8zydmfq8dk6e9PdstVsDgu9RuyIIJqAaF//0IM= github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/ctreminiom/go-atlassian v1.5.1 h1:GYji33ywQyWvePNQzxfvgb02fg6fcSH1g59vDy3ApEw= +github.com/ctreminiom/go-atlassian v1.5.1/go.mod h1:R1EaOjo33pSN9Y6xIJCEgQ68wgwYoFYAXifnaPlmyc8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -55,6 +57,8 @@ github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM= +github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= @@ -94,18 +98,25 @@ github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17 github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o= github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfFxPRy3Bf7vr3h0cechB90XaQs= github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0= github.com/googleapis/gax-go/v2 v2.12.1 h1:9F8GV9r9ztXyAi00gsMQHNoF51xPZm8uj1dpYt2ZETM= github.com/googleapis/gax-go/v2 v2.12.1/go.mod h1:61M8vcyyXR2kqKFxKrfA22jaA8JGF7Dc8App1U3H6jc= +github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= +github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc= github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/manifoldco/promptui v0.9.0 h1:3V4HzJk1TtXW1MTZMP7mdlwbBpIinw3HztaIlYthEiA= github.com/manifoldco/promptui v0.9.0/go.mod h1:ka04sppxSGFAtxX0qhlYQjISsg9mR4GWtQEhdbn6Pgg= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= @@ -113,6 +124,8 @@ github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovk github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/perimeterx/marshmallow v1.1.5 h1:a2LALqQ1BlHM8PZblsDdidgv1mWi1DgC2UmX50IvK2s= +github.com/perimeterx/marshmallow v1.1.5/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw= github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU= github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= @@ -125,12 +138,23 @@ github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/tidwall/gjson v1.16.0 h1:SyXa+dsSPpUlcwEDuKuEBJEz5vzTvOea+9rjyYodQFg= +github.com/tidwall/gjson v1.16.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= +github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= +github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= +github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= +github.com/ugorji/go v1.2.7 h1:qYhyWUUd6WbiM+C6JZAUkIJt/1WrjzNHY9+KCIjVqTo= +github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M= +github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= +github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= diff --git a/pkg/atlassian/main.go b/pkg/atlassian/main.go new file mode 100644 index 0000000..5b870cb --- /dev/null +++ b/pkg/atlassian/main.go @@ -0,0 +1,28 @@ +package atlassian + +import ( + "context" + "log" + + jira "github.com/ctreminiom/go-atlassian/jira/v2" +) + +type client struct { + *jira.Client +} + +func New(ctx context.Context) *client { + + jiraHost := "https://<_jira_instance_>.atlassian.net" + mailAddress := "" + apiToken := "" + + jiraClient, err := jira.New(nil, jiraHost) + if err != nil { + log.Fatal(err) + } + + jiraClient.Auth.SetBasicAuth(mailAddress, apiToken) + + return &client{jiraClient} +} diff --git a/pkg/engine/gemini/text.go b/pkg/engine/gemini/text.go index 9252980..7a61a83 100644 --- a/pkg/engine/gemini/text.go +++ b/pkg/engine/gemini/text.go @@ -13,6 +13,7 @@ import ( "google.golang.org/api/iterator" ) +// GenerateText GenerateContent func (c *client) GenerateText(ctx context.Context, prompt string) (*genai.GenerateContentResponse, error) { resp, err := c.ProModel().GenerateContent(ctx, genai.Text(prompt)) if err != nil { @@ -27,7 +28,7 @@ func (c *client) GenerateTextStream(ctx context.Context, specs []genai.Text, spe for _, spec := range specs { prompts = append(prompts, spec) } - prompts = append(prompts, genai.Text(fmt.Sprintf("what are possible test scenarios for the provided %s spec file.", specType))) + prompts = append(prompts, genai.Text(fmt.Sprintf("Generate all possible test scenarios in simple english for the provided %s spec file.", specType))) resp := c.ProModel().GenerateContentStream(ctx, prompts...) for { @@ -42,20 +43,23 @@ func (c *client) GenerateTextStream(ctx context.Context, specs []genai.Text, spe return nil } for _, candidate := range resp.Candidates { - for _, c := range candidate.Content.Parts { - fmt.Println(c) - } + go func(parts []genai.Part) { + for _, c := range parts { + fmt.Println(c) + } + }(candidate.Content.Parts) } } return nil } +// GenerateTextStreamWriter GenerateContentStream func (c *client) GenerateTextStreamWriter(ctx context.Context, specs []genai.Text, language, specType string, outputFolder string) error { var prompts []genai.Part for _, spec := range specs { prompts = append(prompts, spec) } - prompts = append(prompts, genai.Text(fmt.Sprintf("generate %s tests based for this %s spec.", language, specType))) + prompts = append(prompts, genai.Text(fmt.Sprintf("Generate %s tests based on this %s spec.", language, specType))) ct := time.Now().Format("2006-01-02-15-04-05") files.CheckDirectryExists(outputFolder) @@ -81,9 +85,11 @@ func (c *client) GenerateTextStreamWriter(ctx context.Context, specs []genai.Tex return nil } for _, candidate := range resp.Candidates { - for _, c := range candidate.Content.Parts { - fmt.Fprintln(writer, c) - } + go func(parts []genai.Part) { + for _, c := range parts { + fmt.Fprintln(writer, c) + } + }(candidate.Content.Parts) } } return nil diff --git a/pkg/engine/gemini/vision.go b/pkg/engine/gemini/vision.go index 4188b39..380176a 100644 --- a/pkg/engine/gemini/vision.go +++ b/pkg/engine/gemini/vision.go @@ -8,6 +8,7 @@ import ( "github.com/google/generative-ai-go/genai" ) +// GenerateVision ... func (c *client) GenerateVision(ctx context.Context, promptPart []genai.Part) (*genai.GenerateContentResponse, error) { resp, err := c.VisionModel().GenerateContent(ctx, promptPart...) if err != nil { @@ -16,6 +17,7 @@ func (c *client) GenerateVision(ctx context.Context, promptPart []genai.Part) (* return resp, nil } +// CompareImage ... func (c *client) CompareImage(ctx context.Context, promptParts []string, search string) (*genai.GenerateContentResponse, error) { if len(promptParts) == 0 { return nil, fmt.Errorf("promptParts is empty") @@ -47,6 +49,7 @@ func (c *client) CompareImage(ctx context.Context, promptParts []string, search return resp, nil } +// GenerateVisionStream ... func (c *client) GenerateVisionStream(ctx context.Context, prompt string) (*genai.GenerateContentResponseIterator, error) { resp := c.ProModel().GenerateContentStream(ctx, genai.Text(prompt)) for { diff --git a/specs/avro/customer.avsc b/specs/avro/customer.avsc new file mode 100644 index 0000000..0179e66 --- /dev/null +++ b/specs/avro/customer.avsc @@ -0,0 +1,45 @@ +{ + "namespace": "com.testing.avro", + "type": "record", + "name": "User", + "fields": [ + {"name": "id", "type": "int"}, + {"name": "username", "type": "string"}, + {"name": "email", "type": "string"}, + {"name": "address", "type": { + "type": "record", + "name": "Address", + "fields": [ + {"name": "street", "type": "string"}, + {"name": "city", "type": "string"}, + {"name": "zipcode", "type": "string"}, + {"name": "geocoordinates", "type": { + "type": "record", + "name": "GeoCoordinates", + "fields": [ + {"name": "latitude", "type": "double"}, + {"name": "longitude", "type": "double"} + ] + }, "default": null } + ] + }, "default": null + }, + {"name": "signup_timestamp", "type": {"type": "long", "logicalType": "timestamp-millis"}}, + {"name": "preferences", "type": { + "type": "map", + "values": "string" + }, "default": {} }, + {"name": "order_history", "type": { + "type": "array", + "items": { + "type": "record", + "name": "Order", + "fields": [ + {"name": "order_id", "type": "string"}, + {"name": "items", "type": {"type": "array", "items": "string"}}, + {"name": "total_cost", "type": "double"} + ] + } + }, "default": [] } + ] +} diff --git a/specs/openapi/v3.0/mini_blog.yaml b/specs/openapi/v3.0/mini_blog.yaml new file mode 100644 index 0000000..e6711be --- /dev/null +++ b/specs/openapi/v3.0/mini_blog.yaml @@ -0,0 +1,142 @@ +openapi: 3.0.0 +info: + title: Enhanced Mini-Blog API + description: Expanded API for managing blog posts, comments, and user profiles. + version: 1.2.0 + +servers: + - url: https://api.myminiblog.com/v1 + +paths: + # --- Posts Endpoint --- + /posts: + get: # ... (Similar to the basic example) + post: # ... (Similar to the basic example) + + /posts/{postId}: + get: # ... (Similar to the basic example) + patch: + summary: Update a blog post + description: Allows partial updates to a blog post + parameters: + - in: path + name: postId + required: true + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/BlogPost' + responses: + '200': + description: Post Updated + '400': + description: Invalid input + '404': + description: Post not found + delete: + summary: Delete a blog post + parameters: + - in: path + name: postId + required: true + schema: + type: string + responses: + '204': + description: Post deleted successfully + '404': + description: Post not found + + # --- Comments Endpoint --- + /posts/{postId}/comments: + get: + summary: Get comments for a blog post + parameters: + - in: path + name: postId + required: true + schema: + type: string + responses: + '200': + description: An array of comments + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/Comment' + post: + summary: Add a new comment + parameters: + - in: path + name: postId + required: true + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/Comment' + + # --- User Endpoint --- + /users/{userId}: + get: + summary: Get user profile + parameters: + - in: path + name: userId + required: true + schema: + type: string + responses: + '200': + description: User profile + content: + application/json: + schema: + $ref: '#/components/schemas/User' + '404': + description: User not found + +components: + schemas: + BlogPost: # ... (From basic example) + Comment: + type: object + properties: + id: + type: string + format: uuid + content: + type: string + author: + type: string + createdAt: + type: string + format: date-time + User: + type: object + properties: + id: + type: string + format: uuid + username: + type: string + email: + type: string + format: email + + # Example for security implementation + securitySchemes: + apiKeyAuth: + type: apiKey + in: header + name: X-API-Key + +security: + - apiKeyAuth: [] diff --git a/specs/openapi/v3.0/petstore.yaml b/specs/openapi/v3.0/petstore.yaml deleted file mode 100644 index 2b42dfe..0000000 --- a/specs/openapi/v3.0/petstore.yaml +++ /dev/null @@ -1,119 +0,0 @@ -openapi: "3.0.0" -info: - version: 1.0.0 - title: Swagger Petstore - license: - name: MIT -servers: - - url: http://petstore.swagger.io/v1 -paths: - /pets: - get: - summary: List all pets - operationId: listPets - tags: - - pets - parameters: - - name: limit - in: query - description: How many items to return at one time (max 100) - required: false - schema: - type: integer - maximum: 100 - format: int32 - responses: - '200': - description: A paged array of pets - headers: - x-next: - description: A link to the next page of responses - schema: - type: string - content: - application/json: - schema: - $ref: "#/components/schemas/Pets" - default: - description: unexpected error - content: - application/json: - schema: - $ref: "#/components/schemas/Error" - post: - summary: Create a pet - operationId: createPets - tags: - - pets - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/Pet' - required: true - responses: - '201': - description: Null response - default: - description: unexpected error - content: - application/json: - schema: - $ref: "#/components/schemas/Error" - /pets/{petId}: - get: - summary: Info for a specific pet - operationId: showPetById - tags: - - pets - parameters: - - name: petId - in: path - required: true - description: The id of the pet to retrieve - schema: - type: string - responses: - '200': - description: Expected response to a valid request - content: - application/json: - schema: - $ref: "#/components/schemas/Pet" - default: - description: unexpected error - content: - application/json: - schema: - $ref: "#/components/schemas/Error" -components: - schemas: - Pet: - type: object - required: - - id - - name - properties: - id: - type: integer - format: int64 - name: - type: string - tag: - type: string - Pets: - type: array - maxItems: 100 - items: - $ref: "#/components/schemas/Pet" - Error: - type: object - required: - - code - - message - properties: - code: - type: integer - format: int32 - message: - type: string \ No newline at end of file diff --git a/specs/openapi/v2.0/petstore.yaml b/specs/swagger/v2.0/petstore.yaml similarity index 100% rename from specs/openapi/v2.0/petstore.yaml rename to specs/swagger/v2.0/petstore.yaml