diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 00000000..04873dba --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,18 @@ +## PR Description + +_Add your description_ + +## Related Issues + +- Related Issue # +- Closes # + +### Checklist +- [ ] I have gone through the [contributing guide](https://github.com/foss42/apidash/blob/main/CONTRIBUTING.md) +- [ ] I have run the tests (`flutter test`) and all tests are passing + +## Added/updated tests? +_We encourage you to add relevant test cases._ + +- [ ] Yes +- [ ] No, and this is why: _please replace this line with details on why tests have not been included_ diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 140188ac..46a9b053 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -83,7 +83,7 @@ In case you have already setup Flutter, make sure to switch to `stable` branch a 1. Fork the project. 2. Create a clone of the forked project on your computer to run it locally. 3. Based on your desktop environment, enable Windows, macOS or Linux for the project. Select the same target device. -4. This project uses [Records feature in Dart](https://github.com/dart-lang/language/blob/main/accepted/future-releases/records/records-feature-specification.md), so to run the project execute the following command: +4. Run the project by executing the following command: ``` flutter run @@ -128,3 +128,23 @@ flutter test test/widgets/codegen_previewer_test.dart ### How to add a new package to pubspec.yaml? Instead of copy pasting from pub.dev, it is recommended that you use `flutter pub add package_name` to add a new package to `pubspec.yaml`. You can read more [here](https://docs.flutter.dev/packages-and-plugins/using-packages#adding-a-package-dependency-to-an-app-using-flutter-pub-add). + +## Troubleshooting Common Issues + +### Network Connection Issues on macOS + +If you encounter a network connection error similar to the following while running your Flutter app on macOS: + +``` +ClientException with SocketException: Connection failed (OS Error: Operation not permitted, errno = 1) +``` +Add below key to `macos/Runner/DebugProfile.entitlements` and `macos/Runner/Release.entitlements`. + +``` + com.apple.security.network.client + +``` + +You can read more [here](https://docs.flutter.dev/platform-integration/macos/building#setting-up-entitlements) + + diff --git a/README.md b/README.md index 7c750dad..c2760f5d 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,18 @@ [![Discord Server Invite](https://img.shields.io/badge/DISCORD-JOIN%20SERVER-5663F7?style=for-the-badge&logo=discord&logoColor=white)](https://bit.ly/heyfoss) +🚨 We are participating in GSoC 2024 🎉 + +GSoC + +| | Link | +|--|--| +| Learn about GSoC | [Link](https://summerofcode.withgoogle.com) | +| Organization page on GSoC | [Link](https://summerofcode.withgoogle.com/programs/2024/organizations/api-dash) | +| Project Ideas List | [Link](https://github.com/foss42/apidash/discussions/112) | +| Application Guide | [Link](https://github.com/foss42/apidash/discussions/111) | +| Discord Channel | [Link](https://discord.com/invite/2s49SCNfyJ) | + ### Please support this initiative by giving this project a Star ⭐️ API Dash is a beautiful open-source cross-platform API Client that can help you easily create & customize your API requests, visually inspect responses ([full list of supported mime-types](https://github.com/foss42/apidash?tab=readme-ov-file#mime-types-supported-by-api-dash-response-previewer)) and generate API integration code ([full list](https://github.com/foss42/apidash?tab=readme-ov-file#code-generators)) on the go. @@ -123,6 +135,7 @@ API Dash currently supports API integration code generation for the following la | Python | `http.client` | | Python | `requests` | | Kotlin | `okhttp3` | +| Java | `okhttp3` | We welcome contributions to support other programming languages/libraries/frameworks. Please check out more details [here](https://github.com/foss42/apidash/discussions/80). @@ -135,6 +148,7 @@ Here is the complete list of mimetypes that can be directly previewed in API Das | File Type | Mimetype | Extension | Comment | | --------- | -------------------------- | ----------------- | -------- | | PDF | `application/pdf` | `.pdf` | | +| CSV | `text/csv` | `.csv` | Can be improved | | Image | `image/apng` | `.apng` | Animated | | Image | `image/avif` | `.avif` | | | Image | `image/bmp` | `.bmp` | | @@ -175,14 +189,14 @@ Here is the complete list of mimetypes that are syntax highlighted in API Dash: | ------------------ | --------- | ------------------------------------------------------------------------------------------------------------------ | | `application/json` | `.json` | Other mimetypes like `application/geo+json`, `application/vcard+json` that are based on `json` are also supported. | | `application/xml` | `.xml` | Other mimetypes like `application/xhtml+xml`, `application/vcard+xml` that are based on `xml` are also supported. | -| `text/xml` | `.xml` | | -| `application/yaml` | `.yaml` | Others - `application/x-yaml` or `application/x-yml` | -| `text/yaml` | `.yaml` | Others - `text/yml` | -| `application/sql` | `.sql` | | -| `text/css` | `.css` | | -| `text/html` | `.html` | Only syntax highlighting, no web preview. | -| `text/javascript` | `.js` | | -| `text/markdown` | `.md` | | +| `text/xml` | `.xml` | | +| `application/yaml` | `.yaml` | Others - `application/x-yaml` or `application/x-yml` | +| `text/yaml` | `.yaml` | Others - `text/yml` | +| `application/sql` | `.sql` | | +| `text/css` | `.css` | | +| `text/html` | `.html` | Only syntax highlighting, no web preview. | +| `text/javascript` | `.js` | | +| `text/markdown` | `.md` | | ## What's new in v0.3.0? diff --git a/analysis_options.yaml b/analysis_options.yaml index 1d5eafa4..9a1eabb4 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -3,8 +3,9 @@ include: package:flutter_lints/flutter.yaml analyzer: errors: invalid_annotation_target: ignore - enable-experiment: - - records + exclude: + - "**/*.freezed.dart" + - "**/*.g.dart" linter: rules: diff --git a/lib/codegen/codegen.dart b/lib/codegen/codegen.dart index 7276ed29..5100f7aa 100644 --- a/lib/codegen/codegen.dart +++ b/lib/codegen/codegen.dart @@ -1,50 +1,81 @@ import 'package:apidash/models/models.dart' show RequestModel; import 'package:apidash/consts.dart'; +import 'package:apidash/utils/utils.dart' show getNewUuid; import 'dart/http.dart'; import 'dart/dio.dart'; +import 'go/http.dart'; import 'kotlin/okhttp.dart'; import 'python/http_client.dart'; import 'python/requests.dart'; +import 'rust/actix.dart'; +import 'rust/reqwest.dart'; +import 'rust/ureq.dart'; import 'js/axios.dart'; import 'js/fetch.dart'; import 'others/har.dart'; import 'others/curl.dart'; +import 'julia/http.dart'; +import 'java/okhttp.dart'; +import 'java/async_http_client.dart'; import 'java/httpclient.dart'; class Codegen { String? getCode( CodegenLanguage codegenLanguage, RequestModel requestModel, - String defaultUriScheme, - ) { + String defaultUriScheme, { + String? boundary, + }) { + String url = requestModel.url; + + if (url.isEmpty) { + url = kDefaultUri; + } + if (!url.contains("://") && url.isNotEmpty) { + url = "$defaultUriScheme://$url"; + } + var rM = requestModel.copyWith(url: url); + switch (codegenLanguage) { case CodegenLanguage.curl: - return cURLCodeGen().getCode(requestModel, defaultUriScheme); + return cURLCodeGen().getCode(rM); case CodegenLanguage.har: - return HARCodeGen().getCode(requestModel, defaultUriScheme); + return HARCodeGen().getCode(rM, defaultUriScheme, boundary: boundary); case CodegenLanguage.dartHttp: - return DartHttpCodeGen().getCode(requestModel, defaultUriScheme); + return DartHttpCodeGen().getCode(rM); case CodegenLanguage.dartDio: - return DartDioCodeGen().getCode(requestModel, defaultUriScheme); + return DartDioCodeGen().getCode(rM); case CodegenLanguage.jsAxios: - return AxiosCodeGen().getCode(requestModel, defaultUriScheme); + return AxiosCodeGen().getCode(rM); case CodegenLanguage.jsFetch: - return FetchCodeGen().getCode(requestModel, defaultUriScheme); + return FetchCodeGen().getCode(rM); case CodegenLanguage.nodejsAxios: - return AxiosCodeGen(isNodeJs: true) - .getCode(requestModel, defaultUriScheme); + return AxiosCodeGen(isNodeJs: true).getCode(rM); case CodegenLanguage.nodejsFetch: - return FetchCodeGen(isNodeJs: true) - .getCode(requestModel, defaultUriScheme); + return FetchCodeGen(isNodeJs: true).getCode(rM); case CodegenLanguage.kotlinOkHttp: - return KotlinOkHttpCodeGen().getCode(requestModel, defaultUriScheme); + return KotlinOkHttpCodeGen().getCode(rM); + case CodegenLanguage.javaOkHttp: + return JavaOkHttpCodeGen().getCode(rM); case CodegenLanguage.pythonHttpClient: return PythonHttpClientCodeGen() - .getCode(requestModel, defaultUriScheme); + .getCode(rM, boundary: boundary ?? getNewUuid()); case CodegenLanguage.pythonRequests: - return PythonRequestsCodeGen().getCode(requestModel, defaultUriScheme); + return PythonRequestsCodeGen().getCode(rM, boundary: boundary); + case CodegenLanguage.rustActix: + return RustActixCodeGen().getCode(rM, boundary: boundary); + case CodegenLanguage.rustReqwest: + return RustReqwestCodeGen().getCode(rM); + case CodegenLanguage.rustUreq: + return RustUreqCodeGen().getCode(rM, boundary: boundary); + case CodegenLanguage.goHttp: + return GoHttpCodeGen().getCode(rM); + case CodegenLanguage.juliaHttp: + return JuliaHttpClientCodeGen().getCode(rM); + case CodegenLanguage.javaAsyncHttpClient: + return JavaAsyncHttpClientGen().getCode(rM); case CodegenLanguage.javaHttpClient: - return JavaHttpClientCodeGen().getCode(requestModel, defaultUriScheme); + return JavaHttpClientCodeGen().getCode(rM); } } } diff --git a/lib/codegen/codegen_utils.dart b/lib/codegen/codegen_utils.dart new file mode 100644 index 00000000..2d7a1846 --- /dev/null +++ b/lib/codegen/codegen_utils.dart @@ -0,0 +1,15 @@ +String jsonToPyDict(String jsonString) { + Map replaceWithMap = { + "null": "None", + "true": "True", + "false": "False" + }; + String pyDict = jsonString; + for (var k in replaceWithMap.keys) { + RegExp regExp = RegExp(k + r'(?=([^"]*"[^"]*")*[^"]*$)'); + pyDict = pyDict.replaceAllMapped(regExp, (match) { + return replaceWithMap[match.group(0)] ?? match.group(0)!; + }); + } + return pyDict; +} diff --git a/lib/codegen/dart/dio.dart b/lib/codegen/dart/dio.dart index c4a7ed8e..e9590f79 100644 --- a/lib/codegen/dart/dio.dart +++ b/lib/codegen/dart/dio.dart @@ -8,15 +8,10 @@ import 'shared.dart'; class DartDioCodeGen { String? getCode( RequestModel requestModel, - String defaultUriScheme, ) { try { - String url = requestModel.url; - if (!url.contains("://") && url.isNotEmpty) { - url = "$defaultUriScheme://$url"; - } final next = generatedDartCode( - url: url, + url: requestModel.url, method: requestModel.method, queryParams: requestModel.enabledParamsMap, headers: requestModel.enabledHeadersMap, @@ -60,12 +55,17 @@ class DartDioCodeGen { final List> formDataList = ${json.encode(formData)}; for (var formField in formDataList) { if (formField['type'] == 'file') { - formData.files.add(MapEntry( - formField['name'], - await MultipartFile.fromFile(formField['value'], filename: formField['value']), + if (formField['value'] != null) { + data.files.add(MapEntry( + formField['name']!, + await dio.MultipartFile.fromFile(formField['value']!, + filename: formField['value']!), )); + } } else { - formData.fields.add(MapEntry(formField['name'], formField['value'])); + if (formField['value'] != null) { + data.fields.add(MapEntry(formField['name']!, formField['value']!)); + } } } '''); @@ -84,16 +84,16 @@ class DartDioCodeGen { dataExp = declareFinal('data').assign(strContent); // when add new type of [ContentType], need update [dataExp]. case ContentType.formdata: - dataExp = declareFinal('data').assign(refer('FormData()')); + dataExp = declareFinal('data').assign(refer('dio.FormData()')); } } final responseExp = declareFinal('response').assign(InvokeExpression.newOf( - refer('dio.Dio'), + refer('dio.Dio()'), [literalString(url)], { if (queryParamExp != null) 'queryParameters': refer('queryParams'), if (headerExp != null) - 'options': refer('Options').newInstance( + 'options': refer('dio.Options').newInstance( [], {'headers': refer('headers')}, ), @@ -117,7 +117,7 @@ class DartDioCodeGen { refer('print').call([refer('response').property('data')]), ], onError: { - 'DioException': [ + 'dio.DioException': [ refer('print').call([ refer('e').property('response').nullSafeProperty('statusCode'), ]), diff --git a/lib/codegen/dart/http.dart b/lib/codegen/dart/http.dart index 3e423743..8419757c 100644 --- a/lib/codegen/dart/http.dart +++ b/lib/codegen/dart/http.dart @@ -9,15 +9,10 @@ import 'shared.dart'; class DartHttpCodeGen { String? getCode( RequestModel requestModel, - String defaultUriScheme, ) { try { - String url = requestModel.url; - if (!url.contains("://") && url.isNotEmpty) { - url = "$defaultUriScheme://$url"; - } final next = generatedDartCode( - url: url, + url: requestModel.url, method: requestModel.method, queryParams: requestModel.enabledParamsMap, headers: {...requestModel.enabledHeadersMap}, @@ -53,7 +48,9 @@ class DartHttpCodeGen { declareVar('uri').assign(refer('Uri.parse').call([literalString(url)])); Expression? dataExp; - if (kMethodsWithBody.contains(method) && (body?.isNotEmpty ?? false)) { + if (kMethodsWithBody.contains(method) && + (body?.isNotEmpty ?? false) && + contentType != ContentType.formdata) { final strContent = CodeExpression(Code('r\'\'\'$body\'\'\'')); dataExp = declareVar('body', type: refer('String')).assign(strContent); if (!hasContentTypeHeader) { @@ -125,17 +122,29 @@ class DartHttpCodeGen { final addHeaders = refer('request.headers.addAll').call([refer('headers')]); const multiPartList = Code(''' - for (Map formData in formDataList){ - if (formData['type'] == 'text') { - request.fields.addAll({formData['name']: formData['value']}); - } else { - request.files.add( - await http.MultipartFile.fromPath( - formData['name'], - formData['value'], - ), - ); - } + for (var formData in formDataList) { + if (formData != null) { + final name = formData['name']; + final value = formData['value']; + final type = formData['type']; + + if (name != null && value != null && type != null) { + if (type == 'text') { + request.fields.addAll({name: value}); + } else { + request.files.add( + await http.MultipartFile.fromPath( + name, + value, + ), + ); + } + } else { + print('Error: formData has null name, value, or type.'); + } + } else { + print('Error: formData is null.'); + } } '''); var multiPartRequestSend = diff --git a/lib/codegen/go/http.dart b/lib/codegen/go/http.dart new file mode 100644 index 00000000..4bdecf48 --- /dev/null +++ b/lib/codegen/go/http.dart @@ -0,0 +1,172 @@ +import 'package:apidash/consts.dart'; +import 'package:jinja/jinja.dart' as jj; +import 'package:apidash/utils/utils.dart' show getValidRequestUri; +import 'package:apidash/models/models.dart' show RequestModel; + +class GoHttpCodeGen { + final String kTemplateStart = """package main + +import ( + "fmt" + "io" + "net/http" + "net/url"{% if hasBody %} + "bytes"{% if hasFormData %} + "mime/multipart"{% if hasFileInFormData %} + "os"{% endif %}{% endif %}{% endif %} +) + +func main() { + client := &http.Client{} + +"""; + + String kTemplateUrl = """ + url, _ := url.Parse("{{url}}") + +"""; + + String kTemplateBody = """ + {% if body %}payload := bytes.NewBuffer([]byte(`{{body}}`)){% endif %} + +"""; + + String kTemplateFormData = """ + payload := &bytes.Buffer{} + writer := multipart.NewWriter(payload){% if hasFileInFormData %} + var ( + file *os.File + part io.Writer + ){% endif %} + {% for field in fields %} + {% if field.type == "file" %}file, _ = os.Open("{{field.value}}") + defer file.Close() + part, _ = writer.CreateFormFile("{{field.name}}", "{{field.value}}") + io.Copy(part, file) + {% else %}writer.WriteField("{{field.name}}", "{{field.value}}"){% endif %}{% endfor %} + writer.Close() + + +"""; + + String kTemplateHeader = """ +{% if headers %}{% for header, value in headers %} + req.Header.Set("{{header}}", "{{value}}"){% endfor %} +{% endif %} +"""; + + String kStringFormDataHeader = """ + req.Header.Set("Content-Type", writer.FormDataContentType()) +"""; + + String kTemplateQueryParam = """ + query := url.Query() + {% for key, value in params %} + query.Set("{{key}}", "{{value}}"){% endfor %} + + url.RawQuery = query.Encode() + +"""; + + String kTemplateRequest = """ + req, _ := http.NewRequest("{{method}}", url.String(), {% if hasBody %}payload{% else %}nil{% endif %}) + +"""; + + final String kTemplateEnd = """ + + response, err := client.Do(req) + if err != nil { + fmt.Println(err) + return + } + defer response.Body.Close() + + fmt.Println("Status Code:", response.StatusCode) + body, _ := io.ReadAll(response.Body) + fmt.Println("Response body:", string(body)) +}"""; + + String? getCode( + RequestModel requestModel, + ) { + try { + String result = ""; + var hasBody = false; + var requestBody = requestModel.requestBody; + + String url = requestModel.url; + + var templateStart = jj.Template(kTemplateStart); + result += templateStart.render({ + "hasBody": requestModel.hasData, + "hasFormData": requestModel.hasFormData, + "hasFileInFormData": requestModel.hasFileInFormData, + }); + + var templateUrl = jj.Template(kTemplateUrl); + result += templateUrl.render({"url": url}); + + var rec = getValidRequestUri( + url, + requestModel.enabledRequestParams, + ); + + Uri? uri = rec.$1; + + if (uri != null) { + if (requestModel.hasTextData || requestModel.hasJsonData) { + hasBody = true; + var templateRawBody = jj.Template(kTemplateBody); + result += templateRawBody.render({"body": requestBody}); + } else if (requestModel.hasFormData) { + hasBody = true; + var templateFormData = jj.Template(kTemplateFormData); + result += templateFormData.render({ + "hasFileInFormData": requestModel.hasFileInFormData, + "fields": requestModel.formDataMapList, + }); + } + + if (uri.hasQuery) { + var params = uri.queryParameters; + if (params.isNotEmpty) { + var templateQueryParam = jj.Template(kTemplateQueryParam); + result += templateQueryParam.render({"params": params}); + } + } + + var method = requestModel.method.name.toUpperCase(); + var templateRequest = jj.Template(kTemplateRequest); + result += templateRequest.render({ + "method": method, + "hasBody": hasBody, + }); + + var headersList = requestModel.enabledRequestHeaders; + if (headersList != null || requestModel.hasData) { + var headers = requestModel.enabledHeadersMap; + if (requestModel.hasJsonData || requestModel.hasTextData) { + headers.putIfAbsent(kHeaderContentType, + () => requestModel.requestBodyContentType.header); + } + if (headers.isNotEmpty) { + var templateHeader = jj.Template(kTemplateHeader); + result += templateHeader.render({ + "headers": headers, + }); + } + } + if (requestModel.hasFormData) { + result += kStringFormDataHeader; + } + + result += kTemplateEnd; + } + + return result; + } catch (e) { + return null; + } + } +} diff --git a/lib/codegen/java/async_http_client.dart b/lib/codegen/java/async_http_client.dart new file mode 100644 index 00000000..ec804cc1 --- /dev/null +++ b/lib/codegen/java/async_http_client.dart @@ -0,0 +1,189 @@ +import 'dart:convert'; +import 'package:apidash/utils/har_utils.dart'; +import 'package:apidash/utils/http_utils.dart'; +import 'package:jinja/jinja.dart' as jj; +import 'package:apidash/models/models.dart' show RequestModel; +import 'package:apidash/consts.dart'; + +class JavaAsyncHttpClientGen { + final String kTemplateStart = ''' +import org.asynchttpclient.*; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Executors; +import java.util.stream.Collectors; + +public class Main { + public static void main(String[] args) { + try (AsyncHttpClient asyncHttpClient = Dsl.asyncHttpClient()) { +'''; + + final String kTemplateUrl = ''' + String url = "{{url}}";\n +'''; + + final String kTemplateRequestCreation = ''' + Request request = asyncHttpClient + .prepare("{{method}}", url)\n +'''; + + final String kTemplateUrlQueryParam = ''' + .addQueryParam("{{name}}", "{{value}}")\n +'''; + + final String kTemplateRequestHeader = ''' + .addHeader("{{name}}", "{{value}}")\n +'''; + final String kTemplateRequestFormData = ''' + .addFormParam("{{name}}", "{{value}}")\n +'''; + + String kTemplateRequestBodyContent = ''' + String bodyContent = "{{body}}";\n +'''; + String kTemplateRequestBodySetup = ''' + .setBody(bodyContent)\n +'''; + + final String kTemplateRequestEnd = """ + .build(); + ListenableFuture listenableFuture = asyncHttpClient.executeRequest(request); + listenableFuture.addListener(() -> { + try { + Response response = listenableFuture.get(); + InputStream is = response.getResponseBodyAsStream(); + BufferedReader br = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8)); + String respBody = br.lines().collect(Collectors.joining("\\n")); + System.out.println(response.getStatusCode()); + System.out.println(respBody); + } catch (InterruptedException | ExecutionException e) { + e.printStackTrace(); + } + }, Executors.newCachedThreadPool()); + listenableFuture.get(); + } catch (InterruptedException | ExecutionException | IOException ignored) { + + } + } +} +\n +"""; + + String? getCode( + RequestModel requestModel, + ) { + try { + String result = ""; + bool hasBody = false; + + var rec = getValidRequestUri( + requestModel.url, + requestModel.enabledRequestParams, + ); + Uri? uri = rec.$1; + + if (uri == null) { + return ""; + } + + var url = stripUriParams(uri); + + // contains the HTTP method associated with the request + var method = requestModel.method; + + // contains the entire request body as a string if body is present + var requestBody = requestModel.requestBody; + + // generating the URL to which the request has to be submitted + var templateUrl = jj.Template(kTemplateUrl); + result += templateUrl.render({"url": url}); + + // creating request body if available + var rM = requestModel.copyWith(url: url); + var harJson = requestModelToHARJsonRequest(rM, useEnabled: true); + + // if request type is not form data, the request method can include + // a body, and the body of the request is not null, in that case + // we need to parse the body as it is, and write it to the body + if (!requestModel.hasFormData && + kMethodsWithBody.contains(method) && + requestBody != null) { + var contentLength = utf8.encode(requestBody).length; + if (contentLength > 0) { + var templateBodyContent = jj.Template(kTemplateRequestBodyContent); + hasBody = true; + if (harJson["postData"]?["text"] != null) { + result += templateBodyContent.render({ + "body": kEncoder.convert(harJson["postData"]["text"]).substring( + 1, kEncoder.convert(harJson["postData"]["text"]).length - 1) + }); + } + } + } + + var templateRequestCreation = jj.Template(kTemplateRequestCreation); + result += + templateRequestCreation.render({"method": method.name.toUpperCase()}); + + // setting up query parameters + if (uri.hasQuery) { + var params = uri.queryParameters; + var templateUrlQueryParam = jj.Template(kTemplateUrlQueryParam); + params.forEach((name, value) { + result += + templateUrlQueryParam.render({"name": name, "value": value}); + }); + } + + result = kTemplateStart + result; + + var contentType = requestModel.requestBodyContentType.header; + var templateRequestHeader = jj.Template(kTemplateRequestHeader); + + // especially sets up Content-Type header if the request has a body + // and Content-Type is not explicitely set by the developer + if (hasBody && + !requestModel.enabledHeadersMap.containsKey('Content-Type')) { + result += templateRequestHeader + .render({"name": 'Content-Type', "value": contentType}); + } + + // setting up rest of the request headers + var headers = requestModel.enabledHeadersMap; + headers.forEach((name, value) { + result += templateRequestHeader.render({"name": name, "value": value}); + }); + + // handling form data + if (requestModel.hasFormData && + requestModel.formDataMapList.isNotEmpty && + kMethodsWithBody.contains(method)) { + // including form data into the request + var formDataList = requestModel.formDataMapList; + var templateRequestFormData = jj.Template(kTemplateRequestFormData); + for (var formDataMap in formDataList) { + result += templateRequestFormData.render( + {"name": formDataMap['name'], "value": formDataMap['value']}); + } + hasBody = true; + } + + var templateRequestBodySetup = jj.Template(kTemplateRequestBodySetup); + if (kMethodsWithBody.contains(method) && hasBody) { + result += templateRequestBodySetup.render(); + } + + var templateRequestBodyEnd = jj.Template(kTemplateRequestEnd); + result += templateRequestBodyEnd.render(); + + return result; + } catch (e) { + return null; + } + } +} diff --git a/lib/codegen/java/okhttp.dart b/lib/codegen/java/okhttp.dart new file mode 100644 index 00000000..ac7a6b09 --- /dev/null +++ b/lib/codegen/java/okhttp.dart @@ -0,0 +1,190 @@ +import 'dart:convert'; +import 'package:jinja/jinja.dart' as jj; +import 'package:apidash/utils/utils.dart' + show getValidRequestUri, stripUriParams; +import '../../models/request_model.dart'; +import 'package:apidash/consts.dart'; + +class JavaOkHttpCodeGen { + final String kTemplateStart = """ +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response;{{importForQuery}}{{importForBody}}{{importForFormData}} + +import java.io.IOException; + +public class Main { + public static void main(String[] args) { + OkHttpClient client = new OkHttpClient().newBuilder().build(); + +"""; + + final String kStringImportForQuery = """ + +import okhttp3.HttpUrl;"""; + + final String kStringImportForBody = """ + +import okhttp3.RequestBody; +import okhttp3.MediaType;"""; + + final String kStringImportForFormData = """ + +import okhttp3.RequestBody; +import okhttp3.MultipartBody;"""; + + final String kTemplateUrl = ''' + + String url = "{{url}}"; + +'''; + + final String kTemplateUrlQuery = ''' + + HttpUrl url = HttpUrl.parse("{{url}}").newBuilder() + {{params}} + .build(); + +'''; + + String kTemplateRequestBody = ''' + + MediaType mediaType = MediaType.parse("{{contentType}}"); + + RequestBody body = RequestBody.create({{body}}, mediaType); + +'''; + + final String kStringRequestStart = """ + + Request request = new Request.Builder() + .url(url) +"""; + + final String kTemplateRequestEnd = """ + .{{method}}({{hasBody}}) + .build(); + + try (Response response = client.newCall(request).execute()) { + System.out.println(response.code()); + if (response.body() != null) { + System.out.println(response.body().string()); + } + } catch (IOException e) { + System.out.println(e.getMessage()); + } + } +} + +"""; +// Converting list of form data objects to kolin multi part data + String kFormDataBody = ''' + RequestBody body = new MultipartBody.Builder().setType(MultipartBody.FORM) + {%- for item in formDataList -%} + {% if item.type == 'file' %} + .addFormDataPart("{{ item.name }}",null,RequestBody.create(MediaType.parse("application/octet-stream"),new File("{{ item.value }}"))) + {%- else %} + .addFormDataPart("{{ item.name }}","{{ item.value }}") + {%- endif %} + {%- endfor %} + .build(); + +'''; + + String? getCode( + RequestModel requestModel, + ) { + try { + String result = ""; + bool hasQuery = false; + bool hasBody = false; + bool hasFormData = false; + + var rec = getValidRequestUri( + requestModel.url, + requestModel.enabledRequestParams, + ); + Uri? uri = rec.$1; + + if (uri != null) { + String url = stripUriParams(uri); + + if (uri.hasQuery) { + var params = uri.queryParameters; + if (params.isNotEmpty) { + hasQuery = true; + var templateParams = jj.Template(kTemplateUrlQuery); + result += templateParams + .render({"url": url, "params": getQueryParams(params)}); + } + } + if (!hasQuery) { + var templateUrl = jj.Template(kTemplateUrl); + result += templateUrl.render({"url": url}); + } + + var method = requestModel.method; + var requestBody = requestModel.requestBody; + if (requestModel.hasFormData) { + hasFormData = true; + var formDataTemplate = jj.Template(kFormDataBody); + + result += formDataTemplate.render({ + "formDataList": requestModel.formDataMapList, + }); + } else if (kMethodsWithBody.contains(method) && requestBody != null) { + var contentLength = utf8.encode(requestBody).length; + if (contentLength > 0) { + hasBody = true; + String contentType = requestModel.requestBodyContentType.header; + var templateBody = jj.Template(kTemplateRequestBody); + result += templateBody.render({ + "contentType": contentType, + "body": kEncoder.convert(requestBody) + }); + } + } + + var templateStart = jj.Template(kTemplateStart); + var stringStart = templateStart.render({ + "importForQuery": hasQuery ? kStringImportForQuery : "", + "importForBody": hasBody ? kStringImportForBody : "", + "importForFormData": hasFormData ? kStringImportForFormData : "" + }); + + result = stringStart + result; + result += kStringRequestStart; + + var headersList = requestModel.enabledRequestHeaders; + if (headersList != null) { + var headers = requestModel.enabledHeadersMap; + if (headers.isNotEmpty) { + result += getHeaders(headers); + } + } + + var templateRequestEnd = jj.Template(kTemplateRequestEnd); + result += templateRequestEnd.render({ + "method": method.name.toLowerCase(), + "hasBody": (hasBody || requestModel.hasFormData) ? "body" : "", + }); + } + return result; + } catch (e) { + return null; + } + } + + String getQueryParams(Map params) { + final paramStrings = params.entries.map((entry) => '.addQueryParameter("${entry.key}", "${entry.value}")').toList(); + return paramStrings.join('\n '); + } + + String getHeaders(Map headers) { + String result = ""; + for (final k in headers.keys) { + result = """$result .addHeader("$k", "${headers[k]}")\n"""; + } + return result; + } +} \ No newline at end of file diff --git a/lib/codegen/js/axios.dart b/lib/codegen/js/axios.dart index 1aeee285..71456d6e 100644 --- a/lib/codegen/js/axios.dart +++ b/lib/codegen/js/axios.dart @@ -12,7 +12,7 @@ class AxiosCodeGen { String kStringImportNode = """{% if isNodeJs %}import axios from 'axios'; -{% endif %}{% if isFormDataRequest and isNodeJs %}const fs = require('fs');{% endif %} +{% endif %}{% if hasFormData and isNodeJs %}const fs = require('fs');{% endif %} """; String kTemplateStart = """let config = { @@ -73,18 +73,16 @@ async function buildFormData(fields) { '''; String? getCode( RequestModel requestModel, - String defaultUriScheme, ) { try { jj.Template kNodejsImportTemplate = jj.Template(kStringImportNode); String importsData = kNodejsImportTemplate.render({ - "isFormDataRequest": requestModel.isFormDataRequest, + "hasFormData": requestModel.hasFormData, "isNodeJs": isNodeJs, }); String result = importsData; - if (requestModel.isFormDataRequest && - requestModel.formDataMapList.isNotEmpty) { + if (requestModel.hasFormData && requestModel.formDataMapList.isNotEmpty) { var templateMultiPartBody = jj.Template(kMultiPartBodyTemplate); var renderedMultiPartBody = templateMultiPartBody.render({ "isNodeJs": isNodeJs, @@ -92,17 +90,14 @@ async function buildFormData(fields) { result += renderedMultiPartBody; } - String url = requestModel.url; - if (!url.contains("://") && url.isNotEmpty) { - url = "$defaultUriScheme://$url"; - } - var rM = requestModel.copyWith(url: url); - - var harJson = requestModelToHARJsonRequest(rM, useEnabled: true); + var harJson = requestModelToHARJsonRequest( + requestModel, + useEnabled: true, + ); var templateStart = jj.Template(kTemplateStart); result += templateStart.render({ - "url": stripUrlParams(url), + "url": stripUrlParams(requestModel.url), "method": harJson["method"].toLowerCase(), }); @@ -118,22 +113,21 @@ async function buildFormData(fields) { } var headers = harJson["headers"]; - if (headers.isNotEmpty || requestModel.isFormDataRequest) { + if (headers.isNotEmpty || requestModel.hasFormData) { var templateHeader = jj.Template(kTemplateHeader); var m = {}; for (var i in headers) { m[i["name"]] = i["value"]; } - if (requestModel.isFormDataRequest) { - m['Content-Type'] = 'multipart/form-data'; + if (requestModel.hasFormData) { + m[kHeaderContentType] = 'multipart/form-data'; } result += templateHeader .render({"headers": padMultilineString(kEncoder.convert(m), 2)}); } var templateBody = jj.Template(kTemplateBody); - if (requestModel.isFormDataRequest && - requestModel.formDataMapList.isNotEmpty) { + if (requestModel.hasFormData && requestModel.formDataMapList.isNotEmpty) { var getFieldDataTemplate = jj.Template(kGetFormDataTemplate); result += templateBody.render({ diff --git a/lib/codegen/js/fetch.dart b/lib/codegen/js/fetch.dart index 4ef2e551..9b5f8161 100644 --- a/lib/codegen/js/fetch.dart +++ b/lib/codegen/js/fetch.dart @@ -1,4 +1,3 @@ -import 'dart:convert'; import 'package:jinja/jinja.dart' as jj; import 'package:apidash/utils/utils.dart' show padMultilineString, requestModelToHARJsonRequest; @@ -11,14 +10,16 @@ class FetchCodeGen { final bool isNodeJs; String kStringImportNode = """ -import fetch from 'node-fetch'; -{% if isFormDataRequest %}const fs = require('fs');{% endif %} +import fetch from 'node-fetch' +{% if hasFormData -%} +import { {% if hasFileInFormData %}fileFromSync, {% endif %}FormData } from 'node-fetch' +{% endif %} """; - String kTemplateStart = """let url = '{{url}}'; + String kTemplateStart = """const url = '{{url}}'; -let options = { +const options = { method: '{{method}}' """; @@ -27,75 +28,63 @@ let options = { """; String kTemplateBody = """, - body: -{{body}} + body: {{body}} """; String kMultiPartBodyTemplate = r''' -async function buildDataList(fields) { - var formdata = new FormData(); - for (const field of fields) { - const name = field.name || ''; - const value = field.value || ''; - const type = field.type || 'text'; - - if (type === 'text') { - formdata.append(name, value); - } else if (type === 'file') { - formdata.append(name,{% if isNodeJs %} fs.createReadStream(value){% else %} fileInput.files[0],value{% endif %}); - } - } - return formdata; -} - -const payload = buildDataList({{fields_list}}); +payload.append("{{name}}", {{value}}) '''; String kStringRequest = """ }; -let status; fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:\${err}`); + }); """; - String? getCode( - RequestModel requestModel, - String defaultUriScheme, - ) { + String? getCode(RequestModel requestModel) { try { jj.Template kNodejsImportTemplate = jj.Template(kStringImportNode); String importsData = kNodejsImportTemplate.render({ - "isFormDataRequest": requestModel.isFormDataRequest, + "hasFormData": requestModel.hasFormData, + "hasFileInFormData": requestModel.hasFileInFormData, }); - String result = isNodeJs ? importsData : ""; - if (requestModel.isFormDataRequest) { + String result = isNodeJs + ? importsData + : requestModel.hasFileInFormData + ? "// refer https://github.com/foss42/apidash/issues/293#issuecomment-1995208098 for details regarding integration\n\n" + : ""; + if (requestModel.hasFormData) { + result += "const payload = new FormData();\n"; var templateMultiPartBody = jj.Template(kMultiPartBodyTemplate); - result += templateMultiPartBody.render({ - "isNodeJs": isNodeJs, - "fields_list": json.encode(requestModel.formDataMapList), - }); + var formFileCounter = 1; + for (var element in requestModel.formDataMapList) { + result += templateMultiPartBody.render({ + "name": element["name"], + "value": element["type"] == "text" + ? "\"${element["value"]}\"" + : isNodeJs + ? "fileFromSync(\"${element["value"]}\")" + : "fileInput$formFileCounter.files[0]" + }); + if (element["type"] != "text") formFileCounter++; + } + result += "\n"; } - String url = requestModel.url; - if (!url.contains("://") && url.isNotEmpty) { - url = "$defaultUriScheme://$url"; - } - var rM = requestModel.copyWith(url: url); - var harJson = requestModelToHARJsonRequest(rM, useEnabled: true); + var harJson = + requestModelToHARJsonRequest(requestModel, useEnabled: true); var templateStart = jj.Template(kTemplateStart); result += templateStart.render({ @@ -108,15 +97,18 @@ fetch(url, options) if (headers.isNotEmpty) { var templateHeader = jj.Template(kTemplateHeader); var m = {}; - if (requestModel.isFormDataRequest) { - m["Content-Type"] = "multipart/form-data"; - } for (var i in headers) { + // fetch can automatically add the Content-Type header when FormData is passed as body + if (i["name"] == "Content-Type" && requestModel.hasFormData) { + continue; + } m[i["name"]] = i["value"]; } - result += templateHeader.render({ - "headers": padMultilineString(kEncoder.convert(m), 2), - }); + if (m.isNotEmpty) { + result += templateHeader.render({ + "headers": padMultilineString(kEncoder.convert(m), 2), + }); + } } if (harJson["postData"]?["text"] != null) { @@ -124,7 +116,7 @@ fetch(url, options) result += templateBody.render({ "body": kEncoder.convert(harJson["postData"]["text"]), }); - } else if (requestModel.isFormDataRequest) { + } else if (requestModel.hasFormData) { var templateBody = jj.Template(kTemplateBody); result += templateBody.render({ "body": 'payload', diff --git a/lib/codegen/julia/http.dart b/lib/codegen/julia/http.dart new file mode 100644 index 00000000..b1d1e96b --- /dev/null +++ b/lib/codegen/julia/http.dart @@ -0,0 +1,198 @@ +import 'dart:io'; +import 'dart:convert'; +import 'package:jinja/jinja.dart' as jj; +import 'package:apidash/consts.dart'; +import 'package:apidash/utils/utils.dart' + show getNewUuid, getValidRequestUri, padMultilineString, stripUriParams; +import 'package:apidash/models/models.dart' show RequestModel; + +class JuliaHttpClientCodeGen { + final String kTemplateStart = """using HTTP,JSON + +url = "{{url}}" + +"""; + + String kTemplateParams = """ +{% set new_params = params | replace(":", "=>") | replace("{", "(") | replace("}", ")") %} + +params = Dict{{new_params}} +"""; + + int kParamsPadding = 9; + + String kTemplateBody = ''' +{% set new_params = body | replace(":", "=>") | replace("{", "(") | replace("}", ")") %} + +payload = Dict{{new_params}} +'''; + + String kTemplateJson = """ +{% set new_params = body | replace(":", "=>") | replace("{", "(") | replace("}", ")") %} + +payload = Dict{{new_params}} +"""; + + String kTemplateHeaders = """ +{% set new_params = headers | replace(":", "=>") | replace("{", "(") | replace("}", ")") %} + +headers = Dict{{new_params}} +"""; + + String kTemplateFormHeaderContentType = ''' +multipart/form-data; boundary={{boundary}}'''; + + int kHeadersPadding = 10; + + String kTemplateRequest = """ + + +response = HTTP.{{method}}(url +"""; + + final String kStringFormDataBody = r''' +function build_data_list(fields) + dataList = [] + for field in fields + name = field["name"] + value = field["value"] + type_ = get(field, "type", "text") + + push!(dataList, b"--{{boundary}}") + if type_ == "text" + push!(dataList, b"Content-Disposition: form-data; name=\"$name\"") + push!(dataList, b"Content-Type: text/plain") + push!(dataList, b"") + push!(dataList, codeunits(value)) + elseif type_ == "file" + push!(dataList, b"Content-Disposition: form-data; name=\"$name\"; filename=\"$value\"") + push!(dataList, b"Content-Type: $value") + push!(dataList, b"") + push!(dataList, String(read(value))) + end + end + push!(dataList, "--{{boundary}}--") + push!(dataList, b"") + return dataList +end + +dataList = build_data_list({{fields_list}}) +payload = join(dataList, b"\r\n") +'''; + + String kStringRequestParams = """, query=params"""; + + String kStringRequestBody = """, payload=payload"""; + + String kStringRequestJson = """, JSON.json(payload)"""; + + String kStringRequestHeaders = """, headers=headers"""; + + final String kStringRequestEnd = """ +) + +println("Status Code:", response.status) +println("Response Body:", String(response.body)) +"""; + + String? getCode(RequestModel requestModel) { + try { + String result = ""; + bool hasQuery = false; + bool hasHeaders = false; + bool hasBody = false; + bool hasJsonBody = false; + String uuid = getNewUuid(); + + var rec = getValidRequestUri( + requestModel.url, + requestModel.enabledRequestParams, + ); + Uri? uri = rec.$1; + if (uri != null) { + var templateStartUrl = jj.Template(kTemplateStart); + result += templateStartUrl.render({ + "url": stripUriParams(uri), + }); + + if (uri.hasQuery) { + var params = uri.queryParameters; + if (params.isNotEmpty) { + hasQuery = true; + var templateParams = jj.Template(kTemplateParams); + var paramsString = kEncoder.convert(params); + paramsString = padMultilineString(paramsString, kParamsPadding); + result += templateParams.render({"params": paramsString}); + } + } + + if (requestModel.hasJsonData) { + hasJsonBody = true; + var templateBody = jj.Template(kTemplateJson); + result += templateBody.render({"body": requestModel.requestBody}); + } else if (requestModel.hasTextData) { + hasBody = true; + var templateBody = jj.Template(kTemplateBody); + result += templateBody.render({"body": requestModel.requestBody}); + } + + var headersList = requestModel.enabledRequestHeaders; + if (headersList != null || hasBody) { + var headers = requestModel.enabledHeadersMap; + if (requestModel.hasFormData) { + var formHeaderTemplate = + jj.Template(kTemplateFormHeaderContentType); + headers[HttpHeaders.contentTypeHeader] = formHeaderTemplate.render({ + "boundary": uuid, + }); + } + if (headers.isNotEmpty || hasBody) { + hasHeaders = true; + if (hasBody) { + headers[HttpHeaders.contentTypeHeader] = + requestModel.requestBodyContentType.header; + } + var headersString = kEncoder.convert(headers); + headersString = padMultilineString(headersString, kHeadersPadding); + var templateHeaders = jj.Template(kTemplateHeaders); + result += templateHeaders.render({"headers": headersString}); + } + } + if (requestModel.hasFormData) { + var formDataBodyData = jj.Template(kStringFormDataBody); + result += formDataBodyData.render( + { + "fields_list": json.encode(requestModel.formDataMapList), + "boundary": uuid, + }, + ); + } + var templateRequest = jj.Template(kTemplateRequest); + result += templateRequest.render({ + "method": requestModel.method.name.toLowerCase(), + }); + + if (hasQuery) { + result += kStringRequestParams; + } + + if (hasBody || requestModel.hasFormData) { + result += kStringRequestBody; + } + + if (hasJsonBody || requestModel.hasFormData) { + result += kStringRequestJson; + } + + if (hasHeaders || requestModel.hasFormData) { + result += kStringRequestHeaders; + } + + result += kStringRequestEnd; + } + return result; + } catch (e) { + return null; + } + } +} diff --git a/lib/codegen/kotlin/okhttp.dart b/lib/codegen/kotlin/okhttp.dart index 07e5a92b..c717dc97 100644 --- a/lib/codegen/kotlin/okhttp.dart +++ b/lib/codegen/kotlin/okhttp.dart @@ -7,7 +7,7 @@ import 'package:apidash/consts.dart'; class KotlinOkHttpCodeGen { final String kTemplateStart = """import okhttp3.OkHttpClient -import okhttp3.Request{{importForQuery}}{{importForBody}} +import okhttp3.Request{{importForQuery}}{{importForBody}}{{importForFormData}} fun main() { val client = OkHttpClient() @@ -23,6 +23,10 @@ import okhttp3.HttpUrl.Companion.toHttpUrl"""; import okhttp3.RequestBody.Companion.toRequestBody import okhttp3.MediaType.Companion.toMediaType"""; + final String kStringImportForFormData = """ + +import okhttp3.MultipartBody"""; + final String kTemplateUrl = ''' val url = "{{url}}" @@ -71,20 +75,15 @@ import okhttp3.MediaType.Companion.toMediaType"""; String? getCode( RequestModel requestModel, - String defaultUriScheme, ) { try { String result = ""; bool hasQuery = false; bool hasBody = false; - - String url = requestModel.url; - if (!url.contains("://") && url.isNotEmpty) { - url = "$defaultUriScheme://$url"; - } + bool hasFormData = false; var rec = getValidRequestUri( - url, + requestModel.url, requestModel.enabledRequestParams, ); Uri? uri = rec.$1; @@ -108,7 +107,8 @@ import okhttp3.MediaType.Companion.toMediaType"""; var method = requestModel.method; var requestBody = requestModel.requestBody; - if (requestModel.isFormDataRequest) { + if (requestModel.hasFormData) { + hasFormData = true; var formDataTemplate = jj.Template(kFormDataBody); result += formDataTemplate.render({ @@ -128,7 +128,8 @@ import okhttp3.MediaType.Companion.toMediaType"""; var templateStart = jj.Template(kTemplateStart); var stringStart = templateStart.render({ "importForQuery": hasQuery ? kStringImportForQuery : "", - "importForBody": hasBody ? kStringImportForBody : "" + "importForBody": hasBody ? kStringImportForBody : "", + "importForFormData": hasFormData ? kStringImportForFormData : "" }); result = stringStart + result; @@ -145,7 +146,7 @@ import okhttp3.MediaType.Companion.toMediaType"""; var templateRequestEnd = jj.Template(kTemplateRequestEnd); result += templateRequestEnd.render({ "method": method.name.toLowerCase(), - "hasBody": (hasBody || requestModel.isFormDataRequest) ? "body" : "", + "hasBody": (hasBody || requestModel.hasFormData) ? "body" : "", }); } return result; diff --git a/lib/codegen/others/curl.dart b/lib/codegen/others/curl.dart index 4ae610de..2ba59765 100644 --- a/lib/codegen/others/curl.dart +++ b/lib/codegen/others/curl.dart @@ -1,6 +1,7 @@ import 'package:jinja/jinja.dart' as jj; import 'package:apidash/utils/utils.dart' show requestModelToHARJsonRequest; import 'package:apidash/models/models.dart' show RequestModel; +import 'package:apidash/consts.dart'; // ignore: camel_case_types class cURLCodeGen { @@ -11,7 +12,7 @@ class cURLCodeGen { --header '{{name}}: {{value}}' """; String kTemplateFormData = """ \\ - --form '{{name}}: {{value}}' + --form '{{name}}={{value}}' """; String kTemplateBody = """ \\ @@ -20,25 +21,21 @@ class cURLCodeGen { String? getCode( RequestModel requestModel, - String defaultUriScheme, ) { try { String result = ""; - String url = requestModel.url; - if (!url.contains("://") && url.isNotEmpty) { - url = "$defaultUriScheme://$url"; - } - var rM = requestModel.copyWith(url: url); - - var harJson = requestModelToHARJsonRequest(rM, useEnabled: true); + var harJson = requestModelToHARJsonRequest( + requestModel, + useEnabled: true, + ); var templateStart = jj.Template(kTemplateStart); result += templateStart.render({ "method": switch (harJson["method"]) { "GET" => "", "HEAD" => " --head", - _ => " --request ${harJson["method"]} \\\n" + _ => " --request ${harJson["method"]} \\\n " }, "url": harJson["url"], }); @@ -46,33 +43,31 @@ class cURLCodeGen { var headers = harJson["headers"]; if (headers.isNotEmpty) { for (var item in headers) { + if (requestModel.hasFormData && item["name"] == kHeaderContentType) { + continue; + } var templateHeader = jj.Template(kTemplateHeader); result += templateHeader .render({"name": item["name"], "value": item["value"]}); } } - if (harJson['formData'] != null) { - var formDataList = harJson['formData'] as List>; - for (var formData in formDataList) { + + if (requestModel.hasJsonData || requestModel.hasTextData) { + var templateBody = jj.Template(kTemplateBody); + result += templateBody.render({"body": requestModel.requestBody}); + } else if (requestModel.hasFormData) { + for (var formData in requestModel.formDataList) { var templateFormData = jj.Template(kTemplateFormData); - if (formData['type'] != null && - formData['name'] != null && - formData['value'] != null && - formData['name']!.isNotEmpty && - formData['value']!.isNotEmpty) { + if (formData.name.isNotEmpty && formData.value.isNotEmpty) { result += templateFormData.render({ - "name": formData["name"], + "name": formData.name, "value": - "${formData['type'] == 'file' ? '@' : ''}${formData["value"]}", + "${formData.type == FormDataType.file ? '@' : ''}${formData.value}", }); } } } - if (harJson["postData"]?["text"] != null) { - var templateBody = jj.Template(kTemplateBody); - result += templateBody.render({"body": harJson["postData"]["text"]}); - } return result; } catch (e) { return null; diff --git a/lib/codegen/others/har.dart b/lib/codegen/others/har.dart index 77d78f58..72ab8731 100644 --- a/lib/codegen/others/har.dart +++ b/lib/codegen/others/har.dart @@ -5,13 +5,15 @@ import 'package:apidash/models/models.dart' show RequestModel; class HARCodeGen { String? getCode( RequestModel requestModel, - String defaultUriScheme, - ) { + String defaultUriScheme, { + String? boundary, + }) { try { var harString = kEncoder.convert(requestModelToHARJsonRequest( requestModel, defaultUriScheme: defaultUriScheme, useEnabled: true, + boundary: boundary, )); return harString; } catch (e) { diff --git a/lib/codegen/python/http_client.dart b/lib/codegen/python/http_client.dart index 4406effb..05fb8253 100644 --- a/lib/codegen/python/http_client.dart +++ b/lib/codegen/python/http_client.dart @@ -1,14 +1,13 @@ import 'dart:io'; import 'dart:convert'; import 'package:jinja/jinja.dart' as jj; -import 'package:apidash/utils/utils.dart' - show getNewUuid, getValidRequestUri, padMultilineString; +import 'package:apidash/utils/utils.dart' show getValidRequestUri; import 'package:apidash/models/models.dart' show RequestModel; import 'package:apidash/consts.dart'; class PythonHttpClientCodeGen { final String kTemplateStart = """import http.client -{% if isFormDataRequest %}import mimetypes +{% if hasFormData %}import mimetypes from codecs import encode {% endif %} """; @@ -20,7 +19,6 @@ queryParams = {{params}} queryParamsStr = '?' + urlencode(queryParams) """; - int kParamsPadding = 14; String kTemplateBody = """ @@ -36,8 +34,6 @@ headers = {{headers}} String kTemplateFormHeaderContentType = ''' multipart/form-data; boundary={{boundary}}'''; - int kHeadersPadding = 10; - String kTemplateConnection = """ conn = http.client.HTTP{{isHttps}}Connection("{{authority}}")"""; @@ -87,30 +83,23 @@ dataList = build_data_list({{fields_list}}) body = b'\r\n'.join(dataList) '''; String? getCode( - RequestModel requestModel, - String defaultUriScheme, - ) { - String uuid = getNewUuid(); - + RequestModel requestModel, { + String? boundary, + }) { try { String result = ""; bool hasHeaders = false; bool hasQuery = false; bool hasBody = false; - String url = requestModel.url; - if (!url.contains("://") && url.isNotEmpty) { - url = "$defaultUriScheme://$url"; - } - var templateStartUrl = jj.Template(kTemplateStart); result += templateStartUrl.render( { - "isFormDataRequest": requestModel.isFormDataRequest, + "hasFormData": requestModel.hasFormData, }, ); var rec = getValidRequestUri( - url, + requestModel.url, requestModel.enabledRequestParams, ); @@ -123,51 +112,48 @@ body = b'\r\n'.join(dataList) hasQuery = true; var templateParams = jj.Template(kTemplateParams); var paramsString = kEncoder.convert(params); - paramsString = padMultilineString(paramsString, kParamsPadding); result += templateParams.render({"params": paramsString}); } } - var method = requestModel.method; - var requestBody = requestModel.requestBody; - if (kMethodsWithBody.contains(method) && requestBody != null) { - var contentLength = utf8.encode(requestBody).length; - if (contentLength > 0) { - hasBody = true; + if (requestModel.hasData) { + hasBody = true; + if (requestModel.hasJsonData || requestModel.hasTextData) { var templateBody = jj.Template(kTemplateBody); - result += templateBody.render({"body": requestBody}); + result += templateBody.render({"body": requestModel.requestBody}); } } var headersList = requestModel.enabledRequestHeaders; if (headersList != null || hasBody) { var headers = requestModel.enabledHeadersMap; - if (requestModel.isFormDataRequest) { - var formHeaderTemplate = - jj.Template(kTemplateFormHeaderContentType); - headers[HttpHeaders.contentTypeHeader] = formHeaderTemplate.render({ - "boundary": uuid, - }); - } if (headers.isNotEmpty || hasBody) { hasHeaders = true; if (hasBody && !requestModel.hasContentTypeHeader) { - headers[HttpHeaders.contentTypeHeader] = - requestModel.requestBodyContentType.header; + if (requestModel.hasJsonData || requestModel.hasTextData) { + headers[HttpHeaders.contentTypeHeader] = + requestModel.requestBodyContentType.header; + } else if (requestModel.hasFormData) { + var formHeaderTemplate = + jj.Template(kTemplateFormHeaderContentType); + headers[HttpHeaders.contentTypeHeader] = + formHeaderTemplate.render({ + "boundary": boundary, + }); + } } var headersString = kEncoder.convert(headers); - headersString = padMultilineString(headersString, kHeadersPadding); var templateHeaders = jj.Template(kTemplateHeaders); result += templateHeaders.render({"headers": headersString}); } } - if (requestModel.isFormDataRequest) { + if (requestModel.hasFormData) { var formDataBodyData = jj.Template(kStringFormDataBody); result += formDataBodyData.render( { "fields_list": json.encode(requestModel.formDataMapList), - "boundary": uuid, + "boundary": boundary, }, ); } @@ -179,16 +165,16 @@ body = b'\r\n'.join(dataList) var templateRequest = jj.Template(kTemplateRequest); result += templateRequest.render({ - "method": method.name.toUpperCase(), + "method": requestModel.method.name.toUpperCase(), "path": uri.path, "queryParamsStr": hasQuery ? " + queryParamsStr" : "", }); - if (hasBody || requestModel.isFormDataRequest) { + if (hasBody || requestModel.hasFormData) { result += kStringRequestBody; } - if (hasHeaders || requestModel.isFormDataRequest) { + if (hasHeaders || requestModel.hasFormData) { result += kStringRequestHeaders; } diff --git a/lib/codegen/python/requests.dart b/lib/codegen/python/requests.dart index 3a5beeb6..6fb07908 100644 --- a/lib/codegen/python/requests.dart +++ b/lib/codegen/python/requests.dart @@ -1,15 +1,14 @@ import 'dart:io'; -import 'dart:convert'; import 'package:jinja/jinja.dart' as jj; import 'package:apidash/consts.dart'; import 'package:apidash/utils/utils.dart' - show getNewUuid, getValidRequestUri, padMultilineString, stripUriParams; + show getValidRequestUri, stripUriParams, getFilenameFromPath; import 'package:apidash/models/models.dart' show RequestModel; +import '../codegen_utils.dart'; class PythonRequestsCodeGen { final String kTemplateStart = """import requests -{% if isFormDataRequest %}import mimetypes -from codecs import encode +{% if hasFormData %}from requests_toolbelt.multipart.encoder import MultipartEncoder {% endif %} url = '{{url}}' @@ -20,7 +19,6 @@ url = '{{url}}' params = {{params}} """; - int kParamsPadding = 9; String kTemplateBody = """ @@ -39,44 +37,27 @@ payload = {{body}} headers = {{headers}} """; - String kTemplateFormHeaderContentType = ''' -multipart/form-data; boundary={{boundary}}'''; - - int kHeadersPadding = 10; String kTemplateRequest = """ response = requests.{{method}}(url """; - final String kStringFormDataBody = r''' + final String kTemplateFormDataBody = r''' -def build_data_list(fields): - dataList = [] - for field in fields: - name = field.get('name', '') - value = field.get('value', '') - type_ = field.get('type', 'text') +payload = MultipartEncoder({ +{{formdata_payload}} +}{% if boundary != '' %}, + boundary="{{boundary}}" +{% endif %}) - dataList.append(encode('--{{boundary}}')) - if type_ == 'text': - dataList.append(encode(f'Content-Disposition: form-data; name="{name}"')) - dataList.append(encode('Content-Type: text/plain')) - dataList.append(encode('')) - dataList.append(encode(value)) - elif type_ == 'file': - dataList.append(encode(f'Content-Disposition: form-data; name="{name}"; filename="{value}"')) - dataList.append(encode(f'Content-Type: {mimetypes.guess_type(value)[0] or "application/octet-stream"}')) - dataList.append(encode('')) - dataList.append(open(value, 'rb').read()) - dataList.append(encode('--{{boundary}}--')) - dataList.append(encode('')) - return dataList - -dataList = build_data_list({{fields_list}}) -payload = b'\r\n'.join(dataList) '''; + String kTemplateFormDataRowText = r""" "{{name}}": "{{value}}","""; + + String kTemplateFormDataRowFile = + r""" "{{name}}": ("{{filename}}", open("{{path}}", "rb")),"""; + String kStringRequestParams = """, params=params"""; String kStringRequestBody = """, data=payload"""; @@ -91,25 +72,26 @@ print('Status Code:', response.status_code) print('Response Body:', response.text) """; + String kStringFormDataContentType = "payload.content_type"; + + String refactorHeaderString(String headerString) { + return headerString.replaceAll( + '"$kStringFormDataContentType"', kStringFormDataContentType); + } + String? getCode( - RequestModel requestModel, - String defaultUriScheme, - ) { + RequestModel requestModel, { + String? boundary, + }) { try { String result = ""; bool hasQuery = false; bool hasHeaders = false; bool hasBody = false; bool hasJsonBody = false; - String uuid = getNewUuid(); - - String url = requestModel.url; - if (!url.contains("://") && url.isNotEmpty) { - url = "$defaultUriScheme://$url"; - } var rec = getValidRequestUri( - url, + requestModel.url, requestModel.enabledRequestParams, ); Uri? uri = rec.$1; @@ -117,7 +99,7 @@ print('Response Body:', response.text) var templateStartUrl = jj.Template(kTemplateStart); result += templateStartUrl.render({ "url": stripUriParams(uri), - 'isFormDataRequest': requestModel.isFormDataRequest + 'hasFormData': requestModel.hasFormData }); if (uri.hasQuery) { @@ -126,77 +108,85 @@ print('Response Body:', response.text) hasQuery = true; var templateParams = jj.Template(kTemplateParams); var paramsString = kEncoder.convert(params); - paramsString = padMultilineString(paramsString, kParamsPadding); result += templateParams.render({"params": paramsString}); } } - var method = requestModel.method; - var requestBody = requestModel.requestBody; - if (kMethodsWithBody.contains(method) && requestBody != null) { - var contentLength = utf8.encode(requestBody).length; - if (contentLength > 0) { - if (requestModel.requestBodyContentType == ContentType.json) { - hasJsonBody = true; - var templateBody = jj.Template(kTemplateJson); - result += templateBody.render({"body": requestBody}); - } else { - hasBody = true; - var templateBody = jj.Template(kTemplateBody); - result += templateBody.render({"body": requestBody}); + if (requestModel.hasFormData) { + hasBody = true; + List formdataPayload = []; + for (var item in requestModel.formDataList) { + if (item.type == FormDataType.text) { + formdataPayload.add(jj.Template(kTemplateFormDataRowText).render({ + "name": item.name, + "value": item.value, + })); + } + if (item.type == FormDataType.file) { + formdataPayload.add(jj.Template(kTemplateFormDataRowFile).render({ + "name": item.name, + "filename": getFilenameFromPath(item.value), + "path": item.value, + })); } } + var formDataBodyData = jj.Template(kTemplateFormDataBody); + result += formDataBodyData.render( + { + "formdata_payload": formdataPayload.join("\n"), + "boundary": boundary ?? '', + }, + ); + } else if (requestModel.hasJsonData) { + hasJsonBody = true; + var templateBody = jj.Template(kTemplateJson); + var pyDict = jsonToPyDict(requestModel.requestBody ?? ""); + result += templateBody.render({"body": pyDict}); + } else if (requestModel.hasTextData) { + hasBody = true; + var templateBody = jj.Template(kTemplateBody); + result += templateBody.render({"body": requestModel.requestBody}); } var headersList = requestModel.enabledRequestHeaders; if (headersList != null || hasBody) { var headers = requestModel.enabledHeadersMap; - if (requestModel.isFormDataRequest) { - var formHeaderTemplate = - jj.Template(kTemplateFormHeaderContentType); - headers[HttpHeaders.contentTypeHeader] = formHeaderTemplate.render({ - "boundary": uuid, - }); - } - if (headers.isNotEmpty || hasBody) { - hasHeaders = true; - if (hasBody) { + if (hasBody) { + if (requestModel.hasFormData) { + headers[HttpHeaders.contentTypeHeader] = + kStringFormDataContentType; + } else { headers[HttpHeaders.contentTypeHeader] = requestModel.requestBodyContentType.header; } + } + if (headers.isNotEmpty) { + hasHeaders = true; var headersString = kEncoder.convert(headers); - headersString = padMultilineString(headersString, kHeadersPadding); + headersString = refactorHeaderString(headersString); var templateHeaders = jj.Template(kTemplateHeaders); result += templateHeaders.render({"headers": headersString}); } } - if (requestModel.isFormDataRequest) { - var formDataBodyData = jj.Template(kStringFormDataBody); - result += formDataBodyData.render( - { - "fields_list": json.encode(requestModel.formDataMapList), - "boundary": uuid, - }, - ); - } + var templateRequest = jj.Template(kTemplateRequest); result += templateRequest.render({ - "method": method.name.toLowerCase(), + "method": requestModel.method.name.toLowerCase(), }); if (hasQuery) { result += kStringRequestParams; } - if (hasBody || requestModel.isFormDataRequest) { + if (hasBody) { result += kStringRequestBody; } - if (hasJsonBody || requestModel.isFormDataRequest) { + if (hasJsonBody) { result += kStringRequestJson; } - if (hasHeaders || requestModel.isFormDataRequest) { + if (hasHeaders) { result += kStringRequestHeaders; } diff --git a/lib/codegen/rust/actix.dart b/lib/codegen/rust/actix.dart new file mode 100644 index 00000000..4e13b0f1 --- /dev/null +++ b/lib/codegen/rust/actix.dart @@ -0,0 +1,217 @@ +import 'dart:io'; +import 'dart:convert'; +import 'package:jinja/jinja.dart' as jj; +import 'package:apidash/consts.dart'; +import 'package:apidash/utils/utils.dart' + show getNewUuid, getValidRequestUri, stripUriParams; +import 'package:apidash/models/models.dart' show RequestModel; + +class RustActixCodeGen { + final String kTemplateStart = """ +{%- if isFormDataRequest -%} +use std::io::Read; +{% endif -%} +#[actix_rt::main] +async fn main() -> Result<(), Box> { + let url = "{{url}}"; + let client = awc::Client::default(); + +"""; + + String kTemplateParams = + """\n .query(&{{ params }})\n .unwrap()"""; + + String kTemplateBody = """ + + let payload = r#"{{body}}"#; + +"""; + + String kTemplateJson = """ + + let payload = serde_json::json!({{body}}); + +"""; + + String kTemplateHeaders = + """\n {% for key, val in headers -%}.insert_header(("{{key}}", "{{val}}")){% if not loop.last %}{{ '\n ' }}{% endif %}{%- endfor -%}"""; + + String kTemplateFormHeaderContentType = ''' +multipart/form-data; boundary={{boundary}}'''; + + String kTemplateRequest = """ + + let mut response = client\n .{{method}}(url) +"""; + + final String kStringFormDataBody = r""" + + struct FormDataItem { + name: String, + value: String, + field_type: String, + } + + let form_data_items: Vec = vec![ + {%- for formitem in fields_list %} + FormDataItem { + {%- for key, val in formitem %} + {% if key == "type" %}field_type: "{{ val }}".to_string(),{% else %}{{ key }}: "{{ val }}".to_string(),{% endif %} + {%- endfor %} + }, + {%- endfor %} + ]; + + fn build_data_list(fields: Vec) -> Vec { + let mut data_list = Vec::new(); + + for field in fields { + data_list.extend_from_slice(b"--{{boundary}}\r\n"); + + if field.field_type == "text" { + data_list.extend_from_slice(format!("Content-Disposition: form-data; name=\"{}\"\r\n", field.name).as_bytes()); + data_list.extend_from_slice(b"Content-Type: text/plain\r\n\r\n"); + data_list.extend_from_slice(field.value.as_bytes()); + data_list.extend_from_slice(b"\r\n"); + } else if field.field_type == "file" { + data_list.extend_from_slice(format!("Content-Disposition: form-data; name=\"{}\"; filename=\"{}\"\r\n", field.name, field.value).as_bytes()); + + let mime_type = mime_guess::from_path(&field.value).first_or(mime_guess::mime::APPLICATION_OCTET_STREAM); + data_list.extend_from_slice(format!("Content-Type: {}\r\n\r\n", mime_type).as_bytes()); + + let mut file = std::fs::File::open(&field.value).unwrap(); + let mut file_contents = Vec::new(); + file.read_to_end(&mut file_contents).unwrap(); + data_list.extend_from_slice(&file_contents); + data_list.extend_from_slice(b"\r\n"); + } + } + + data_list.extend_from_slice(b"--{{boundary}}--\r\n"); + data_list + } + + let payload = build_data_list(form_data_items); +"""; + + String kStringRequestBody = """\n .send_body(payload)"""; + + String kStringRequestJson = """\n .send_json(&payload)"""; + + String kStringRequestNormal = """\n .send()"""; + + final String kStringRequestEnd = """\n .await\n .unwrap(); + + let body_bytes = response.body().await.unwrap(); + let body = std::str::from_utf8(&body_bytes).unwrap(); + println!("Response Status: {}", response.status()); + println!("Response: {:?}", body); + + Ok(()) +} +"""; + + String? getCode( + RequestModel requestModel, { + String? boundary, + }) { + try { + String uuid = getNewUuid(); + String result = ""; + bool hasBody = false; + bool hasJsonBody = false; + + String url = requestModel.url; + + var rec = getValidRequestUri( + url, + requestModel.enabledRequestParams, + ); + Uri? uri = rec.$1; + if (uri != null) { + var templateStartUrl = jj.Template(kTemplateStart); + result += templateStartUrl.render({ + "url": stripUriParams(uri), + 'isFormDataRequest': requestModel.hasFormData, + "method": requestModel.method.name.toLowerCase() + }); + + var method = requestModel.method; + var requestBody = requestModel.requestBody; + if (kMethodsWithBody.contains(method) && requestBody != null) { + var contentLength = utf8.encode(requestBody).length; + if (contentLength > 0) { + if (requestModel.requestBodyContentType == ContentType.json) { + hasJsonBody = true; + var templateBody = jj.Template(kTemplateJson); + result += templateBody.render({"body": requestBody}); + } else if (!requestModel.hasFormData) { + hasBody = true; + var templateBody = jj.Template(kTemplateBody); + result += templateBody.render({"body": requestBody}); + } + } + } + + if (requestModel.hasFormData) { + var formDataBodyData = jj.Template(kStringFormDataBody); + result += formDataBodyData.render( + { + "fields_list": requestModel.formDataMapList, + "boundary": boundary ?? uuid, + }, + ); + } + var templateRequest = jj.Template(kTemplateRequest); + result += templateRequest.render({ + "method": method.name.toLowerCase(), + }); + + if (uri.hasQuery) { + var params = uri.queryParameters; + if (params.isNotEmpty) { + var tupleStrings = params.entries + .map((entry) => '("${entry.key}", "${entry.value}")') + .toList(); + var paramsString = "[${tupleStrings.join(', ')}]"; + var templateParms = jj.Template(kTemplateParams); + result += templateParms.render({"params": paramsString}); + } + } + + var headersList = requestModel.enabledRequestHeaders; + if (headersList != null || hasBody || requestModel.hasFormData) { + var headers = requestModel.enabledHeadersMap; + if (requestModel.hasFormData) { + var formHeaderTemplate = + jj.Template(kTemplateFormHeaderContentType); + headers[HttpHeaders.contentTypeHeader] = formHeaderTemplate.render({ + "boundary": boundary ?? uuid, + }); + } else if (hasBody) { + headers[HttpHeaders.contentTypeHeader] = + requestModel.requestBodyContentType.header; + } + + if (headers.isNotEmpty) { + var templateHeaders = jj.Template(kTemplateHeaders); + result += templateHeaders.render({"headers": headers}); + } + } + + if (hasBody || requestModel.hasFormData) { + result += kStringRequestBody; + } else if (hasJsonBody) { + result += kStringRequestJson; + } else { + result += kStringRequestNormal; + } + + result += kStringRequestEnd; + } + return result; + } catch (e) { + return null; + } + } +} diff --git a/lib/codegen/rust/reqwest.dart b/lib/codegen/rust/reqwest.dart new file mode 100644 index 00000000..4eb0accd --- /dev/null +++ b/lib/codegen/rust/reqwest.dart @@ -0,0 +1,180 @@ +import 'dart:io'; +import 'dart:convert'; +import 'package:jinja/jinja.dart' as jj; +import 'package:apidash/consts.dart'; +import 'package:apidash/utils/utils.dart' + show getValidRequestUri, stripUriParams; +import 'package:apidash/models/models.dart' show RequestModel; + +class RustReqwestCodeGen { + final String kTemplateStart = + """fn main() -> Result<(), Box> { + let client = reqwest::blocking::Client::new(); + let url = "{{url}}"; + +"""; + + String kTemplateParams = """\n .query(&{{params}})"""; + + String kTemplateBody = """ + + let payload = r#"{{body}}"#; + +"""; + + String kTemplateJson = """ + + let payload = serde_json::json!({{body}}); + +"""; + + String kTemplateHeaders = + """\n {% for key, val in headers -%}.header("{{key}}", "{{val}}"){% if not loop.last %}{{ '\n ' }}{% endif %}{%- endfor -%}"""; + + String kTemplateRequest = """ + + let response = client\n .{{method}}(url) +"""; + + final String kStringFormDataBody = r''' + + struct FormDataItem { + name: String, + value: String, + field_type: String, + } + + let form_data_items: Vec = vec![ + {%- for formitem in fields_list %} + FormDataItem { + {%- for key, val in formitem %} + {% if key == "type" %}field_type: "{{ val }}".to_string(),{% else %}{{ key }}: "{{ val }}".to_string(),{% endif %} + {%- endfor %} + }, + {%- endfor %} + ]; + + let mut form = reqwest::blocking::multipart::Form::new(); + + for item in form_data_items { + if item.field_type == "text" { + form = form.text(item.name, item.value); + } else if item.field_type == "file" { + form = form.file(item.name, &item.value)?; + } + } +'''; + + String kStringRequestBody = """\n .body(payload)"""; + + String kStringRequestJson = """\n .json(&payload)"""; + + String kStringRequestForm = """\n .multipart(form)"""; + + final String kStringRequestEnd = """\n .send()?; + + println!("Status Code: {}", response.status()); + println!("Response Body: {}", response.text()?); + + Ok(()) +} +"""; + + String? getCode( + RequestModel requestModel, + ) { + try { + String result = ""; + bool hasBody = false; + bool hasJsonBody = false; + + String url = requestModel.url; + + var rec = getValidRequestUri( + url, + requestModel.enabledRequestParams, + ); + Uri? uri = rec.$1; + if (uri != null) { + var templateStartUrl = jj.Template(kTemplateStart); + result += templateStartUrl.render({ + "url": stripUriParams(uri), + 'isFormDataRequest': requestModel.hasFormData, + 'isJson': requestModel.requestBodyContentType == ContentType.json + }); + + var method = requestModel.method; + var requestBody = requestModel.requestBody; + if (kMethodsWithBody.contains(method) && requestBody != null) { + var contentLength = utf8.encode(requestBody).length; + if (contentLength > 0) { + if (requestModel.requestBodyContentType == ContentType.json) { + hasJsonBody = true; + var templateBody = jj.Template(kTemplateJson); + result += templateBody.render({"body": requestBody}); + } else if (!requestModel.hasFormData) { + hasBody = true; + var templateBody = jj.Template(kTemplateBody); + result += templateBody.render({"body": requestBody}); + } + } + } + + if (requestModel.hasFormData) { + var formDataBodyData = jj.Template(kStringFormDataBody); + result += formDataBodyData.render( + { + "fields_list": requestModel.formDataMapList, + }, + ); + } + var templateRequest = jj.Template(kTemplateRequest); + result += templateRequest.render({ + "method": method.name.toLowerCase(), + }); + + if (uri.hasQuery) { + var params = uri.queryParameters; + if (params.isNotEmpty) { + var tupleStrings = params.entries + .map((entry) => '("${entry.key}", "${entry.value}")') + .toList(); + var paramsString = "[${tupleStrings.join(', ')}]"; + var templateParams = jj.Template(kTemplateParams); + result += templateParams.render({"params": paramsString}); + } + } + + var headersList = requestModel.enabledRequestHeaders; + if (headersList != null || hasBody) { + var headers = requestModel.enabledHeadersMap; + if (hasBody) { + headers[HttpHeaders.contentTypeHeader] = + requestModel.requestBodyContentType.header; + } + if (headers.isNotEmpty) { + var templateHeaders = jj.Template(kTemplateHeaders); + result += templateHeaders.render({"headers": headers}); + } + } + + if (hasBody && !requestModel.hasFormData) { + result += kStringRequestBody; + } + + if (hasJsonBody) { + result += kStringRequestJson; + } + + if (requestModel.hasFormData) { + result += kStringRequestForm; + } + + result += kStringRequestEnd; + } + return result; + } catch (e) { + return null; + } + } +} diff --git a/lib/codegen/rust/ureq.dart b/lib/codegen/rust/ureq.dart new file mode 100644 index 00000000..c1c170d2 --- /dev/null +++ b/lib/codegen/rust/ureq.dart @@ -0,0 +1,211 @@ +import 'dart:io'; +import 'dart:convert'; +import 'package:jinja/jinja.dart' as jj; +import 'package:apidash/consts.dart'; +import 'package:apidash/utils/utils.dart' + show getNewUuid, getValidRequestUri, stripUriParams; +import 'package:apidash/models/models.dart' show RequestModel; + +class RustUreqCodeGen { + final String kTemplateStart = """ +{%- if isFormDataRequest -%} +use std::io::Read; +{% endif -%} +fn main() -> Result<(), ureq::Error> { + let url = "{{url}}"; +"""; + + // String kTemplateParams = """\n .query_pairs({{ params }})"""; + String kTemplateParams = + """\n {% for key, val in params -%}.query("{{key}}", "{{val}}"){% if not loop.last %}{{ '\n ' }}{% endif %}{%- endfor -%}"""; + + String kTemplateBody = """ + + let payload = r#"{{body}}"#; + +"""; + + String kTemplateJson = """ + + let payload = ureq::json!({{body}}); + +"""; + + String kTemplateHeaders = + """\n {% for key, val in headers -%}.set("{{key}}", "{{val}}"){% if not loop.last %}{{ '\n ' }}{% endif %}{%- endfor -%}"""; + + String kTemplateFormHeaderContentType = ''' +multipart/form-data; boundary={{boundary}}'''; + + String kTemplateRequest = """ + + let response = ureq::{{method}}(url) +"""; + + final String kStringFormDataBody = r""" + + struct FormDataItem { + name: String, + value: String, + field_type: String, + } + + let form_data_items: Vec = vec![ + {%- for formitem in fields_list %} + FormDataItem { + {%- for key, val in formitem %} + {% if key == "type" %}field_type: "{{ val }}".to_string(),{% else %}{{ key }}: "{{ val }}".to_string(),{% endif %} + {%- endfor %} + }, + {%- endfor %} + ]; + + fn build_data_list(fields: Vec) -> Vec { + let mut data_list = Vec::new(); + + for field in fields { + data_list.extend_from_slice(b"--{{boundary}}\r\n"); + + if field.field_type == "text" { + data_list.extend_from_slice(format!("Content-Disposition: form-data; name=\"{}\"\r\n", field.name).as_bytes()); + data_list.extend_from_slice(b"Content-Type: text/plain\r\n\r\n"); + data_list.extend_from_slice(field.value.as_bytes()); + data_list.extend_from_slice(b"\r\n"); + } else if field.field_type == "file" { + data_list.extend_from_slice(format!("Content-Disposition: form-data; name=\"{}\"; filename=\"{}\"\r\n", field.name, field.value).as_bytes()); + + let mime_type = mime_guess::from_path(&field.value).first_or(mime_guess::mime::APPLICATION_OCTET_STREAM); + data_list.extend_from_slice(format!("Content-Type: {}\r\n\r\n", mime_type).as_bytes()); + + let mut file = std::fs::File::open(&field.value).unwrap(); + let mut file_contents = Vec::new(); + file.read_to_end(&mut file_contents).unwrap(); + data_list.extend_from_slice(&file_contents); + data_list.extend_from_slice(b"\r\n"); + } + } + + data_list.extend_from_slice(b"--{{boundary}}--\r\n"); + data_list + } + + let payload = build_data_list(form_data_items); +"""; + + String kStringRequestBody = """\n .send_string(payload)?;"""; + + String kStringRequestForm = """\n .send_bytes(&payload)?;"""; + + String kStringRequestJson = """\n .send_json(payload)?;"""; + + String kStringRequestNormal = """\n .call()?;"""; + + final String kStringRequestEnd = """\n + println!("Response Status: {}", response.status()); + println!("Response: {}", response.into_string()?); + + Ok(()) +} +"""; + + String? getCode( + RequestModel requestModel, { + String? boundary, + }) { + try { + String result = ""; + bool hasBody = false; + bool hasJsonBody = false; + String uuid = getNewUuid(); + + String url = requestModel.url; + + var rec = getValidRequestUri( + url, + requestModel.enabledRequestParams, + ); + Uri? uri = rec.$1; + if (uri != null) { + var templateStartUrl = jj.Template(kTemplateStart); + result += templateStartUrl.render({ + "url": stripUriParams(uri), + 'isFormDataRequest': requestModel.hasFormData, + "method": requestModel.method.name.toLowerCase() + }); + + var method = requestModel.method; + var requestBody = requestModel.requestBody; + if (kMethodsWithBody.contains(method) && requestBody != null) { + var contentLength = utf8.encode(requestBody).length; + if (contentLength > 0) { + if (requestModel.requestBodyContentType == ContentType.json) { + hasJsonBody = true; + var templateBody = jj.Template(kTemplateJson); + result += templateBody.render({"body": requestBody}); + } else if (!requestModel.hasFormData) { + hasBody = true; + var templateBody = jj.Template(kTemplateBody); + result += templateBody.render({"body": requestBody}); + } + } + } + + if (requestModel.hasFormData) { + var formDataBodyData = jj.Template(kStringFormDataBody); + result += formDataBodyData.render( + { + "fields_list": requestModel.formDataMapList, + "boundary": boundary ?? uuid, + }, + ); + } + var templateRequest = jj.Template(kTemplateRequest); + result += templateRequest.render({ + "method": method.name.toLowerCase(), + }); + + if (uri.hasQuery) { + var params = uri.queryParameters; + if (params.isNotEmpty) { + var templateParms = jj.Template(kTemplateParams); + result += templateParms.render({"params": params}); + } + } + + var headersList = requestModel.enabledRequestHeaders; + if (headersList != null || hasBody || requestModel.hasFormData) { + var headers = requestModel.enabledHeadersMap; + if (requestModel.hasFormData) { + var formHeaderTemplate = + jj.Template(kTemplateFormHeaderContentType); + headers[HttpHeaders.contentTypeHeader] = formHeaderTemplate.render({ + "boundary": boundary ?? uuid, + }); + } else if (hasBody) { + headers[HttpHeaders.contentTypeHeader] = + requestModel.requestBodyContentType.header; + } + + if (headers.isNotEmpty) { + var templateHeaders = jj.Template(kTemplateHeaders); + result += templateHeaders.render({"headers": headers}); + } + } + if (requestModel.hasFormData) { + result += kStringRequestForm; + } else if (hasBody) { + result += kStringRequestBody; + } else if (hasJsonBody) { + result += kStringRequestJson; + } else { + result += kStringRequestNormal; + } + + result += kStringRequestEnd; + } + return result; + } catch (e) { + return null; + } + } +} diff --git a/lib/consts.dart b/lib/consts.dart index 5c460043..c290d79c 100644 --- a/lib/consts.dart +++ b/lib/consts.dart @@ -8,6 +8,7 @@ import 'package:davi/davi.dart'; const kDiscordUrl = "https://bit.ly/heyfoss"; const kGitUrl = "https://github.com/foss42/apidash"; const kIssueUrl = "$kGitUrl/issues"; +const kDefaultUri = "api.apidash.dev"; final kIsMacOS = !kIsWeb && Platform.isMacOS; final kIsWindows = !kIsWeb && Platform.isWindows; @@ -90,6 +91,9 @@ const kP8CollectionPane = EdgeInsets.only( //right: 4.0, // bottom: 8.0, ); +const kPb10 = EdgeInsets.only( + bottom: 10, +); const kPr8CollectionPane = EdgeInsets.only(right: 8.0); const kpsV5 = EdgeInsets.symmetric(vertical: 2); const kHSpacer4 = SizedBox(width: 4); @@ -262,6 +266,7 @@ enum CodegenLanguage { har("HAR", "json", "har"), dartHttp("Dart (http)", "dart", "dart"), dartDio("Dart (dio)", "dart", "dart"), + goHttp("Go (http)", "go", "go"), jsAxios("JavaScript (axios)", "javascript", "js"), jsFetch("JavaScript (fetch)", "javascript", "js"), nodejsAxios("node.js (axios)", "javascript", "js"), @@ -269,8 +274,13 @@ enum CodegenLanguage { kotlinOkHttp("Kotlin (okhttp3)", "java", "kt"), pythonHttpClient("Python (http.client)", "python", "py"), pythonRequests("Python (requests)", "python", "py"), + rustActix("Rust (Actix Client)", "rust", "rs"), + rustReqwest("Rust (reqwest)", "rust", "rs"), + rustUreq("Rust (ureq)", "rust", "rs"), + javaOkHttp("Java (okhttp3)", "java", 'java'), + javaAsyncHttpClient("Java (async-http-client)", "java", "java"), javaHttpClient("Java (HttpClient)", "java", "java") - ; + juliaHttp("Julia (HTTP)", "julia", "jl"); const CodegenLanguage(this.label, this.codeHighlightLang, this.ext); final String label; @@ -281,6 +291,8 @@ enum CodegenLanguage { const JsonEncoder kEncoder = JsonEncoder.withIndent(' '); const LineSplitter kSplitter = LineSplitter(); +const kHeaderContentType = "Content-Type"; + const kTypeApplication = 'application'; // application const kSubTypeJson = 'json'; @@ -311,12 +323,15 @@ const kSubTypeSvg = 'svg+xml'; const kTypeAudio = 'audio'; const kTypeVideo = 'video'; +const kTypeMultipart = "multipart"; +const kSubTypeFormData = "form-data"; + const kSubTypeDefaultViewOptions = 'all'; enum ContentType { json("$kTypeApplication/$kSubTypeJson"), text("$kTypeText/$kSubTypePlain"), - formdata("multipart/form-data"); + formdata("$kTypeMultipart/$kSubTypeFormData"); const ContentType(this.header); final String header; @@ -377,6 +392,7 @@ const Map>> kSubTypeDefaultViewOptions: kRawBodyViewOptions, kSubTypeCss: kCodeRawBodyViewOptions, kSubTypeHtml: kCodeRawBodyViewOptions, + kSubTypeCsv: kPreviewRawBodyViewOptions, kSubTypeJavascript: kCodeRawBodyViewOptions, kSubTypeMarkdown: kCodeRawBodyViewOptions, kSubTypeTextXml: kCodeRawBodyViewOptions, @@ -494,7 +510,10 @@ const kAudioError = const kRaiseIssue = "\nPlease raise an issue in API Dash GitHub repo so that we can resolve it."; -const kHintTextUrlCard = "Enter API endpoint like api.foss42.com/country/codes"; +const kCsvError = + "There seems to be an issue rendering this CSV. Please raise an issue in API Dash GitHub repo so that we can resolve it."; + +const kHintTextUrlCard = "Enter API endpoint like https://$kDefaultUri/"; const kLabelPlusNew = "+ New"; const kLabelSend = "Send"; const kLabelSending = "Sending.."; diff --git a/lib/models/request_model.dart b/lib/models/request_model.dart index 9154e428..8a1fea7e 100644 --- a/lib/models/request_model.dart +++ b/lib/models/request_model.dart @@ -1,4 +1,5 @@ import 'dart:io'; +import 'dart:convert'; import 'package:flutter/foundation.dart'; import '../utils/utils.dart' show @@ -29,6 +30,7 @@ class RequestModel { this.responseStatus, this.message, this.responseModel, + this.isWorking = false, }); final String id; @@ -47,6 +49,7 @@ class RequestModel { final int? responseStatus; final String? message; final ResponseModel? responseModel; + final bool isWorking; List? get enabledRequestHeaders => getEnabledRows(requestHeaders, isHeaderEnabledList); @@ -60,9 +63,31 @@ class RequestModel { Map get headersMap => rowsToMap(requestHeaders) ?? {}; Map get paramsMap => rowsToMap(requestParams) ?? {}; + bool get hasFormDataContentType => + requestBodyContentType == ContentType.formdata; + bool get hasJsonContentType => requestBodyContentType == ContentType.json; + bool get hasTextContentType => requestBodyContentType == ContentType.text; + int get contentLength => utf8.encode(requestBody ?? "").length; + bool get hasData => hasJsonData || hasTextData || hasFormData; + bool get hasJsonData => + kMethodsWithBody.contains(method) && + hasJsonContentType && + contentLength > 0; + bool get hasTextData => + kMethodsWithBody.contains(method) && + hasTextContentType && + contentLength > 0; + bool get hasFormData => + kMethodsWithBody.contains(method) && + hasFormDataContentType && + (requestFormDataList ?? []).isNotEmpty; + List get formDataList => + requestFormDataList ?? []; List> get formDataMapList => rowsToFormDataMapList(requestFormDataList) ?? []; - bool get isFormDataRequest => requestBodyContentType == ContentType.formdata; + bool get hasFileInFormData => formDataList + .map((e) => e.type == FormDataType.file) + .any((element) => element); bool get hasContentTypeHeader => enabledHeadersMap.keys .any((k) => k.toLowerCase() == HttpHeaders.contentTypeHeader); @@ -106,6 +131,7 @@ class RequestModel { int? responseStatus, String? message, ResponseModel? responseModel, + bool? isWorking, }) { var headers = requestHeaders ?? this.requestHeaders; var params = requestParams ?? this.requestParams; @@ -129,6 +155,7 @@ class RequestModel { responseStatus: responseStatus ?? this.responseStatus, message: message ?? this.message, responseModel: responseModel ?? this.responseModel, + isWorking: isWorking ?? this.isWorking, ); } diff --git a/lib/providers/collection_providers.dart b/lib/providers/collection_providers.dart index 0432b0e4..4ecc51ab 100644 --- a/lib/providers/collection_providers.dart +++ b/lib/providers/collection_providers.dart @@ -3,7 +3,7 @@ import 'settings_providers.dart'; import 'ui_providers.dart'; import '../models/models.dart'; import '../services/services.dart' show hiveHandler, HiveHandler, request; -import '../utils/utils.dart' show uuid, collectionToHAR; +import '../utils/utils.dart' show getNewUuid, collectionToHAR; import '../consts.dart'; import 'package:http/http.dart' as http; @@ -54,7 +54,7 @@ class CollectionStateNotifier } void add() { - final id = uuid.v1(); + final id = getNewUuid(); final newRequestModel = RequestModel( id: id, ); @@ -97,7 +97,7 @@ class CollectionStateNotifier } void duplicate(String id) { - final newId = uuid.v1(); + final newId = getNewUuid(); var itemIds = ref.read(requestSequenceProvider); int idx = itemIds.indexOf(id); @@ -156,22 +156,30 @@ class CollectionStateNotifier } Future sendRequest(String id) async { - ref.read(sentRequestIdStateProvider.notifier).state = id; ref.read(codePaneVisibleStateProvider.notifier).state = false; - final defaultUriScheme = - ref.read(settingsProvider.select((value) => value.defaultUriScheme)); + final defaultUriScheme = ref.read( + settingsProvider.select( + (value) => value.defaultUriScheme, + ), + ); + RequestModel requestModel = state![id]!; + + // set current model's isWorking to true and update state + var map = {...state!}; + map[id] = requestModel.copyWith(isWorking: true); + state = map; + (http.Response?, Duration?, String?)? responseRec = await request( requestModel, defaultUriScheme: defaultUriScheme, - isMultiPartRequest: - requestModel.requestBodyContentType == ContentType.formdata, ); late final RequestModel newRequestModel; if (responseRec.$1 == null) { newRequestModel = requestModel.copyWith( responseStatus: -1, message: responseRec.$3, + isWorking: false, ); } else { final responseModel = baseResponseModel.fromResponse( @@ -183,10 +191,12 @@ class CollectionStateNotifier responseStatus: statusCode, message: kResponseCodeReasons[statusCode], responseModel: responseModel, + isWorking: false, ); } - ref.read(sentRequestIdStateProvider.notifier).state = null; - var map = {...state!}; + + // update state with response data + map = {...state!}; map[id] = newRequestModel; state = map; } @@ -203,7 +213,7 @@ class CollectionStateNotifier bool loadData() { var ids = hiveHandler.getIds(); if (ids == null || ids.length == 0) { - String newId = uuid.v1(); + String newId = getNewUuid(); state = { newId: RequestModel( id: newId, diff --git a/lib/providers/ui_providers.dart b/lib/providers/ui_providers.dart index ef576974..2fddb2ad 100644 --- a/lib/providers/ui_providers.dart +++ b/lib/providers/ui_providers.dart @@ -3,7 +3,6 @@ import 'package:flutter_riverpod/flutter_riverpod.dart'; final navRailIndexStateProvider = StateProvider((ref) => 0); final selectedIdEditStateProvider = StateProvider((ref) => null); -final sentRequestIdStateProvider = StateProvider((ref) => null); final codePaneVisibleStateProvider = StateProvider((ref) => false); final saveDataStateProvider = StateProvider((ref) => false); final clearDataStateProvider = StateProvider((ref) => false); diff --git a/lib/screens/home_page/editor_pane/details_card/response_pane.dart b/lib/screens/home_page/editor_pane/details_card/response_pane.dart index e7fc9f09..548d17a8 100644 --- a/lib/screens/home_page/editor_pane/details_card/response_pane.dart +++ b/lib/screens/home_page/editor_pane/details_card/response_pane.dart @@ -9,13 +9,14 @@ class ResponsePane extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { - final selectedId = ref.watch(selectedIdStateProvider); - final sentRequestId = ref.watch(sentRequestIdStateProvider); + final isWorking = ref.watch( + selectedRequestModelProvider.select((value) => value?.isWorking)) ?? + false; final responseStatus = ref.watch( selectedRequestModelProvider.select((value) => value?.responseStatus)); final message = ref .watch(selectedRequestModelProvider.select((value) => value?.message)); - if (sentRequestId != null && sentRequestId == selectedId) { + if (isWorking) { return const SendingWidget(); } if (responseStatus == null) { diff --git a/lib/screens/home_page/editor_pane/editor_request.dart b/lib/screens/home_page/editor_pane/editor_request.dart index ce567483..90a60349 100644 --- a/lib/screens/home_page/editor_pane/editor_request.dart +++ b/lib/screens/home_page/editor_pane/editor_request.dart @@ -1,4 +1,6 @@ import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:apidash/providers/collection_providers.dart'; import 'package:apidash/consts.dart'; import 'details_card/details_card.dart'; import 'url_card.dart'; @@ -10,6 +12,7 @@ class RequestEditor extends StatelessWidget { Widget build(BuildContext context) { return const Column( children: [ + RequestEditorTopBar(), EditorPaneRequestURLCard(), kVSpacer10, Expanded( @@ -19,3 +22,91 @@ class RequestEditor extends StatelessWidget { ); } } + +class RequestEditorTopBar extends ConsumerWidget { + const RequestEditorTopBar({super.key}); + + @override + Widget build(BuildContext context, WidgetRef ref) { + final id = ref.watch(selectedIdStateProvider); + final name = + ref.watch(selectedRequestModelProvider.select((value) => value?.name)); + return Padding( + padding: const EdgeInsets.only( + left: 12.0, + top: 4.0, + right: 8.0, + bottom: 4.0, + ), + child: Row( + children: [ + Expanded( + child: Text( + name ?? "", + style: Theme.of(context).textTheme.bodyMedium, + overflow: TextOverflow.ellipsis, + maxLines: 1, + ), + ), + const SizedBox( + width: 6, + ), + SizedBox( + width: 90, + height: 24, + child: FilledButton.tonalIcon( + style: const ButtonStyle( + padding: MaterialStatePropertyAll(EdgeInsets.zero), + ), + onPressed: () { + showDialog( + context: context, + builder: (context) { + final controller = + TextEditingController(text: name ?? ""); + controller.selection = TextSelection( + baseOffset: 0, extentOffset: controller.text.length); + return AlertDialog( + title: const Text('Rename Request'), + content: TextField( + autofocus: true, + controller: controller, + decoration: + const InputDecoration(hintText: "Enter new name"), + ), + actions: [ + OutlinedButton( + onPressed: () { + Navigator.pop(context); + }, + child: const Text('CANCEL')), + FilledButton( + onPressed: () { + final val = controller.text.trim(); + ref + .read(collectionStateNotifierProvider + .notifier) + .update(id!, name: val); + Navigator.pop(context); + controller.dispose(); + }, + child: const Text('OK')), + ], + ); + }); + }, + icon: const Icon( + Icons.edit, + size: 12, + ), + label: Text( + "Rename", + style: Theme.of(context).textTheme.bodySmall, + ), + ), + ) + ], + ), + ); + } +} diff --git a/lib/screens/home_page/editor_pane/url_card.dart b/lib/screens/home_page/editor_pane/url_card.dart index 5fa4b404..012d067c 100644 --- a/lib/screens/home_page/editor_pane/url_card.dart +++ b/lib/screens/home_page/editor_pane/url_card.dart @@ -81,6 +81,11 @@ class URLTextField extends ConsumerWidget { .read(collectionStateNotifierProvider.notifier) .update(selectedId, url: value); }, + onFieldSubmitted: (value) { + ref + .read(collectionStateNotifierProvider.notifier) + .sendRequest(selectedId); + }, ); } } @@ -93,10 +98,11 @@ class SendButton extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { final selectedId = ref.watch(selectedIdStateProvider); - final sentRequestId = ref.watch(sentRequestIdStateProvider); + final isWorking = ref.watch( + selectedRequestModelProvider.select((value) => value?.isWorking)); + return SendRequestButton( - selectedId: selectedId, - sentRequestId: sentRequestId, + isWorking: isWorking ?? false, onTap: () { ref .read(collectionStateNotifierProvider.notifier) diff --git a/lib/screens/settings_page.dart b/lib/screens/settings_page.dart index d979af80..fde7dce7 100644 --- a/lib/screens/settings_page.dart +++ b/lib/screens/settings_page.dart @@ -61,11 +61,11 @@ class SettingsPage extends ConsumerWidget { }, ), ListTile( - contentPadding: EdgeInsets.zero, + contentPadding: kPb10, hoverColor: kColorTransparent, title: const Text('Default URI Scheme'), subtitle: Text( - 'api.foss42.com → ${settings.defaultUriScheme}://api.foss42.com'), + '$kDefaultUri → ${settings.defaultUriScheme}://$kDefaultUri'), trailing: DropdownMenu( onSelected: (value) { ref @@ -82,7 +82,7 @@ class SettingsPage extends ConsumerWidget { }).toList()), ), ListTile( - contentPadding: EdgeInsets.zero, + contentPadding: kPb10, hoverColor: kColorTransparent, title: const Text('Default Code Generator'), trailing: DropdownMenu( diff --git a/lib/services/http_service.dart b/lib/services/http_service.dart index c5a7b4ce..dec0b516 100644 --- a/lib/services/http_service.dart +++ b/lib/services/http_service.dart @@ -9,7 +9,6 @@ import 'package:apidash/consts.dart'; Future<(http.Response?, Duration?, String?)> request( RequestModel requestModel, { String defaultUriScheme = kDefaultUriScheme, - bool isMultiPartRequest = false, }) async { (Uri?, String?) uriRec = getValidRequestUri( requestModel.url, @@ -22,44 +21,48 @@ Future<(http.Response?, Duration?, String?)> request( http.Response response; String? body; try { - var requestBody = requestModel.requestBody; - if (kMethodsWithBody.contains(requestModel.method) && - requestBody != null) { - var contentLength = utf8.encode(requestBody).length; - if (contentLength > 0) { - body = requestBody; - headers[HttpHeaders.contentLengthHeader] = contentLength.toString(); - if (!requestModel.hasContentTypeHeader) { - headers[HttpHeaders.contentTypeHeader] = - requestModel.requestBodyContentType.header; - } - } - } Stopwatch stopwatch = Stopwatch()..start(); - if (isMultiPartRequest) { - var multiPartRequest = http.MultipartRequest( - requestModel.method.name.toUpperCase(), - requestUrl, - ); - multiPartRequest.headers.addAll(headers); - for (FormDataModel formData - in (requestModel.requestFormDataList ?? [])) { - if (formData.type == FormDataType.text) { - multiPartRequest.fields.addAll({formData.name: formData.value}); - } else { - multiPartRequest.files.add( - await http.MultipartFile.fromPath( - formData.name, - formData.value, - ), - ); + var isMultiPartRequest = + requestModel.requestBodyContentType == ContentType.formdata; + if (kMethodsWithBody.contains(requestModel.method)) { + var requestBody = requestModel.requestBody; + if (requestBody != null && !isMultiPartRequest) { + var contentLength = utf8.encode(requestBody).length; + if (contentLength > 0) { + body = requestBody; + headers[HttpHeaders.contentLengthHeader] = contentLength.toString(); + if (!requestModel.hasContentTypeHeader) { + headers[HttpHeaders.contentTypeHeader] = + requestModel.requestBodyContentType.header; + } } } - http.StreamedResponse multiPartResponse = await multiPartRequest.send(); - stopwatch.stop(); - http.Response convertedMultiPartResponse = - await convertStreamedResponse(multiPartResponse); - return (convertedMultiPartResponse, stopwatch.elapsed, null); + if (isMultiPartRequest) { + var multiPartRequest = http.MultipartRequest( + requestModel.method.name.toUpperCase(), + requestUrl, + ); + multiPartRequest.headers.addAll(headers); + for (var formData + in (requestModel.requestFormDataList ?? [])) { + if (formData.type == FormDataType.text) { + multiPartRequest.fields.addAll({formData.name: formData.value}); + } else { + multiPartRequest.files.add( + await http.MultipartFile.fromPath( + formData.name, + formData.value, + ), + ); + } + } + http.StreamedResponse multiPartResponse = + await multiPartRequest.send(); + stopwatch.stop(); + http.Response convertedMultiPartResponse = + await convertStreamedResponse(multiPartResponse); + return (convertedMultiPartResponse, stopwatch.elapsed, null); + } } switch (requestModel.method) { case HTTPVerb.get: diff --git a/lib/utils/file_utils.dart b/lib/utils/file_utils.dart index 69306b7f..68554153 100644 --- a/lib/utils/file_utils.dart +++ b/lib/utils/file_utils.dart @@ -43,13 +43,18 @@ String getShortPath(String path) { var f = p.split(path); if (f.length > 2) { f = f.sublist(f.length - 2); - return ".../${p.joinAll(f)}"; + return p.join("...", p.joinAll(f)); } return path; } +String getFilenameFromPath(String path) { + var f = p.split(path); + return f.last; +} + String getTempFileName() { - return uuid.v1(); + return getNewUuid(); } Future pickFile() async { diff --git a/lib/utils/har_utils.dart b/lib/utils/har_utils.dart index 38913c6e..86ada7fe 100644 --- a/lib/utils/har_utils.dart +++ b/lib/utils/har_utils.dart @@ -1,6 +1,10 @@ +// http://www.softwareishard.com/blog/har-12-spec/ +// https://github.com/ahmadnassri/har-spec/blob/master/versions/1.2.md + import 'dart:convert'; import 'package:apidash/consts.dart'; -import 'package:apidash/utils/utils.dart' show getValidRequestUri; +import 'package:apidash/utils/utils.dart' + show getValidRequestUri, getNewUuid, getFilenameFromPath; import 'package:apidash/models/models.dart' show RequestModel; import 'package:package_info_plus/package_info_plus.dart'; @@ -75,6 +79,7 @@ Map requestModelToHARJsonRequest( defaultUriScheme = kDefaultUriScheme, bool exportMode = false, bool useEnabled = false, + String? boundary, }) { Map json = {}; bool hasBody = false; @@ -110,19 +115,37 @@ Map requestModelToHARJsonRequest( } } - var method = requestModel.method; - var requestBody = requestModel.requestBody; - if (kMethodsWithBody.contains(method) && requestBody != null) { - var contentLength = utf8.encode(requestBody).length; - if (contentLength > 0) { - hasBody = true; - json["postData"] = {}; - json["postData"]["mimeType"] = - requestModel.requestBodyContentType.header; - json["postData"]["text"] = requestBody; - if (exportMode) { - json["postData"]["comment"] = ""; + if (requestModel.hasJsonData || requestModel.hasTextData) { + hasBody = true; + json["postData"] = {}; + json["postData"]["mimeType"] = requestModel.requestBodyContentType.header; + json["postData"]["text"] = requestModel.requestBody; + if (exportMode) { + json["postData"]["comment"] = ""; + } + } + + if (requestModel.hasFormData) { + boundary = boundary ?? getNewUuid(); + hasBody = true; + json["postData"] = {}; + json["postData"]["mimeType"] = + "${requestModel.requestBodyContentType.header}; boundary=$boundary"; + json["postData"]["params"] = []; + for (var item in requestModel.formDataList) { + Map d = exportMode ? {"comment": ""} : {}; + if (item.type == FormDataType.text) { + d["name"] = item.name; + d["value"] = item.value; } + if (item.type == FormDataType.file) { + d["name"] = item.name; + d["fileName"] = getFilenameFromPath(item.value); + } + json["postData"]["params"].add(d); + } + if (exportMode) { + json["postData"]["comment"] = ""; } } @@ -135,8 +158,8 @@ Map requestModelToHARJsonRequest( if (headers.isNotEmpty || hasBody) { if (hasBody && !requestModel.hasContentTypeHeader) { var m = { - "name": "Content-Type", - "value": requestModel.requestBodyContentType.header + "name": kHeaderContentType, + "value": json["postData"]["mimeType"] }; if (exportMode) { m["comment"] = ""; @@ -152,14 +175,12 @@ Map requestModelToHARJsonRequest( } } } - if (requestModel.isFormDataRequest) { - json["formData"] = requestModel.formDataMapList; - } if (exportMode) { json["comment"] = ""; json["cookies"] = []; json["headersSize"] = -1; - json["bodySize"] = hasBody ? utf8.encode(requestBody!).length : 0; + json["bodySize"] = + hasBody ? utf8.encode(json["postData"]["text"] ?? "").length : 0; } } return json; diff --git a/lib/utils/header_utils.dart b/lib/utils/header_utils.dart index 45a24fe9..1450cc01 100644 --- a/lib/utils/header_utils.dart +++ b/lib/utils/header_utils.dart @@ -2,6 +2,7 @@ Map headers = { "Accept": "Specifies the media types that are acceptable for the response.", "Accept-Encoding": "Indicates the encoding methods the client can understand.", + "Accept-Charset": "Specifies the character sets that are acceptable.", "Access-Control-Allow-Headers": "Specifies a list of HTTP headers that can be used in an actual request after a preflight request including the Access-Control-Request-Headers header is made.", "Access-Control-Allow-Methods": @@ -41,11 +42,16 @@ Map headers = { "Cross-Origin-Resource-Policy": "Controls how cross-origin requests for resources are handled.", "Date": "Indicates the date and time at which the message was sent.", + "Device-Memory": + "Indicates the approximate amount of device memory in gigabytes.", "DNT": "Informs websites whether the user's preference is to opt out of online tracking.", "Expect": "Indicates certain expectations that need to be met by the server.", "Expires": "Contains the date/time after which the response is considered expired", + "Forwarded": + "Contains information from the client-facing side of proxy servers that is altered or lost when a proxy is involved in the path of the request.", + "From": "Contains an Internet email address for a human user who controls the requesting user agent.", "Host": "Specifies the domain name of the server and the port number.", "If-Match": "Used for conditional requests, allows the server to respond based on certain conditions.", @@ -57,9 +63,15 @@ Map headers = { "Used in conjunction with the Range header to conditionally request a partial resource.", "If-Unmodified-Since": "Used for conditional requests, allows the server to respond based on certain conditions.", + "Keep-Alive": + "Used to allow the connection to be reused for further requests.", "Location": "Indicates the URL a client should redirect to for further interaction.", + "Max-Forwards": + "Indicates the remaining number of times a request can be forwarded by proxies.", "Origin": "Specifies the origin of a cross-origin request.", + "Proxy-Authorization": + "Contains credentials for authenticating a client with a proxy server.", "Range": "Used to request only part of a resource, typically in the context of downloading large files.", "Referer": @@ -68,10 +80,14 @@ Map headers = { "Specifies how much information the browser should include in the Referer header when navigating to other pages.", "Retry-After": "Informs the client how long it should wait before making another request after a server has responded with a rate-limiting status code.", + "Save-Data": + "Indicates the client's preference for reduced data usage.", "Server": "Indicates the software used by the origin server.", "Strict-Transport-Security": "Instructs the browser to always use HTTPS for the given domain.", "TE": "Specifies the transfer encodings that are acceptable to the client.", + "Upgrade-Insecure-Requests": + "Instructs the browser to prefer secure connections when available.", "User-Agent": "Identifies the client software and version making the request.", "Via": diff --git a/lib/widgets/buttons.dart b/lib/widgets/buttons.dart index 2d63ede7..f9baf0c4 100644 --- a/lib/widgets/buttons.dart +++ b/lib/widgets/buttons.dart @@ -47,36 +47,37 @@ class CopyButton extends StatelessWidget { class SendRequestButton extends StatelessWidget { const SendRequestButton({ super.key, - required this.selectedId, - required this.sentRequestId, + required this.isWorking, required this.onTap, }); - final String? selectedId; - final String? sentRequestId; + final bool isWorking; final void Function() onTap; @override Widget build(BuildContext context) { - bool disable = sentRequestId != null; return FilledButton( - onPressed: disable ? null : onTap, + onPressed: isWorking ? null : onTap, child: Row( mainAxisSize: MainAxisSize.min, - children: [ - Text( - disable - ? (selectedId == sentRequestId ? kLabelSending : kLabelBusy) - : kLabelSend, - style: kTextStyleButton, - ), - if (!disable) kHSpacer10, - if (!disable) - const Icon( - size: 16, - Icons.send, - ), - ], + children: isWorking + ? const [ + Text( + kLabelSending, + style: kTextStyleButton, + ), + ] + : const [ + Text( + kLabelSend, + style: kTextStyleButton, + ), + kHSpacer10, + Icon( + size: 16, + Icons.send, + ), + ], ), ); } diff --git a/lib/widgets/cards.dart b/lib/widgets/cards.dart index 740ddbc8..943227ce 100644 --- a/lib/widgets/cards.dart +++ b/lib/widgets/cards.dart @@ -97,6 +97,9 @@ class SidebarRequestCard extends StatelessWidget { onTapOutsideNameEditor?.call(); //FocusScope.of(context).unfocus(); }, + onFieldSubmitted: (value) { + onTapOutsideNameEditor?.call(); + }, onChanged: onChangedNameEditor, decoration: const InputDecoration( isCollapsed: true, diff --git a/lib/widgets/csv_previewer.dart b/lib/widgets/csv_previewer.dart new file mode 100644 index 00000000..17e8dd48 --- /dev/null +++ b/lib/widgets/csv_previewer.dart @@ -0,0 +1,53 @@ +import 'package:flutter/material.dart'; +import 'package:csv/csv.dart'; +import 'error_message.dart'; +import '../consts.dart'; + +class CsvPreviewer extends StatelessWidget { + const CsvPreviewer({super.key, required this.body}); + + final String body; + + @override + Widget build(BuildContext context) { + try { + final List> csvData = + const CsvToListConverter().convert(body, eol: '\n'); + return SingleChildScrollView( + scrollDirection: Axis.vertical, + child: SingleChildScrollView( + scrollDirection: Axis.horizontal, + child: DataTable( + columns: csvData[0] + .map( + (item) => DataColumn( + label: Text( + item.toString(), + ), + ), + ) + .toList(), + rows: csvData + .skip(1) + .map( + (csvrow) => DataRow( + cells: csvrow + .map( + (csvItem) => DataCell( + Text( + csvItem.toString(), + ), + ), + ) + .toList(), + ), + ) + .toList(), + ), + ), + ); + } catch (e) { + return const ErrorMessage(message: kCsvError); + } + } +} diff --git a/lib/widgets/form_data_field.dart b/lib/widgets/form_data_field.dart index eb4c8862..29f210c4 100644 --- a/lib/widgets/form_data_field.dart +++ b/lib/widgets/form_data_field.dart @@ -46,32 +46,34 @@ class _FormDataFieldState extends State { color: colorScheme.onSurface, ), decoration: InputDecoration( - hintStyle: kCodeStyle.copyWith( - color: colorScheme.outline.withOpacity( + hintStyle: kCodeStyle.copyWith( + color: colorScheme.outline.withOpacity( + kHintOpacity, + ), + ), + hintText: widget.hintText, + contentPadding: const EdgeInsets.only(bottom: 16), + focusedBorder: UnderlineInputBorder( + borderSide: BorderSide( + color: colorScheme.primary.withOpacity( kHintOpacity, ), ), - hintText: widget.hintText, - focusedBorder: UnderlineInputBorder( - borderSide: BorderSide( - color: colorScheme.primary.withOpacity( - kHintOpacity, - ), - ), + ), + enabledBorder: UnderlineInputBorder( + borderSide: BorderSide( + color: colorScheme.surfaceVariant, ), - enabledBorder: UnderlineInputBorder( - borderSide: BorderSide( - color: colorScheme.surfaceVariant, - ), - ), - suffixIcon: DropdownButtonFormData( - formDataType: widget.formDataType, - onChanged: (p0) { - if (widget.onFormDataTypeChanged != null) { - widget.onFormDataTypeChanged!(p0); - } - }, - )), + ), + suffixIcon: DropdownButtonFormData( + formDataType: widget.formDataType, + onChanged: (p0) { + if (widget.onFormDataTypeChanged != null) { + widget.onFormDataTypeChanged!(p0); + } + }, + ), + ), onChanged: widget.onChanged, ), ), diff --git a/lib/widgets/headerfield.dart b/lib/widgets/headerfield.dart index 9c678ee3..5bce6c8f 100644 --- a/lib/widgets/headerfield.dart +++ b/lib/widgets/headerfield.dart @@ -1,6 +1,6 @@ +import 'package:apidash/consts.dart'; import 'package:apidash/utils/header_utils.dart'; import 'package:flutter/material.dart'; -import 'package:apidash/consts.dart'; import 'package:flutter_typeahead/flutter_typeahead.dart'; class HeaderField extends StatefulWidget { @@ -41,6 +41,7 @@ class _HeaderFieldState extends State { @override void didUpdateWidget(HeaderField oldWidget) { + super.didUpdateWidget(oldWidget); if (oldWidget.initialValue != widget.initialValue) { controller.text = widget.initialValue ?? ""; controller.selection = @@ -54,8 +55,8 @@ class _HeaderFieldState extends State { return TypeAheadField( key: Key(widget.keyId), hideOnEmpty: true, - minCharsForSuggestions: 1, - onSuggestionSelected: (value) { + controller: controller, + onSelected: (value) { setState(() { controller.text = value; }); @@ -68,19 +69,17 @@ class _HeaderFieldState extends State { ); }, suggestionsCallback: headerSuggestionCallback, - suggestionsBoxDecoration: suggestionBoxDecorations(context), - textFieldConfiguration: TextFieldConfiguration( + decorationBuilder: (context, child) => + suggestionBoxDecorations(context, child, colorScheme), + constraints: const BoxConstraints(maxHeight: 400), + builder: (context, controller, focusNode) => TextField( onChanged: widget.onChanged, controller: controller, - style: kCodeStyle.copyWith( - color: colorScheme.onSurface, - ), + focusNode: focusNode, + style: kCodeStyle.copyWith(color: colorScheme.onSurface), decoration: InputDecoration( hintStyle: kCodeStyle.copyWith( - color: colorScheme.outline.withOpacity( - kHintOpacity, - ), - ), + color: colorScheme.outline.withOpacity(kHintOpacity)), hintText: widget.hintText, focusedBorder: UnderlineInputBorder( borderSide: BorderSide( @@ -99,22 +98,26 @@ class _HeaderFieldState extends State { ); } - SuggestionsBoxDecoration suggestionBoxDecorations(BuildContext context) { - return SuggestionsBoxDecoration( - elevation: 4, - constraints: const BoxConstraints(maxHeight: 400), - shape: RoundedRectangleBorder( - side: BorderSide( - color: Theme.of(context).dividerColor, - width: 1.2, + Theme suggestionBoxDecorations( + BuildContext context, Widget child, ColorScheme colorScheme) { + return Theme( + data: ThemeData(colorScheme: colorScheme), + child: Material( + elevation: 4, + shape: RoundedRectangleBorder( + side: BorderSide(color: Theme.of(context).dividerColor, width: 1.2), + borderRadius: const BorderRadius.vertical(bottom: Radius.circular(8)), ), - borderRadius: const BorderRadius.vertical(bottom: Radius.circular(8)), + clipBehavior: Clip.hardEdge, + child: child, ), - clipBehavior: Clip.hardEdge, ); } - Future> headerSuggestionCallback(String pattern) async { + Future?> headerSuggestionCallback(String pattern) async { + if (pattern.isEmpty) { + return null; + } return getHeaderSuggestions(pattern); } } diff --git a/lib/widgets/intro_message.dart b/lib/widgets/intro_message.dart index 970596d3..7e7ff2e0 100644 --- a/lib/widgets/intro_message.dart +++ b/lib/widgets/intro_message.dart @@ -23,6 +23,9 @@ class IntroMessage extends StatelessWidget { return FutureBuilder( future: introData(), builder: (BuildContext context, AsyncSnapshot snapshot) { + if (snapshot.hasError) { + return const ErrorMessage(message: "An error occured"); + } if (snapshot.connectionState == ConnectionState.done) { if (Theme.of(context).brightness == Brightness.dark) { text = text.replaceAll("{{mode}}", "dark"); @@ -37,9 +40,6 @@ class IntroMessage extends StatelessWidget { padding: kPh60, ); } - if (snapshot.hasError) { - return const ErrorMessage(message: "An error occured"); - } return const Center(child: CircularProgressIndicator()); }, ); diff --git a/lib/widgets/json_previewer.dart b/lib/widgets/json_previewer.dart index 078a9721..46d066bf 100644 --- a/lib/widgets/json_previewer.dart +++ b/lib/widgets/json_previewer.dart @@ -154,6 +154,7 @@ class _JsonPreviewerState extends State { @override void didUpdateWidget(JsonPreviewer oldWidget) { + super.didUpdateWidget(oldWidget); if (oldWidget.code != widget.code) { store.buildNodes(widget.code, areAllCollapsed: true); store.expandAll(); diff --git a/lib/widgets/markdown.dart b/lib/widgets/markdown.dart index c1467fba..ce06efa0 100644 --- a/lib/widgets/markdown.dart +++ b/lib/widgets/markdown.dart @@ -9,9 +9,12 @@ class CustomMarkdown extends StatelessWidget { super.key, required this.data, this.padding = const EdgeInsets.all(16.0), + this.onTapLink, }); + final String data; final EdgeInsets padding; + final void Function(String text, String? href, String title)? onTapLink; @override Widget build(BuildContext context) { @@ -25,9 +28,10 @@ class CustomMarkdown extends StatelessWidget { data: data, selectable: true, extensionSet: md.ExtensionSet.gitHubFlavored, - onTapLink: (text, href, title) { - launchUrl(Uri.parse(href ?? "")); - }, + onTapLink: onTapLink ?? + (text, href, title) { + launchUrl(Uri.parse(href ?? "")); + }, builders: { "inlineButton": InlineButton(), }, diff --git a/lib/widgets/previewer.dart b/lib/widgets/previewer.dart index 9841ac5b..dd2f5186 100644 --- a/lib/widgets/previewer.dart +++ b/lib/widgets/previewer.dart @@ -7,6 +7,7 @@ import 'package:vector_graphics_compiler/vector_graphics_compiler.dart'; import 'error_message.dart'; import 'uint8_audio_player.dart'; import 'json_previewer.dart'; +import 'csv_previewer.dart'; import '../consts.dart'; class Previewer extends StatefulWidget { @@ -81,6 +82,9 @@ class _PreviewerState extends State { }, ); } + if (widget.type == kTypeText && widget.subtype == kSubTypeCsv) { + return CsvPreviewer(body: widget.body); + } if (widget.type == kTypeVideo) { // TODO: Video Player } diff --git a/lib/widgets/textfields.dart b/lib/widgets/textfields.dart index c288b0a6..da68f9e2 100644 --- a/lib/widgets/textfields.dart +++ b/lib/widgets/textfields.dart @@ -7,11 +7,13 @@ class URLField extends StatelessWidget { required this.selectedId, this.initialValue, this.onChanged, + this.onFieldSubmitted, }); final String selectedId; final String? initialValue; final void Function(String)? onChanged; + final void Function(String)? onFieldSubmitted; @override Widget build(BuildContext context) { @@ -29,6 +31,7 @@ class URLField extends StatelessWidget { border: InputBorder.none, ), onChanged: onChanged, + onFieldSubmitted: onFieldSubmitted, ); } } @@ -95,7 +98,6 @@ class JsonSearchField extends StatelessWidget { controller: controller, onChanged: onChanged, style: kCodeStyle, - cursorHeight: 18, decoration: const InputDecoration( isDense: true, border: InputBorder.none, diff --git a/pubspec.lock b/pubspec.lock index 2f3f7f55..4125ed98 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -217,6 +217,14 @@ packages: url: "https://pub.dev" source: hosted version: "3.0.3" + csv: + dependency: "direct main" + description: + name: csv + sha256: "63ed2871dd6471193dffc52c0e6c76fb86269c00244d244297abbb355c84a86e" + url: "https://pub.dev" + source: hosted + version: "5.1.1" dart_style: dependency: "direct main" description: @@ -306,10 +314,10 @@ packages: dependency: transitive description: name: flutter_keyboard_visibility - sha256: "4983655c26ab5b959252ee204c2fffa4afeb4413cd030455194ec0caa3b8e7cb" + sha256: "98664be7be0e3ffca00de50f7f6a287ab62c763fc8c762e0a21584584a3ff4f8" url: "https://pub.dev" source: hosted - version: "5.4.1" + version: "6.0.0" flutter_keyboard_visibility_linux: dependency: transitive description: @@ -407,10 +415,10 @@ packages: dependency: "direct main" description: name: flutter_typeahead - sha256: b9942bd5b7611a6ec3f0730c477146cffa4cd4b051077983ba67ddfc9e7ee818 + sha256: d64712c65db240b1057559b952398ebb6e498077baeebf9b0731dade62438a6d url: "https://pub.dev" source: hosted - version: "4.8.0" + version: "5.2.0" flutter_web_plugins: dependency: transitive description: flutter @@ -500,10 +508,10 @@ packages: dependency: "direct main" description: name: http - sha256: d4872660c46d929f6b8a9ef4e7a7eff7e49bbf0c4ec3f385ee32df5119175139 + sha256: "761a297c042deedc1ffbb156d6e2af13886bb305c2a343a4d972504cd67dd938" url: "https://pub.dev" source: hosted - version: "1.1.2" + version: "1.2.1" http_multi_server: dependency: transitive description: @@ -625,6 +633,30 @@ packages: url: "https://pub.dev" source: hosted version: "0.2.0" + leak_tracker: + dependency: transitive + description: + name: leak_tracker + sha256: "78eb209deea09858f5269f5a5b02be4049535f568c07b275096836f01ea323fa" + url: "https://pub.dev" + source: hosted + version: "10.0.0" + leak_tracker_flutter_testing: + dependency: transitive + description: + name: leak_tracker_flutter_testing + sha256: b46c5e37c19120a8a01918cfaf293547f47269f7cb4b0058f21531c2465d6ef0 + url: "https://pub.dev" + source: hosted + version: "2.0.1" + leak_tracker_testing: + dependency: transitive + description: + name: leak_tracker_testing + sha256: a597f72a664dbd293f3bfc51f9ba69816f84dcd403cdac7066cb3f6003f3ab47 + url: "https://pub.dev" + source: hosted + version: "2.0.1" lints: dependency: transitive description: @@ -661,26 +693,26 @@ packages: dependency: transitive description: name: matcher - sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e" + sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb url: "https://pub.dev" source: hosted - version: "0.12.16" + version: "0.12.16+1" material_color_utilities: dependency: transitive description: name: material_color_utilities - sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41" + sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a" url: "https://pub.dev" source: hosted - version: "0.5.0" + version: "0.8.0" meta: dependency: transitive description: name: meta - sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e + sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04 url: "https://pub.dev" source: hosted - version: "1.10.0" + version: "1.11.0" mime: dependency: transitive description: @@ -757,10 +789,10 @@ packages: dependency: "direct main" description: name: path - sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" + sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" url: "https://pub.dev" source: hosted - version: "1.8.3" + version: "1.9.0" path_parsing: dependency: transitive description: @@ -853,10 +885,34 @@ packages: dependency: transitive description: name: pointer_interceptor - sha256: adf7a637f97c077041d36801b43be08559fd4322d2127b3f20bb7be1b9eebc22 + sha256: bd18321519718678d5fa98ad3a3359cbc7a31f018554eab80b73d08a7f0c165a url: "https://pub.dev" source: hosted - version: "0.9.3+7" + version: "0.10.1" + pointer_interceptor_ios: + dependency: transitive + description: + name: pointer_interceptor_ios + sha256: "2e73c39452830adc4695757130676a39412a3b7f3c34e3f752791b5384770877" + url: "https://pub.dev" + source: hosted + version: "0.10.0+2" + pointer_interceptor_platform_interface: + dependency: transitive + description: + name: pointer_interceptor_platform_interface + sha256: "0597b0560e14354baeb23f8375cd612e8bd4841bf8306ecb71fcd0bb78552506" + url: "https://pub.dev" + source: hosted + version: "0.10.0+1" + pointer_interceptor_web: + dependency: transitive + description: + name: pointer_interceptor_web + sha256: a6237528b46c411d8d55cdfad8fcb3269fc4cbb26060b14bff94879165887d1e + url: "https://pub.dev" + source: hosted + version: "0.10.2" pointycastle: dependency: transitive description: @@ -1178,10 +1234,10 @@ packages: dependency: transitive description: name: url_launcher_web - sha256: "7286aec002c8feecc338cc33269e96b73955ab227456e9fb2a91f7fab8a358e9" + sha256: "3692a459204a33e04bc94f5fb91158faf4f2c8903281ddd82915adecdb1a901d" url: "https://pub.dev" source: hosted - version: "2.2.2" + version: "2.3.0" url_launcher_windows: dependency: transitive description: @@ -1247,13 +1303,13 @@ packages: source: hosted version: "1.1.0" web: - dependency: transitive + dependency: "direct main" description: name: web - sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152 + sha256: "97da13628db363c635202ad97068d47c5b8aa555808e7a9411963c533b449b27" url: "https://pub.dev" source: hosted - version: "0.3.0" + version: "0.5.1" web_socket_channel: dependency: transitive description: @@ -1320,5 +1376,5 @@ packages: source: hosted version: "3.1.2" sdks: - dart: ">=3.2.3 <4.0.0" - flutter: ">=3.16.0" + dart: ">=3.3.0 <4.0.0" + flutter: ">=3.19.0" diff --git a/pubspec.yaml b/pubspec.yaml index 4196d007..ab250f26 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -5,11 +5,12 @@ version: 0.3.0+3 environment: sdk: ">=3.0.0 <4.0.0" - flutter: ">=3.7.2" + flutter: ">=3.16.0" dependencies: flutter: sdk: flutter + web: ^0.5.0 multi_split_view: ^2.4.0 url_launcher: ^6.1.12 flutter_riverpod: ^2.3.7 @@ -41,7 +42,7 @@ dependencies: json_annotation: ^4.8.1 printing: ^5.11.1 package_info_plus: ^4.1.0 - flutter_typeahead: ^4.8.0 + flutter_typeahead: ^5.2.0 provider: ^6.0.5 json_data_explorer: git: @@ -54,6 +55,7 @@ dependencies: code_builder: ^4.9.0 dart_style: ^2.3.4 json_text_field: ^1.1.0 + csv: ^5.1.1 dev_dependencies: flutter_test: diff --git a/test/codegen/codegen_test.dart b/test/codegen/codegen_test.dart deleted file mode 100644 index 63102e0a..00000000 --- a/test/codegen/codegen_test.dart +++ /dev/null @@ -1,239 +0,0 @@ -import 'package:apidash/codegen/codegen.dart'; -import 'package:apidash/consts.dart'; -import '../request_models.dart'; -import 'package:test/test.dart'; - -void main() { - final codeGen = Codegen(); - - group('Test various Code generators', () { - test('cURL', () { - const expectedCode = r"""curl --url 'https://api.foss42.com'"""; - expect(codeGen.getCode(CodegenLanguage.curl, requestModelGet1, "https"), - expectedCode); - }); - - test('Dart Dio', () { - const expectedCode = r"""import 'package:dio/dio.dart' as dio; - -void main() async { - try { - final response = await dio.Dio.get('https://api.foss42.com'); - print(response.statusCode); - print(response.data); - } on DioException catch (e, s) { - print(e.response?.statusCode); - print(e.response?.data); - print(s); - } catch (e, s) { - print(e); - print(s); - } -} -"""; - expect( - codeGen.getCode(CodegenLanguage.dartDio, requestModelGet1, "https"), - expectedCode); - }); - - test('Dart HTTP', () { - const expectedCode = r"""import 'package:http/http.dart' as http; - -void main() async { - var uri = Uri.parse('https://api.foss42.com'); - - final response = await http.get(uri); - - int statusCode = response.statusCode; - if (statusCode >= 200 && statusCode < 300) { - print('Status Code: $statusCode'); - print('Response Body: ${response.body}'); - } else { - print('Error Status Code: $statusCode'); - print('Error Response Body: ${response.body}'); - } -} -"""; - expect( - codeGen.getCode(CodegenLanguage.dartHttp, requestModelGet1, "https"), - expectedCode); - }); - - test('HAR', () { - const expectedCode = r"""{ - "method": "GET", - "url": "https://api.foss42.com", - "httpVersion": "HTTP/1.1", - "queryString": [], - "headers": [] -}"""; - expect(codeGen.getCode(CodegenLanguage.har, requestModelGet1, "https"), - expectedCode); - }); - - test('JS Axios', () { - const expectedCode = r"""let config = { - url: 'https://api.foss42.com', - method: 'get' -}; - -axios(config) - .then(function (response) { - // handle success - console.log(response.status); - console.log(response.data); - }) - .catch(function (error) { - // handle error - console.log(error.response.status); - console.log(error); - }); -"""; - expect( - codeGen.getCode(CodegenLanguage.jsAxios, requestModelGet1, "https"), - expectedCode); - }); - - test('JS Fetch', () { - const expectedCode = r"""let url = 'https://api.foss42.com'; - -let options = { - method: 'GET' -}; - -let status; -fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); -"""; - expect( - codeGen.getCode(CodegenLanguage.jsFetch, requestModelGet1, "https"), - expectedCode); - }); - - test('Kotlin OkHttp', () { - const expectedCode = r"""import okhttp3.OkHttpClient -import okhttp3.Request - -fun main() { - val client = OkHttpClient() - - val url = "https://api.foss42.com" - - val request = Request.Builder() - .url(url) - .get() - .build() - - val response = client.newCall(request).execute() - - println(response.code) - println(response.body?.string()) -} -"""; - expect( - codeGen.getCode( - CodegenLanguage.kotlinOkHttp, requestModelGet1, "https"), - expectedCode); - }); - - test('NodeJs Axios', () { - const expectedCode = r"""import axios from 'axios'; - -let config = { - url: 'https://api.foss42.com', - method: 'get' -}; - -axios(config) - .then(function (response) { - // handle success - console.log(response.status); - console.log(response.data); - }) - .catch(function (error) { - // handle error - console.log(error.response.status); - console.log(error); - }); -"""; - expect( - codeGen.getCode( - CodegenLanguage.nodejsAxios, requestModelGet1, "https"), - expectedCode); - }); - - test('Nodejs Fetch', () { - const expectedCode = r"""import fetch from 'node-fetch'; - -let url = 'https://api.foss42.com'; - -let options = { - method: 'GET' -}; - -let status; -fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); -"""; - expect( - codeGen.getCode( - CodegenLanguage.nodejsFetch, requestModelGet1, "https"), - expectedCode); - }); - - test('Python http.client', () { - const expectedCode = r"""import http.client - -conn = http.client.HTTPSConnection("api.foss42.com") -conn.request("GET", "") - -res = conn.getresponse() -data = res.read() - -print(data.decode("utf-8")) -"""; - expect( - codeGen.getCode( - CodegenLanguage.pythonHttpClient, requestModelGet1, "https"), - expectedCode); - }); - - test('Python requests', () { - const expectedCode = r"""import requests - -url = 'https://api.foss42.com' - -response = requests.get(url) - -print('Status Code:', response.status_code) -print('Response Body:', response.text) -"""; - expect( - codeGen.getCode( - CodegenLanguage.pythonRequests, requestModelGet1, "https"), - expectedCode); - }); - }); -} diff --git a/test/codegen/curl_codegen_test.dart b/test/codegen/curl_codegen_test.dart index e9bb7f60..ec0df5db 100644 --- a/test/codegen/curl_codegen_test.dart +++ b/test/codegen/curl_codegen_test.dart @@ -1,72 +1,83 @@ -import 'package:apidash/codegen/others/curl.dart'; -import '../request_models.dart'; +import 'package:apidash/codegen/codegen.dart'; +import 'package:apidash/consts.dart'; import 'package:test/test.dart'; +import '../request_models.dart'; void main() { - final curlCodeGen = cURLCodeGen(); + final codeGen = Codegen(); group('GET Request', () { test('GET 1', () { - const expectedCode = r"""curl --url 'https://api.foss42.com'"""; - expect(curlCodeGen.getCode(requestModelGet1, "https"), expectedCode); + const expectedCode = r"""curl --url 'https://api.apidash.dev'"""; + expect(codeGen.getCode(CodegenLanguage.curl, requestModelGet1, "https"), + expectedCode); }); test('GET 2', () { const expectedCode = - r"""curl --url 'https://api.foss42.com/country/data?code=US'"""; - expect(curlCodeGen.getCode(requestModelGet2, "https"), expectedCode); + r"""curl --url 'https://api.apidash.dev/country/data?code=US'"""; + expect(codeGen.getCode(CodegenLanguage.curl, requestModelGet2, "https"), + expectedCode); }); test('GET 3', () { const expectedCode = - r"""curl --url 'https://api.foss42.com/country/data?code=IND'"""; - expect(curlCodeGen.getCode(requestModelGet3, "https"), expectedCode); + r"""curl --url 'https://api.apidash.dev/country/data?code=IND'"""; + expect(codeGen.getCode(CodegenLanguage.curl, requestModelGet3, "https"), + expectedCode); }); test('GET 4', () { const expectedCode = - r"""curl --url 'https://api.foss42.com/humanize/social?num=8700000&digits=3&system=SS&add_space=true&trailing_zeros=true'"""; - expect(curlCodeGen.getCode(requestModelGet4, "https"), expectedCode); + r"""curl --url 'https://api.apidash.dev/humanize/social?num=8700000&digits=3&system=SS&add_space=true&trailing_zeros=true'"""; + expect(codeGen.getCode(CodegenLanguage.curl, requestModelGet4, "https"), + expectedCode); }); test('GET 5', () { const expectedCode = r"""curl --url 'https://api.github.com/repos/foss42/apidash' \ --header 'User-Agent: Test Agent'"""; - expect(curlCodeGen.getCode(requestModelGet5, "https"), expectedCode); + expect(codeGen.getCode(CodegenLanguage.curl, requestModelGet5, "https"), + expectedCode); }); test('GET 6', () { const expectedCode = r"""curl --url 'https://api.github.com/repos/foss42/apidash?raw=true' \ --header 'User-Agent: Test Agent'"""; - expect(curlCodeGen.getCode(requestModelGet6, "https"), expectedCode); + expect(codeGen.getCode(CodegenLanguage.curl, requestModelGet6, "https"), + expectedCode); }); test('GET 7', () { - const expectedCode = r"""curl --url 'https://api.foss42.com'"""; - expect(curlCodeGen.getCode(requestModelGet7, "https"), expectedCode); + const expectedCode = r"""curl --url 'https://api.apidash.dev'"""; + expect(codeGen.getCode(CodegenLanguage.curl, requestModelGet7, "https"), + expectedCode); }); test('GET 8', () { const expectedCode = r"""curl --url 'https://api.github.com/repos/foss42/apidash?raw=true' \ --header 'User-Agent: Test Agent'"""; - expect(curlCodeGen.getCode(requestModelGet8, "https"), expectedCode); + expect(codeGen.getCode(CodegenLanguage.curl, requestModelGet8, "https"), + expectedCode); }); test('GET 9', () { const expectedCode = - r"""curl --url 'https://api.foss42.com/humanize/social?num=8700000&add_space=true'"""; - expect(curlCodeGen.getCode(requestModelGet9, "https"), expectedCode); + r"""curl --url 'https://api.apidash.dev/humanize/social?num=8700000&add_space=true'"""; + expect(codeGen.getCode(CodegenLanguage.curl, requestModelGet9, "https"), + expectedCode); }); test('GET 10', () { const expectedCode = - r"""curl --url 'https://api.foss42.com/humanize/social' \ + r"""curl --url 'https://api.apidash.dev/humanize/social' \ --header 'User-Agent: Test Agent'"""; expect( - curlCodeGen.getCode( + codeGen.getCode( + CodegenLanguage.curl, requestModelGet10, "https", ), @@ -75,105 +86,183 @@ void main() { test('GET 11', () { const expectedCode = - r"""curl --url 'https://api.foss42.com/humanize/social?num=8700000&digits=3' \ + r"""curl --url 'https://api.apidash.dev/humanize/social?num=8700000&digits=3' \ --header 'User-Agent: Test Agent'"""; - expect(curlCodeGen.getCode(requestModelGet11, "https"), expectedCode); + expect(codeGen.getCode(CodegenLanguage.curl, requestModelGet11, "https"), + expectedCode); }); test('GET 12', () { const expectedCode = - r"""curl --url 'https://api.foss42.com/humanize/social'"""; - expect(curlCodeGen.getCode(requestModelGet12, "https"), expectedCode); + r"""curl --url 'https://api.apidash.dev/humanize/social'"""; + expect(codeGen.getCode(CodegenLanguage.curl, requestModelGet12, "https"), + expectedCode); }); }); group('HEAD Request', () { test('HEAD 1', () { - const expectedCode = r"""curl --head --url 'https://api.foss42.com'"""; - expect(curlCodeGen.getCode(requestModelHead1, "https"), expectedCode); + const expectedCode = r"""curl --head --url 'https://api.apidash.dev'"""; + expect(codeGen.getCode(CodegenLanguage.curl, requestModelHead1, "https"), + expectedCode); }); test('HEAD 2', () { - const expectedCode = r"""curl --head --url 'http://api.foss42.com'"""; - expect(curlCodeGen.getCode(requestModelHead2, "http"), expectedCode); + const expectedCode = r"""curl --head --url 'http://api.apidash.dev'"""; + expect(codeGen.getCode(CodegenLanguage.curl, requestModelHead2, "http"), + expectedCode); }); }); group('POST Request', () { test('POST 1', () { const expectedCode = r"""curl --request POST \ - --url 'https://api.foss42.com/case/lower' \ + --url 'https://api.apidash.dev/case/lower' \ --header 'Content-Type: text/plain' \ --data '{ "text": "I LOVE Flutter" }'"""; - expect(curlCodeGen.getCode(requestModelPost1, "https"), expectedCode); + expect(codeGen.getCode(CodegenLanguage.curl, requestModelPost1, "https"), + expectedCode); }); test('POST 2', () { const expectedCode = r"""curl --request POST \ - --url 'https://api.foss42.com/case/lower' \ + --url 'https://api.apidash.dev/case/lower' \ --header 'Content-Type: application/json' \ --data '{ -"text": "I LOVE Flutter" +"text": "I LOVE Flutter", +"flag": null, +"male": true, +"female": false, +"no": 1.2, +"arr": ["null", "true", "false", null] }'"""; - expect(curlCodeGen.getCode(requestModelPost2, "https"), expectedCode); + expect(codeGen.getCode(CodegenLanguage.curl, requestModelPost2, "https"), + expectedCode); }); test('POST 3', () { const expectedCode = r"""curl --request POST \ - --url 'https://api.foss42.com/case/lower' \ + --url 'https://api.apidash.dev/case/lower' \ --header 'Content-Type: application/json' \ --header 'User-Agent: Test Agent' \ --data '{ "text": "I LOVE Flutter" }'"""; - expect(curlCodeGen.getCode(requestModelPost3, "https"), expectedCode); + expect(codeGen.getCode(CodegenLanguage.curl, requestModelPost3, "https"), + expectedCode); + }); + + test('POST 4', () { + const expectedCode = r"""curl --request POST \ + --url 'https://api.apidash.dev/io/form' \ + --form 'text=API' \ + --form 'sep=|' \ + --form 'times=3'"""; + expect(codeGen.getCode(CodegenLanguage.curl, requestModelPost4, "https"), + expectedCode); + }); + + test('POST 5', () { + const expectedCode = r"""curl --request POST \ + --url 'https://api.apidash.dev/io/form' \ + --header 'User-Agent: Test Agent' \ + --form 'text=API' \ + --form 'sep=|' \ + --form 'times=3'"""; + expect(codeGen.getCode(CodegenLanguage.curl, requestModelPost5, "https"), + expectedCode); + }); + + test('POST 6', () { + const expectedCode = r"""curl --request POST \ + --url 'https://api.apidash.dev/io/img' \ + --form 'token=xyz' \ + --form 'imfile=@/Documents/up/1.png'"""; + expect(codeGen.getCode(CodegenLanguage.curl, requestModelPost6, "https"), + expectedCode); + }); + + test('POST 7', () { + const expectedCode = r"""curl --request POST \ + --url 'https://api.apidash.dev/io/img' \ + --form 'token=xyz' \ + --form 'imfile=@/Documents/up/1.png'"""; + expect(codeGen.getCode(CodegenLanguage.curl, requestModelPost7, "https"), + expectedCode); + }); + + test('POST 8', () { + const expectedCode = r"""curl --request POST \ + --url 'https://api.apidash.dev/io/form?size=2&len=3' \ + --form 'text=API' \ + --form 'sep=|' \ + --form 'times=3'"""; + expect(codeGen.getCode(CodegenLanguage.curl, requestModelPost8, "https"), + expectedCode); + }); + + test('POST 9', () { + const expectedCode = r"""curl --request POST \ + --url 'https://api.apidash.dev/io/img?size=2&len=3' \ + --header 'User-Agent: Test Agent' \ + --header 'Keep-Alive: true' \ + --form 'token=xyz' \ + --form 'imfile=@/Documents/up/1.png'"""; + expect(codeGen.getCode(CodegenLanguage.curl, requestModelPost9, "https"), + expectedCode); }); }); group('PUT Request', () { test('PUT 1', () { const expectedCode = r"""curl --request PUT \ - --url 'https://reqres.in/api/users/2' \ + --url 'https://reqres.in/api/users/2' \ --header 'Content-Type: application/json' \ --data '{ "name": "morpheus", "job": "zion resident" }'"""; - expect(curlCodeGen.getCode(requestModelPut1, "https"), expectedCode); + expect(codeGen.getCode(CodegenLanguage.curl, requestModelPut1, "https"), + expectedCode); }); }); group('PATCH Request', () { test('PATCH 1', () { const expectedCode = r"""curl --request PATCH \ - --url 'https://reqres.in/api/users/2' \ + --url 'https://reqres.in/api/users/2' \ --header 'Content-Type: application/json' \ --data '{ "name": "marfeus", "job": "accountant" }'"""; - expect(curlCodeGen.getCode(requestModelPatch1, "https"), expectedCode); + expect(codeGen.getCode(CodegenLanguage.curl, requestModelPatch1, "https"), + expectedCode); }); }); group('DELETE Request', () { test('DELETE 1', () { const expectedCode = r"""curl --request DELETE \ - --url 'https://reqres.in/api/users/2'"""; - expect(curlCodeGen.getCode(requestModelDelete1, "https"), expectedCode); + --url 'https://reqres.in/api/users/2'"""; + expect( + codeGen.getCode(CodegenLanguage.curl, requestModelDelete1, "https"), + expectedCode); }); test('DELETE 2', () { const expectedCode = r"""curl --request DELETE \ - --url 'https://reqres.in/api/users/2' \ + --url 'https://reqres.in/api/users/2' \ --header 'Content-Type: application/json' \ --data '{ "name": "marfeus", "job": "accountant" }'"""; - expect(curlCodeGen.getCode(requestModelDelete2, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.curl, requestModelDelete2, "https"), + expectedCode); }); }); } diff --git a/test/codegen/dart_dio_codegen_test.dart b/test/codegen/dart_dio_codegen_test.dart index 30b371fd..8f111d41 100644 --- a/test/codegen/dart_dio_codegen_test.dart +++ b/test/codegen/dart_dio_codegen_test.dart @@ -1,10 +1,10 @@ -import 'package:apidash/codegen/dart/dio.dart'; +import 'package:apidash/codegen/codegen.dart'; +import 'package:apidash/consts.dart'; import 'package:test/test.dart'; - import '../request_models.dart'; void main() { - final dartDioCodeGen = DartDioCodeGen(); + final codeGen = Codegen(); group('GET Request', () { test('GET 1', () { @@ -12,10 +12,10 @@ void main() { void main() async { try { - final response = await dio.Dio.get('https://api.foss42.com'); + final response = await dio.Dio().get('https://api.apidash.dev'); print(response.statusCode); print(response.data); - } on DioException catch (e, s) { + } on dio.DioException catch (e, s) { print(e.response?.statusCode); print(e.response?.data); print(s); @@ -25,7 +25,9 @@ void main() async { } } """; - expect(dartDioCodeGen.getCode(requestModelGet1, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.dartDio, requestModelGet1, "https"), + expectedCode); }); test('GET 2', () { @@ -34,13 +36,13 @@ void main() async { void main() async { try { final queryParams = {'code': 'US'}; - final response = await dio.Dio.get( - 'https://api.foss42.com/country/data', + final response = await dio.Dio().get( + 'https://api.apidash.dev/country/data', queryParameters: queryParams, ); print(response.statusCode); print(response.data); - } on DioException catch (e, s) { + } on dio.DioException catch (e, s) { print(e.response?.statusCode); print(e.response?.data); print(s); @@ -50,7 +52,9 @@ void main() async { } } """; - expect(dartDioCodeGen.getCode(requestModelGet2, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.dartDio, requestModelGet2, "https"), + expectedCode); }); test('GET 3', () { @@ -59,13 +63,13 @@ void main() async { void main() async { try { final queryParams = {'code': 'IND'}; - final response = await dio.Dio.get( - 'https://api.foss42.com/country/data?code=US', + final response = await dio.Dio().get( + 'https://api.apidash.dev/country/data?code=US', queryParameters: queryParams, ); print(response.statusCode); print(response.data); - } on DioException catch (e, s) { + } on dio.DioException catch (e, s) { print(e.response?.statusCode); print(e.response?.data); print(s); @@ -75,7 +79,9 @@ void main() async { } } """; - expect(dartDioCodeGen.getCode(requestModelGet3, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.dartDio, requestModelGet3, "https"), + expectedCode); }); test('GET 4', () { @@ -90,13 +96,13 @@ void main() async { 'add_space': 'true', 'trailing_zeros': 'true', }; - final response = await dio.Dio.get( - 'https://api.foss42.com/humanize/social', + final response = await dio.Dio().get( + 'https://api.apidash.dev/humanize/social', queryParameters: queryParams, ); print(response.statusCode); print(response.data); - } on DioException catch (e, s) { + } on dio.DioException catch (e, s) { print(e.response?.statusCode); print(e.response?.data); print(s); @@ -106,7 +112,9 @@ void main() async { } } """; - expect(dartDioCodeGen.getCode(requestModelGet4, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.dartDio, requestModelGet4, "https"), + expectedCode); }); test('GET 5', () { @@ -115,13 +123,13 @@ void main() async { void main() async { try { final headers = {'User-Agent': 'Test Agent'}; - final response = await dio.Dio.get( + final response = await dio.Dio().get( 'https://api.github.com/repos/foss42/apidash', - options: Options(headers: headers), + options: dio.Options(headers: headers), ); print(response.statusCode); print(response.data); - } on DioException catch (e, s) { + } on dio.DioException catch (e, s) { print(e.response?.statusCode); print(e.response?.data); print(s); @@ -131,7 +139,9 @@ void main() async { } } """; - expect(dartDioCodeGen.getCode(requestModelGet5, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.dartDio, requestModelGet5, "https"), + expectedCode); }); test('GET 6', () { @@ -141,14 +151,14 @@ void main() async { try { final queryParams = {'raw': 'true'}; final headers = {'User-Agent': 'Test Agent'}; - final response = await dio.Dio.get( + final response = await dio.Dio().get( 'https://api.github.com/repos/foss42/apidash', queryParameters: queryParams, - options: Options(headers: headers), + options: dio.Options(headers: headers), ); print(response.statusCode); print(response.data); - } on DioException catch (e, s) { + } on dio.DioException catch (e, s) { print(e.response?.statusCode); print(e.response?.data); print(s); @@ -158,7 +168,9 @@ void main() async { } } """; - expect(dartDioCodeGen.getCode(requestModelGet6, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.dartDio, requestModelGet6, "https"), + expectedCode); }); test('GET 7', () { @@ -166,10 +178,10 @@ void main() async { void main() async { try { - final response = await dio.Dio.get('https://api.foss42.com'); + final response = await dio.Dio().get('https://api.apidash.dev'); print(response.statusCode); print(response.data); - } on DioException catch (e, s) { + } on dio.DioException catch (e, s) { print(e.response?.statusCode); print(e.response?.data); print(s); @@ -179,7 +191,9 @@ void main() async { } } """; - expect(dartDioCodeGen.getCode(requestModelGet7, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.dartDio, requestModelGet7, "https"), + expectedCode); }); test('GET 8', () { @@ -189,14 +203,14 @@ void main() async { try { final queryParams = {'raw': 'true'}; final headers = {'User-Agent': 'Test Agent'}; - final response = await dio.Dio.get( + final response = await dio.Dio().get( 'https://api.github.com/repos/foss42/apidash', queryParameters: queryParams, - options: Options(headers: headers), + options: dio.Options(headers: headers), ); print(response.statusCode); print(response.data); - } on DioException catch (e, s) { + } on dio.DioException catch (e, s) { print(e.response?.statusCode); print(e.response?.data); print(s); @@ -206,7 +220,9 @@ void main() async { } } """; - expect(dartDioCodeGen.getCode(requestModelGet8, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.dartDio, requestModelGet8, "https"), + expectedCode); }); test('GET 9', () { @@ -218,38 +234,13 @@ void main() async { 'num': '8700000', 'add_space': 'true', }; - final response = await dio.Dio.get( - 'https://api.foss42.com/humanize/social', + final response = await dio.Dio().get( + 'https://api.apidash.dev/humanize/social', queryParameters: queryParams, ); print(response.statusCode); print(response.data); - } on DioException catch (e, s) { - print(e.response?.statusCode); - print(e.response?.data); - print(s); - } catch (e, s) { - print(e); - print(s); - } -} -"""; - expect(dartDioCodeGen.getCode(requestModelGet9, "https"), expectedCode); - }); - - test('GET 10', () { - const expectedCode = r"""import 'package:dio/dio.dart' as dio; - -void main() async { - try { - final headers = {'User-Agent': 'Test Agent'}; - final response = await dio.Dio.get( - 'https://api.foss42.com/humanize/social', - options: Options(headers: headers), - ); - print(response.statusCode); - print(response.data); - } on DioException catch (e, s) { + } on dio.DioException catch (e, s) { print(e.response?.statusCode); print(e.response?.data); print(s); @@ -260,7 +251,35 @@ void main() async { } """; expect( - dartDioCodeGen.getCode( + codeGen.getCode(CodegenLanguage.dartDio, requestModelGet9, "https"), + expectedCode); + }); + + test('GET 10', () { + const expectedCode = r"""import 'package:dio/dio.dart' as dio; + +void main() async { + try { + final headers = {'User-Agent': 'Test Agent'}; + final response = await dio.Dio().get( + 'https://api.apidash.dev/humanize/social', + options: dio.Options(headers: headers), + ); + print(response.statusCode); + print(response.data); + } on dio.DioException catch (e, s) { + print(e.response?.statusCode); + print(e.response?.data); + print(s); + } catch (e, s) { + print(e); + print(s); + } +} +"""; + expect( + codeGen.getCode( + CodegenLanguage.dartDio, requestModelGet10, "https", ), @@ -277,14 +296,14 @@ void main() async { 'digits': '3', }; final headers = {'User-Agent': 'Test Agent'}; - final response = await dio.Dio.get( - 'https://api.foss42.com/humanize/social', + final response = await dio.Dio().get( + 'https://api.apidash.dev/humanize/social', queryParameters: queryParams, - options: Options(headers: headers), + options: dio.Options(headers: headers), ); print(response.statusCode); print(response.data); - } on DioException catch (e, s) { + } on dio.DioException catch (e, s) { print(e.response?.statusCode); print(e.response?.data); print(s); @@ -294,7 +313,9 @@ void main() async { } } """; - expect(dartDioCodeGen.getCode(requestModelGet11, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.dartDio, requestModelGet11, "https"), + expectedCode); }); test('GET 12', () { @@ -302,10 +323,10 @@ void main() async { void main() async { try { - final response = await dio.Dio.get('https://api.foss42.com/humanize/social'); + final response = await dio.Dio().get('https://api.apidash.dev/humanize/social'); print(response.statusCode); print(response.data); - } on DioException catch (e, s) { + } on dio.DioException catch (e, s) { print(e.response?.statusCode); print(e.response?.data); print(s); @@ -315,7 +336,9 @@ void main() async { } } """; - expect(dartDioCodeGen.getCode(requestModelGet12, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.dartDio, requestModelGet12, "https"), + expectedCode); }); }); @@ -325,10 +348,10 @@ void main() async { void main() async { try { - final response = await dio.Dio.head('https://api.foss42.com'); + final response = await dio.Dio().head('https://api.apidash.dev'); print(response.statusCode); print(response.data); - } on DioException catch (e, s) { + } on dio.DioException catch (e, s) { print(e.response?.statusCode); print(e.response?.data); print(s); @@ -338,7 +361,9 @@ void main() async { } } """; - expect(dartDioCodeGen.getCode(requestModelHead1, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.dartDio, requestModelHead1, "https"), + expectedCode); }); test('HEAD 2', () { @@ -346,10 +371,10 @@ void main() async { void main() async { try { - final response = await dio.Dio.head('http://api.foss42.com'); + final response = await dio.Dio().head('http://api.apidash.dev'); print(response.statusCode); print(response.data); - } on DioException catch (e, s) { + } on dio.DioException catch (e, s) { print(e.response?.statusCode); print(e.response?.data); print(s); @@ -359,7 +384,9 @@ void main() async { } } """; - expect(dartDioCodeGen.getCode(requestModelHead2, "http"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.dartDio, requestModelHead2, "http"), + expectedCode); }); }); @@ -372,13 +399,13 @@ void main() async { final data = r'''{ "text": "I LOVE Flutter" }'''; - final response = await dio.Dio.post( - 'https://api.foss42.com/case/lower', + final response = await dio.Dio().post( + 'https://api.apidash.dev/case/lower', data: data, ); print(response.statusCode); print(response.data); - } on DioException catch (e, s) { + } on dio.DioException catch (e, s) { print(e.response?.statusCode); print(e.response?.data); print(s); @@ -388,7 +415,9 @@ void main() async { } } """; - expect(dartDioCodeGen.getCode(requestModelPost1, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.dartDio, requestModelPost1, "https"), + expectedCode); }); test('POST 2', () { @@ -398,15 +427,20 @@ import 'dart:convert' as convert; void main() async { try { final data = convert.json.decode(r'''{ -"text": "I LOVE Flutter" +"text": "I LOVE Flutter", +"flag": null, +"male": true, +"female": false, +"no": 1.2, +"arr": ["null", "true", "false", null] }'''); - final response = await dio.Dio.post( - 'https://api.foss42.com/case/lower', + final response = await dio.Dio().post( + 'https://api.apidash.dev/case/lower', data: data, ); print(response.statusCode); print(response.data); - } on DioException catch (e, s) { + } on dio.DioException catch (e, s) { print(e.response?.statusCode); print(e.response?.data); print(s); @@ -416,7 +450,9 @@ void main() async { } } """; - expect(dartDioCodeGen.getCode(requestModelPost2, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.dartDio, requestModelPost2, "https"), + expectedCode); }); test('POST 3', () { @@ -429,14 +465,14 @@ void main() async { final data = convert.json.decode(r'''{ "text": "I LOVE Flutter" }'''); - final response = await dio.Dio.post( - 'https://api.foss42.com/case/lower', - options: Options(headers: headers), + final response = await dio.Dio().post( + 'https://api.apidash.dev/case/lower', + options: dio.Options(headers: headers), data: data, ); print(response.statusCode); print(response.data); - } on DioException catch (e, s) { + } on dio.DioException catch (e, s) { print(e.response?.statusCode); print(e.response?.data); print(s); @@ -446,10 +482,330 @@ void main() async { } } """; - expect(dartDioCodeGen.getCode(requestModelPost3, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.dartDio, requestModelPost3, "https"), + expectedCode); + }); + test('POST 4', () { + const expectedCode = r"""import 'package:dio/dio.dart' as dio; + +void main() async { + try { + final data = dio.FormData(); + final List> formDataList = [ + {"name": "text", "value": "API", "type": "text"}, + {"name": "sep", "value": "|", "type": "text"}, + {"name": "times", "value": "3", "type": "text"} + ]; + for (var formField in formDataList) { + if (formField['type'] == 'file') { + if (formField['value'] != null) { + data.files.add(MapEntry( + formField['name']!, + await dio.MultipartFile.fromFile(formField['value']!, + filename: formField['value']!), + )); + } + } else { + if (formField['value'] != null) { + data.fields + .add(MapEntry(formField['name']!, formField['value']!)); + } + } + } + + final response = await dio.Dio().post( + 'https://api.apidash.dev/io/form', + data: data, + ); + print(response.statusCode); + print(response.data); + } on dio.DioException catch (e, s) { + print(e.response?.statusCode); + print(e.response?.data); + print(s); + } catch (e, s) { + print(e); + print(s); + } +} +"""; + expect( + codeGen.getCode(CodegenLanguage.dartDio, requestModelPost4, "https"), + expectedCode); + }); + + test('POST 5', () { + const expectedCode = r"""import 'package:dio/dio.dart' as dio; + +void main() async { + try { + final headers = {'User-Agent': 'Test Agent'}; + final data = dio.FormData(); + final List> formDataList = [ + {"name": "text", "value": "API", "type": "text"}, + {"name": "sep", "value": "|", "type": "text"}, + {"name": "times", "value": "3", "type": "text"} + ]; + for (var formField in formDataList) { + if (formField['type'] == 'file') { + if (formField['value'] != null) { + data.files.add(MapEntry( + formField['name']!, + await dio.MultipartFile.fromFile(formField['value']!, + filename: formField['value']!), + )); + } + } else { + if (formField['value'] != null) { + data.fields + .add(MapEntry(formField['name']!, formField['value']!)); + } + } + } + + final response = await dio.Dio().post( + 'https://api.apidash.dev/io/form', + options: dio.Options(headers: headers), + data: data, + ); + print(response.statusCode); + print(response.data); + } on dio.DioException catch (e, s) { + print(e.response?.statusCode); + print(e.response?.data); + print(s); + } catch (e, s) { + print(e); + print(s); + } +} +"""; + expect( + codeGen.getCode(CodegenLanguage.dartDio, requestModelPost5, "https"), + expectedCode); + }); + + test('POST 6', () { + const expectedCode = r"""import 'package:dio/dio.dart' as dio; + +void main() async { + try { + final data = dio.FormData(); + final List> formDataList = [ + {"name": "token", "value": "xyz", "type": "text"}, + { + "name": "imfile", + "value": "/Documents/up/1.png", + "type": "file" + } + ]; + for (var formField in formDataList) { + if (formField['type'] == 'file') { + if (formField['value'] != null) { + data.files.add(MapEntry( + formField['name']!, + await dio.MultipartFile.fromFile(formField['value']!, + filename: formField['value']!), + )); + } + } else { + if (formField['value'] != null) { + data.fields + .add(MapEntry(formField['name']!, formField['value']!)); + } + } + } + + final response = await dio.Dio().post( + 'https://api.apidash.dev/io/img', + data: data, + ); + print(response.statusCode); + print(response.data); + } on dio.DioException catch (e, s) { + print(e.response?.statusCode); + print(e.response?.data); + print(s); + } catch (e, s) { + print(e); + print(s); + } +} +"""; + expect( + codeGen.getCode(CodegenLanguage.dartDio, requestModelPost6, "https"), + expectedCode); + }); + + test('POST 7', () { + const expectedCode = r"""import 'package:dio/dio.dart' as dio; + +void main() async { + try { + final data = dio.FormData(); + final List> formDataList = [ + {"name": "token", "value": "xyz", "type": "text"}, + { + "name": "imfile", + "value": "/Documents/up/1.png", + "type": "file" + } + ]; + for (var formField in formDataList) { + if (formField['type'] == 'file') { + if (formField['value'] != null) { + data.files.add(MapEntry( + formField['name']!, + await dio.MultipartFile.fromFile(formField['value']!, + filename: formField['value']!), + )); + } + } else { + if (formField['value'] != null) { + data.fields + .add(MapEntry(formField['name']!, formField['value']!)); + } + } + } + + final response = await dio.Dio().post( + 'https://api.apidash.dev/io/img', + data: data, + ); + print(response.statusCode); + print(response.data); + } on dio.DioException catch (e, s) { + print(e.response?.statusCode); + print(e.response?.data); + print(s); + } catch (e, s) { + print(e); + print(s); + } +} +"""; + expect( + codeGen.getCode(CodegenLanguage.dartDio, requestModelPost7, "https"), + expectedCode); + }); + + test('POST 8', () { + const expectedCode = r"""import 'package:dio/dio.dart' as dio; + +void main() async { + try { + final queryParams = { + 'size': '2', + 'len': '3', + }; + final data = dio.FormData(); + final List> formDataList = [ + {"name": "text", "value": "API", "type": "text"}, + {"name": "sep", "value": "|", "type": "text"}, + {"name": "times", "value": "3", "type": "text"} + ]; + for (var formField in formDataList) { + if (formField['type'] == 'file') { + if (formField['value'] != null) { + data.files.add(MapEntry( + formField['name']!, + await dio.MultipartFile.fromFile(formField['value']!, + filename: formField['value']!), + )); + } + } else { + if (formField['value'] != null) { + data.fields + .add(MapEntry(formField['name']!, formField['value']!)); + } + } + } + + final response = await dio.Dio().post( + 'https://api.apidash.dev/io/form', + queryParameters: queryParams, + data: data, + ); + print(response.statusCode); + print(response.data); + } on dio.DioException catch (e, s) { + print(e.response?.statusCode); + print(e.response?.data); + print(s); + } catch (e, s) { + print(e); + print(s); + } +} +"""; + expect( + codeGen.getCode(CodegenLanguage.dartDio, requestModelPost8, "https"), + expectedCode); + }); + + test('POST 9', () { + const expectedCode = r"""import 'package:dio/dio.dart' as dio; + +void main() async { + try { + final queryParams = { + 'size': '2', + 'len': '3', + }; + final headers = { + 'User-Agent': 'Test Agent', + 'Keep-Alive': 'true', + }; + final data = dio.FormData(); + final List> formDataList = [ + {"name": "token", "value": "xyz", "type": "text"}, + { + "name": "imfile", + "value": "/Documents/up/1.png", + "type": "file" + } + ]; + for (var formField in formDataList) { + if (formField['type'] == 'file') { + if (formField['value'] != null) { + data.files.add(MapEntry( + formField['name']!, + await dio.MultipartFile.fromFile(formField['value']!, + filename: formField['value']!), + )); + } + } else { + if (formField['value'] != null) { + data.fields + .add(MapEntry(formField['name']!, formField['value']!)); + } + } + } + + final response = await dio.Dio().post( + 'https://api.apidash.dev/io/img', + queryParameters: queryParams, + options: dio.Options(headers: headers), + data: data, + ); + print(response.statusCode); + print(response.data); + } on dio.DioException catch (e, s) { + print(e.response?.statusCode); + print(e.response?.data); + print(s); + } catch (e, s) { + print(e); + print(s); + } +} +"""; + expect( + codeGen.getCode(CodegenLanguage.dartDio, requestModelPost9, "https"), + expectedCode); }); }); - group('PUT Request', () { test('PUT 1', () { const expectedCode = r"""import 'package:dio/dio.dart' as dio; @@ -461,13 +817,13 @@ void main() async { "name": "morpheus", "job": "zion resident" }'''); - final response = await dio.Dio.put( + final response = await dio.Dio().put( 'https://reqres.in/api/users/2', data: data, ); print(response.statusCode); print(response.data); - } on DioException catch (e, s) { + } on dio.DioException catch (e, s) { print(e.response?.statusCode); print(e.response?.data); print(s); @@ -477,7 +833,9 @@ void main() async { } } """; - expect(dartDioCodeGen.getCode(requestModelPut1, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.dartDio, requestModelPut1, "https"), + expectedCode); }); }); @@ -492,36 +850,13 @@ void main() async { "name": "marfeus", "job": "accountant" }'''); - final response = await dio.Dio.patch( + final response = await dio.Dio().patch( 'https://reqres.in/api/users/2', data: data, ); print(response.statusCode); print(response.data); - } on DioException catch (e, s) { - print(e.response?.statusCode); - print(e.response?.data); - print(s); - } catch (e, s) { - print(e); - print(s); - } -} -"""; - expect(dartDioCodeGen.getCode(requestModelPatch1, "https"), expectedCode); - }); - }); - - group('DELETE Request', () { - test('DELETE 1', () { - const expectedCode = r"""import 'package:dio/dio.dart' as dio; - -void main() async { - try { - final response = await dio.Dio.delete('https://reqres.in/api/users/2'); - print(response.statusCode); - print(response.data); - } on DioException catch (e, s) { + } on dio.DioException catch (e, s) { print(e.response?.statusCode); print(e.response?.data); print(s); @@ -532,7 +867,34 @@ void main() async { } """; expect( - dartDioCodeGen.getCode(requestModelDelete1, "https"), expectedCode); + codeGen.getCode(CodegenLanguage.dartDio, requestModelPatch1, "https"), + expectedCode); + }); + }); + + group('DELETE Request', () { + test('DELETE 1', () { + const expectedCode = r"""import 'package:dio/dio.dart' as dio; + +void main() async { + try { + final response = await dio.Dio().delete('https://reqres.in/api/users/2'); + print(response.statusCode); + print(response.data); + } on dio.DioException catch (e, s) { + print(e.response?.statusCode); + print(e.response?.data); + print(s); + } catch (e, s) { + print(e); + print(s); + } +} +"""; + expect( + codeGen.getCode( + CodegenLanguage.dartDio, requestModelDelete1, "https"), + expectedCode); }); test('DELETE 2', () { @@ -545,13 +907,13 @@ void main() async { "name": "marfeus", "job": "accountant" }'''); - final response = await dio.Dio.delete( + final response = await dio.Dio().delete( 'https://reqres.in/api/users/2', data: data, ); print(response.statusCode); print(response.data); - } on DioException catch (e, s) { + } on dio.DioException catch (e, s) { print(e.response?.statusCode); print(e.response?.data); print(s); @@ -562,7 +924,9 @@ void main() async { } """; expect( - dartDioCodeGen.getCode(requestModelDelete2, "https"), expectedCode); + codeGen.getCode( + CodegenLanguage.dartDio, requestModelDelete2, "https"), + expectedCode); }); }); } diff --git a/test/codegen/dart_http_codegen_test.dart b/test/codegen/dart_http_codegen_test.dart index 55ab070a..6bf16114 100644 --- a/test/codegen/dart_http_codegen_test.dart +++ b/test/codegen/dart_http_codegen_test.dart @@ -1,17 +1,17 @@ -import 'package:apidash/codegen/dart/http.dart'; +import 'package:apidash/codegen/codegen.dart'; +import 'package:apidash/consts.dart'; import 'package:test/test.dart'; - import '../request_models.dart'; void main() { - final dartHttpCodeGen = DartHttpCodeGen(); + final codeGen = Codegen(); group('GET Request', () { test('GET 1', () { const expectedCode = r"""import 'package:http/http.dart' as http; void main() async { - var uri = Uri.parse('https://api.foss42.com'); + var uri = Uri.parse('https://api.apidash.dev'); final response = await http.get(uri); @@ -25,14 +25,16 @@ void main() async { } } """; - expect(dartHttpCodeGen.getCode(requestModelGet1, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.dartHttp, requestModelGet1, "https"), + expectedCode); }); test('GET 2', () { const expectedCode = r"""import 'package:http/http.dart' as http; void main() async { - var uri = Uri.parse('https://api.foss42.com/country/data'); + var uri = Uri.parse('https://api.apidash.dev/country/data'); var queryParams = {'code': 'US'}; uri = uri.replace(queryParameters: queryParams); @@ -50,14 +52,16 @@ void main() async { } """; - expect(dartHttpCodeGen.getCode(requestModelGet2, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.dartHttp, requestModelGet2, "https"), + expectedCode); }); test('GET 3', () { const expectedCode = r"""import 'package:http/http.dart' as http; void main() async { - var uri = Uri.parse('https://api.foss42.com/country/data?code=US'); + var uri = Uri.parse('https://api.apidash.dev/country/data?code=US'); var queryParams = {'code': 'IND'}; var urlQueryParams = Map.from(uri.queryParameters); @@ -76,14 +80,16 @@ void main() async { } } """; - expect(dartHttpCodeGen.getCode(requestModelGet3, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.dartHttp, requestModelGet3, "https"), + expectedCode); }); test('GET 4', () { const expectedCode = r"""import 'package:http/http.dart' as http; void main() async { - var uri = Uri.parse('https://api.foss42.com/humanize/social'); + var uri = Uri.parse('https://api.apidash.dev/humanize/social'); var queryParams = { 'num': '8700000', @@ -106,7 +112,9 @@ void main() async { } } """; - expect(dartHttpCodeGen.getCode(requestModelGet4, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.dartHttp, requestModelGet4, "https"), + expectedCode); }); test('GET 5', () { @@ -132,7 +140,9 @@ void main() async { } } """; - expect(dartHttpCodeGen.getCode(requestModelGet5, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.dartHttp, requestModelGet5, "https"), + expectedCode); }); test('GET 6', () { @@ -161,14 +171,16 @@ void main() async { } } """; - expect(dartHttpCodeGen.getCode(requestModelGet6, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.dartHttp, requestModelGet6, "https"), + expectedCode); }); test('GET 7', () { const expectedCode = r"""import 'package:http/http.dart' as http; void main() async { - var uri = Uri.parse('https://api.foss42.com'); + var uri = Uri.parse('https://api.apidash.dev'); final response = await http.get(uri); @@ -182,7 +194,9 @@ void main() async { } } """; - expect(dartHttpCodeGen.getCode(requestModelGet7, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.dartHttp, requestModelGet7, "https"), + expectedCode); }); test('GET 8', () { @@ -211,14 +225,16 @@ void main() async { } } """; - expect(dartHttpCodeGen.getCode(requestModelGet8, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.dartHttp, requestModelGet8, "https"), + expectedCode); }); test('GET 9', () { const expectedCode = r"""import 'package:http/http.dart' as http; void main() async { - var uri = Uri.parse('https://api.foss42.com/humanize/social'); + var uri = Uri.parse('https://api.apidash.dev/humanize/social'); var queryParams = { 'num': '8700000', @@ -238,14 +254,16 @@ void main() async { } } """; - expect(dartHttpCodeGen.getCode(requestModelGet9, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.dartHttp, requestModelGet9, "https"), + expectedCode); }); test('GET 10', () { const expectedCode = r"""import 'package:http/http.dart' as http; void main() async { - var uri = Uri.parse('https://api.foss42.com/humanize/social'); + var uri = Uri.parse('https://api.apidash.dev/humanize/social'); var headers = {'User-Agent': 'Test Agent'}; @@ -265,7 +283,8 @@ void main() async { } """; expect( - dartHttpCodeGen.getCode( + codeGen.getCode( + CodegenLanguage.dartHttp, requestModelGet10, "https", ), @@ -276,7 +295,7 @@ void main() async { const expectedCode = r"""import 'package:http/http.dart' as http; void main() async { - var uri = Uri.parse('https://api.foss42.com/humanize/social'); + var uri = Uri.parse('https://api.apidash.dev/humanize/social'); var queryParams = { 'num': '8700000', @@ -301,14 +320,16 @@ void main() async { } } """; - expect(dartHttpCodeGen.getCode(requestModelGet11, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.dartHttp, requestModelGet11, "https"), + expectedCode); }); test('GET 12', () { const expectedCode = r"""import 'package:http/http.dart' as http; void main() async { - var uri = Uri.parse('https://api.foss42.com/humanize/social'); + var uri = Uri.parse('https://api.apidash.dev/humanize/social'); final response = await http.get(uri); @@ -322,7 +343,9 @@ void main() async { } } """; - expect(dartHttpCodeGen.getCode(requestModelGet12, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.dartHttp, requestModelGet12, "https"), + expectedCode); }); }); @@ -331,7 +354,7 @@ void main() async { const expectedCode = r"""import 'package:http/http.dart' as http; void main() async { - var uri = Uri.parse('https://api.foss42.com'); + var uri = Uri.parse('https://api.apidash.dev'); final response = await http.head(uri); @@ -345,14 +368,16 @@ void main() async { } } """; - expect(dartHttpCodeGen.getCode(requestModelHead1, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.dartHttp, requestModelHead1, "https"), + expectedCode); }); test('HEAD 2', () { const expectedCode = r"""import 'package:http/http.dart' as http; void main() async { - var uri = Uri.parse('http://api.foss42.com'); + var uri = Uri.parse('http://api.apidash.dev'); final response = await http.head(uri); @@ -366,7 +391,9 @@ void main() async { } } """; - expect(dartHttpCodeGen.getCode(requestModelHead2, "http"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.dartHttp, requestModelHead2, "http"), + expectedCode); }); }); @@ -375,7 +402,7 @@ void main() async { const expectedCode = r"""import 'package:http/http.dart' as http; void main() async { - var uri = Uri.parse('https://api.foss42.com/case/lower'); + var uri = Uri.parse('https://api.apidash.dev/case/lower'); String body = r'''{ "text": "I LOVE Flutter" @@ -399,17 +426,24 @@ void main() async { } } """; - expect(dartHttpCodeGen.getCode(requestModelPost1, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.dartHttp, requestModelPost1, "https"), + expectedCode); }); test('POST 2', () { const expectedCode = r"""import 'package:http/http.dart' as http; void main() async { - var uri = Uri.parse('https://api.foss42.com/case/lower'); + var uri = Uri.parse('https://api.apidash.dev/case/lower'); String body = r'''{ -"text": "I LOVE Flutter" +"text": "I LOVE Flutter", +"flag": null, +"male": true, +"female": false, +"no": 1.2, +"arr": ["null", "true", "false", null] }'''; var headers = {'content-type': 'application/json'}; @@ -430,14 +464,16 @@ void main() async { } } """; - expect(dartHttpCodeGen.getCode(requestModelPost2, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.dartHttp, requestModelPost2, "https"), + expectedCode); }); test('POST 3', () { const expectedCode = r"""import 'package:http/http.dart' as http; void main() async { - var uri = Uri.parse('https://api.foss42.com/case/lower'); + var uri = Uri.parse('https://api.apidash.dev/case/lower'); String body = r'''{ "text": "I LOVE Flutter" @@ -464,8 +500,377 @@ void main() async { } } """; - expect(dartHttpCodeGen.getCode(requestModelPost3, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.dartHttp, requestModelPost3, "https"), + expectedCode); }); + test('POST 4', () { + const expectedCode = r"""import 'package:http/http.dart' as http; + +void main() async { + var uri = Uri.parse('https://api.apidash.dev/io/form'); + + final formDataList = [ + {"name": "text", "value": "API", "type": "text"}, + {"name": "sep", "value": "|", "type": "text"}, + {"name": "times", "value": "3", "type": "text"} + ]; + final request = http.MultipartRequest( + "POST", + uri, + ); + for (var formData in formDataList) { + if (formData != null) { + final name = formData['name']; + final value = formData['value']; + final type = formData['type']; + + if (name != null && value != null && type != null) { + if (type == 'text') { + request.fields.addAll({name: value}); + } else { + request.files.add( + await http.MultipartFile.fromPath( + name, + value, + ), + ); + } + } else { + print('Error: formData has null name, value, or type.'); + } + } else { + print('Error: formData is null.'); + } + } + + final response = await request.send(); + final responseBody = await response.stream.bytesToString(); + int statusCode = response.statusCode; + + if (statusCode >= 200 && statusCode < 300) { + print('Status Code: $statusCode'); + print('Response Body: :$responseBody'); + } else { + print('Error Status Code: $statusCode'); + print('Error Response Body: :$responseBody'); + } +} +"""; + expect( + codeGen.getCode( + CodegenLanguage.dartHttp, requestModelPost4, "https"), + expectedCode); + }); + test('POST 5', () { + const expectedCode = r"""import 'package:http/http.dart' as http; + +void main() async { + var uri = Uri.parse('https://api.apidash.dev/io/form'); + + var headers = {'User-Agent': 'Test Agent'}; + + final formDataList = [ + {"name": "text", "value": "API", "type": "text"}, + {"name": "sep", "value": "|", "type": "text"}, + {"name": "times", "value": "3", "type": "text"} + ]; + final request = http.MultipartRequest( + "POST", + uri, + ); + for (var formData in formDataList) { + if (formData != null) { + final name = formData['name']; + final value = formData['value']; + final type = formData['type']; + + if (name != null && value != null && type != null) { + if (type == 'text') { + request.fields.addAll({name: value}); + } else { + request.files.add( + await http.MultipartFile.fromPath( + name, + value, + ), + ); + } + } else { + print('Error: formData has null name, value, or type.'); + } + } else { + print('Error: formData is null.'); + } + } + + request.headers.addAll(headers); + final response = await request.send(); + final responseBody = await response.stream.bytesToString(); + int statusCode = response.statusCode; + + if (statusCode >= 200 && statusCode < 300) { + print('Status Code: $statusCode'); + print('Response Body: :$responseBody'); + } else { + print('Error Status Code: $statusCode'); + print('Error Response Body: :$responseBody'); + } +} +"""; + expect( + codeGen.getCode( + CodegenLanguage.dartHttp, requestModelPost5, "https"), + expectedCode); + }); + test('POST 6', () { + const expectedCode = r"""import 'package:http/http.dart' as http; + +void main() async { + var uri = Uri.parse('https://api.apidash.dev/io/img'); + + final formDataList = [ + {"name": "token", "value": "xyz", "type": "text"}, + {"name": "imfile", "value": "/Documents/up/1.png", "type": "file"} + ]; + final request = http.MultipartRequest( + "POST", + uri, + ); + for (var formData in formDataList) { + if (formData != null) { + final name = formData['name']; + final value = formData['value']; + final type = formData['type']; + + if (name != null && value != null && type != null) { + if (type == 'text') { + request.fields.addAll({name: value}); + } else { + request.files.add( + await http.MultipartFile.fromPath( + name, + value, + ), + ); + } + } else { + print('Error: formData has null name, value, or type.'); + } + } else { + print('Error: formData is null.'); + } + } + + final response = await request.send(); + final responseBody = await response.stream.bytesToString(); + int statusCode = response.statusCode; + + if (statusCode >= 200 && statusCode < 300) { + print('Status Code: $statusCode'); + print('Response Body: :$responseBody'); + } else { + print('Error Status Code: $statusCode'); + print('Error Response Body: :$responseBody'); + } +} +"""; + expect( + codeGen.getCode( + CodegenLanguage.dartHttp, requestModelPost6, "https"), + expectedCode); + }); + test('POST 7', () { + const expectedCode = r"""import 'package:http/http.dart' as http; + +void main() async { + var uri = Uri.parse('https://api.apidash.dev/io/img'); + + final formDataList = [ + {"name": "token", "value": "xyz", "type": "text"}, + {"name": "imfile", "value": "/Documents/up/1.png", "type": "file"} + ]; + final request = http.MultipartRequest( + "POST", + uri, + ); + for (var formData in formDataList) { + if (formData != null) { + final name = formData['name']; + final value = formData['value']; + final type = formData['type']; + + if (name != null && value != null && type != null) { + if (type == 'text') { + request.fields.addAll({name: value}); + } else { + request.files.add( + await http.MultipartFile.fromPath( + name, + value, + ), + ); + } + } else { + print('Error: formData has null name, value, or type.'); + } + } else { + print('Error: formData is null.'); + } + } + + final response = await request.send(); + final responseBody = await response.stream.bytesToString(); + int statusCode = response.statusCode; + + if (statusCode >= 200 && statusCode < 300) { + print('Status Code: $statusCode'); + print('Response Body: :$responseBody'); + } else { + print('Error Status Code: $statusCode'); + print('Error Response Body: :$responseBody'); + } +} +"""; + expect( + codeGen.getCode( + CodegenLanguage.dartHttp, requestModelPost7, "https"), + expectedCode); + }); + test('POST 8', () { + const expectedCode = r"""import 'package:http/http.dart' as http; + +void main() async { + var uri = Uri.parse('https://api.apidash.dev/io/form'); + + var queryParams = { + 'size': '2', + 'len': '3', + }; + uri = uri.replace(queryParameters: queryParams); + + final formDataList = [ + {"name": "text", "value": "API", "type": "text"}, + {"name": "sep", "value": "|", "type": "text"}, + {"name": "times", "value": "3", "type": "text"} + ]; + final request = http.MultipartRequest( + "POST", + uri, + ); + for (var formData in formDataList) { + if (formData != null) { + final name = formData['name']; + final value = formData['value']; + final type = formData['type']; + + if (name != null && value != null && type != null) { + if (type == 'text') { + request.fields.addAll({name: value}); + } else { + request.files.add( + await http.MultipartFile.fromPath( + name, + value, + ), + ); + } + } else { + print('Error: formData has null name, value, or type.'); + } + } else { + print('Error: formData is null.'); + } + } + + final response = await request.send(); + final responseBody = await response.stream.bytesToString(); + int statusCode = response.statusCode; + + if (statusCode >= 200 && statusCode < 300) { + print('Status Code: $statusCode'); + print('Response Body: :$responseBody'); + } else { + print('Error Status Code: $statusCode'); + print('Error Response Body: :$responseBody'); + } +} +"""; + expect( + codeGen.getCode( + CodegenLanguage.dartHttp, requestModelPost8, "https"), + expectedCode); + }); + test('POST 9', () { + const expectedCode = r"""import 'package:http/http.dart' as http; + +void main() async { + var uri = Uri.parse('https://api.apidash.dev/io/img'); + + var queryParams = { + 'size': '2', + 'len': '3', + }; + uri = uri.replace(queryParameters: queryParams); + + var headers = { + 'User-Agent': 'Test Agent', + 'Keep-Alive': 'true', + }; + + final formDataList = [ + {"name": "token", "value": "xyz", "type": "text"}, + {"name": "imfile", "value": "/Documents/up/1.png", "type": "file"} + ]; + final request = http.MultipartRequest( + "POST", + uri, + ); + for (var formData in formDataList) { + if (formData != null) { + final name = formData['name']; + final value = formData['value']; + final type = formData['type']; + + if (name != null && value != null && type != null) { + if (type == 'text') { + request.fields.addAll({name: value}); + } else { + request.files.add( + await http.MultipartFile.fromPath( + name, + value, + ), + ); + } + } else { + print('Error: formData has null name, value, or type.'); + } + } else { + print('Error: formData is null.'); + } + } + + request.headers.addAll(headers); + final response = await request.send(); + final responseBody = await response.stream.bytesToString(); + int statusCode = response.statusCode; + + if (statusCode >= 200 && statusCode < 300) { + print('Status Code: $statusCode'); + print('Response Body: :$responseBody'); + } else { + print('Error Status Code: $statusCode'); + print('Error Response Body: :$responseBody'); + } +} +"""; + expect( + codeGen.getCode( + CodegenLanguage.dartHttp, requestModelPost9, "https"), + expectedCode); + }); + }); group('PUT Request', () { @@ -498,7 +903,9 @@ void main() async { } } """; - expect(dartHttpCodeGen.getCode(requestModelPut1, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.dartHttp, requestModelPut1, "https"), + expectedCode); }); }); @@ -533,7 +940,9 @@ void main() async { } """; expect( - dartHttpCodeGen.getCode(requestModelPatch1, "https"), expectedCode); + codeGen.getCode( + CodegenLanguage.dartHttp, requestModelPatch1, "https"), + expectedCode); }); }); @@ -557,7 +966,9 @@ void main() async { } """; expect( - dartHttpCodeGen.getCode(requestModelDelete1, "https"), expectedCode); + codeGen.getCode( + CodegenLanguage.dartHttp, requestModelDelete1, "https"), + expectedCode); }); test('DELETE 2', () { @@ -590,7 +1001,9 @@ void main() async { } """; expect( - dartHttpCodeGen.getCode(requestModelDelete2, "https"), expectedCode); + codeGen.getCode( + CodegenLanguage.dartHttp, requestModelDelete2, "https"), + expectedCode); }); }); } diff --git a/test/codegen/go_http_codegen_test.dart b/test/codegen/go_http_codegen_test.dart new file mode 100644 index 00000000..421f8018 --- /dev/null +++ b/test/codegen/go_http_codegen_test.dart @@ -0,0 +1,1047 @@ +import 'package:apidash/codegen/codegen.dart'; +import 'package:apidash/consts.dart'; +import 'package:apidash/screens/home_page/editor_pane/details_card/code_pane.dart'; +import 'package:test/test.dart'; +import '../request_models.dart'; + +void main() { + final codeGen = Codegen(); + + group('GET Request', () { + test('GET 1', () { + const expectedCode = r"""package main + +import ( + "fmt" + "io" + "net/http" + "net/url" +) + +func main() { + client := &http.Client{} + url, _ := url.Parse("https://api.apidash.dev") + req, _ := http.NewRequest("GET", url.String(), nil) + + response, err := client.Do(req) + if err != nil { + fmt.Println(err) + return + } + defer response.Body.Close() + + fmt.Println("Status Code:", response.StatusCode) + body, _ := io.ReadAll(response.Body) + fmt.Println("Response body:", string(body)) +}"""; + expect(codeGen.getCode(CodegenLanguage.goHttp, requestModelGet1, "https"), + expectedCode); + }); + + test('GET 2', () { + const expectedCode = r"""package main + +import ( + "fmt" + "io" + "net/http" + "net/url" +) + +func main() { + client := &http.Client{} + url, _ := url.Parse("https://api.apidash.dev/country/data") + query := url.Query() + + query.Set("code", "US") + + url.RawQuery = query.Encode() + req, _ := http.NewRequest("GET", url.String(), nil) + + response, err := client.Do(req) + if err != nil { + fmt.Println(err) + return + } + defer response.Body.Close() + + fmt.Println("Status Code:", response.StatusCode) + body, _ := io.ReadAll(response.Body) + fmt.Println("Response body:", string(body)) +}"""; + expect(codeGen.getCode(CodegenLanguage.goHttp, requestModelGet2, "https"), + expectedCode); + }); + + test('GET 3', () { + const expectedCode = r"""package main + +import ( + "fmt" + "io" + "net/http" + "net/url" +) + +func main() { + client := &http.Client{} + url, _ := url.Parse("https://api.apidash.dev/country/data?code=US") + query := url.Query() + + query.Set("code", "IND") + + url.RawQuery = query.Encode() + req, _ := http.NewRequest("GET", url.String(), nil) + + response, err := client.Do(req) + if err != nil { + fmt.Println(err) + return + } + defer response.Body.Close() + + fmt.Println("Status Code:", response.StatusCode) + body, _ := io.ReadAll(response.Body) + fmt.Println("Response body:", string(body)) +}"""; + expect(codeGen.getCode(CodegenLanguage.goHttp, requestModelGet3, "https"), + expectedCode); + }); + + test('GET 4', () { + const expectedCode = r"""package main + +import ( + "fmt" + "io" + "net/http" + "net/url" +) + +func main() { + client := &http.Client{} + url, _ := url.Parse("https://api.apidash.dev/humanize/social") + query := url.Query() + + query.Set("num", "8700000") + query.Set("digits", "3") + query.Set("system", "SS") + query.Set("add_space", "true") + query.Set("trailing_zeros", "true") + + url.RawQuery = query.Encode() + req, _ := http.NewRequest("GET", url.String(), nil) + + response, err := client.Do(req) + if err != nil { + fmt.Println(err) + return + } + defer response.Body.Close() + + fmt.Println("Status Code:", response.StatusCode) + body, _ := io.ReadAll(response.Body) + fmt.Println("Response body:", string(body)) +}"""; + expect(codeGen.getCode(CodegenLanguage.goHttp, requestModelGet4, "https"), + expectedCode); + }); + + test('GET 5', () { + const expectedCode = r"""package main + +import ( + "fmt" + "io" + "net/http" + "net/url" +) + +func main() { + client := &http.Client{} + url, _ := url.Parse("https://api.github.com/repos/foss42/apidash") + req, _ := http.NewRequest("GET", url.String(), nil) + + req.Header.Set("User-Agent", "Test Agent") + + response, err := client.Do(req) + if err != nil { + fmt.Println(err) + return + } + defer response.Body.Close() + + fmt.Println("Status Code:", response.StatusCode) + body, _ := io.ReadAll(response.Body) + fmt.Println("Response body:", string(body)) +}"""; + expect(codeGen.getCode(CodegenLanguage.goHttp, requestModelGet5, "https"), + expectedCode); + }); + + test('GET 6', () { + const expectedCode = r"""package main + +import ( + "fmt" + "io" + "net/http" + "net/url" +) + +func main() { + client := &http.Client{} + url, _ := url.Parse("https://api.github.com/repos/foss42/apidash") + query := url.Query() + + query.Set("raw", "true") + + url.RawQuery = query.Encode() + req, _ := http.NewRequest("GET", url.String(), nil) + + req.Header.Set("User-Agent", "Test Agent") + + response, err := client.Do(req) + if err != nil { + fmt.Println(err) + return + } + defer response.Body.Close() + + fmt.Println("Status Code:", response.StatusCode) + body, _ := io.ReadAll(response.Body) + fmt.Println("Response body:", string(body)) +}"""; + expect(codeGen.getCode(CodegenLanguage.goHttp, requestModelGet6, "https"), + expectedCode); + }); + + test('GET 7', () { + const expectedCode = r"""package main + +import ( + "fmt" + "io" + "net/http" + "net/url" +) + +func main() { + client := &http.Client{} + url, _ := url.Parse("https://api.apidash.dev") + req, _ := http.NewRequest("GET", url.String(), nil) + + response, err := client.Do(req) + if err != nil { + fmt.Println(err) + return + } + defer response.Body.Close() + + fmt.Println("Status Code:", response.StatusCode) + body, _ := io.ReadAll(response.Body) + fmt.Println("Response body:", string(body)) +}"""; + expect(codeGen.getCode(CodegenLanguage.goHttp, requestModelGet7, "https"), + expectedCode); + }); + + test('GET 8', () { + const expectedCode = r"""package main + +import ( + "fmt" + "io" + "net/http" + "net/url" +) + +func main() { + client := &http.Client{} + url, _ := url.Parse("https://api.github.com/repos/foss42/apidash") + query := url.Query() + + query.Set("raw", "true") + + url.RawQuery = query.Encode() + req, _ := http.NewRequest("GET", url.String(), nil) + + req.Header.Set("User-Agent", "Test Agent") + + response, err := client.Do(req) + if err != nil { + fmt.Println(err) + return + } + defer response.Body.Close() + + fmt.Println("Status Code:", response.StatusCode) + body, _ := io.ReadAll(response.Body) + fmt.Println("Response body:", string(body)) +}"""; + expect(codeGen.getCode(CodegenLanguage.goHttp, requestModelGet8, "https"), + expectedCode); + }); + + test('GET 9', () { + const expectedCode = r"""package main + +import ( + "fmt" + "io" + "net/http" + "net/url" +) + +func main() { + client := &http.Client{} + url, _ := url.Parse("https://api.apidash.dev/humanize/social") + query := url.Query() + + query.Set("num", "8700000") + query.Set("add_space", "true") + + url.RawQuery = query.Encode() + req, _ := http.NewRequest("GET", url.String(), nil) + + response, err := client.Do(req) + if err != nil { + fmt.Println(err) + return + } + defer response.Body.Close() + + fmt.Println("Status Code:", response.StatusCode) + body, _ := io.ReadAll(response.Body) + fmt.Println("Response body:", string(body)) +}"""; + expect(codeGen.getCode(CodegenLanguage.goHttp, requestModelGet9, "https"), + expectedCode); + }); + + test('GET 10', () { + const expectedCode = r"""package main + +import ( + "fmt" + "io" + "net/http" + "net/url" +) + +func main() { + client := &http.Client{} + url, _ := url.Parse("https://api.apidash.dev/humanize/social") + req, _ := http.NewRequest("GET", url.String(), nil) + + req.Header.Set("User-Agent", "Test Agent") + + response, err := client.Do(req) + if err != nil { + fmt.Println(err) + return + } + defer response.Body.Close() + + fmt.Println("Status Code:", response.StatusCode) + body, _ := io.ReadAll(response.Body) + fmt.Println("Response body:", string(body)) +}"""; + expect( + codegen.getCode( + CodegenLanguage.goHttp, + requestModelGet10, + "https", + ), + expectedCode); + }); + + test('GET 11', () { + const expectedCode = r"""package main + +import ( + "fmt" + "io" + "net/http" + "net/url" +) + +func main() { + client := &http.Client{} + url, _ := url.Parse("https://api.apidash.dev/humanize/social") + query := url.Query() + + query.Set("num", "8700000") + query.Set("digits", "3") + + url.RawQuery = query.Encode() + req, _ := http.NewRequest("GET", url.String(), nil) + + req.Header.Set("User-Agent", "Test Agent") + + response, err := client.Do(req) + if err != nil { + fmt.Println(err) + return + } + defer response.Body.Close() + + fmt.Println("Status Code:", response.StatusCode) + body, _ := io.ReadAll(response.Body) + fmt.Println("Response body:", string(body)) +}"""; + expect( + codeGen.getCode(CodegenLanguage.goHttp, requestModelGet11, "https"), + expectedCode); + }); + + test('GET 12', () { + const expectedCode = r"""package main + +import ( + "fmt" + "io" + "net/http" + "net/url" +) + +func main() { + client := &http.Client{} + url, _ := url.Parse("https://api.apidash.dev/humanize/social") + req, _ := http.NewRequest("GET", url.String(), nil) + + response, err := client.Do(req) + if err != nil { + fmt.Println(err) + return + } + defer response.Body.Close() + + fmt.Println("Status Code:", response.StatusCode) + body, _ := io.ReadAll(response.Body) + fmt.Println("Response body:", string(body)) +}"""; + expect( + codeGen.getCode(CodegenLanguage.goHttp, requestModelGet12, "https"), + expectedCode); + }); + }); + + group('HEAD Request', () { + test('HEAD 1', () { + const expectedCode = r"""package main + +import ( + "fmt" + "io" + "net/http" + "net/url" +) + +func main() { + client := &http.Client{} + url, _ := url.Parse("https://api.apidash.dev") + req, _ := http.NewRequest("HEAD", url.String(), nil) + + response, err := client.Do(req) + if err != nil { + fmt.Println(err) + return + } + defer response.Body.Close() + + fmt.Println("Status Code:", response.StatusCode) + body, _ := io.ReadAll(response.Body) + fmt.Println("Response body:", string(body)) +}"""; + expect( + codeGen.getCode(CodegenLanguage.goHttp, requestModelHead1, "https"), + expectedCode); + }); + + test('HEAD 2', () { + const expectedCode = r"""package main + +import ( + "fmt" + "io" + "net/http" + "net/url" +) + +func main() { + client := &http.Client{} + url, _ := url.Parse("http://api.apidash.dev") + req, _ := http.NewRequest("HEAD", url.String(), nil) + + response, err := client.Do(req) + if err != nil { + fmt.Println(err) + return + } + defer response.Body.Close() + + fmt.Println("Status Code:", response.StatusCode) + body, _ := io.ReadAll(response.Body) + fmt.Println("Response body:", string(body)) +}"""; + expect(codeGen.getCode(CodegenLanguage.goHttp, requestModelHead2, "http"), + expectedCode); + }); + }); + + group('POST Request', () { + test('POST 1', () { + const expectedCode = r'''package main + +import ( + "fmt" + "io" + "net/http" + "net/url" + "bytes" +) + +func main() { + client := &http.Client{} + url, _ := url.Parse("https://api.apidash.dev/case/lower") + payload := bytes.NewBuffer([]byte(`{ +"text": "I LOVE Flutter" +}`)) + req, _ := http.NewRequest("POST", url.String(), payload) + + req.Header.Set("Content-Type", "text/plain") + + response, err := client.Do(req) + if err != nil { + fmt.Println(err) + return + } + defer response.Body.Close() + + fmt.Println("Status Code:", response.StatusCode) + body, _ := io.ReadAll(response.Body) + fmt.Println("Response body:", string(body)) +}'''; + expect( + codeGen.getCode(CodegenLanguage.goHttp, requestModelPost1, "https"), + expectedCode); + }); + + test('POST 2', () { + const expectedCode = r'''package main + +import ( + "fmt" + "io" + "net/http" + "net/url" + "bytes" +) + +func main() { + client := &http.Client{} + url, _ := url.Parse("https://api.apidash.dev/case/lower") + payload := bytes.NewBuffer([]byte(`{ +"text": "I LOVE Flutter", +"flag": null, +"male": true, +"female": false, +"no": 1.2, +"arr": ["null", "true", "false", null] +}`)) + req, _ := http.NewRequest("POST", url.String(), payload) + + req.Header.Set("Content-Type", "application/json") + + response, err := client.Do(req) + if err != nil { + fmt.Println(err) + return + } + defer response.Body.Close() + + fmt.Println("Status Code:", response.StatusCode) + body, _ := io.ReadAll(response.Body) + fmt.Println("Response body:", string(body)) +}'''; + expect( + codeGen.getCode(CodegenLanguage.goHttp, requestModelPost2, "https"), + expectedCode); + }); + + test('POST 3', () { + const expectedCode = r'''package main + +import ( + "fmt" + "io" + "net/http" + "net/url" + "bytes" +) + +func main() { + client := &http.Client{} + url, _ := url.Parse("https://api.apidash.dev/case/lower") + payload := bytes.NewBuffer([]byte(`{ +"text": "I LOVE Flutter" +}`)) + req, _ := http.NewRequest("POST", url.String(), payload) + + req.Header.Set("User-Agent", "Test Agent") + req.Header.Set("Content-Type", "application/json") + + response, err := client.Do(req) + if err != nil { + fmt.Println(err) + return + } + defer response.Body.Close() + + fmt.Println("Status Code:", response.StatusCode) + body, _ := io.ReadAll(response.Body) + fmt.Println("Response body:", string(body)) +}'''; + expect( + codeGen.getCode(CodegenLanguage.goHttp, requestModelPost3, "https"), + expectedCode); + }); + + test('POST 4', () { + const expectedCode = r'''package main + +import ( + "fmt" + "io" + "net/http" + "net/url" + "bytes" + "mime/multipart" +) + +func main() { + client := &http.Client{} + url, _ := url.Parse("https://api.apidash.dev/io/form") + payload := &bytes.Buffer{} + writer := multipart.NewWriter(payload) + + writer.WriteField("text", "API") + writer.WriteField("sep", "|") + writer.WriteField("times", "3") + writer.Close() + + req, _ := http.NewRequest("POST", url.String(), payload) + req.Header.Set("Content-Type", writer.FormDataContentType()) + + response, err := client.Do(req) + if err != nil { + fmt.Println(err) + return + } + defer response.Body.Close() + + fmt.Println("Status Code:", response.StatusCode) + body, _ := io.ReadAll(response.Body) + fmt.Println("Response body:", string(body)) +}'''; + expect( + codeGen.getCode(CodegenLanguage.goHttp, requestModelPost4, "https"), + expectedCode); + }); + + test('POST 5', () { + const expectedCode = r'''package main + +import ( + "fmt" + "io" + "net/http" + "net/url" + "bytes" + "mime/multipart" +) + +func main() { + client := &http.Client{} + url, _ := url.Parse("https://api.apidash.dev/io/form") + payload := &bytes.Buffer{} + writer := multipart.NewWriter(payload) + + writer.WriteField("text", "API") + writer.WriteField("sep", "|") + writer.WriteField("times", "3") + writer.Close() + + req, _ := http.NewRequest("POST", url.String(), payload) + + req.Header.Set("User-Agent", "Test Agent") + req.Header.Set("Content-Type", writer.FormDataContentType()) + + response, err := client.Do(req) + if err != nil { + fmt.Println(err) + return + } + defer response.Body.Close() + + fmt.Println("Status Code:", response.StatusCode) + body, _ := io.ReadAll(response.Body) + fmt.Println("Response body:", string(body)) +}'''; + expect( + codeGen.getCode(CodegenLanguage.goHttp, requestModelPost5, "https"), + expectedCode); + }); + }); + + test("POST 6", () { + const expectedCode = r'''package main + +import ( + "fmt" + "io" + "net/http" + "net/url" + "bytes" + "mime/multipart" + "os" +) + +func main() { + client := &http.Client{} + url, _ := url.Parse("https://api.apidash.dev/io/img") + payload := &bytes.Buffer{} + writer := multipart.NewWriter(payload) + var ( + file *os.File + part io.Writer + ) + + writer.WriteField("token", "xyz") + file, _ = os.Open("/Documents/up/1.png") + defer file.Close() + part, _ = writer.CreateFormFile("imfile", "/Documents/up/1.png") + io.Copy(part, file) + + writer.Close() + + req, _ := http.NewRequest("POST", url.String(), payload) + req.Header.Set("Content-Type", writer.FormDataContentType()) + + response, err := client.Do(req) + if err != nil { + fmt.Println(err) + return + } + defer response.Body.Close() + + fmt.Println("Status Code:", response.StatusCode) + body, _ := io.ReadAll(response.Body) + fmt.Println("Response body:", string(body)) +}'''; + expect(codeGen.getCode(CodegenLanguage.goHttp, requestModelPost6, "https"), + expectedCode); + }); + test("POST 7", () { + const expectedCode = r'''package main + +import ( + "fmt" + "io" + "net/http" + "net/url" + "bytes" + "mime/multipart" + "os" +) + +func main() { + client := &http.Client{} + url, _ := url.Parse("https://api.apidash.dev/io/img") + payload := &bytes.Buffer{} + writer := multipart.NewWriter(payload) + var ( + file *os.File + part io.Writer + ) + + writer.WriteField("token", "xyz") + file, _ = os.Open("/Documents/up/1.png") + defer file.Close() + part, _ = writer.CreateFormFile("imfile", "/Documents/up/1.png") + io.Copy(part, file) + + writer.Close() + + req, _ := http.NewRequest("POST", url.String(), payload) + req.Header.Set("Content-Type", writer.FormDataContentType()) + + response, err := client.Do(req) + if err != nil { + fmt.Println(err) + return + } + defer response.Body.Close() + + fmt.Println("Status Code:", response.StatusCode) + body, _ := io.ReadAll(response.Body) + fmt.Println("Response body:", string(body)) +}'''; + expect(codeGen.getCode(CodegenLanguage.goHttp, requestModelPost7, "https"), + expectedCode); + }); + test("POST 8", () { + const expectedCode = r'''package main + +import ( + "fmt" + "io" + "net/http" + "net/url" + "bytes" + "mime/multipart" +) + +func main() { + client := &http.Client{} + url, _ := url.Parse("https://api.apidash.dev/io/form") + payload := &bytes.Buffer{} + writer := multipart.NewWriter(payload) + + writer.WriteField("text", "API") + writer.WriteField("sep", "|") + writer.WriteField("times", "3") + writer.Close() + + query := url.Query() + + query.Set("size", "2") + query.Set("len", "3") + + url.RawQuery = query.Encode() + req, _ := http.NewRequest("POST", url.String(), payload) + req.Header.Set("Content-Type", writer.FormDataContentType()) + + response, err := client.Do(req) + if err != nil { + fmt.Println(err) + return + } + defer response.Body.Close() + + fmt.Println("Status Code:", response.StatusCode) + body, _ := io.ReadAll(response.Body) + fmt.Println("Response body:", string(body)) +}'''; + expect(codeGen.getCode(CodegenLanguage.goHttp, requestModelPost8, "https"), + expectedCode); + }); + test("POST 9", () { + const expectedCode = r'''package main + +import ( + "fmt" + "io" + "net/http" + "net/url" + "bytes" + "mime/multipart" + "os" +) + +func main() { + client := &http.Client{} + url, _ := url.Parse("https://api.apidash.dev/io/img") + payload := &bytes.Buffer{} + writer := multipart.NewWriter(payload) + var ( + file *os.File + part io.Writer + ) + + writer.WriteField("token", "xyz") + file, _ = os.Open("/Documents/up/1.png") + defer file.Close() + part, _ = writer.CreateFormFile("imfile", "/Documents/up/1.png") + io.Copy(part, file) + + writer.Close() + + query := url.Query() + + query.Set("size", "2") + query.Set("len", "3") + + url.RawQuery = query.Encode() + req, _ := http.NewRequest("POST", url.String(), payload) + + req.Header.Set("User-Agent", "Test Agent") + req.Header.Set("Keep-Alive", "true") + req.Header.Set("Content-Type", writer.FormDataContentType()) + + response, err := client.Do(req) + if err != nil { + fmt.Println(err) + return + } + defer response.Body.Close() + + fmt.Println("Status Code:", response.StatusCode) + body, _ := io.ReadAll(response.Body) + fmt.Println("Response body:", string(body)) +}'''; + expect(codeGen.getCode(CodegenLanguage.goHttp, requestModelPost9, "https"), + expectedCode); + }); + + group('PUT Request', () { + test('PUT 1', () { + const expectedCode = r'''package main + +import ( + "fmt" + "io" + "net/http" + "net/url" + "bytes" +) + +func main() { + client := &http.Client{} + url, _ := url.Parse("https://reqres.in/api/users/2") + payload := bytes.NewBuffer([]byte(`{ +"name": "morpheus", +"job": "zion resident" +}`)) + req, _ := http.NewRequest("PUT", url.String(), payload) + + req.Header.Set("Content-Type", "application/json") + + response, err := client.Do(req) + if err != nil { + fmt.Println(err) + return + } + defer response.Body.Close() + + fmt.Println("Status Code:", response.StatusCode) + body, _ := io.ReadAll(response.Body) + fmt.Println("Response body:", string(body)) +}'''; + expect(codeGen.getCode(CodegenLanguage.goHttp, requestModelPut1, "https"), + expectedCode); + }); + }); + + group('PATCH Request', () { + test('PATCH 1', () { + const expectedCode = r'''package main + +import ( + "fmt" + "io" + "net/http" + "net/url" + "bytes" +) + +func main() { + client := &http.Client{} + url, _ := url.Parse("https://reqres.in/api/users/2") + payload := bytes.NewBuffer([]byte(`{ +"name": "marfeus", +"job": "accountant" +}`)) + req, _ := http.NewRequest("PATCH", url.String(), payload) + + req.Header.Set("Content-Type", "application/json") + + response, err := client.Do(req) + if err != nil { + fmt.Println(err) + return + } + defer response.Body.Close() + + fmt.Println("Status Code:", response.StatusCode) + body, _ := io.ReadAll(response.Body) + fmt.Println("Response body:", string(body)) +}'''; + expect( + codeGen.getCode(CodegenLanguage.goHttp, requestModelPatch1, "https"), + expectedCode); + }); + }); + + group('DELETE Request', () { + test('DELETE 1', () { + const expectedCode = r"""package main + +import ( + "fmt" + "io" + "net/http" + "net/url" +) + +func main() { + client := &http.Client{} + url, _ := url.Parse("https://reqres.in/api/users/2") + req, _ := http.NewRequest("DELETE", url.String(), nil) + + response, err := client.Do(req) + if err != nil { + fmt.Println(err) + return + } + defer response.Body.Close() + + fmt.Println("Status Code:", response.StatusCode) + body, _ := io.ReadAll(response.Body) + fmt.Println("Response body:", string(body)) +}"""; + expect( + codeGen.getCode(CodegenLanguage.goHttp, requestModelDelete1, "https"), + expectedCode); + }); + + test('DELETE 2', () { + const expectedCode = r'''package main + +import ( + "fmt" + "io" + "net/http" + "net/url" + "bytes" +) + +func main() { + client := &http.Client{} + url, _ := url.Parse("https://reqres.in/api/users/2") + payload := bytes.NewBuffer([]byte(`{ +"name": "marfeus", +"job": "accountant" +}`)) + req, _ := http.NewRequest("DELETE", url.String(), payload) + + req.Header.Set("Content-Type", "application/json") + + response, err := client.Do(req) + if err != nil { + fmt.Println(err) + return + } + defer response.Body.Close() + + fmt.Println("Status Code:", response.StatusCode) + body, _ := io.ReadAll(response.Body) + fmt.Println("Response body:", string(body)) +}'''; + expect( + codeGen.getCode(CodegenLanguage.goHttp, requestModelDelete2, "https"), + expectedCode); + }); + }); +} diff --git a/test/codegen/har_codegen_test.dart b/test/codegen/har_codegen_test.dart index 8e6b7bb0..767afc98 100644 --- a/test/codegen/har_codegen_test.dart +++ b/test/codegen/har_codegen_test.dart @@ -1,26 +1,28 @@ -import 'package:apidash/codegen/others/har.dart'; -import '../request_models.dart'; +import 'package:apidash/codegen/codegen.dart'; +import 'package:apidash/consts.dart'; import 'package:test/test.dart'; +import '../request_models.dart'; void main() { - final harCodeGen = HARCodeGen(); + final codeGen = Codegen(); group('GET Request', () { test('GET 1', () { const expectedCode = r"""{ "method": "GET", - "url": "https://api.foss42.com", + "url": "https://api.apidash.dev", "httpVersion": "HTTP/1.1", "queryString": [], "headers": [] }"""; - expect(harCodeGen.getCode(requestModelGet1, "https"), expectedCode); + expect(codeGen.getCode(CodegenLanguage.har, requestModelGet1, "https"), + expectedCode); }); test('GET 2', () { const expectedCode = r"""{ "method": "GET", - "url": "https://api.foss42.com/country/data?code=US", + "url": "https://api.apidash.dev/country/data?code=US", "httpVersion": "HTTP/1.1", "queryString": [ { @@ -30,13 +32,14 @@ void main() { ], "headers": [] }"""; - expect(harCodeGen.getCode(requestModelGet2, "https"), expectedCode); + expect(codeGen.getCode(CodegenLanguage.har, requestModelGet2, "https"), + expectedCode); }); test('GET 3', () { const expectedCode = r"""{ "method": "GET", - "url": "https://api.foss42.com/country/data?code=IND", + "url": "https://api.apidash.dev/country/data?code=IND", "httpVersion": "HTTP/1.1", "queryString": [ { @@ -46,13 +49,14 @@ void main() { ], "headers": [] }"""; - expect(harCodeGen.getCode(requestModelGet3, "https"), expectedCode); + expect(codeGen.getCode(CodegenLanguage.har, requestModelGet3, "https"), + expectedCode); }); test('GET 4', () { const expectedCode = r"""{ "method": "GET", - "url": "https://api.foss42.com/humanize/social?num=8700000&digits=3&system=SS&add_space=true&trailing_zeros=true", + "url": "https://api.apidash.dev/humanize/social?num=8700000&digits=3&system=SS&add_space=true&trailing_zeros=true", "httpVersion": "HTTP/1.1", "queryString": [ { @@ -78,7 +82,8 @@ void main() { ], "headers": [] }"""; - expect(harCodeGen.getCode(requestModelGet4, "https"), expectedCode); + expect(codeGen.getCode(CodegenLanguage.har, requestModelGet4, "https"), + expectedCode); }); test('GET 5', () { @@ -94,7 +99,8 @@ void main() { } ] }"""; - expect(harCodeGen.getCode(requestModelGet5, "https"), expectedCode); + expect(codeGen.getCode(CodegenLanguage.har, requestModelGet5, "https"), + expectedCode); }); test('GET 6', () { @@ -115,18 +121,20 @@ void main() { } ] }"""; - expect(harCodeGen.getCode(requestModelGet6, "https"), expectedCode); + expect(codeGen.getCode(CodegenLanguage.har, requestModelGet6, "https"), + expectedCode); }); test('GET 7', () { const expectedCode = r"""{ "method": "GET", - "url": "https://api.foss42.com", + "url": "https://api.apidash.dev", "httpVersion": "HTTP/1.1", "queryString": [], "headers": [] }"""; - expect(harCodeGen.getCode(requestModelGet7, "https"), expectedCode); + expect(codeGen.getCode(CodegenLanguage.har, requestModelGet7, "https"), + expectedCode); }); test('GET 8', () { @@ -147,13 +155,14 @@ void main() { } ] }"""; - expect(harCodeGen.getCode(requestModelGet8, "https"), expectedCode); + expect(codeGen.getCode(CodegenLanguage.har, requestModelGet8, "https"), + expectedCode); }); test('GET 9', () { const expectedCode = r"""{ "method": "GET", - "url": "https://api.foss42.com/humanize/social?num=8700000&add_space=true", + "url": "https://api.apidash.dev/humanize/social?num=8700000&add_space=true", "httpVersion": "HTTP/1.1", "queryString": [ { @@ -167,13 +176,14 @@ void main() { ], "headers": [] }"""; - expect(harCodeGen.getCode(requestModelGet9, "https"), expectedCode); + expect(codeGen.getCode(CodegenLanguage.har, requestModelGet9, "https"), + expectedCode); }); test('GET 10', () { const expectedCode = r"""{ "method": "GET", - "url": "https://api.foss42.com/humanize/social", + "url": "https://api.apidash.dev/humanize/social", "httpVersion": "HTTP/1.1", "queryString": [], "headers": [ @@ -184,7 +194,8 @@ void main() { ] }"""; expect( - harCodeGen.getCode( + codeGen.getCode( + CodegenLanguage.har, requestModelGet10, "https", ), @@ -194,7 +205,7 @@ void main() { test('GET 11', () { const expectedCode = r"""{ "method": "GET", - "url": "https://api.foss42.com/humanize/social?num=8700000&digits=3", + "url": "https://api.apidash.dev/humanize/social?num=8700000&digits=3", "httpVersion": "HTTP/1.1", "queryString": [ { @@ -213,18 +224,20 @@ void main() { } ] }"""; - expect(harCodeGen.getCode(requestModelGet11, "https"), expectedCode); + expect(codeGen.getCode(CodegenLanguage.har, requestModelGet11, "https"), + expectedCode); }); test('GET 12', () { const expectedCode = r"""{ "method": "GET", - "url": "https://api.foss42.com/humanize/social", + "url": "https://api.apidash.dev/humanize/social", "httpVersion": "HTTP/1.1", "queryString": [], "headers": [] }"""; - expect(harCodeGen.getCode(requestModelGet12, "https"), expectedCode); + expect(codeGen.getCode(CodegenLanguage.har, requestModelGet12, "https"), + expectedCode); }); }); @@ -232,23 +245,25 @@ void main() { test('HEAD 1', () { const expectedCode = r"""{ "method": "HEAD", - "url": "https://api.foss42.com", + "url": "https://api.apidash.dev", "httpVersion": "HTTP/1.1", "queryString": [], "headers": [] }"""; - expect(harCodeGen.getCode(requestModelHead1, "https"), expectedCode); + expect(codeGen.getCode(CodegenLanguage.har, requestModelHead1, "https"), + expectedCode); }); test('HEAD 2', () { const expectedCode = r"""{ "method": "HEAD", - "url": "http://api.foss42.com", + "url": "http://api.apidash.dev", "httpVersion": "HTTP/1.1", "queryString": [], "headers": [] }"""; - expect(harCodeGen.getCode(requestModelHead2, "http"), expectedCode); + expect(codeGen.getCode(CodegenLanguage.har, requestModelHead2, "http"), + expectedCode); }); }); @@ -256,7 +271,7 @@ void main() { test('POST 1', () { const expectedCode = r"""{ "method": "POST", - "url": "https://api.foss42.com/case/lower", + "url": "https://api.apidash.dev/case/lower", "httpVersion": "HTTP/1.1", "queryString": [], "headers": [ @@ -270,13 +285,14 @@ void main() { "text": "{\n\"text\": \"I LOVE Flutter\"\n}" } }"""; - expect(harCodeGen.getCode(requestModelPost1, "https"), expectedCode); + expect(codeGen.getCode(CodegenLanguage.har, requestModelPost1, "https"), + expectedCode); }); test('POST 2', () { const expectedCode = r"""{ "method": "POST", - "url": "https://api.foss42.com/case/lower", + "url": "https://api.apidash.dev/case/lower", "httpVersion": "HTTP/1.1", "queryString": [], "headers": [ @@ -287,16 +303,17 @@ void main() { ], "postData": { "mimeType": "application/json", - "text": "{\n\"text\": \"I LOVE Flutter\"\n}" + "text": "{\n\"text\": \"I LOVE Flutter\",\n\"flag\": null,\n\"male\": true,\n\"female\": false,\n\"no\": 1.2,\n\"arr\": [\"null\", \"true\", \"false\", null]\n}" } }"""; - expect(harCodeGen.getCode(requestModelPost2, "https"), expectedCode); + expect(codeGen.getCode(CodegenLanguage.har, requestModelPost2, "https"), + expectedCode); }); test('POST 3', () { const expectedCode = r"""{ "method": "POST", - "url": "https://api.foss42.com/case/lower", + "url": "https://api.apidash.dev/case/lower", "httpVersion": "HTTP/1.1", "queryString": [], "headers": [ @@ -314,7 +331,242 @@ void main() { "text": "{\n\"text\": \"I LOVE Flutter\"\n}" } }"""; - expect(harCodeGen.getCode(requestModelPost3, "https"), expectedCode); + expect(codeGen.getCode(CodegenLanguage.har, requestModelPost3, "https"), + expectedCode); + }); + + test('POST 4', () { + const expectedCode = r"""{ + "method": "POST", + "url": "https://api.apidash.dev/io/form", + "httpVersion": "HTTP/1.1", + "queryString": [], + "headers": [ + { + "name": "Content-Type", + "value": "multipart/form-data; boundary=d43e2510-a25e-1f08-b0a5-591aeb704467" + } + ], + "postData": { + "mimeType": "multipart/form-data; boundary=d43e2510-a25e-1f08-b0a5-591aeb704467", + "params": [ + { + "name": "text", + "value": "API" + }, + { + "name": "sep", + "value": "|" + }, + { + "name": "times", + "value": "3" + } + ] + } +}"""; + expect( + codeGen.getCode(CodegenLanguage.har, requestModelPost4, "https", + boundary: "d43e2510-a25e-1f08-b0a5-591aeb704467"), + expectedCode); + }); + + test('POST 5', () { + const expectedCode = r"""{ + "method": "POST", + "url": "https://api.apidash.dev/io/form", + "httpVersion": "HTTP/1.1", + "queryString": [], + "headers": [ + { + "name": "Content-Type", + "value": "multipart/form-data; boundary=ce268b20-a3e6-1f08-b0a5-591aeb704467" + }, + { + "name": "User-Agent", + "value": "Test Agent" + } + ], + "postData": { + "mimeType": "multipart/form-data; boundary=ce268b20-a3e6-1f08-b0a5-591aeb704467", + "params": [ + { + "name": "text", + "value": "API" + }, + { + "name": "sep", + "value": "|" + }, + { + "name": "times", + "value": "3" + } + ] + } +}"""; + expect( + codeGen.getCode(CodegenLanguage.har, requestModelPost5, "https", + boundary: "ce268b20-a3e6-1f08-b0a5-591aeb704467"), + expectedCode); + }); + + test('POST 6', () { + const expectedCode = r"""{ + "method": "POST", + "url": "https://api.apidash.dev/io/img", + "httpVersion": "HTTP/1.1", + "queryString": [], + "headers": [ + { + "name": "Content-Type", + "value": "multipart/form-data; boundary=c90d21a0-a44d-1f08-b0a5-591aeb704467" + } + ], + "postData": { + "mimeType": "multipart/form-data; boundary=c90d21a0-a44d-1f08-b0a5-591aeb704467", + "params": [ + { + "name": "token", + "value": "xyz" + }, + { + "name": "imfile", + "fileName": "1.png" + } + ] + } +}"""; + expect( + codeGen.getCode(CodegenLanguage.har, requestModelPost6, "https", + boundary: "c90d21a0-a44d-1f08-b0a5-591aeb704467"), + expectedCode); + }); + + test('POST 7', () { + const expectedCode = r"""{ + "method": "POST", + "url": "https://api.apidash.dev/io/img", + "httpVersion": "HTTP/1.1", + "queryString": [], + "headers": [ + { + "name": "Content-Type", + "value": "multipart/form-data; boundary=4ac86770-a4dc-1f08-b0a5-591aeb704467" + } + ], + "postData": { + "mimeType": "multipart/form-data; boundary=4ac86770-a4dc-1f08-b0a5-591aeb704467", + "params": [ + { + "name": "token", + "value": "xyz" + }, + { + "name": "imfile", + "fileName": "1.png" + } + ] + } +}"""; + expect( + codeGen.getCode(CodegenLanguage.har, requestModelPost7, "https", + boundary: "4ac86770-a4dc-1f08-b0a5-591aeb704467"), + expectedCode); + }); + + test('POST 8', () { + const expectedCode = r"""{ + "method": "POST", + "url": "https://api.apidash.dev/io/form?size=2&len=3", + "httpVersion": "HTTP/1.1", + "queryString": [ + { + "name": "size", + "value": "2" + }, + { + "name": "len", + "value": "3" + } + ], + "headers": [ + { + "name": "Content-Type", + "value": "multipart/form-data; boundary=78403a20-a54a-1f08-b0a5-591aeb704467" + } + ], + "postData": { + "mimeType": "multipart/form-data; boundary=78403a20-a54a-1f08-b0a5-591aeb704467", + "params": [ + { + "name": "text", + "value": "API" + }, + { + "name": "sep", + "value": "|" + }, + { + "name": "times", + "value": "3" + } + ] + } +}"""; + expect( + codeGen.getCode(CodegenLanguage.har, requestModelPost8, "https", + boundary: "78403a20-a54a-1f08-b0a5-591aeb704467"), + expectedCode); + }); + + test('POST 9', () { + const expectedCode = r"""{ + "method": "POST", + "url": "https://api.apidash.dev/io/img?size=2&len=3", + "httpVersion": "HTTP/1.1", + "queryString": [ + { + "name": "size", + "value": "2" + }, + { + "name": "len", + "value": "3" + } + ], + "headers": [ + { + "name": "Content-Type", + "value": "multipart/form-data; boundary=2d9cd390-a593-1f08-b0a5-591aeb704467" + }, + { + "name": "User-Agent", + "value": "Test Agent" + }, + { + "name": "Keep-Alive", + "value": "true" + } + ], + "postData": { + "mimeType": "multipart/form-data; boundary=2d9cd390-a593-1f08-b0a5-591aeb704467", + "params": [ + { + "name": "token", + "value": "xyz" + }, + { + "name": "imfile", + "fileName": "1.png" + } + ] + } +}"""; + expect( + codeGen.getCode(CodegenLanguage.har, requestModelPost9, "https", + boundary: "2d9cd390-a593-1f08-b0a5-591aeb704467"), + expectedCode); }); }); @@ -336,7 +588,8 @@ void main() { "text": "{\n\"name\": \"morpheus\",\n\"job\": \"zion resident\"\n}" } }"""; - expect(harCodeGen.getCode(requestModelPut1, "https"), expectedCode); + expect(codeGen.getCode(CodegenLanguage.har, requestModelPut1, "https"), + expectedCode); }); }); @@ -358,7 +611,8 @@ void main() { "text": "{\n\"name\": \"marfeus\",\n\"job\": \"accountant\"\n}" } }"""; - expect(harCodeGen.getCode(requestModelPatch1, "https"), expectedCode); + expect(codeGen.getCode(CodegenLanguage.har, requestModelPatch1, "https"), + expectedCode); }); }); @@ -371,7 +625,8 @@ void main() { "queryString": [], "headers": [] }"""; - expect(harCodeGen.getCode(requestModelDelete1, "https"), expectedCode); + expect(codeGen.getCode(CodegenLanguage.har, requestModelDelete1, "https"), + expectedCode); }); test('DELETE 2', () { @@ -391,7 +646,8 @@ void main() { "text": "{\n\"name\": \"marfeus\",\n\"job\": \"accountant\"\n}" } }"""; - expect(harCodeGen.getCode(requestModelDelete2, "https"), expectedCode); + expect(codeGen.getCode(CodegenLanguage.har, requestModelDelete2, "https"), + expectedCode); }); }); } diff --git a/test/codegen/java_okhttp_codegen_test.dart b/test/codegen/java_okhttp_codegen_test.dart new file mode 100644 index 00000000..20a8a17a --- /dev/null +++ b/test/codegen/java_okhttp_codegen_test.dart @@ -0,0 +1,1032 @@ +import 'package:apidash/codegen/java/okhttp.dart'; +import 'package:test/test.dart'; +import '../request_models.dart'; + +void main() { + final javaOkHttpCodeGen = JavaOkHttpCodeGen(); + + group('GET Request', () { + test('GET 1', () { + const expectedCode = r"""import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; + +import java.io.IOException; + +public class Main { + public static void main(String[] args) { + OkHttpClient client = new OkHttpClient().newBuilder().build(); + + String url = "https://api.apidash.dev"; + + Request request = new Request.Builder() + .url(url) + .get() + .build(); + + try (Response response = client.newCall(request).execute()) { + System.out.println(response.code()); + if (response.body() != null) { + System.out.println(response.body().string()); + } + } catch (IOException e) { + System.out.println(e.getMessage()); + } + } +} +"""; + expect( + javaOkHttpCodeGen.getCode(requestModelGet1), expectedCode); + }); + + test('GET 2', () { + const expectedCode = r"""import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.HttpUrl; + +import java.io.IOException; + +public class Main { + public static void main(String[] args) { + OkHttpClient client = new OkHttpClient().newBuilder().build(); + + HttpUrl url = HttpUrl.parse("https://api.apidash.dev/country/data").newBuilder() + .addQueryParameter("code", "US") + .build(); + + Request request = new Request.Builder() + .url(url) + .get() + .build(); + + try (Response response = client.newCall(request).execute()) { + System.out.println(response.code()); + if (response.body() != null) { + System.out.println(response.body().string()); + } + } catch (IOException e) { + System.out.println(e.getMessage()); + } + } +} +"""; + expect( + javaOkHttpCodeGen.getCode(requestModelGet2), expectedCode); + }); + + test('GET 3', () { + const expectedCode = r"""import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.HttpUrl; + +import java.io.IOException; + +public class Main { + public static void main(String[] args) { + OkHttpClient client = new OkHttpClient().newBuilder().build(); + + HttpUrl url = HttpUrl.parse("https://api.apidash.dev/country/data").newBuilder() + .addQueryParameter("code", "IND") + .build(); + + Request request = new Request.Builder() + .url(url) + .get() + .build(); + + try (Response response = client.newCall(request).execute()) { + System.out.println(response.code()); + if (response.body() != null) { + System.out.println(response.body().string()); + } + } catch (IOException e) { + System.out.println(e.getMessage()); + } + } +} +"""; + expect( + javaOkHttpCodeGen.getCode(requestModelGet3), expectedCode); + }); + + test('GET 4', () { + const expectedCode = r"""import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.HttpUrl; + +import java.io.IOException; + +public class Main { + public static void main(String[] args) { + OkHttpClient client = new OkHttpClient().newBuilder().build(); + + HttpUrl url = HttpUrl.parse("https://api.apidash.dev/humanize/social").newBuilder() + .addQueryParameter("num", "8700000") + .addQueryParameter("digits", "3") + .addQueryParameter("system", "SS") + .addQueryParameter("add_space", "true") + .addQueryParameter("trailing_zeros", "true") + .build(); + + Request request = new Request.Builder() + .url(url) + .get() + .build(); + + try (Response response = client.newCall(request).execute()) { + System.out.println(response.code()); + if (response.body() != null) { + System.out.println(response.body().string()); + } + } catch (IOException e) { + System.out.println(e.getMessage()); + } + } +} +"""; + expect( + javaOkHttpCodeGen.getCode(requestModelGet4), expectedCode); + }); + + test('GET 5', () { + const expectedCode = r"""import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; + +import java.io.IOException; + +public class Main { + public static void main(String[] args) { + OkHttpClient client = new OkHttpClient().newBuilder().build(); + + String url = "https://api.github.com/repos/foss42/apidash"; + + Request request = new Request.Builder() + .url(url) + .addHeader("User-Agent", "Test Agent") + .get() + .build(); + + try (Response response = client.newCall(request).execute()) { + System.out.println(response.code()); + if (response.body() != null) { + System.out.println(response.body().string()); + } + } catch (IOException e) { + System.out.println(e.getMessage()); + } + } +} +"""; + expect( + javaOkHttpCodeGen.getCode(requestModelGet5), expectedCode); + }); + + test('GET 6', () { + const expectedCode = r"""import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.HttpUrl; + +import java.io.IOException; + +public class Main { + public static void main(String[] args) { + OkHttpClient client = new OkHttpClient().newBuilder().build(); + + HttpUrl url = HttpUrl.parse("https://api.github.com/repos/foss42/apidash").newBuilder() + .addQueryParameter("raw", "true") + .build(); + + Request request = new Request.Builder() + .url(url) + .addHeader("User-Agent", "Test Agent") + .get() + .build(); + + try (Response response = client.newCall(request).execute()) { + System.out.println(response.code()); + if (response.body() != null) { + System.out.println(response.body().string()); + } + } catch (IOException e) { + System.out.println(e.getMessage()); + } + } +} +"""; + expect( + javaOkHttpCodeGen.getCode(requestModelGet6), expectedCode); + }); + + test('GET 7', () { + const expectedCode = r"""import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; + +import java.io.IOException; + +public class Main { + public static void main(String[] args) { + OkHttpClient client = new OkHttpClient().newBuilder().build(); + + String url = "https://api.apidash.dev"; + + Request request = new Request.Builder() + .url(url) + .get() + .build(); + + try (Response response = client.newCall(request).execute()) { + System.out.println(response.code()); + if (response.body() != null) { + System.out.println(response.body().string()); + } + } catch (IOException e) { + System.out.println(e.getMessage()); + } + } +} +"""; + expect( + javaOkHttpCodeGen.getCode(requestModelGet7), expectedCode); + }); + + test('GET 8', () { + const expectedCode = r"""import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.HttpUrl; + +import java.io.IOException; + +public class Main { + public static void main(String[] args) { + OkHttpClient client = new OkHttpClient().newBuilder().build(); + + HttpUrl url = HttpUrl.parse("https://api.github.com/repos/foss42/apidash").newBuilder() + .addQueryParameter("raw", "true") + .build(); + + Request request = new Request.Builder() + .url(url) + .addHeader("User-Agent", "Test Agent") + .get() + .build(); + + try (Response response = client.newCall(request).execute()) { + System.out.println(response.code()); + if (response.body() != null) { + System.out.println(response.body().string()); + } + } catch (IOException e) { + System.out.println(e.getMessage()); + } + } +} +"""; + expect( + javaOkHttpCodeGen.getCode(requestModelGet8), expectedCode); + }); + + test('GET 9', () { + const expectedCode = r"""import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.HttpUrl; + +import java.io.IOException; + +public class Main { + public static void main(String[] args) { + OkHttpClient client = new OkHttpClient().newBuilder().build(); + + HttpUrl url = HttpUrl.parse("https://api.apidash.dev/humanize/social").newBuilder() + .addQueryParameter("num", "8700000") + .addQueryParameter("add_space", "true") + .build(); + + Request request = new Request.Builder() + .url(url) + .get() + .build(); + + try (Response response = client.newCall(request).execute()) { + System.out.println(response.code()); + if (response.body() != null) { + System.out.println(response.body().string()); + } + } catch (IOException e) { + System.out.println(e.getMessage()); + } + } +} +"""; + expect( + javaOkHttpCodeGen.getCode(requestModelGet9), expectedCode); + }); + + test('GET 10', () { + const expectedCode = r"""import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; + +import java.io.IOException; + +public class Main { + public static void main(String[] args) { + OkHttpClient client = new OkHttpClient().newBuilder().build(); + + String url = "https://api.apidash.dev/humanize/social"; + + Request request = new Request.Builder() + .url(url) + .addHeader("User-Agent", "Test Agent") + .get() + .build(); + + try (Response response = client.newCall(request).execute()) { + System.out.println(response.code()); + if (response.body() != null) { + System.out.println(response.body().string()); + } + } catch (IOException e) { + System.out.println(e.getMessage()); + } + } +} +"""; + expect( + javaOkHttpCodeGen.getCode( + requestModelGet10, + ), + expectedCode); + }); + + test('GET 11', () { + const expectedCode = r"""import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.HttpUrl; + +import java.io.IOException; + +public class Main { + public static void main(String[] args) { + OkHttpClient client = new OkHttpClient().newBuilder().build(); + + HttpUrl url = HttpUrl.parse("https://api.apidash.dev/humanize/social").newBuilder() + .addQueryParameter("num", "8700000") + .addQueryParameter("digits", "3") + .build(); + + Request request = new Request.Builder() + .url(url) + .addHeader("User-Agent", "Test Agent") + .get() + .build(); + + try (Response response = client.newCall(request).execute()) { + System.out.println(response.code()); + if (response.body() != null) { + System.out.println(response.body().string()); + } + } catch (IOException e) { + System.out.println(e.getMessage()); + } + } +} +"""; + expect( + javaOkHttpCodeGen.getCode(requestModelGet11), expectedCode); + }); + + test('GET 12', () { + const expectedCode = r"""import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; + +import java.io.IOException; + +public class Main { + public static void main(String[] args) { + OkHttpClient client = new OkHttpClient().newBuilder().build(); + + String url = "https://api.apidash.dev/humanize/social"; + + Request request = new Request.Builder() + .url(url) + .get() + .build(); + + try (Response response = client.newCall(request).execute()) { + System.out.println(response.code()); + if (response.body() != null) { + System.out.println(response.body().string()); + } + } catch (IOException e) { + System.out.println(e.getMessage()); + } + } +} +"""; + expect( + javaOkHttpCodeGen.getCode(requestModelGet12), expectedCode); + }); + }); + + group('HEAD Request', () { + test('HEAD 1', () { + const expectedCode = r"""import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; + +import java.io.IOException; + +public class Main { + public static void main(String[] args) { + OkHttpClient client = new OkHttpClient().newBuilder().build(); + + String url = "https://api.apidash.dev"; + + Request request = new Request.Builder() + .url(url) + .head() + .build(); + + try (Response response = client.newCall(request).execute()) { + System.out.println(response.code()); + if (response.body() != null) { + System.out.println(response.body().string()); + } + } catch (IOException e) { + System.out.println(e.getMessage()); + } + } +} +"""; + expect( + javaOkHttpCodeGen.getCode(requestModelHead1), expectedCode); + }); + + test('HEAD 2', () { + const expectedCode = r"""import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; + +import java.io.IOException; + +public class Main { + public static void main(String[] args) { + OkHttpClient client = new OkHttpClient().newBuilder().build(); + + String url = "https://api.apidash.dev"; + + Request request = new Request.Builder() + .url(url) + .head() + .build(); + + try (Response response = client.newCall(request).execute()) { + System.out.println(response.code()); + if (response.body() != null) { + System.out.println(response.body().string()); + } + } catch (IOException e) { + System.out.println(e.getMessage()); + } + } +} +"""; + expect( + javaOkHttpCodeGen.getCode(requestModelHead2), expectedCode); + }); + }); + + group('POST Request', () { + test('POST 1', () { + const expectedCode = r'''import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.RequestBody; +import okhttp3.MediaType; + +import java.io.IOException; + +public class Main { + public static void main(String[] args) { + OkHttpClient client = new OkHttpClient().newBuilder().build(); + + String url = "https://api.apidash.dev/case/lower"; + + MediaType mediaType = MediaType.parse("text/plain"); + + RequestBody body = RequestBody.create("{\n\"text\": \"I LOVE Flutter\"\n}", mediaType); + + Request request = new Request.Builder() + .url(url) + .post(body) + .build(); + + try (Response response = client.newCall(request).execute()) { + System.out.println(response.code()); + if (response.body() != null) { + System.out.println(response.body().string()); + } + } catch (IOException e) { + System.out.println(e.getMessage()); + } + } +} +'''; + expect( + javaOkHttpCodeGen.getCode(requestModelPost1), expectedCode); + }); + + test('POST 2', () { + const expectedCode = r'''import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.RequestBody; +import okhttp3.MediaType; + +import java.io.IOException; + +public class Main { + public static void main(String[] args) { + OkHttpClient client = new OkHttpClient().newBuilder().build(); + + String url = "https://api.apidash.dev/case/lower"; + + MediaType mediaType = MediaType.parse("application/json"); + + RequestBody body = RequestBody.create("{\n\"text\": \"I LOVE Flutter\",\n\"flag\": null,\n\"male\": true,\n\"female\": false,\n\"no\": 1.2,\n\"arr\": [\"null\", \"true\", \"false\", null]\n}", mediaType); + + Request request = new Request.Builder() + .url(url) + .post(body) + .build(); + + try (Response response = client.newCall(request).execute()) { + System.out.println(response.code()); + if (response.body() != null) { + System.out.println(response.body().string()); + } + } catch (IOException e) { + System.out.println(e.getMessage()); + } + } +} +'''; + expect( + javaOkHttpCodeGen.getCode(requestModelPost2), expectedCode); + }); + + test('POST 3', () { + const expectedCode = r'''import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.RequestBody; +import okhttp3.MediaType; + +import java.io.IOException; + +public class Main { + public static void main(String[] args) { + OkHttpClient client = new OkHttpClient().newBuilder().build(); + + String url = "https://api.apidash.dev/case/lower"; + + MediaType mediaType = MediaType.parse("application/json"); + + RequestBody body = RequestBody.create("{\n\"text\": \"I LOVE Flutter\"\n}", mediaType); + + Request request = new Request.Builder() + .url(url) + .addHeader("User-Agent", "Test Agent") + .post(body) + .build(); + + try (Response response = client.newCall(request).execute()) { + System.out.println(response.code()); + if (response.body() != null) { + System.out.println(response.body().string()); + } + } catch (IOException e) { + System.out.println(e.getMessage()); + } + } +} +'''; + expect( + javaOkHttpCodeGen.getCode(requestModelPost3), expectedCode); + }); + + test('POST 4', () { + const expectedCode = r'''import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.RequestBody; +import okhttp3.MultipartBody; + +import java.io.IOException; + +public class Main { + public static void main(String[] args) { + OkHttpClient client = new OkHttpClient().newBuilder().build(); + + String url = "https://api.apidash.dev/io/form"; + RequestBody body = new MultipartBody.Builder().setType(MultipartBody.FORM) + .addFormDataPart("text","API") + .addFormDataPart("sep","|") + .addFormDataPart("times","3") + .build(); + + Request request = new Request.Builder() + .url(url) + .post(body) + .build(); + + try (Response response = client.newCall(request).execute()) { + System.out.println(response.code()); + if (response.body() != null) { + System.out.println(response.body().string()); + } + } catch (IOException e) { + System.out.println(e.getMessage()); + } + } +} +'''; + expect( + javaOkHttpCodeGen.getCode(requestModelPost4), expectedCode); + }); + + test('POST 5', () { + const expectedCode = r'''import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.RequestBody; +import okhttp3.MultipartBody; + +import java.io.IOException; + +public class Main { + public static void main(String[] args) { + OkHttpClient client = new OkHttpClient().newBuilder().build(); + + String url = "https://api.apidash.dev/io/form"; + RequestBody body = new MultipartBody.Builder().setType(MultipartBody.FORM) + .addFormDataPart("text","API") + .addFormDataPart("sep","|") + .addFormDataPart("times","3") + .build(); + + Request request = new Request.Builder() + .url(url) + .addHeader("User-Agent", "Test Agent") + .post(body) + .build(); + + try (Response response = client.newCall(request).execute()) { + System.out.println(response.code()); + if (response.body() != null) { + System.out.println(response.body().string()); + } + } catch (IOException e) { + System.out.println(e.getMessage()); + } + } +} +'''; + expect( + javaOkHttpCodeGen.getCode(requestModelPost5), expectedCode); + }); + + test('POST 6', () { + const expectedCode = r'''import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.RequestBody; +import okhttp3.MultipartBody; + +import java.io.IOException; + +public class Main { + public static void main(String[] args) { + OkHttpClient client = new OkHttpClient().newBuilder().build(); + + String url = "https://api.apidash.dev/io/img"; + RequestBody body = new MultipartBody.Builder().setType(MultipartBody.FORM) + .addFormDataPart("token","xyz") + .addFormDataPart("imfile",null,RequestBody.create(MediaType.parse("application/octet-stream"),new File("/Documents/up/1.png"))) + .build(); + + Request request = new Request.Builder() + .url(url) + .post(body) + .build(); + + try (Response response = client.newCall(request).execute()) { + System.out.println(response.code()); + if (response.body() != null) { + System.out.println(response.body().string()); + } + } catch (IOException e) { + System.out.println(e.getMessage()); + } + } +} +'''; + expect( + javaOkHttpCodeGen.getCode(requestModelPost6), expectedCode); + }); + + test('POST 7', () { + const expectedCode = r'''import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.RequestBody; +import okhttp3.MultipartBody; + +import java.io.IOException; + +public class Main { + public static void main(String[] args) { + OkHttpClient client = new OkHttpClient().newBuilder().build(); + + String url = "https://api.apidash.dev/io/img"; + RequestBody body = new MultipartBody.Builder().setType(MultipartBody.FORM) + .addFormDataPart("token","xyz") + .addFormDataPart("imfile",null,RequestBody.create(MediaType.parse("application/octet-stream"),new File("/Documents/up/1.png"))) + .build(); + + Request request = new Request.Builder() + .url(url) + .post(body) + .build(); + + try (Response response = client.newCall(request).execute()) { + System.out.println(response.code()); + if (response.body() != null) { + System.out.println(response.body().string()); + } + } catch (IOException e) { + System.out.println(e.getMessage()); + } + } +} +'''; + expect( + javaOkHttpCodeGen.getCode(requestModelPost7), expectedCode); + }); + + test('POST 8', () { + const expectedCode = r'''import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.HttpUrl; +import okhttp3.RequestBody; +import okhttp3.MultipartBody; + +import java.io.IOException; + +public class Main { + public static void main(String[] args) { + OkHttpClient client = new OkHttpClient().newBuilder().build(); + + HttpUrl url = HttpUrl.parse("https://api.apidash.dev/io/form").newBuilder() + .addQueryParameter("size", "2") + .addQueryParameter("len", "3") + .build(); + RequestBody body = new MultipartBody.Builder().setType(MultipartBody.FORM) + .addFormDataPart("text","API") + .addFormDataPart("sep","|") + .addFormDataPart("times","3") + .build(); + + Request request = new Request.Builder() + .url(url) + .post(body) + .build(); + + try (Response response = client.newCall(request).execute()) { + System.out.println(response.code()); + if (response.body() != null) { + System.out.println(response.body().string()); + } + } catch (IOException e) { + System.out.println(e.getMessage()); + } + } +} +'''; + expect( + javaOkHttpCodeGen.getCode(requestModelPost8), expectedCode); + }); + + test('POST 9', () { + const expectedCode = r'''import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.HttpUrl; +import okhttp3.RequestBody; +import okhttp3.MultipartBody; + +import java.io.IOException; + +public class Main { + public static void main(String[] args) { + OkHttpClient client = new OkHttpClient().newBuilder().build(); + + HttpUrl url = HttpUrl.parse("https://api.apidash.dev/io/img").newBuilder() + .addQueryParameter("size", "2") + .addQueryParameter("len", "3") + .build(); + RequestBody body = new MultipartBody.Builder().setType(MultipartBody.FORM) + .addFormDataPart("token","xyz") + .addFormDataPart("imfile",null,RequestBody.create(MediaType.parse("application/octet-stream"),new File("/Documents/up/1.png"))) + .build(); + + Request request = new Request.Builder() + .url(url) + .addHeader("User-Agent", "Test Agent") + .addHeader("Keep-Alive", "true") + .post(body) + .build(); + + try (Response response = client.newCall(request).execute()) { + System.out.println(response.code()); + if (response.body() != null) { + System.out.println(response.body().string()); + } + } catch (IOException e) { + System.out.println(e.getMessage()); + } + } +} +'''; + expect( + javaOkHttpCodeGen.getCode(requestModelPost9), expectedCode); + }); + }); + + group('PUT Request', () { + test('PUT 1', () { + const expectedCode = r'''import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.RequestBody; +import okhttp3.MediaType; + +import java.io.IOException; + +public class Main { + public static void main(String[] args) { + OkHttpClient client = new OkHttpClient().newBuilder().build(); + + String url = "https://reqres.in/api/users/2"; + + MediaType mediaType = MediaType.parse("application/json"); + + RequestBody body = RequestBody.create("{\n\"name\": \"morpheus\",\n\"job\": \"zion resident\"\n}", mediaType); + + Request request = new Request.Builder() + .url(url) + .put(body) + .build(); + + try (Response response = client.newCall(request).execute()) { + System.out.println(response.code()); + if (response.body() != null) { + System.out.println(response.body().string()); + } + } catch (IOException e) { + System.out.println(e.getMessage()); + } + } +} +'''; + expect( + javaOkHttpCodeGen.getCode(requestModelPut1), expectedCode); + }); + }); + + group('PATCH Request', () { + test('PATCH 1', () { + const expectedCode = r'''import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.RequestBody; +import okhttp3.MediaType; + +import java.io.IOException; + +public class Main { + public static void main(String[] args) { + OkHttpClient client = new OkHttpClient().newBuilder().build(); + + String url = "https://reqres.in/api/users/2"; + + MediaType mediaType = MediaType.parse("application/json"); + + RequestBody body = RequestBody.create("{\n\"name\": \"marfeus\",\n\"job\": \"accountant\"\n}", mediaType); + + Request request = new Request.Builder() + .url(url) + .patch(body) + .build(); + + try (Response response = client.newCall(request).execute()) { + System.out.println(response.code()); + if (response.body() != null) { + System.out.println(response.body().string()); + } + } catch (IOException e) { + System.out.println(e.getMessage()); + } + } +} +'''; + expect( + javaOkHttpCodeGen.getCode(requestModelPatch1), expectedCode); + }); + }); + + group('DELETE Request', () { + test('DELETE 1', () { + const expectedCode = r"""import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; + +import java.io.IOException; + +public class Main { + public static void main(String[] args) { + OkHttpClient client = new OkHttpClient().newBuilder().build(); + + String url = "https://reqres.in/api/users/2"; + + Request request = new Request.Builder() + .url(url) + .delete() + .build(); + + try (Response response = client.newCall(request).execute()) { + System.out.println(response.code()); + if (response.body() != null) { + System.out.println(response.body().string()); + } + } catch (IOException e) { + System.out.println(e.getMessage()); + } + } +} +"""; + expect(javaOkHttpCodeGen.getCode(requestModelDelete1), + expectedCode); + }); + + test('DELETE 2', () { + const expectedCode = r'''import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.RequestBody; +import okhttp3.MediaType; + +import java.io.IOException; + +public class Main { + public static void main(String[] args) { + OkHttpClient client = new OkHttpClient().newBuilder().build(); + + String url = "https://reqres.in/api/users/2"; + + MediaType mediaType = MediaType.parse("application/json"); + + RequestBody body = RequestBody.create("{\n\"name\": \"marfeus\",\n\"job\": \"accountant\"\n}", mediaType); + + Request request = new Request.Builder() + .url(url) + .delete(body) + .build(); + + try (Response response = client.newCall(request).execute()) { + System.out.println(response.code()); + if (response.body() != null) { + System.out.println(response.body().string()); + } + } catch (IOException e) { + System.out.println(e.getMessage()); + } + } +} +'''; + expect(javaOkHttpCodeGen.getCode(requestModelDelete2), + expectedCode); + }); + }); +} \ No newline at end of file diff --git a/test/codegen/js_axios_codegen_test.dart b/test/codegen/js_axios_codegen_test.dart index 9498da1c..40b420e4 100644 --- a/test/codegen/js_axios_codegen_test.dart +++ b/test/codegen/js_axios_codegen_test.dart @@ -1,14 +1,15 @@ -import 'package:apidash/codegen/js/axios.dart'; -import '../request_models.dart'; +import 'package:apidash/codegen/codegen.dart'; +import 'package:apidash/consts.dart'; import 'package:test/test.dart'; +import '../request_models.dart'; void main() { - final axiosCodeGen = AxiosCodeGen(); + final codeGen = Codegen(); group('GET Request', () { test('GET 1', () { const expectedCode = r"""let config = { - url: 'https://api.foss42.com', + url: 'https://api.apidash.dev', method: 'get' }; @@ -24,12 +25,14 @@ axios(config) console.log(error); }); """; - expect(axiosCodeGen.getCode(requestModelGet1, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.jsAxios, requestModelGet1, "https"), + expectedCode); }); test('GET 2', () { const expectedCode = r"""let config = { - url: 'https://api.foss42.com/country/data', + url: 'https://api.apidash.dev/country/data', method: 'get', params: { "code": "US" @@ -48,12 +51,14 @@ axios(config) console.log(error); }); """; - expect(axiosCodeGen.getCode(requestModelGet2, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.jsAxios, requestModelGet2, "https"), + expectedCode); }); test('GET 3', () { const expectedCode = r"""let config = { - url: 'https://api.foss42.com/country/data', + url: 'https://api.apidash.dev/country/data', method: 'get', params: { "code": "IND" @@ -72,12 +77,14 @@ axios(config) console.log(error); }); """; - expect(axiosCodeGen.getCode(requestModelGet3, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.jsAxios, requestModelGet3, "https"), + expectedCode); }); test('GET 4', () { const expectedCode = r"""let config = { - url: 'https://api.foss42.com/humanize/social', + url: 'https://api.apidash.dev/humanize/social', method: 'get', params: { "num": "8700000", @@ -100,7 +107,9 @@ axios(config) console.log(error); }); """; - expect(axiosCodeGen.getCode(requestModelGet4, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.jsAxios, requestModelGet4, "https"), + expectedCode); }); test('GET 5', () { @@ -124,7 +133,9 @@ axios(config) console.log(error); }); """; - expect(axiosCodeGen.getCode(requestModelGet5, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.jsAxios, requestModelGet5, "https"), + expectedCode); }); test('GET 6', () { @@ -151,12 +162,14 @@ axios(config) console.log(error); }); """; - expect(axiosCodeGen.getCode(requestModelGet6, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.jsAxios, requestModelGet6, "https"), + expectedCode); }); test('GET 7', () { const expectedCode = r"""let config = { - url: 'https://api.foss42.com', + url: 'https://api.apidash.dev', method: 'get' }; @@ -172,7 +185,9 @@ axios(config) console.log(error); }); """; - expect(axiosCodeGen.getCode(requestModelGet7, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.jsAxios, requestModelGet7, "https"), + expectedCode); }); test('GET 8', () { @@ -199,12 +214,14 @@ axios(config) console.log(error); }); """; - expect(axiosCodeGen.getCode(requestModelGet8, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.jsAxios, requestModelGet8, "https"), + expectedCode); }); test('GET 9', () { const expectedCode = r"""let config = { - url: 'https://api.foss42.com/humanize/social', + url: 'https://api.apidash.dev/humanize/social', method: 'get', params: { "num": "8700000", @@ -224,12 +241,14 @@ axios(config) console.log(error); }); """; - expect(axiosCodeGen.getCode(requestModelGet9, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.jsAxios, requestModelGet9, "https"), + expectedCode); }); test('GET 10', () { const expectedCode = r"""let config = { - url: 'https://api.foss42.com/humanize/social', + url: 'https://api.apidash.dev/humanize/social', method: 'get', headers: { "User-Agent": "Test Agent" @@ -249,7 +268,8 @@ axios(config) }); """; expect( - axiosCodeGen.getCode( + codeGen.getCode( + CodegenLanguage.jsAxios, requestModelGet10, "https", ), @@ -258,7 +278,7 @@ axios(config) test('GET 11', () { const expectedCode = r"""let config = { - url: 'https://api.foss42.com/humanize/social', + url: 'https://api.apidash.dev/humanize/social', method: 'get', params: { "num": "8700000", @@ -281,12 +301,14 @@ axios(config) console.log(error); }); """; - expect(axiosCodeGen.getCode(requestModelGet11, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.jsAxios, requestModelGet11, "https"), + expectedCode); }); test('GET 12', () { const expectedCode = r"""let config = { - url: 'https://api.foss42.com/humanize/social', + url: 'https://api.apidash.dev/humanize/social', method: 'get' }; @@ -302,14 +324,16 @@ axios(config) console.log(error); }); """; - expect(axiosCodeGen.getCode(requestModelGet12, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.jsAxios, requestModelGet12, "https"), + expectedCode); }); }); group('HEAD Request', () { test('HEAD 1', () { const expectedCode = r"""let config = { - url: 'https://api.foss42.com', + url: 'https://api.apidash.dev', method: 'head' }; @@ -325,12 +349,14 @@ axios(config) console.log(error); }); """; - expect(axiosCodeGen.getCode(requestModelHead1, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.jsAxios, requestModelHead1, "https"), + expectedCode); }); test('HEAD 2', () { const expectedCode = r"""let config = { - url: 'http://api.foss42.com', + url: 'http://api.apidash.dev', method: 'head' }; @@ -346,14 +372,16 @@ axios(config) console.log(error); }); """; - expect(axiosCodeGen.getCode(requestModelHead2, "http"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.jsAxios, requestModelHead2, "http"), + expectedCode); }); }); group('POST Request', () { test('POST 1', () { const expectedCode = r"""let config = { - url: 'https://api.foss42.com/case/lower', + url: 'https://api.apidash.dev/case/lower', method: 'post', headers: { "Content-Type": "text/plain" @@ -373,17 +401,19 @@ axios(config) console.log(error); }); """; - expect(axiosCodeGen.getCode(requestModelPost1, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.jsAxios, requestModelPost1, "https"), + expectedCode); }); test('POST 2', () { const expectedCode = r"""let config = { - url: 'https://api.foss42.com/case/lower', + url: 'https://api.apidash.dev/case/lower', method: 'post', headers: { "Content-Type": "application/json" }, - data: "{\n\"text\": \"I LOVE Flutter\"\n}" + data: "{\n\"text\": \"I LOVE Flutter\",\n\"flag\": null,\n\"male\": true,\n\"female\": false,\n\"no\": 1.2,\n\"arr\": [\"null\", \"true\", \"false\", null]\n}" }; axios(config) @@ -398,12 +428,14 @@ axios(config) console.log(error); }); """; - expect(axiosCodeGen.getCode(requestModelPost2, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.jsAxios, requestModelPost2, "https"), + expectedCode); }); test('POST 3', () { const expectedCode = r"""let config = { - url: 'https://api.foss42.com/case/lower', + url: 'https://api.apidash.dev/case/lower', method: 'post', headers: { "Content-Type": "application/json", @@ -424,7 +456,9 @@ axios(config) console.log(error); }); """; - expect(axiosCodeGen.getCode(requestModelPost3, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.jsAxios, requestModelPost3, "https"), + expectedCode); }); }); @@ -451,7 +485,9 @@ axios(config) console.log(error); }); """; - expect(axiosCodeGen.getCode(requestModelPut1, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.jsAxios, requestModelPut1, "https"), + expectedCode); }); }); @@ -478,7 +514,9 @@ axios(config) console.log(error); }); """; - expect(axiosCodeGen.getCode(requestModelPatch1, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.jsAxios, requestModelPatch1, "https"), + expectedCode); }); }); @@ -501,7 +539,10 @@ axios(config) console.log(error); }); """; - expect(axiosCodeGen.getCode(requestModelDelete1, "https"), expectedCode); + expect( + codeGen.getCode( + CodegenLanguage.jsAxios, requestModelDelete1, "https"), + expectedCode); }); test('DELETE 2', () { @@ -526,7 +567,10 @@ axios(config) console.log(error); }); """; - expect(axiosCodeGen.getCode(requestModelDelete2, "https"), expectedCode); + expect( + codeGen.getCode( + CodegenLanguage.jsAxios, requestModelDelete2, "https"), + expectedCode); }); }); } diff --git a/test/codegen/js_fetch_codegen_test.dart b/test/codegen/js_fetch_codegen_test.dart index 43d053f9..83ee687c 100644 --- a/test/codegen/js_fetch_codegen_test.dart +++ b/test/codegen/js_fetch_codegen_test.dart @@ -1,280 +1,270 @@ -import 'package:apidash/codegen/js/fetch.dart'; -import '../request_models.dart'; +import 'package:apidash/codegen/codegen.dart'; +import 'package:apidash/consts.dart'; import 'package:test/test.dart'; +import '../request_models.dart'; void main() { - final fetchCodeGen = FetchCodeGen(); + final codeGen = Codegen(); group('GET Request', () { test('GET 1', () { - const expectedCode = r"""let url = 'https://api.foss42.com'; + const expectedCode = r"""const url = 'https://api.apidash.dev'; -let options = { +const options = { method: 'GET' }; -let status; fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); """; - expect(fetchCodeGen.getCode(requestModelGet1, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.jsFetch, requestModelGet1, "https"), + expectedCode); }); test('GET 2', () { const expectedCode = - r"""let url = 'https://api.foss42.com/country/data?code=US'; + r"""const url = 'https://api.apidash.dev/country/data?code=US'; -let options = { +const options = { method: 'GET' }; -let status; fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); """; - expect(fetchCodeGen.getCode(requestModelGet2, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.jsFetch, requestModelGet2, "https"), + expectedCode); }); test('GET 3', () { const expectedCode = - r"""let url = 'https://api.foss42.com/country/data?code=IND'; + r"""const url = 'https://api.apidash.dev/country/data?code=IND'; -let options = { +const options = { method: 'GET' }; -let status; fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); """; - expect(fetchCodeGen.getCode(requestModelGet3, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.jsFetch, requestModelGet3, "https"), + expectedCode); }); test('GET 4', () { const expectedCode = - r"""let url = 'https://api.foss42.com/humanize/social?num=8700000&digits=3&system=SS&add_space=true&trailing_zeros=true'; + r"""const url = 'https://api.apidash.dev/humanize/social?num=8700000&digits=3&system=SS&add_space=true&trailing_zeros=true'; -let options = { +const options = { method: 'GET' }; -let status; fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); """; - expect(fetchCodeGen.getCode(requestModelGet4, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.jsFetch, requestModelGet4, "https"), + expectedCode); }); test('GET 5', () { const expectedCode = - r"""let url = 'https://api.github.com/repos/foss42/apidash'; + r"""const url = 'https://api.github.com/repos/foss42/apidash'; -let options = { +const options = { method: 'GET', headers: { "User-Agent": "Test Agent" } }; -let status; fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); """; - expect(fetchCodeGen.getCode(requestModelGet5, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.jsFetch, requestModelGet5, "https"), + expectedCode); }); test('GET 6', () { const expectedCode = - r"""let url = 'https://api.github.com/repos/foss42/apidash?raw=true'; + r"""const url = 'https://api.github.com/repos/foss42/apidash?raw=true'; -let options = { +const options = { method: 'GET', headers: { "User-Agent": "Test Agent" } }; -let status; fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); """; - expect(fetchCodeGen.getCode(requestModelGet6, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.jsFetch, requestModelGet6, "https"), + expectedCode); }); test('GET 7', () { - const expectedCode = r"""let url = 'https://api.foss42.com'; + const expectedCode = r"""const url = 'https://api.apidash.dev'; -let options = { +const options = { method: 'GET' }; -let status; fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); """; - expect(fetchCodeGen.getCode(requestModelGet7, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.jsFetch, requestModelGet7, "https"), + expectedCode); }); test('GET 8', () { const expectedCode = - r"""let url = 'https://api.github.com/repos/foss42/apidash?raw=true'; + r"""const url = 'https://api.github.com/repos/foss42/apidash?raw=true'; -let options = { +const options = { method: 'GET', headers: { "User-Agent": "Test Agent" } }; -let status; fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); """; - expect(fetchCodeGen.getCode(requestModelGet8, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.jsFetch, requestModelGet8, "https"), + expectedCode); }); test('GET 9', () { const expectedCode = - r"""let url = 'https://api.foss42.com/humanize/social?num=8700000&add_space=true'; + r"""const url = 'https://api.apidash.dev/humanize/social?num=8700000&add_space=true'; -let options = { +const options = { method: 'GET' }; -let status; fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); """; - expect(fetchCodeGen.getCode(requestModelGet9, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.jsFetch, requestModelGet9, "https"), + expectedCode); }); test('GET 10', () { const expectedCode = - r"""let url = 'https://api.foss42.com/humanize/social'; + r"""const url = 'https://api.apidash.dev/humanize/social'; -let options = { +const options = { method: 'GET', headers: { "User-Agent": "Test Agent" } }; -let status; fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); """; expect( - fetchCodeGen.getCode( + codeGen.getCode( + CodegenLanguage.jsFetch, requestModelGet10, "https", ), @@ -283,323 +273,520 @@ fetch(url, options) test('GET 11', () { const expectedCode = - r"""let url = 'https://api.foss42.com/humanize/social?num=8700000&digits=3'; + r"""const url = 'https://api.apidash.dev/humanize/social?num=8700000&digits=3'; -let options = { +const options = { method: 'GET', headers: { "User-Agent": "Test Agent" } }; -let status; fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); """; - expect(fetchCodeGen.getCode(requestModelGet11, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.jsFetch, requestModelGet11, "https"), + expectedCode); }); test('GET 12', () { const expectedCode = - r"""let url = 'https://api.foss42.com/humanize/social'; + r"""const url = 'https://api.apidash.dev/humanize/social'; -let options = { +const options = { method: 'GET' }; -let status; fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); """; - expect(fetchCodeGen.getCode(requestModelGet12, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.jsFetch, requestModelGet12, "https"), + expectedCode); }); }); group('HEAD Request', () { test('HEAD 1', () { - const expectedCode = r"""let url = 'https://api.foss42.com'; + const expectedCode = r"""const url = 'https://api.apidash.dev'; -let options = { +const options = { method: 'HEAD' }; -let status; fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); """; - expect(fetchCodeGen.getCode(requestModelHead1, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.jsFetch, requestModelHead1, "https"), + expectedCode); }); test('HEAD 2', () { - const expectedCode = r"""let url = 'http://api.foss42.com'; + const expectedCode = r"""const url = 'http://api.apidash.dev'; -let options = { +const options = { method: 'HEAD' }; -let status; fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); """; - expect(fetchCodeGen.getCode(requestModelHead2, "http"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.jsFetch, requestModelHead2, "http"), + expectedCode); }); }); group('POST Request', () { test('POST 1', () { - const expectedCode = r"""let url = 'https://api.foss42.com/case/lower'; + const expectedCode = r"""const url = 'https://api.apidash.dev/case/lower'; -let options = { +const options = { method: 'POST', headers: { "Content-Type": "text/plain" }, - body: -"{\n\"text\": \"I LOVE Flutter\"\n}" + body: "{\n\"text\": \"I LOVE Flutter\"\n}" }; -let status; fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); """; - expect(fetchCodeGen.getCode(requestModelPost1, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.jsFetch, requestModelPost1, "https"), + expectedCode); }); test('POST 2', () { - const expectedCode = r"""let url = 'https://api.foss42.com/case/lower'; + const expectedCode = r"""const url = 'https://api.apidash.dev/case/lower'; -let options = { +const options = { method: 'POST', headers: { "Content-Type": "application/json" }, - body: -"{\n\"text\": \"I LOVE Flutter\"\n}" + body: "{\n\"text\": \"I LOVE Flutter\",\n\"flag\": null,\n\"male\": true,\n\"female\": false,\n\"no\": 1.2,\n\"arr\": [\"null\", \"true\", \"false\", null]\n}" }; -let status; fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); """; - expect(fetchCodeGen.getCode(requestModelPost2, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.jsFetch, requestModelPost2, "https"), + expectedCode); }); test('POST 3', () { - const expectedCode = r"""let url = 'https://api.foss42.com/case/lower'; + const expectedCode = r"""const url = 'https://api.apidash.dev/case/lower'; -let options = { +const options = { method: 'POST', headers: { "Content-Type": "application/json", "User-Agent": "Test Agent" }, - body: -"{\n\"text\": \"I LOVE Flutter\"\n}" + body: "{\n\"text\": \"I LOVE Flutter\"\n}" }; -let status; fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); """; - expect(fetchCodeGen.getCode(requestModelPost3, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.jsFetch, requestModelPost3, "https"), + expectedCode); + }); + test('POST 4', () { + const expectedCode = r"""const payload = new FormData(); +payload.append("text", "API") +payload.append("sep", "|") +payload.append("times", "3") + +const url = 'https://api.apidash.dev/io/form'; + +const options = { + method: 'POST', + body: payload +}; + +fetch(url, options) + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); +"""; + expect( + codeGen.getCode( + CodegenLanguage.jsFetch, + requestModelPost4, + "https", + ), + expectedCode); + }); + + test('POST 5', () { + const expectedCode = r"""const payload = new FormData(); +payload.append("text", "API") +payload.append("sep", "|") +payload.append("times", "3") + +const url = 'https://api.apidash.dev/io/form'; + +const options = { + method: 'POST', + headers: { + "User-Agent": "Test Agent" + }, + body: payload +}; + +fetch(url, options) + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); +"""; + expect( + codeGen.getCode( + CodegenLanguage.jsFetch, + requestModelPost5, + "https", + ), + expectedCode); + }); + test('POST 6', () { + const expectedCode = + r"""// refer https://github.com/foss42/apidash/issues/293#issuecomment-1995208098 for details regarding integration + +const payload = new FormData(); +payload.append("token", "xyz") +payload.append("imfile", fileInput1.files[0]) + +const url = 'https://api.apidash.dev/io/img'; + +const options = { + method: 'POST', + body: payload +}; + +fetch(url, options) + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); +"""; + expect( + codeGen.getCode( + CodegenLanguage.jsFetch, + requestModelPost6, + "https", + ), + expectedCode); + }); + test('POST 7', () { + const expectedCode = + r"""// refer https://github.com/foss42/apidash/issues/293#issuecomment-1995208098 for details regarding integration + +const payload = new FormData(); +payload.append("token", "xyz") +payload.append("imfile", fileInput1.files[0]) + +const url = 'https://api.apidash.dev/io/img'; + +const options = { + method: 'POST', + body: payload +}; + +fetch(url, options) + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); +"""; + expect( + codeGen.getCode( + CodegenLanguage.jsFetch, + requestModelPost7, + "https", + ), + expectedCode); + }); + test('POST 8', () { + const expectedCode = r"""const payload = new FormData(); +payload.append("text", "API") +payload.append("sep", "|") +payload.append("times", "3") + +const url = 'https://api.apidash.dev/io/form?size=2&len=3'; + +const options = { + method: 'POST', + body: payload +}; + +fetch(url, options) + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); +"""; + expect( + codeGen.getCode( + CodegenLanguage.jsFetch, + requestModelPost8, + "https", + ), + expectedCode); + }); + test('POST 9', () { + const expectedCode = + r"""// refer https://github.com/foss42/apidash/issues/293#issuecomment-1995208098 for details regarding integration + +const payload = new FormData(); +payload.append("token", "xyz") +payload.append("imfile", fileInput1.files[0]) + +const url = 'https://api.apidash.dev/io/img?size=2&len=3'; + +const options = { + method: 'POST', + headers: { + "User-Agent": "Test Agent", + "Keep-Alive": "true" + }, + body: payload +}; + +fetch(url, options) + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); +"""; + expect( + codeGen.getCode( + CodegenLanguage.jsFetch, + requestModelPost9, + "https", + ), + expectedCode); }); }); group('PUT Request', () { test('PUT 1', () { - const expectedCode = r"""let url = 'https://reqres.in/api/users/2'; + const expectedCode = r"""const url = 'https://reqres.in/api/users/2'; -let options = { +const options = { method: 'PUT', headers: { "Content-Type": "application/json" }, - body: -"{\n\"name\": \"morpheus\",\n\"job\": \"zion resident\"\n}" + body: "{\n\"name\": \"morpheus\",\n\"job\": \"zion resident\"\n}" }; -let status; fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); """; - expect(fetchCodeGen.getCode(requestModelPut1, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.jsFetch, requestModelPut1, "https"), + expectedCode); }); }); group('PATCH Request', () { test('PATCH 1', () { - const expectedCode = r"""let url = 'https://reqres.in/api/users/2'; + const expectedCode = r"""const url = 'https://reqres.in/api/users/2'; -let options = { +const options = { method: 'PATCH', headers: { "Content-Type": "application/json" }, - body: -"{\n\"name\": \"marfeus\",\n\"job\": \"accountant\"\n}" + body: "{\n\"name\": \"marfeus\",\n\"job\": \"accountant\"\n}" }; -let status; fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); """; - expect(fetchCodeGen.getCode(requestModelPatch1, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.jsFetch, requestModelPatch1, "https"), + expectedCode); }); }); group('DELETE Request', () { test('DELETE 1', () { - const expectedCode = r"""let url = 'https://reqres.in/api/users/2'; + const expectedCode = r"""const url = 'https://reqres.in/api/users/2'; -let options = { +const options = { method: 'DELETE' }; -let status; fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); """; - expect(fetchCodeGen.getCode(requestModelDelete1, "https"), expectedCode); + expect( + codeGen.getCode( + CodegenLanguage.jsFetch, requestModelDelete1, "https"), + expectedCode); }); test('DELETE 2', () { - const expectedCode = r"""let url = 'https://reqres.in/api/users/2'; + const expectedCode = r"""const url = 'https://reqres.in/api/users/2'; -let options = { +const options = { method: 'DELETE', headers: { "Content-Type": "application/json" }, - body: -"{\n\"name\": \"marfeus\",\n\"job\": \"accountant\"\n}" + body: "{\n\"name\": \"marfeus\",\n\"job\": \"accountant\"\n}" }; -let status; fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); """; - expect(fetchCodeGen.getCode(requestModelDelete2, "https"), expectedCode); + expect( + codeGen.getCode( + CodegenLanguage.jsFetch, requestModelDelete2, "https"), + expectedCode); }); }); } diff --git a/test/codegen/julia_http_codegen_test.dart b/test/codegen/julia_http_codegen_test.dart new file mode 100644 index 00000000..2b5161eb --- /dev/null +++ b/test/codegen/julia_http_codegen_test.dart @@ -0,0 +1,453 @@ +import 'package:apidash/codegen/codegen.dart'; +import 'package:apidash/consts.dart'; +import 'package:test/test.dart'; +import '../request_models.dart'; + +void main() { + final codeGen = Codegen(); + + group('GET Request', () { + test('GET 1', () { + const expectedCode = r"""using HTTP,JSON + +url = "https://api.apidash.dev" + + +response = HTTP.get(url) + +println("Status Code:", response.status) +println("Response Body:", String(response.body)) +"""; + expect( + codeGen.getCode(CodegenLanguage.juliaHttp, requestModelGet1, "https"), + expectedCode); + }); + test('GET 2', () { + const expectedCode = r"""using HTTP,JSON + +url = "https://api.apidash.dev/country/data" + + +params = Dict( + "code"=> "US" + ) + +response = HTTP.get(url, query=params) + +println("Status Code:", response.status) +println("Response Body:", String(response.body)) +"""; + expect( + codeGen.getCode(CodegenLanguage.juliaHttp, requestModelGet2, "https"), + expectedCode); + }); + test('GET 3', () { + const expectedCode = r"""using HTTP,JSON + +url = "https://api.apidash.dev/country/data" + + +params = Dict( + "code"=> "IND" + ) + +response = HTTP.get(url, query=params) + +println("Status Code:", response.status) +println("Response Body:", String(response.body)) +"""; + expect( + codeGen.getCode(CodegenLanguage.juliaHttp, requestModelGet3, "https"), + expectedCode); + }); + test('GET 4', () { + const expectedCode = r"""using HTTP,JSON + +url = "https://api.apidash.dev/humanize/social" + + +params = Dict( + "num"=> "8700000", + "digits"=> "3", + "system"=> "SS", + "add_space"=> "true", + "trailing_zeros"=> "true" + ) + +response = HTTP.get(url, query=params) + +println("Status Code:", response.status) +println("Response Body:", String(response.body)) +"""; + expect( + codeGen.getCode(CodegenLanguage.juliaHttp, requestModelGet4, "https"), + expectedCode); + }); + + test('GET 5', () { + const expectedCode = r"""using HTTP,JSON + +url = "https://api.github.com/repos/foss42/apidash" + + +headers = Dict( + "User-Agent"=> "Test Agent" + ) + +response = HTTP.get(url, headers=headers) + +println("Status Code:", response.status) +println("Response Body:", String(response.body)) +"""; + expect( + codeGen.getCode(CodegenLanguage.juliaHttp, requestModelGet5, "https"), + expectedCode); + }); + + test('GET 6', () { + const expectedCode = r"""using HTTP,JSON + +url = "https://api.github.com/repos/foss42/apidash" + + +params = Dict( + "raw"=> "true" + ) + +headers = Dict( + "User-Agent"=> "Test Agent" + ) + +response = HTTP.get(url, query=params, headers=headers) + +println("Status Code:", response.status) +println("Response Body:", String(response.body)) +"""; + expect( + codeGen.getCode(CodegenLanguage.juliaHttp, requestModelGet6, "https"), + expectedCode); + }); + + test('GET 7', () { + const expectedCode = r"""using HTTP,JSON + +url = "https://api.apidash.dev" + + +response = HTTP.get(url) + +println("Status Code:", response.status) +println("Response Body:", String(response.body)) +"""; + expect( + codeGen.getCode(CodegenLanguage.juliaHttp, requestModelGet7, "https"), + expectedCode); + }); + + test('GET 8', () { + const expectedCode = r"""using HTTP,JSON + +url = "https://api.github.com/repos/foss42/apidash" + + +params = Dict( + "raw"=> "true" + ) + +headers = Dict( + "User-Agent"=> "Test Agent" + ) + +response = HTTP.get(url, query=params, headers=headers) + +println("Status Code:", response.status) +println("Response Body:", String(response.body)) +"""; + expect( + codeGen.getCode(CodegenLanguage.juliaHttp, requestModelGet8, "https"), + expectedCode); + }); + + test('GET 9', () { + const expectedCode = r"""using HTTP,JSON + +url = "https://api.apidash.dev/humanize/social" + + +params = Dict( + "num"=> "8700000", + "add_space"=> "true" + ) + +response = HTTP.get(url, query=params) + +println("Status Code:", response.status) +println("Response Body:", String(response.body)) +"""; + expect( + codeGen.getCode(CodegenLanguage.juliaHttp, requestModelGet9, "https"), + expectedCode); + }); + + test('GET 10', () { + const expectedCode = r"""using HTTP,JSON + +url = "https://api.apidash.dev/humanize/social" + + +headers = Dict( + "User-Agent"=> "Test Agent" + ) + +response = HTTP.get(url, headers=headers) + +println("Status Code:", response.status) +println("Response Body:", String(response.body)) +"""; + expect( + codeGen.getCode( + CodegenLanguage.juliaHttp, requestModelGet10, "https"), + expectedCode); + }); + + test('GET 11', () { + const expectedCode = r"""using HTTP,JSON + +url = "https://api.apidash.dev/humanize/social" + + +params = Dict( + "num"=> "8700000", + "digits"=> "3" + ) + +headers = Dict( + "User-Agent"=> "Test Agent" + ) + +response = HTTP.get(url, query=params, headers=headers) + +println("Status Code:", response.status) +println("Response Body:", String(response.body)) +"""; + expect( + codeGen.getCode( + CodegenLanguage.juliaHttp, requestModelGet11, "https"), + expectedCode); + }); + + test('GET 12', () { + const expectedCode = r"""using HTTP,JSON + +url = "https://api.apidash.dev/humanize/social" + + +response = HTTP.get(url) + +println("Status Code:", response.status) +println("Response Body:", String(response.body)) +"""; + expect( + codeGen.getCode( + CodegenLanguage.juliaHttp, requestModelGet12, "https"), + expectedCode); + }); + }); + + group('HEAD Request', () { + test('HEAD 1', () { + const expectedCode = r"""using HTTP,JSON + +url = "https://api.apidash.dev" + + +response = HTTP.head(url) + +println("Status Code:", response.status) +println("Response Body:", String(response.body)) +"""; + expect( + codeGen.getCode( + CodegenLanguage.juliaHttp, requestModelHead1, "https"), + expectedCode); + }); + + test('HEAD 2', () { + const expectedCode = r"""using HTTP,JSON + +url = "https://api.apidash.dev" + + +response = HTTP.head(url) + +println("Status Code:", response.status) +println("Response Body:", String(response.body)) +"""; + expect( + codeGen.getCode( + CodegenLanguage.juliaHttp, requestModelHead2, "https"), + expectedCode); + }); + }); + + group('POST Request', () { + test('POST 1', () { + const expectedCode = r"""using HTTP,JSON + +url = "https://api.apidash.dev/case/lower" + + +payload = Dict( +"text"=> "I LOVE Flutter" +) + +headers = Dict( + "content-type"=> "text/plain" + ) + +response = HTTP.post(url, payload=payload, headers=headers) + +println("Status Code:", response.status) +println("Response Body:", String(response.body)) +"""; + expect( + codeGen.getCode( + CodegenLanguage.juliaHttp, requestModelPost1, "https"), + expectedCode); + }); + + test('POST 2', () { + const expectedCode = r"""using HTTP,JSON + +url = "https://api.apidash.dev/case/lower" + + +payload = Dict( +"text"=> "I LOVE Flutter", +"flag"=> null, +"male"=> true, +"female"=> false, +"no"=> 1.2, +"arr"=> ["null", "true", "false", null] +) + +response = HTTP.post(url, JSON.json(payload)) + +println("Status Code:", response.status) +println("Response Body:", String(response.body)) +"""; + expect( + codeGen.getCode( + CodegenLanguage.juliaHttp, requestModelPost2, "https"), + expectedCode); + }); + test('POST 3', () { + const expectedCode = r"""using HTTP,JSON + +url = "https://api.apidash.dev/case/lower" + + +payload = Dict( +"text"=> "I LOVE Flutter" +) + +headers = Dict( + "User-Agent"=> "Test Agent" + ) + +response = HTTP.post(url, JSON.json(payload), headers=headers) + +println("Status Code:", response.status) +println("Response Body:", String(response.body)) +"""; + expect( + codeGen.getCode( + CodegenLanguage.juliaHttp, requestModelPost3, "https"), + expectedCode); + }); + }); + group('PUT Request', () { + test('PUT 1', () { + const expectedCode = r"""using HTTP,JSON + +url = "https://reqres.in/api/users/2" + + +payload = Dict( +"name"=> "morpheus", +"job"=> "zion resident" +) + +response = HTTP.put(url, JSON.json(payload)) + +println("Status Code:", response.status) +println("Response Body:", String(response.body)) +"""; + expect( + codeGen.getCode(CodegenLanguage.juliaHttp, requestModelPut1, "https"), + expectedCode); + }); + }); + group('PATCH Request', () { + test('PATCH 1', () { + const expectedCode = r"""using HTTP,JSON + +url = "https://reqres.in/api/users/2" + + +payload = Dict( +"name"=> "marfeus", +"job"=> "accountant" +) + +response = HTTP.patch(url, JSON.json(payload)) + +println("Status Code:", response.status) +println("Response Body:", String(response.body)) +"""; + expect( + codeGen.getCode( + CodegenLanguage.juliaHttp, requestModelPatch1, "https"), + expectedCode); + }); + }); + group('DELETE Request', () { + test('DELETE 1', () { + const expectedCode = r"""using HTTP,JSON + +url = "https://reqres.in/api/users/2" + + +response = HTTP.delete(url) + +println("Status Code:", response.status) +println("Response Body:", String(response.body)) +"""; + expect( + codeGen.getCode( + CodegenLanguage.juliaHttp, requestModelDelete1, "https"), + expectedCode); + }); + test('DELETE 2', () { + const expectedCode = r"""using HTTP,JSON + +url = "https://reqres.in/api/users/2" + + +payload = Dict( +"name"=> "marfeus", +"job"=> "accountant" +) + +response = HTTP.delete(url, JSON.json(payload)) + +println("Status Code:", response.status) +println("Response Body:", String(response.body)) +"""; + expect( + codeGen.getCode( + CodegenLanguage.juliaHttp, requestModelDelete2, "https"), + expectedCode); + }); + }); +} diff --git a/test/codegen/kotlin_okhttp_codegen_test.dart b/test/codegen/kotlin_okhttp_codegen_test.dart index 4f3220fa..f91f183c 100644 --- a/test/codegen/kotlin_okhttp_codegen_test.dart +++ b/test/codegen/kotlin_okhttp_codegen_test.dart @@ -1,9 +1,10 @@ -import 'package:apidash/codegen/kotlin/okhttp.dart'; +import 'package:apidash/codegen/codegen.dart'; +import 'package:apidash/consts.dart'; import 'package:test/test.dart'; import '../request_models.dart'; void main() { - final kotlinOkHttpCodeGen = KotlinOkHttpCodeGen(); + final codeGen = Codegen(); group('GET Request', () { test('GET 1', () { @@ -13,7 +14,7 @@ import okhttp3.Request fun main() { val client = OkHttpClient() - val url = "https://api.foss42.com" + val url = "https://api.apidash.dev" val request = Request.Builder() .url(url) @@ -27,7 +28,9 @@ fun main() { } """; expect( - kotlinOkHttpCodeGen.getCode(requestModelGet1, "https"), expectedCode); + codeGen.getCode( + CodegenLanguage.kotlinOkHttp, requestModelGet1, "https"), + expectedCode); }); test('GET 2', () { @@ -38,7 +41,7 @@ import okhttp3.HttpUrl.Companion.toHttpUrl fun main() { val client = OkHttpClient() - val url = "https://api.foss42.com/country/data".toHttpUrl().newBuilder() + val url = "https://api.apidash.dev/country/data".toHttpUrl().newBuilder() .addQueryParameter("code", "US") .build() @@ -54,7 +57,9 @@ fun main() { } """; expect( - kotlinOkHttpCodeGen.getCode(requestModelGet2, "https"), expectedCode); + codeGen.getCode( + CodegenLanguage.kotlinOkHttp, requestModelGet2, "https"), + expectedCode); }); test('GET 3', () { @@ -65,7 +70,7 @@ import okhttp3.HttpUrl.Companion.toHttpUrl fun main() { val client = OkHttpClient() - val url = "https://api.foss42.com/country/data".toHttpUrl().newBuilder() + val url = "https://api.apidash.dev/country/data".toHttpUrl().newBuilder() .addQueryParameter("code", "IND") .build() @@ -81,7 +86,9 @@ fun main() { } """; expect( - kotlinOkHttpCodeGen.getCode(requestModelGet3, "https"), expectedCode); + codeGen.getCode( + CodegenLanguage.kotlinOkHttp, requestModelGet3, "https"), + expectedCode); }); test('GET 4', () { @@ -92,7 +99,7 @@ import okhttp3.HttpUrl.Companion.toHttpUrl fun main() { val client = OkHttpClient() - val url = "https://api.foss42.com/humanize/social".toHttpUrl().newBuilder() + val url = "https://api.apidash.dev/humanize/social".toHttpUrl().newBuilder() .addQueryParameter("num", "8700000") .addQueryParameter("digits", "3") .addQueryParameter("system", "SS") @@ -112,7 +119,9 @@ fun main() { } """; expect( - kotlinOkHttpCodeGen.getCode(requestModelGet4, "https"), expectedCode); + codeGen.getCode( + CodegenLanguage.kotlinOkHttp, requestModelGet4, "https"), + expectedCode); }); test('GET 5', () { @@ -137,7 +146,9 @@ fun main() { } """; expect( - kotlinOkHttpCodeGen.getCode(requestModelGet5, "https"), expectedCode); + codeGen.getCode( + CodegenLanguage.kotlinOkHttp, requestModelGet5, "https"), + expectedCode); }); test('GET 6', () { @@ -165,7 +176,9 @@ fun main() { } """; expect( - kotlinOkHttpCodeGen.getCode(requestModelGet6, "https"), expectedCode); + codeGen.getCode( + CodegenLanguage.kotlinOkHttp, requestModelGet6, "https"), + expectedCode); }); test('GET 7', () { @@ -175,7 +188,7 @@ import okhttp3.Request fun main() { val client = OkHttpClient() - val url = "https://api.foss42.com" + val url = "https://api.apidash.dev" val request = Request.Builder() .url(url) @@ -189,7 +202,9 @@ fun main() { } """; expect( - kotlinOkHttpCodeGen.getCode(requestModelGet7, "https"), expectedCode); + codeGen.getCode( + CodegenLanguage.kotlinOkHttp, requestModelGet7, "https"), + expectedCode); }); test('GET 8', () { @@ -217,7 +232,9 @@ fun main() { } """; expect( - kotlinOkHttpCodeGen.getCode(requestModelGet8, "https"), expectedCode); + codeGen.getCode( + CodegenLanguage.kotlinOkHttp, requestModelGet8, "https"), + expectedCode); }); test('GET 9', () { @@ -228,7 +245,7 @@ import okhttp3.HttpUrl.Companion.toHttpUrl fun main() { val client = OkHttpClient() - val url = "https://api.foss42.com/humanize/social".toHttpUrl().newBuilder() + val url = "https://api.apidash.dev/humanize/social".toHttpUrl().newBuilder() .addQueryParameter("num", "8700000") .addQueryParameter("add_space", "true") .build() @@ -245,7 +262,9 @@ fun main() { } """; expect( - kotlinOkHttpCodeGen.getCode(requestModelGet9, "https"), expectedCode); + codeGen.getCode( + CodegenLanguage.kotlinOkHttp, requestModelGet9, "https"), + expectedCode); }); test('GET 10', () { @@ -255,7 +274,7 @@ import okhttp3.Request fun main() { val client = OkHttpClient() - val url = "https://api.foss42.com/humanize/social" + val url = "https://api.apidash.dev/humanize/social" val request = Request.Builder() .url(url) @@ -270,7 +289,8 @@ fun main() { } """; expect( - kotlinOkHttpCodeGen.getCode( + codeGen.getCode( + CodegenLanguage.kotlinOkHttp, requestModelGet10, "https", ), @@ -285,7 +305,7 @@ import okhttp3.HttpUrl.Companion.toHttpUrl fun main() { val client = OkHttpClient() - val url = "https://api.foss42.com/humanize/social".toHttpUrl().newBuilder() + val url = "https://api.apidash.dev/humanize/social".toHttpUrl().newBuilder() .addQueryParameter("num", "8700000") .addQueryParameter("digits", "3") .build() @@ -302,7 +322,9 @@ fun main() { println(response.body?.string()) } """; - expect(kotlinOkHttpCodeGen.getCode(requestModelGet11, "https"), + expect( + codeGen.getCode( + CodegenLanguage.kotlinOkHttp, requestModelGet11, "https"), expectedCode); }); @@ -313,7 +335,7 @@ import okhttp3.Request fun main() { val client = OkHttpClient() - val url = "https://api.foss42.com/humanize/social" + val url = "https://api.apidash.dev/humanize/social" val request = Request.Builder() .url(url) @@ -326,7 +348,9 @@ fun main() { println(response.body?.string()) } """; - expect(kotlinOkHttpCodeGen.getCode(requestModelGet12, "https"), + expect( + codeGen.getCode( + CodegenLanguage.kotlinOkHttp, requestModelGet12, "https"), expectedCode); }); }); @@ -339,31 +363,7 @@ import okhttp3.Request fun main() { val client = OkHttpClient() - val url = "https://api.foss42.com" - - val request = Request.Builder() - .url(url) - .head() - .build() - - val response = client.newCall(request).execute() - - println(response.code) - println(response.body?.string()) -} -"""; - expect(kotlinOkHttpCodeGen.getCode(requestModelHead1, "https"), - expectedCode); - }); - - test('HEAD 2', () { - const expectedCode = r"""import okhttp3.OkHttpClient -import okhttp3.Request - -fun main() { - val client = OkHttpClient() - - val url = "http://api.foss42.com" + val url = "https://api.apidash.dev" val request = Request.Builder() .url(url) @@ -377,7 +377,35 @@ fun main() { } """; expect( - kotlinOkHttpCodeGen.getCode(requestModelHead2, "http"), expectedCode); + codeGen.getCode( + CodegenLanguage.kotlinOkHttp, requestModelHead1, "https"), + expectedCode); + }); + + test('HEAD 2', () { + const expectedCode = r"""import okhttp3.OkHttpClient +import okhttp3.Request + +fun main() { + val client = OkHttpClient() + + val url = "http://api.apidash.dev" + + val request = Request.Builder() + .url(url) + .head() + .build() + + val response = client.newCall(request).execute() + + println(response.code) + println(response.body?.string()) +} +"""; + expect( + codeGen.getCode( + CodegenLanguage.kotlinOkHttp, requestModelHead2, "http"), + expectedCode); }); }); @@ -391,7 +419,7 @@ import okhttp3.MediaType.Companion.toMediaType fun main() { val client = OkHttpClient() - val url = "https://api.foss42.com/case/lower" + val url = "https://api.apidash.dev/case/lower" val mediaType = "text/plain".toMediaType() @@ -410,7 +438,9 @@ fun main() { println(response.body?.string()) } '''; - expect(kotlinOkHttpCodeGen.getCode(requestModelPost1, "https"), + expect( + codeGen.getCode( + CodegenLanguage.kotlinOkHttp, requestModelPost1, "https"), expectedCode); }); @@ -423,12 +453,17 @@ import okhttp3.MediaType.Companion.toMediaType fun main() { val client = OkHttpClient() - val url = "https://api.foss42.com/case/lower" + val url = "https://api.apidash.dev/case/lower" val mediaType = "application/json".toMediaType() val body = """{ -"text": "I LOVE Flutter" +"text": "I LOVE Flutter", +"flag": null, +"male": true, +"female": false, +"no": 1.2, +"arr": ["null", "true", "false", null] }""".toRequestBody(mediaType) val request = Request.Builder() @@ -442,7 +477,9 @@ fun main() { println(response.body?.string()) } '''; - expect(kotlinOkHttpCodeGen.getCode(requestModelPost2, "https"), + expect( + codeGen.getCode( + CodegenLanguage.kotlinOkHttp, requestModelPost2, "https"), expectedCode); }); @@ -455,7 +492,7 @@ import okhttp3.MediaType.Companion.toMediaType fun main() { val client = OkHttpClient() - val url = "https://api.foss42.com/case/lower" + val url = "https://api.apidash.dev/case/lower" val mediaType = "application/json".toMediaType() @@ -475,7 +512,40 @@ fun main() { println(response.body?.string()) } '''; - expect(kotlinOkHttpCodeGen.getCode(requestModelPost3, "https"), + expect( + codeGen.getCode( + CodegenLanguage.kotlinOkHttp, requestModelPost3, "https"), + expectedCode); + }); + + test('POST 5', () { + const expectedCode = r'''import okhttp3.OkHttpClient +import okhttp3.Request +import okhttp3.MultipartBody + +fun main() { + val client = OkHttpClient() + + val url = "https://api.apidash.dev/io/form" + val body = MultipartBody.Builder().setType(MultipartBody.FORM).addFormDataPart("text","API") + .addFormDataPart("sep","|") + .addFormDataPart("times","3") + .build() + val request = Request.Builder() + .url(url) + .addHeader("User-Agent", "Test Agent") + .post(body) + .build() + + val response = client.newCall(request).execute() + + println(response.code) + println(response.body?.string()) +} +'''; + expect( + codeGen.getCode( + CodegenLanguage.kotlinOkHttp, requestModelPost5, "https"), expectedCode); }); }); @@ -511,7 +581,9 @@ fun main() { } '''; expect( - kotlinOkHttpCodeGen.getCode(requestModelPut1, "https"), expectedCode); + codeGen.getCode( + CodegenLanguage.kotlinOkHttp, requestModelPut1, "https"), + expectedCode); }); }); @@ -545,7 +617,9 @@ fun main() { println(response.body?.string()) } '''; - expect(kotlinOkHttpCodeGen.getCode(requestModelPatch1, "https"), + expect( + codeGen.getCode( + CodegenLanguage.kotlinOkHttp, requestModelPatch1, "https"), expectedCode); }); }); @@ -571,7 +645,9 @@ fun main() { println(response.body?.string()) } """; - expect(kotlinOkHttpCodeGen.getCode(requestModelDelete1, "https"), + expect( + codeGen.getCode( + CodegenLanguage.kotlinOkHttp, requestModelDelete1, "https"), expectedCode); }); @@ -604,7 +680,9 @@ fun main() { println(response.body?.string()) } '''; - expect(kotlinOkHttpCodeGen.getCode(requestModelDelete2, "https"), + expect( + codeGen.getCode( + CodegenLanguage.kotlinOkHttp, requestModelDelete2, "https"), expectedCode); }); }); diff --git a/test/codegen/nodejs_axios_codegen_test.dart b/test/codegen/nodejs_axios_codegen_test.dart index 519f5ab5..ab4c2bf5 100644 --- a/test/codegen/nodejs_axios_codegen_test.dart +++ b/test/codegen/nodejs_axios_codegen_test.dart @@ -1,16 +1,17 @@ -import 'package:apidash/codegen/js/axios.dart'; -import '../request_models.dart'; +import 'package:apidash/codegen/codegen.dart'; +import 'package:apidash/consts.dart'; import 'package:test/test.dart'; +import '../request_models.dart'; void main() { - final axiosCodeGen = AxiosCodeGen(isNodeJs: true); + final codeGen = Codegen(); group('GET Request', () { test('GET 1', () { const expectedCode = r"""import axios from 'axios'; let config = { - url: 'https://api.foss42.com', + url: 'https://api.apidash.dev', method: 'get' }; @@ -26,14 +27,17 @@ axios(config) console.log(error); }); """; - expect(axiosCodeGen.getCode(requestModelGet1, "https"), expectedCode); + expect( + codeGen.getCode( + CodegenLanguage.nodejsAxios, requestModelGet1, "https"), + expectedCode); }); test('GET 2', () { const expectedCode = r"""import axios from 'axios'; let config = { - url: 'https://api.foss42.com/country/data', + url: 'https://api.apidash.dev/country/data', method: 'get', params: { "code": "US" @@ -52,14 +56,17 @@ axios(config) console.log(error); }); """; - expect(axiosCodeGen.getCode(requestModelGet2, "https"), expectedCode); + expect( + codeGen.getCode( + CodegenLanguage.nodejsAxios, requestModelGet2, "https"), + expectedCode); }); test('GET 3', () { const expectedCode = r"""import axios from 'axios'; let config = { - url: 'https://api.foss42.com/country/data', + url: 'https://api.apidash.dev/country/data', method: 'get', params: { "code": "IND" @@ -78,14 +85,17 @@ axios(config) console.log(error); }); """; - expect(axiosCodeGen.getCode(requestModelGet3, "https"), expectedCode); + expect( + codeGen.getCode( + CodegenLanguage.nodejsAxios, requestModelGet3, "https"), + expectedCode); }); test('GET 4', () { const expectedCode = r"""import axios from 'axios'; let config = { - url: 'https://api.foss42.com/humanize/social', + url: 'https://api.apidash.dev/humanize/social', method: 'get', params: { "num": "8700000", @@ -108,7 +118,10 @@ axios(config) console.log(error); }); """; - expect(axiosCodeGen.getCode(requestModelGet4, "https"), expectedCode); + expect( + codeGen.getCode( + CodegenLanguage.nodejsAxios, requestModelGet4, "https"), + expectedCode); }); test('GET 5', () { @@ -134,7 +147,10 @@ axios(config) console.log(error); }); """; - expect(axiosCodeGen.getCode(requestModelGet5, "https"), expectedCode); + expect( + codeGen.getCode( + CodegenLanguage.nodejsAxios, requestModelGet5, "https"), + expectedCode); }); test('GET 6', () { @@ -163,14 +179,17 @@ axios(config) console.log(error); }); """; - expect(axiosCodeGen.getCode(requestModelGet6, "https"), expectedCode); + expect( + codeGen.getCode( + CodegenLanguage.nodejsAxios, requestModelGet6, "https"), + expectedCode); }); test('GET 7', () { const expectedCode = r"""import axios from 'axios'; let config = { - url: 'https://api.foss42.com', + url: 'https://api.apidash.dev', method: 'get' }; @@ -186,7 +205,10 @@ axios(config) console.log(error); }); """; - expect(axiosCodeGen.getCode(requestModelGet7, "https"), expectedCode); + expect( + codeGen.getCode( + CodegenLanguage.nodejsAxios, requestModelGet7, "https"), + expectedCode); }); test('GET 8', () { @@ -215,14 +237,17 @@ axios(config) console.log(error); }); """; - expect(axiosCodeGen.getCode(requestModelGet8, "https"), expectedCode); + expect( + codeGen.getCode( + CodegenLanguage.nodejsAxios, requestModelGet8, "https"), + expectedCode); }); test('GET 9', () { const expectedCode = r"""import axios from 'axios'; let config = { - url: 'https://api.foss42.com/humanize/social', + url: 'https://api.apidash.dev/humanize/social', method: 'get', params: { "num": "8700000", @@ -242,14 +267,17 @@ axios(config) console.log(error); }); """; - expect(axiosCodeGen.getCode(requestModelGet9, "https"), expectedCode); + expect( + codeGen.getCode( + CodegenLanguage.nodejsAxios, requestModelGet9, "https"), + expectedCode); }); test('GET 10', () { const expectedCode = r"""import axios from 'axios'; let config = { - url: 'https://api.foss42.com/humanize/social', + url: 'https://api.apidash.dev/humanize/social', method: 'get', headers: { "User-Agent": "Test Agent" @@ -269,7 +297,8 @@ axios(config) }); """; expect( - axiosCodeGen.getCode( + codeGen.getCode( + CodegenLanguage.nodejsAxios, requestModelGet10, "https", ), @@ -280,7 +309,7 @@ axios(config) const expectedCode = r"""import axios from 'axios'; let config = { - url: 'https://api.foss42.com/humanize/social', + url: 'https://api.apidash.dev/humanize/social', method: 'get', params: { "num": "8700000", @@ -303,14 +332,17 @@ axios(config) console.log(error); }); """; - expect(axiosCodeGen.getCode(requestModelGet11, "https"), expectedCode); + expect( + codeGen.getCode( + CodegenLanguage.nodejsAxios, requestModelGet11, "https"), + expectedCode); }); test('GET 12', () { const expectedCode = r"""import axios from 'axios'; let config = { - url: 'https://api.foss42.com/humanize/social', + url: 'https://api.apidash.dev/humanize/social', method: 'get' }; @@ -326,7 +358,10 @@ axios(config) console.log(error); }); """; - expect(axiosCodeGen.getCode(requestModelGet12, "https"), expectedCode); + expect( + codeGen.getCode( + CodegenLanguage.nodejsAxios, requestModelGet12, "https"), + expectedCode); }); }); @@ -335,7 +370,7 @@ axios(config) const expectedCode = r"""import axios from 'axios'; let config = { - url: 'https://api.foss42.com', + url: 'https://api.apidash.dev', method: 'head' }; @@ -351,14 +386,17 @@ axios(config) console.log(error); }); """; - expect(axiosCodeGen.getCode(requestModelHead1, "https"), expectedCode); + expect( + codeGen.getCode( + CodegenLanguage.nodejsAxios, requestModelHead1, "https"), + expectedCode); }); test('HEAD 2', () { const expectedCode = r"""import axios from 'axios'; let config = { - url: 'http://api.foss42.com', + url: 'http://api.apidash.dev', method: 'head' }; @@ -374,7 +412,10 @@ axios(config) console.log(error); }); """; - expect(axiosCodeGen.getCode(requestModelHead2, "http"), expectedCode); + expect( + codeGen.getCode( + CodegenLanguage.nodejsAxios, requestModelHead2, "http"), + expectedCode); }); }); @@ -383,7 +424,7 @@ axios(config) const expectedCode = r"""import axios from 'axios'; let config = { - url: 'https://api.foss42.com/case/lower', + url: 'https://api.apidash.dev/case/lower', method: 'post', headers: { "Content-Type": "text/plain" @@ -403,19 +444,22 @@ axios(config) console.log(error); }); """; - expect(axiosCodeGen.getCode(requestModelPost1, "https"), expectedCode); + expect( + codeGen.getCode( + CodegenLanguage.nodejsAxios, requestModelPost1, "https"), + expectedCode); }); test('POST 2', () { const expectedCode = r"""import axios from 'axios'; let config = { - url: 'https://api.foss42.com/case/lower', + url: 'https://api.apidash.dev/case/lower', method: 'post', headers: { "Content-Type": "application/json" }, - data: "{\n\"text\": \"I LOVE Flutter\"\n}" + data: "{\n\"text\": \"I LOVE Flutter\",\n\"flag\": null,\n\"male\": true,\n\"female\": false,\n\"no\": 1.2,\n\"arr\": [\"null\", \"true\", \"false\", null]\n}" }; axios(config) @@ -430,14 +474,17 @@ axios(config) console.log(error); }); """; - expect(axiosCodeGen.getCode(requestModelPost2, "https"), expectedCode); + expect( + codeGen.getCode( + CodegenLanguage.nodejsAxios, requestModelPost2, "https"), + expectedCode); }); test('POST 3', () { const expectedCode = r"""import axios from 'axios'; let config = { - url: 'https://api.foss42.com/case/lower', + url: 'https://api.apidash.dev/case/lower', method: 'post', headers: { "Content-Type": "application/json", @@ -458,7 +505,10 @@ axios(config) console.log(error); }); """; - expect(axiosCodeGen.getCode(requestModelPost3, "https"), expectedCode); + expect( + codeGen.getCode( + CodegenLanguage.nodejsAxios, requestModelPost3, "https"), + expectedCode); }); }); @@ -487,7 +537,10 @@ axios(config) console.log(error); }); """; - expect(axiosCodeGen.getCode(requestModelPut1, "https"), expectedCode); + expect( + codeGen.getCode( + CodegenLanguage.nodejsAxios, requestModelPut1, "https"), + expectedCode); }); }); @@ -516,7 +569,10 @@ axios(config) console.log(error); }); """; - expect(axiosCodeGen.getCode(requestModelPatch1, "https"), expectedCode); + expect( + codeGen.getCode( + CodegenLanguage.nodejsAxios, requestModelPatch1, "https"), + expectedCode); }); }); @@ -541,7 +597,10 @@ axios(config) console.log(error); }); """; - expect(axiosCodeGen.getCode(requestModelDelete1, "https"), expectedCode); + expect( + codeGen.getCode( + CodegenLanguage.nodejsAxios, requestModelDelete1, "https"), + expectedCode); }); test('DELETE 2', () { @@ -568,7 +627,10 @@ axios(config) console.log(error); }); """; - expect(axiosCodeGen.getCode(requestModelDelete2, "https"), expectedCode); + expect( + codeGen.getCode( + CodegenLanguage.nodejsAxios, requestModelDelete2, "https"), + expectedCode); }); }); } diff --git a/test/codegen/nodejs_fetch_codegen_test.dart b/test/codegen/nodejs_fetch_codegen_test.dart index c06ceee5..88ca7072 100644 --- a/test/codegen/nodejs_fetch_codegen_test.dart +++ b/test/codegen/nodejs_fetch_codegen_test.dart @@ -1,292 +1,291 @@ -import 'package:apidash/codegen/js/fetch.dart'; -import '../request_models.dart'; +import 'package:apidash/codegen/codegen.dart'; +import 'package:apidash/consts.dart'; import 'package:test/test.dart'; +import '../request_models.dart'; void main() { - final fetchCodeGen = FetchCodeGen(isNodeJs: true); + final codeGen = Codegen(); group('GET Request', () { test('GET 1', () { - const expectedCode = r"""import fetch from 'node-fetch'; + const expectedCode = r"""import fetch from 'node-fetch' -let url = 'https://api.foss42.com'; +const url = 'https://api.apidash.dev'; -let options = { +const options = { method: 'GET' }; -let status; fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); """; - expect(fetchCodeGen.getCode(requestModelGet1, "https"), expectedCode); + expect( + codeGen.getCode( + CodegenLanguage.nodejsFetch, requestModelGet1, "https"), + expectedCode); }); test('GET 2', () { - const expectedCode = r"""import fetch from 'node-fetch'; + const expectedCode = r"""import fetch from 'node-fetch' -let url = 'https://api.foss42.com/country/data?code=US'; +const url = 'https://api.apidash.dev/country/data?code=US'; -let options = { +const options = { method: 'GET' }; -let status; fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); """; - expect(fetchCodeGen.getCode(requestModelGet2, "https"), expectedCode); + expect( + codeGen.getCode( + CodegenLanguage.nodejsFetch, requestModelGet2, "https"), + expectedCode); }); test('GET 3', () { - const expectedCode = r"""import fetch from 'node-fetch'; + const expectedCode = r"""import fetch from 'node-fetch' -let url = 'https://api.foss42.com/country/data?code=IND'; +const url = 'https://api.apidash.dev/country/data?code=IND'; -let options = { +const options = { method: 'GET' }; -let status; fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); """; - expect(fetchCodeGen.getCode(requestModelGet3, "https"), expectedCode); + expect( + codeGen.getCode( + CodegenLanguage.nodejsFetch, requestModelGet3, "https"), + expectedCode); }); test('GET 4', () { - const expectedCode = r"""import fetch from 'node-fetch'; + const expectedCode = r"""import fetch from 'node-fetch' -let url = 'https://api.foss42.com/humanize/social?num=8700000&digits=3&system=SS&add_space=true&trailing_zeros=true'; +const url = 'https://api.apidash.dev/humanize/social?num=8700000&digits=3&system=SS&add_space=true&trailing_zeros=true'; -let options = { +const options = { method: 'GET' }; -let status; fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); """; - expect(fetchCodeGen.getCode(requestModelGet4, "https"), expectedCode); + expect( + codeGen.getCode( + CodegenLanguage.nodejsFetch, requestModelGet4, "https"), + expectedCode); }); test('GET 5', () { - const expectedCode = r"""import fetch from 'node-fetch'; + const expectedCode = r"""import fetch from 'node-fetch' -let url = 'https://api.github.com/repos/foss42/apidash'; +const url = 'https://api.github.com/repos/foss42/apidash'; -let options = { +const options = { method: 'GET', headers: { "User-Agent": "Test Agent" } }; -let status; fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); """; - expect(fetchCodeGen.getCode(requestModelGet5, "https"), expectedCode); + expect( + codeGen.getCode( + CodegenLanguage.nodejsFetch, requestModelGet5, "https"), + expectedCode); }); test('GET 6', () { - const expectedCode = r"""import fetch from 'node-fetch'; + const expectedCode = r"""import fetch from 'node-fetch' -let url = 'https://api.github.com/repos/foss42/apidash?raw=true'; +const url = 'https://api.github.com/repos/foss42/apidash?raw=true'; -let options = { +const options = { method: 'GET', headers: { "User-Agent": "Test Agent" } }; -let status; fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); """; - expect(fetchCodeGen.getCode(requestModelGet6, "https"), expectedCode); + expect( + codeGen.getCode( + CodegenLanguage.nodejsFetch, requestModelGet6, "https"), + expectedCode); }); test('GET 7', () { - const expectedCode = r"""import fetch from 'node-fetch'; + const expectedCode = r"""import fetch from 'node-fetch' -let url = 'https://api.foss42.com'; +const url = 'https://api.apidash.dev'; -let options = { +const options = { method: 'GET' }; -let status; fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); """; - expect(fetchCodeGen.getCode(requestModelGet7, "https"), expectedCode); + expect( + codeGen.getCode( + CodegenLanguage.nodejsFetch, requestModelGet7, "https"), + expectedCode); }); test('GET 8', () { - const expectedCode = r"""import fetch from 'node-fetch'; + const expectedCode = r"""import fetch from 'node-fetch' -let url = 'https://api.github.com/repos/foss42/apidash?raw=true'; +const url = 'https://api.github.com/repos/foss42/apidash?raw=true'; -let options = { +const options = { method: 'GET', headers: { "User-Agent": "Test Agent" } }; -let status; fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); """; - expect(fetchCodeGen.getCode(requestModelGet8, "https"), expectedCode); + expect( + codeGen.getCode( + CodegenLanguage.nodejsFetch, requestModelGet8, "https"), + expectedCode); }); test('GET 9', () { - const expectedCode = r"""import fetch from 'node-fetch'; + const expectedCode = r"""import fetch from 'node-fetch' -let url = 'https://api.foss42.com/humanize/social?num=8700000&add_space=true'; +const url = 'https://api.apidash.dev/humanize/social?num=8700000&add_space=true'; -let options = { +const options = { method: 'GET' }; -let status; fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); """; - expect(fetchCodeGen.getCode(requestModelGet9, "https"), expectedCode); + expect( + codeGen.getCode( + CodegenLanguage.nodejsFetch, requestModelGet9, "https"), + expectedCode); }); test('GET 10', () { - const expectedCode = r"""import fetch from 'node-fetch'; + const expectedCode = r"""import fetch from 'node-fetch' -let url = 'https://api.foss42.com/humanize/social'; +const url = 'https://api.apidash.dev/humanize/social'; -let options = { +const options = { method: 'GET', headers: { "User-Agent": "Test Agent" } }; -let status; fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); """; expect( - fetchCodeGen.getCode( + codeGen.getCode( + CodegenLanguage.nodejsFetch, requestModelGet10, "https", ), @@ -294,344 +293,547 @@ fetch(url, options) }); test('GET 11', () { - const expectedCode = r"""import fetch from 'node-fetch'; + const expectedCode = r"""import fetch from 'node-fetch' -let url = 'https://api.foss42.com/humanize/social?num=8700000&digits=3'; +const url = 'https://api.apidash.dev/humanize/social?num=8700000&digits=3'; -let options = { +const options = { method: 'GET', headers: { "User-Agent": "Test Agent" } }; -let status; fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); """; - expect(fetchCodeGen.getCode(requestModelGet11, "https"), expectedCode); + expect( + codeGen.getCode( + CodegenLanguage.nodejsFetch, requestModelGet11, "https"), + expectedCode); }); test('GET 12', () { - const expectedCode = r"""import fetch from 'node-fetch'; + const expectedCode = r"""import fetch from 'node-fetch' -let url = 'https://api.foss42.com/humanize/social'; +const url = 'https://api.apidash.dev/humanize/social'; -let options = { +const options = { method: 'GET' }; -let status; fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); """; - expect(fetchCodeGen.getCode(requestModelGet12, "https"), expectedCode); + expect( + codeGen.getCode( + CodegenLanguage.nodejsFetch, requestModelGet12, "https"), + expectedCode); }); }); group('HEAD Request', () { test('HEAD 1', () { - const expectedCode = r"""import fetch from 'node-fetch'; + const expectedCode = r"""import fetch from 'node-fetch' -let url = 'https://api.foss42.com'; +const url = 'https://api.apidash.dev'; -let options = { +const options = { method: 'HEAD' }; -let status; fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); """; - expect(fetchCodeGen.getCode(requestModelHead1, "https"), expectedCode); + expect( + codeGen.getCode( + CodegenLanguage.nodejsFetch, requestModelHead1, "https"), + expectedCode); }); test('HEAD 2', () { - const expectedCode = r"""import fetch from 'node-fetch'; + const expectedCode = r"""import fetch from 'node-fetch' -let url = 'http://api.foss42.com'; +const url = 'http://api.apidash.dev'; -let options = { +const options = { method: 'HEAD' }; -let status; fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); """; - expect(fetchCodeGen.getCode(requestModelHead2, "http"), expectedCode); + expect( + codeGen.getCode( + CodegenLanguage.nodejsFetch, requestModelHead2, "http"), + expectedCode); }); }); group('POST Request', () { test('POST 1', () { - const expectedCode = r"""import fetch from 'node-fetch'; + const expectedCode = r"""import fetch from 'node-fetch' -let url = 'https://api.foss42.com/case/lower'; +const url = 'https://api.apidash.dev/case/lower'; -let options = { +const options = { method: 'POST', headers: { "Content-Type": "text/plain" }, - body: -"{\n\"text\": \"I LOVE Flutter\"\n}" + body: "{\n\"text\": \"I LOVE Flutter\"\n}" }; -let status; fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); """; - expect(fetchCodeGen.getCode(requestModelPost1, "https"), expectedCode); + expect( + codeGen.getCode( + CodegenLanguage.nodejsFetch, requestModelPost1, "https"), + expectedCode); }); test('POST 2', () { - const expectedCode = r"""import fetch from 'node-fetch'; + const expectedCode = r"""import fetch from 'node-fetch' -let url = 'https://api.foss42.com/case/lower'; +const url = 'https://api.apidash.dev/case/lower'; -let options = { +const options = { method: 'POST', headers: { "Content-Type": "application/json" }, - body: -"{\n\"text\": \"I LOVE Flutter\"\n}" + body: "{\n\"text\": \"I LOVE Flutter\",\n\"flag\": null,\n\"male\": true,\n\"female\": false,\n\"no\": 1.2,\n\"arr\": [\"null\", \"true\", \"false\", null]\n}" }; -let status; fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); """; - expect(fetchCodeGen.getCode(requestModelPost2, "https"), expectedCode); + expect( + codeGen.getCode( + CodegenLanguage.nodejsFetch, requestModelPost2, "https"), + expectedCode); }); test('POST 3', () { - const expectedCode = r"""import fetch from 'node-fetch'; + const expectedCode = r"""import fetch from 'node-fetch' -let url = 'https://api.foss42.com/case/lower'; +const url = 'https://api.apidash.dev/case/lower'; -let options = { +const options = { method: 'POST', headers: { "Content-Type": "application/json", "User-Agent": "Test Agent" }, - body: -"{\n\"text\": \"I LOVE Flutter\"\n}" + body: "{\n\"text\": \"I LOVE Flutter\"\n}" }; -let status; fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); """; - expect(fetchCodeGen.getCode(requestModelPost3, "https"), expectedCode); + expect( + codeGen.getCode( + CodegenLanguage.nodejsFetch, requestModelPost3, "https"), + expectedCode); + }); + test('POST 4', () { + const expectedCode = r"""import fetch from 'node-fetch' +import { FormData } from 'node-fetch' + +const payload = new FormData(); +payload.append("text", "API") +payload.append("sep", "|") +payload.append("times", "3") + +const url = 'https://api.apidash.dev/io/form'; + +const options = { + method: 'POST', + body: payload +}; + +fetch(url, options) + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); +"""; + expect( + codeGen.getCode( + CodegenLanguage.nodejsFetch, requestModelPost4, "https", + boundary: "test"), + expectedCode); + }); + + test('POST 5', () { + const expectedCode = r"""import fetch from 'node-fetch' +import { FormData } from 'node-fetch' + +const payload = new FormData(); +payload.append("text", "API") +payload.append("sep", "|") +payload.append("times", "3") + +const url = 'https://api.apidash.dev/io/form'; + +const options = { + method: 'POST', + headers: { + "User-Agent": "Test Agent" + }, + body: payload +}; + +fetch(url, options) + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); +"""; + expect( + codeGen.getCode( + CodegenLanguage.nodejsFetch, requestModelPost5, "https", + boundary: "test"), + expectedCode); + }); + test('POST 6', () { + const expectedCode = r"""import fetch from 'node-fetch' +import { fileFromSync, FormData } from 'node-fetch' + +const payload = new FormData(); +payload.append("token", "xyz") +payload.append("imfile", fileFromSync("/Documents/up/1.png")) + +const url = 'https://api.apidash.dev/io/img'; + +const options = { + method: 'POST', + body: payload +}; + +fetch(url, options) + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); +"""; + expect( + codeGen.getCode( + CodegenLanguage.nodejsFetch, requestModelPost6, "https", + boundary: "test"), + expectedCode); + }); + test('POST 7', () { + const expectedCode = r"""import fetch from 'node-fetch' +import { fileFromSync, FormData } from 'node-fetch' + +const payload = new FormData(); +payload.append("token", "xyz") +payload.append("imfile", fileFromSync("/Documents/up/1.png")) + +const url = 'https://api.apidash.dev/io/img'; + +const options = { + method: 'POST', + body: payload +}; + +fetch(url, options) + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); +"""; + expect( + codeGen.getCode( + CodegenLanguage.nodejsFetch, requestModelPost7, "https", + boundary: "test"), + expectedCode); + }); + test('POST 8', () { + const expectedCode = r"""import fetch from 'node-fetch' +import { FormData } from 'node-fetch' + +const payload = new FormData(); +payload.append("text", "API") +payload.append("sep", "|") +payload.append("times", "3") + +const url = 'https://api.apidash.dev/io/form?size=2&len=3'; + +const options = { + method: 'POST', + body: payload +}; + +fetch(url, options) + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); +"""; + expect( + codeGen.getCode( + CodegenLanguage.nodejsFetch, requestModelPost8, "https", + boundary: "test"), + expectedCode); + }); + test('POST 9', () { + const expectedCode = r"""import fetch from 'node-fetch' +import { fileFromSync, FormData } from 'node-fetch' + +const payload = new FormData(); +payload.append("token", "xyz") +payload.append("imfile", fileFromSync("/Documents/up/1.png")) + +const url = 'https://api.apidash.dev/io/img?size=2&len=3'; + +const options = { + method: 'POST', + headers: { + "User-Agent": "Test Agent", + "Keep-Alive": "true" + }, + body: payload +}; + +fetch(url, options) + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); +"""; + expect( + codeGen.getCode( + CodegenLanguage.nodejsFetch, requestModelPost9, "https", + boundary: "test"), + expectedCode); }); }); group('PUT Request', () { test('PUT 1', () { - const expectedCode = r"""import fetch from 'node-fetch'; + const expectedCode = r"""import fetch from 'node-fetch' -let url = 'https://reqres.in/api/users/2'; +const url = 'https://reqres.in/api/users/2'; -let options = { +const options = { method: 'PUT', headers: { "Content-Type": "application/json" }, - body: -"{\n\"name\": \"morpheus\",\n\"job\": \"zion resident\"\n}" + body: "{\n\"name\": \"morpheus\",\n\"job\": \"zion resident\"\n}" }; -let status; fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); """; - expect(fetchCodeGen.getCode(requestModelPut1, "https"), expectedCode); + expect( + codeGen.getCode( + CodegenLanguage.nodejsFetch, requestModelPut1, "https"), + expectedCode); }); }); group('PATCH Request', () { test('PATCH 1', () { - const expectedCode = r"""import fetch from 'node-fetch'; + const expectedCode = r"""import fetch from 'node-fetch' -let url = 'https://reqres.in/api/users/2'; +const url = 'https://reqres.in/api/users/2'; -let options = { +const options = { method: 'PATCH', headers: { "Content-Type": "application/json" }, - body: -"{\n\"name\": \"marfeus\",\n\"job\": \"accountant\"\n}" + body: "{\n\"name\": \"marfeus\",\n\"job\": \"accountant\"\n}" }; -let status; fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); """; - expect(fetchCodeGen.getCode(requestModelPatch1, "https"), expectedCode); + expect( + codeGen.getCode( + CodegenLanguage.nodejsFetch, requestModelPatch1, "https"), + expectedCode); }); }); group('DELETE Request', () { test('DELETE 1', () { - const expectedCode = r"""import fetch from 'node-fetch'; + const expectedCode = r"""import fetch from 'node-fetch' -let url = 'https://reqres.in/api/users/2'; +const url = 'https://reqres.in/api/users/2'; -let options = { +const options = { method: 'DELETE' }; -let status; fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); """; - expect(fetchCodeGen.getCode(requestModelDelete1, "https"), expectedCode); + expect( + codeGen.getCode( + CodegenLanguage.nodejsFetch, requestModelDelete1, "https"), + expectedCode); }); test('DELETE 2', () { - const expectedCode = r"""import fetch from 'node-fetch'; + const expectedCode = r"""import fetch from 'node-fetch' -let url = 'https://reqres.in/api/users/2'; +const url = 'https://reqres.in/api/users/2'; -let options = { +const options = { method: 'DELETE', headers: { "Content-Type": "application/json" }, - body: -"{\n\"name\": \"marfeus\",\n\"job\": \"accountant\"\n}" + body: "{\n\"name\": \"marfeus\",\n\"job\": \"accountant\"\n}" }; -let status; fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); """; - expect(fetchCodeGen.getCode(requestModelDelete2, "https"), expectedCode); + expect( + codeGen.getCode( + CodegenLanguage.nodejsFetch, requestModelDelete2, "https"), + expectedCode); }); }); } diff --git a/test/codegen/python_http_client_codegen_test.dart b/test/codegen/python_http_client_codegen_test.dart index c617305c..c1d68702 100644 --- a/test/codegen/python_http_client_codegen_test.dart +++ b/test/codegen/python_http_client_codegen_test.dart @@ -1,15 +1,16 @@ -import 'package:apidash/codegen/python/http_client.dart'; -import '../request_models.dart'; +import 'package:apidash/codegen/codegen.dart'; +import 'package:apidash/consts.dart'; import 'package:test/test.dart'; +import '../request_models.dart'; void main() { - final pythonHttpClientCodeGen = PythonHttpClientCodeGen(); + final codeGen = Codegen(); group('GET Request', () { test('GET 1', () { const expectedCode = r"""import http.client -conn = http.client.HTTPSConnection("api.foss42.com") +conn = http.client.HTTPSConnection("api.apidash.dev") conn.request("GET", "") res = conn.getresponse() @@ -17,7 +18,9 @@ data = res.read() print(data.decode("utf-8")) """; - expect(pythonHttpClientCodeGen.getCode(requestModelGet1, "https"), + expect( + codeGen.getCode( + CodegenLanguage.pythonHttpClient, requestModelGet1, "https"), expectedCode); }); @@ -26,11 +29,11 @@ print(data.decode("utf-8")) from urllib.parse import urlencode queryParams = { - "code": "US" - } + "code": "US" +} queryParamsStr = '?' + urlencode(queryParams) -conn = http.client.HTTPSConnection("api.foss42.com") +conn = http.client.HTTPSConnection("api.apidash.dev") conn.request("GET", "/country/data" + queryParamsStr) res = conn.getresponse() @@ -38,7 +41,9 @@ data = res.read() print(data.decode("utf-8")) """; - expect(pythonHttpClientCodeGen.getCode(requestModelGet2, "https"), + expect( + codeGen.getCode( + CodegenLanguage.pythonHttpClient, requestModelGet2, "https"), expectedCode); }); @@ -47,11 +52,11 @@ print(data.decode("utf-8")) from urllib.parse import urlencode queryParams = { - "code": "IND" - } + "code": "IND" +} queryParamsStr = '?' + urlencode(queryParams) -conn = http.client.HTTPSConnection("api.foss42.com") +conn = http.client.HTTPSConnection("api.apidash.dev") conn.request("GET", "/country/data" + queryParamsStr) res = conn.getresponse() @@ -59,7 +64,9 @@ data = res.read() print(data.decode("utf-8")) """; - expect(pythonHttpClientCodeGen.getCode(requestModelGet3, "https"), + expect( + codeGen.getCode( + CodegenLanguage.pythonHttpClient, requestModelGet3, "https"), expectedCode); }); @@ -68,15 +75,15 @@ print(data.decode("utf-8")) from urllib.parse import urlencode queryParams = { - "num": "8700000", - "digits": "3", - "system": "SS", - "add_space": "true", - "trailing_zeros": "true" - } + "num": "8700000", + "digits": "3", + "system": "SS", + "add_space": "true", + "trailing_zeros": "true" +} queryParamsStr = '?' + urlencode(queryParams) -conn = http.client.HTTPSConnection("api.foss42.com") +conn = http.client.HTTPSConnection("api.apidash.dev") conn.request("GET", "/humanize/social" + queryParamsStr) res = conn.getresponse() @@ -84,7 +91,9 @@ data = res.read() print(data.decode("utf-8")) """; - expect(pythonHttpClientCodeGen.getCode(requestModelGet4, "https"), + expect( + codeGen.getCode( + CodegenLanguage.pythonHttpClient, requestModelGet4, "https"), expectedCode); }); @@ -92,8 +101,8 @@ print(data.decode("utf-8")) const expectedCode = r"""import http.client headers = { - "User-Agent": "Test Agent" - } + "User-Agent": "Test Agent" +} conn = http.client.HTTPSConnection("api.github.com") conn.request("GET", "/repos/foss42/apidash", @@ -104,7 +113,9 @@ data = res.read() print(data.decode("utf-8")) """; - expect(pythonHttpClientCodeGen.getCode(requestModelGet5, "https"), + expect( + codeGen.getCode( + CodegenLanguage.pythonHttpClient, requestModelGet5, "https"), expectedCode); }); @@ -113,13 +124,13 @@ print(data.decode("utf-8")) from urllib.parse import urlencode queryParams = { - "raw": "true" - } + "raw": "true" +} queryParamsStr = '?' + urlencode(queryParams) headers = { - "User-Agent": "Test Agent" - } + "User-Agent": "Test Agent" +} conn = http.client.HTTPSConnection("api.github.com") conn.request("GET", "/repos/foss42/apidash" + queryParamsStr, @@ -130,14 +141,16 @@ data = res.read() print(data.decode("utf-8")) """; - expect(pythonHttpClientCodeGen.getCode(requestModelGet6, "https"), + expect( + codeGen.getCode( + CodegenLanguage.pythonHttpClient, requestModelGet6, "https"), expectedCode); }); test('GET 7', () { const expectedCode = r"""import http.client -conn = http.client.HTTPSConnection("api.foss42.com") +conn = http.client.HTTPSConnection("api.apidash.dev") conn.request("GET", "") res = conn.getresponse() @@ -145,7 +158,9 @@ data = res.read() print(data.decode("utf-8")) """; - expect(pythonHttpClientCodeGen.getCode(requestModelGet7, "https"), + expect( + codeGen.getCode( + CodegenLanguage.pythonHttpClient, requestModelGet7, "https"), expectedCode); }); @@ -154,13 +169,13 @@ print(data.decode("utf-8")) from urllib.parse import urlencode queryParams = { - "raw": "true" - } + "raw": "true" +} queryParamsStr = '?' + urlencode(queryParams) headers = { - "User-Agent": "Test Agent" - } + "User-Agent": "Test Agent" +} conn = http.client.HTTPSConnection("api.github.com") conn.request("GET", "/repos/foss42/apidash" + queryParamsStr, @@ -171,7 +186,9 @@ data = res.read() print(data.decode("utf-8")) """; - expect(pythonHttpClientCodeGen.getCode(requestModelGet8, "https"), + expect( + codeGen.getCode( + CodegenLanguage.pythonHttpClient, requestModelGet8, "https"), expectedCode); }); @@ -180,12 +197,12 @@ print(data.decode("utf-8")) from urllib.parse import urlencode queryParams = { - "num": "8700000", - "add_space": "true" - } + "num": "8700000", + "add_space": "true" +} queryParamsStr = '?' + urlencode(queryParams) -conn = http.client.HTTPSConnection("api.foss42.com") +conn = http.client.HTTPSConnection("api.apidash.dev") conn.request("GET", "/humanize/social" + queryParamsStr) res = conn.getresponse() @@ -193,7 +210,9 @@ data = res.read() print(data.decode("utf-8")) """; - expect(pythonHttpClientCodeGen.getCode(requestModelGet9, "https"), + expect( + codeGen.getCode( + CodegenLanguage.pythonHttpClient, requestModelGet9, "https"), expectedCode); }); @@ -201,10 +220,10 @@ print(data.decode("utf-8")) const expectedCode = r"""import http.client headers = { - "User-Agent": "Test Agent" - } + "User-Agent": "Test Agent" +} -conn = http.client.HTTPSConnection("api.foss42.com") +conn = http.client.HTTPSConnection("api.apidash.dev") conn.request("GET", "/humanize/social", headers= headers) @@ -214,7 +233,8 @@ data = res.read() print(data.decode("utf-8")) """; expect( - pythonHttpClientCodeGen.getCode( + codeGen.getCode( + CodegenLanguage.pythonHttpClient, requestModelGet10, "https", ), @@ -226,16 +246,16 @@ print(data.decode("utf-8")) from urllib.parse import urlencode queryParams = { - "num": "8700000", - "digits": "3" - } + "num": "8700000", + "digits": "3" +} queryParamsStr = '?' + urlencode(queryParams) headers = { - "User-Agent": "Test Agent" - } + "User-Agent": "Test Agent" +} -conn = http.client.HTTPSConnection("api.foss42.com") +conn = http.client.HTTPSConnection("api.apidash.dev") conn.request("GET", "/humanize/social" + queryParamsStr, headers= headers) @@ -244,14 +264,16 @@ data = res.read() print(data.decode("utf-8")) """; - expect(pythonHttpClientCodeGen.getCode(requestModelGet11, "https"), + expect( + codeGen.getCode( + CodegenLanguage.pythonHttpClient, requestModelGet11, "https"), expectedCode); }); test('GET 12', () { const expectedCode = r"""import http.client -conn = http.client.HTTPSConnection("api.foss42.com") +conn = http.client.HTTPSConnection("api.apidash.dev") conn.request("GET", "/humanize/social") res = conn.getresponse() @@ -259,7 +281,9 @@ data = res.read() print(data.decode("utf-8")) """; - expect(pythonHttpClientCodeGen.getCode(requestModelGet12, "https"), + expect( + codeGen.getCode( + CodegenLanguage.pythonHttpClient, requestModelGet12, "https"), expectedCode); }); }); @@ -268,7 +292,7 @@ print(data.decode("utf-8")) test('HEAD 1', () { const expectedCode = r"""import http.client -conn = http.client.HTTPSConnection("api.foss42.com") +conn = http.client.HTTPSConnection("api.apidash.dev") conn.request("HEAD", "") res = conn.getresponse() @@ -276,14 +300,16 @@ data = res.read() print(data.decode("utf-8")) """; - expect(pythonHttpClientCodeGen.getCode(requestModelHead1, "https"), + expect( + codeGen.getCode( + CodegenLanguage.pythonHttpClient, requestModelHead1, "https"), expectedCode); }); test('HEAD 2', () { const expectedCode = r"""import http.client -conn = http.client.HTTPConnection("api.foss42.com") +conn = http.client.HTTPConnection("api.apidash.dev") conn.request("HEAD", "") res = conn.getresponse() @@ -291,7 +317,9 @@ data = res.read() print(data.decode("utf-8")) """; - expect(pythonHttpClientCodeGen.getCode(requestModelHead2, "http"), + expect( + codeGen.getCode( + CodegenLanguage.pythonHttpClient, requestModelHead2, "http"), expectedCode); }); }); @@ -305,10 +333,10 @@ body = r'''{ }''' headers = { - "content-type": "text/plain" - } + "content-type": "text/plain" +} -conn = http.client.HTTPSConnection("api.foss42.com") +conn = http.client.HTTPSConnection("api.apidash.dev") conn.request("POST", "/case/lower", body= body, headers= headers) @@ -318,7 +346,9 @@ data = res.read() print(data.decode("utf-8")) """; - expect(pythonHttpClientCodeGen.getCode(requestModelPost1, "https"), + expect( + codeGen.getCode( + CodegenLanguage.pythonHttpClient, requestModelPost1, "https"), expectedCode); }); @@ -326,14 +356,19 @@ print(data.decode("utf-8")) const expectedCode = r"""import http.client body = r'''{ -"text": "I LOVE Flutter" +"text": "I LOVE Flutter", +"flag": null, +"male": true, +"female": false, +"no": 1.2, +"arr": ["null", "true", "false", null] }''' headers = { - "content-type": "application/json" - } + "content-type": "application/json" +} -conn = http.client.HTTPSConnection("api.foss42.com") +conn = http.client.HTTPSConnection("api.apidash.dev") conn.request("POST", "/case/lower", body= body, headers= headers) @@ -343,7 +378,9 @@ data = res.read() print(data.decode("utf-8")) """; - expect(pythonHttpClientCodeGen.getCode(requestModelPost2, "https"), + expect( + codeGen.getCode( + CodegenLanguage.pythonHttpClient, requestModelPost2, "https"), expectedCode); }); @@ -355,11 +392,11 @@ body = r'''{ }''' headers = { - "User-Agent": "Test Agent", - "content-type": "application/json" - } + "User-Agent": "Test Agent", + "content-type": "application/json" +} -conn = http.client.HTTPSConnection("api.foss42.com") +conn = http.client.HTTPSConnection("api.apidash.dev") conn.request("POST", "/case/lower", body= body, headers= headers) @@ -369,7 +406,320 @@ data = res.read() print(data.decode("utf-8")) """; - expect(pythonHttpClientCodeGen.getCode(requestModelPost3, "https"), + expect( + codeGen.getCode( + CodegenLanguage.pythonHttpClient, requestModelPost3, "https"), + expectedCode); + }); + + test('POST 4', () { + const expectedCode = r"""import http.client +import mimetypes +from codecs import encode + +headers = { + "content-type": "multipart/form-data; boundary=b9826c20-773c-1f0c-814d-a1b3d90cd6b3" +} + +def build_data_list(fields): + dataList = [] + for field in fields: + name = field.get('name', '') + value = field.get('value', '') + type_ = field.get('type', 'text') + dataList.append(encode('--b9826c20-773c-1f0c-814d-a1b3d90cd6b3')) + if type_ == 'text': + dataList.append(encode(f'Content-Disposition: form-data; name="{name}"')) + dataList.append(encode('Content-Type: text/plain')) + dataList.append(encode('')) + dataList.append(encode(value)) + elif type_ == 'file': + dataList.append(encode(f'Content-Disposition: form-data; name="{name}"; filename="{value}"')) + dataList.append(encode(f'Content-Type: {mimetypes.guess_type(value)[0] or "application/octet-stream"}')) + dataList.append(encode('')) + dataList.append(open(value, 'rb').read()) + dataList.append(encode(f'--b9826c20-773c-1f0c-814d-a1b3d90cd6b3--')) + dataList.append(encode('')) + return dataList + +dataList = build_data_list([{"name":"text","value":"API","type":"text"},{"name":"sep","value":"|","type":"text"},{"name":"times","value":"3","type":"text"}]) +body = b'\r\n'.join(dataList) +conn = http.client.HTTPSConnection("api.apidash.dev") +conn.request("POST", "/io/form", + body= body, + headers= headers) + +res = conn.getresponse() +data = res.read() + +print(data.decode("utf-8")) +"""; + expect( + codeGen.getCode( + CodegenLanguage.pythonHttpClient, requestModelPost4, "https", + boundary: "b9826c20-773c-1f0c-814d-a1b3d90cd6b3"), + expectedCode); + }); + + test('POST 5', () { + const expectedCode = r"""import http.client +import mimetypes +from codecs import encode + +headers = { + "User-Agent": "Test Agent", + "content-type": "multipart/form-data; boundary=929dc910-7714-1f0c-814d-a1b3d90cd6b3" +} + +def build_data_list(fields): + dataList = [] + for field in fields: + name = field.get('name', '') + value = field.get('value', '') + type_ = field.get('type', 'text') + dataList.append(encode('--929dc910-7714-1f0c-814d-a1b3d90cd6b3')) + if type_ == 'text': + dataList.append(encode(f'Content-Disposition: form-data; name="{name}"')) + dataList.append(encode('Content-Type: text/plain')) + dataList.append(encode('')) + dataList.append(encode(value)) + elif type_ == 'file': + dataList.append(encode(f'Content-Disposition: form-data; name="{name}"; filename="{value}"')) + dataList.append(encode(f'Content-Type: {mimetypes.guess_type(value)[0] or "application/octet-stream"}')) + dataList.append(encode('')) + dataList.append(open(value, 'rb').read()) + dataList.append(encode(f'--929dc910-7714-1f0c-814d-a1b3d90cd6b3--')) + dataList.append(encode('')) + return dataList + +dataList = build_data_list([{"name":"text","value":"API","type":"text"},{"name":"sep","value":"|","type":"text"},{"name":"times","value":"3","type":"text"}]) +body = b'\r\n'.join(dataList) +conn = http.client.HTTPSConnection("api.apidash.dev") +conn.request("POST", "/io/form", + body= body, + headers= headers) + +res = conn.getresponse() +data = res.read() + +print(data.decode("utf-8")) +"""; + expect( + codeGen.getCode( + CodegenLanguage.pythonHttpClient, requestModelPost5, "https", + boundary: "929dc910-7714-1f0c-814d-a1b3d90cd6b3"), + expectedCode); + }); + + test('POST 6', () { + const expectedCode = r"""import http.client +import mimetypes +from codecs import encode + +headers = { + "content-type": "multipart/form-data; boundary=9b1374c0-76e0-1f0c-814d-a1b3d90cd6b3" +} + +def build_data_list(fields): + dataList = [] + for field in fields: + name = field.get('name', '') + value = field.get('value', '') + type_ = field.get('type', 'text') + dataList.append(encode('--9b1374c0-76e0-1f0c-814d-a1b3d90cd6b3')) + if type_ == 'text': + dataList.append(encode(f'Content-Disposition: form-data; name="{name}"')) + dataList.append(encode('Content-Type: text/plain')) + dataList.append(encode('')) + dataList.append(encode(value)) + elif type_ == 'file': + dataList.append(encode(f'Content-Disposition: form-data; name="{name}"; filename="{value}"')) + dataList.append(encode(f'Content-Type: {mimetypes.guess_type(value)[0] or "application/octet-stream"}')) + dataList.append(encode('')) + dataList.append(open(value, 'rb').read()) + dataList.append(encode(f'--9b1374c0-76e0-1f0c-814d-a1b3d90cd6b3--')) + dataList.append(encode('')) + return dataList + +dataList = build_data_list([{"name":"token","value":"xyz","type":"text"},{"name":"imfile","value":"/Documents/up/1.png","type":"file"}]) +body = b'\r\n'.join(dataList) +conn = http.client.HTTPSConnection("api.apidash.dev") +conn.request("POST", "/io/img", + body= body, + headers= headers) + +res = conn.getresponse() +data = res.read() + +print(data.decode("utf-8")) +"""; + expect( + codeGen.getCode( + CodegenLanguage.pythonHttpClient, requestModelPost6, "https", + boundary: "9b1374c0-76e0-1f0c-814d-a1b3d90cd6b3"), + expectedCode); + }); + + test('POST 7', () { + const expectedCode = r"""import http.client +import mimetypes +from codecs import encode + +headers = { + "content-type": "multipart/form-data; boundary=defdf240-76b4-1f0c-814d-a1b3d90cd6b3" +} + +def build_data_list(fields): + dataList = [] + for field in fields: + name = field.get('name', '') + value = field.get('value', '') + type_ = field.get('type', 'text') + dataList.append(encode('--defdf240-76b4-1f0c-814d-a1b3d90cd6b3')) + if type_ == 'text': + dataList.append(encode(f'Content-Disposition: form-data; name="{name}"')) + dataList.append(encode('Content-Type: text/plain')) + dataList.append(encode('')) + dataList.append(encode(value)) + elif type_ == 'file': + dataList.append(encode(f'Content-Disposition: form-data; name="{name}"; filename="{value}"')) + dataList.append(encode(f'Content-Type: {mimetypes.guess_type(value)[0] or "application/octet-stream"}')) + dataList.append(encode('')) + dataList.append(open(value, 'rb').read()) + dataList.append(encode(f'--defdf240-76b4-1f0c-814d-a1b3d90cd6b3--')) + dataList.append(encode('')) + return dataList + +dataList = build_data_list([{"name":"token","value":"xyz","type":"text"},{"name":"imfile","value":"/Documents/up/1.png","type":"file"}]) +body = b'\r\n'.join(dataList) +conn = http.client.HTTPSConnection("api.apidash.dev") +conn.request("POST", "/io/img", + body= body, + headers= headers) + +res = conn.getresponse() +data = res.read() + +print(data.decode("utf-8")) +"""; + expect( + codeGen.getCode( + CodegenLanguage.pythonHttpClient, requestModelPost7, "https", + boundary: "defdf240-76b4-1f0c-814d-a1b3d90cd6b3"), + expectedCode); + }); + + test('POST 8', () { + const expectedCode = r"""import http.client +import mimetypes +from codecs import encode +from urllib.parse import urlencode + +queryParams = { + "size": "2", + "len": "3" +} +queryParamsStr = '?' + urlencode(queryParams) + +headers = { + "content-type": "multipart/form-data; boundary=a990b150-7683-1f0c-814d-a1b3d90cd6b3" +} + +def build_data_list(fields): + dataList = [] + for field in fields: + name = field.get('name', '') + value = field.get('value', '') + type_ = field.get('type', 'text') + dataList.append(encode('--a990b150-7683-1f0c-814d-a1b3d90cd6b3')) + if type_ == 'text': + dataList.append(encode(f'Content-Disposition: form-data; name="{name}"')) + dataList.append(encode('Content-Type: text/plain')) + dataList.append(encode('')) + dataList.append(encode(value)) + elif type_ == 'file': + dataList.append(encode(f'Content-Disposition: form-data; name="{name}"; filename="{value}"')) + dataList.append(encode(f'Content-Type: {mimetypes.guess_type(value)[0] or "application/octet-stream"}')) + dataList.append(encode('')) + dataList.append(open(value, 'rb').read()) + dataList.append(encode(f'--a990b150-7683-1f0c-814d-a1b3d90cd6b3--')) + dataList.append(encode('')) + return dataList + +dataList = build_data_list([{"name":"text","value":"API","type":"text"},{"name":"sep","value":"|","type":"text"},{"name":"times","value":"3","type":"text"}]) +body = b'\r\n'.join(dataList) +conn = http.client.HTTPSConnection("api.apidash.dev") +conn.request("POST", "/io/form" + queryParamsStr, + body= body, + headers= headers) + +res = conn.getresponse() +data = res.read() + +print(data.decode("utf-8")) +"""; + expect( + codeGen.getCode( + CodegenLanguage.pythonHttpClient, requestModelPost8, "https", + boundary: "a990b150-7683-1f0c-814d-a1b3d90cd6b3"), + expectedCode); + }); + + test('POST 9', () { + const expectedCode = r"""import http.client +import mimetypes +from codecs import encode +from urllib.parse import urlencode + +queryParams = { + "size": "2", + "len": "3" +} +queryParamsStr = '?' + urlencode(queryParams) + +headers = { + "User-Agent": "Test Agent", + "Keep-Alive": "true", + "content-type": "multipart/form-data; boundary=79088e00-75ec-1f0c-814d-a1b3d90cd6b3" +} + +def build_data_list(fields): + dataList = [] + for field in fields: + name = field.get('name', '') + value = field.get('value', '') + type_ = field.get('type', 'text') + dataList.append(encode('--79088e00-75ec-1f0c-814d-a1b3d90cd6b3')) + if type_ == 'text': + dataList.append(encode(f'Content-Disposition: form-data; name="{name}"')) + dataList.append(encode('Content-Type: text/plain')) + dataList.append(encode('')) + dataList.append(encode(value)) + elif type_ == 'file': + dataList.append(encode(f'Content-Disposition: form-data; name="{name}"; filename="{value}"')) + dataList.append(encode(f'Content-Type: {mimetypes.guess_type(value)[0] or "application/octet-stream"}')) + dataList.append(encode('')) + dataList.append(open(value, 'rb').read()) + dataList.append(encode(f'--79088e00-75ec-1f0c-814d-a1b3d90cd6b3--')) + dataList.append(encode('')) + return dataList + +dataList = build_data_list([{"name":"token","value":"xyz","type":"text"},{"name":"imfile","value":"/Documents/up/1.png","type":"file"}]) +body = b'\r\n'.join(dataList) +conn = http.client.HTTPSConnection("api.apidash.dev") +conn.request("POST", "/io/img" + queryParamsStr, + body= body, + headers= headers) + +res = conn.getresponse() +data = res.read() + +print(data.decode("utf-8")) +"""; + expect( + codeGen.getCode( + CodegenLanguage.pythonHttpClient, requestModelPost9, "https", + boundary: "79088e00-75ec-1f0c-814d-a1b3d90cd6b3"), expectedCode); }); }); @@ -384,8 +734,8 @@ body = r'''{ }''' headers = { - "content-type": "application/json" - } + "content-type": "application/json" +} conn = http.client.HTTPSConnection("reqres.in") conn.request("PUT", "/api/users/2", @@ -397,7 +747,9 @@ data = res.read() print(data.decode("utf-8")) """; - expect(pythonHttpClientCodeGen.getCode(requestModelPut1, "https"), + expect( + codeGen.getCode( + CodegenLanguage.pythonHttpClient, requestModelPut1, "https"), expectedCode); }); }); @@ -412,8 +764,8 @@ body = r'''{ }''' headers = { - "content-type": "application/json" - } + "content-type": "application/json" +} conn = http.client.HTTPSConnection("reqres.in") conn.request("PATCH", "/api/users/2", @@ -425,7 +777,9 @@ data = res.read() print(data.decode("utf-8")) """; - expect(pythonHttpClientCodeGen.getCode(requestModelPatch1, "https"), + expect( + codeGen.getCode( + CodegenLanguage.pythonHttpClient, requestModelPatch1, "https"), expectedCode); }); }); @@ -442,7 +796,9 @@ data = res.read() print(data.decode("utf-8")) """; - expect(pythonHttpClientCodeGen.getCode(requestModelDelete1, "https"), + expect( + codeGen.getCode( + CodegenLanguage.pythonHttpClient, requestModelDelete1, "https"), expectedCode); }); @@ -455,8 +811,8 @@ body = r'''{ }''' headers = { - "content-type": "application/json" - } + "content-type": "application/json" +} conn = http.client.HTTPSConnection("reqres.in") conn.request("DELETE", "/api/users/2", @@ -468,7 +824,9 @@ data = res.read() print(data.decode("utf-8")) """; - expect(pythonHttpClientCodeGen.getCode(requestModelDelete2, "https"), + expect( + codeGen.getCode( + CodegenLanguage.pythonHttpClient, requestModelDelete2, "https"), expectedCode); }); }); diff --git a/test/codegen/python_requests_codegen_test.dart b/test/codegen/python_requests_codegen_test.dart index 1387accf..057c09c6 100644 --- a/test/codegen/python_requests_codegen_test.dart +++ b/test/codegen/python_requests_codegen_test.dart @@ -1,80 +1,89 @@ -import 'package:apidash/codegen/python/requests.dart'; -import '../request_models.dart'; +import 'package:apidash/codegen/codegen.dart'; +import 'package:apidash/consts.dart'; import 'package:test/test.dart'; +import '../request_models.dart'; void main() { - final pythonRequestsCodeGen = PythonRequestsCodeGen(); + final codeGen = Codegen(); group('GET Request', () { test('GET 1', () { const expectedCode = r"""import requests -url = 'https://api.foss42.com' +url = 'https://api.apidash.dev' response = requests.get(url) print('Status Code:', response.status_code) print('Response Body:', response.text) """; - expect(pythonRequestsCodeGen.getCode(requestModelGet1, "https"), + expect( + codeGen.getCode( + CodegenLanguage.pythonRequests, requestModelGet1, "https"), expectedCode); }); test('GET 2', () { const expectedCode = r"""import requests -url = 'https://api.foss42.com/country/data' +url = 'https://api.apidash.dev/country/data' params = { - "code": "US" - } + "code": "US" +} response = requests.get(url, params=params) print('Status Code:', response.status_code) print('Response Body:', response.text) """; - expect(pythonRequestsCodeGen.getCode(requestModelGet2, "https"), + expect( + codeGen.getCode( + CodegenLanguage.pythonRequests, requestModelGet2, "https"), expectedCode); }); test('GET 3', () { const expectedCode = r"""import requests -url = 'https://api.foss42.com/country/data' +url = 'https://api.apidash.dev/country/data' params = { - "code": "IND" - } + "code": "IND" +} response = requests.get(url, params=params) print('Status Code:', response.status_code) print('Response Body:', response.text) """; - expect(pythonRequestsCodeGen.getCode(requestModelGet3, "https"), + expect( + codeGen.getCode( + CodegenLanguage.pythonRequests, requestModelGet3, "https"), expectedCode); }); test('GET 4', () { const expectedCode = r"""import requests -url = 'https://api.foss42.com/humanize/social' +url = 'https://api.apidash.dev/humanize/social' params = { - "num": "8700000", - "digits": "3", - "system": "SS", - "add_space": "true", - "trailing_zeros": "true" - } + "num": "8700000", + "digits": "3", + "system": "SS", + "add_space": "true", + "trailing_zeros": "true" +} response = requests.get(url, params=params) print('Status Code:', response.status_code) print('Response Body:', response.text) """; - expect(pythonRequestsCodeGen.getCode(requestModelGet4, "https"), + expect( + codeGen.getCode( + CodegenLanguage.pythonRequests, requestModelGet4, "https"), expectedCode); }); @@ -84,15 +93,17 @@ print('Response Body:', response.text) url = 'https://api.github.com/repos/foss42/apidash' headers = { - "User-Agent": "Test Agent" - } + "User-Agent": "Test Agent" +} response = requests.get(url, headers=headers) print('Status Code:', response.status_code) print('Response Body:', response.text) """; - expect(pythonRequestsCodeGen.getCode(requestModelGet5, "https"), + expect( + codeGen.getCode( + CodegenLanguage.pythonRequests, requestModelGet5, "https"), expectedCode); }); @@ -102,33 +113,37 @@ print('Response Body:', response.text) url = 'https://api.github.com/repos/foss42/apidash' params = { - "raw": "true" - } + "raw": "true" +} headers = { - "User-Agent": "Test Agent" - } + "User-Agent": "Test Agent" +} response = requests.get(url, params=params, headers=headers) print('Status Code:', response.status_code) print('Response Body:', response.text) """; - expect(pythonRequestsCodeGen.getCode(requestModelGet6, "https"), + expect( + codeGen.getCode( + CodegenLanguage.pythonRequests, requestModelGet6, "https"), expectedCode); }); test('GET 7', () { const expectedCode = r"""import requests -url = 'https://api.foss42.com' +url = 'https://api.apidash.dev' response = requests.get(url) print('Status Code:', response.status_code) print('Response Body:', response.text) """; - expect(pythonRequestsCodeGen.getCode(requestModelGet7, "https"), + expect( + codeGen.getCode( + CodegenLanguage.pythonRequests, requestModelGet7, "https"), expectedCode); }); @@ -138,49 +153,53 @@ print('Response Body:', response.text) url = 'https://api.github.com/repos/foss42/apidash' params = { - "raw": "true" - } + "raw": "true" +} headers = { - "User-Agent": "Test Agent" - } + "User-Agent": "Test Agent" +} response = requests.get(url, params=params, headers=headers) print('Status Code:', response.status_code) print('Response Body:', response.text) """; - expect(pythonRequestsCodeGen.getCode(requestModelGet8, "https"), + expect( + codeGen.getCode( + CodegenLanguage.pythonRequests, requestModelGet8, "https"), expectedCode); }); test('GET 9', () { const expectedCode = r"""import requests -url = 'https://api.foss42.com/humanize/social' +url = 'https://api.apidash.dev/humanize/social' params = { - "num": "8700000", - "add_space": "true" - } + "num": "8700000", + "add_space": "true" +} response = requests.get(url, params=params) print('Status Code:', response.status_code) print('Response Body:', response.text) """; - expect(pythonRequestsCodeGen.getCode(requestModelGet9, "https"), + expect( + codeGen.getCode( + CodegenLanguage.pythonRequests, requestModelGet9, "https"), expectedCode); }); test('GET 10', () { const expectedCode = r"""import requests -url = 'https://api.foss42.com/humanize/social' +url = 'https://api.apidash.dev/humanize/social' headers = { - "User-Agent": "Test Agent" - } + "User-Agent": "Test Agent" +} response = requests.get(url, headers=headers) @@ -188,7 +207,8 @@ print('Status Code:', response.status_code) print('Response Body:', response.text) """; expect( - pythonRequestsCodeGen.getCode( + codeGen.getCode( + CodegenLanguage.pythonRequests, requestModelGet10, "https", ), @@ -198,37 +218,41 @@ print('Response Body:', response.text) test('GET 11', () { const expectedCode = r"""import requests -url = 'https://api.foss42.com/humanize/social' +url = 'https://api.apidash.dev/humanize/social' params = { - "num": "8700000", - "digits": "3" - } + "num": "8700000", + "digits": "3" +} headers = { - "User-Agent": "Test Agent" - } + "User-Agent": "Test Agent" +} response = requests.get(url, params=params, headers=headers) print('Status Code:', response.status_code) print('Response Body:', response.text) """; - expect(pythonRequestsCodeGen.getCode(requestModelGet11, "https"), + expect( + codeGen.getCode( + CodegenLanguage.pythonRequests, requestModelGet11, "https"), expectedCode); }); test('GET 12', () { const expectedCode = r"""import requests -url = 'https://api.foss42.com/humanize/social' +url = 'https://api.apidash.dev/humanize/social' response = requests.get(url) print('Status Code:', response.status_code) print('Response Body:', response.text) """; - expect(pythonRequestsCodeGen.getCode(requestModelGet12, "https"), + expect( + codeGen.getCode( + CodegenLanguage.pythonRequests, requestModelGet12, "https"), expectedCode); }); }); @@ -237,28 +261,32 @@ print('Response Body:', response.text) test('HEAD 1', () { const expectedCode = r"""import requests -url = 'https://api.foss42.com' +url = 'https://api.apidash.dev' response = requests.head(url) print('Status Code:', response.status_code) print('Response Body:', response.text) """; - expect(pythonRequestsCodeGen.getCode(requestModelHead1, "https"), + expect( + codeGen.getCode( + CodegenLanguage.pythonRequests, requestModelHead1, "https"), expectedCode); }); test('HEAD 2', () { const expectedCode = r"""import requests -url = 'http://api.foss42.com' +url = 'http://api.apidash.dev' response = requests.head(url) print('Status Code:', response.status_code) print('Response Body:', response.text) """; - expect(pythonRequestsCodeGen.getCode(requestModelHead2, "http"), + expect( + codeGen.getCode( + CodegenLanguage.pythonRequests, requestModelHead2, "http"), expectedCode); }); }); @@ -267,32 +295,39 @@ print('Response Body:', response.text) test('POST 1', () { const expectedCode = r"""import requests -url = 'https://api.foss42.com/case/lower' +url = 'https://api.apidash.dev/case/lower' payload = r'''{ "text": "I LOVE Flutter" }''' headers = { - "content-type": "text/plain" - } + "content-type": "text/plain" +} response = requests.post(url, data=payload, headers=headers) print('Status Code:', response.status_code) print('Response Body:', response.text) """; - expect(pythonRequestsCodeGen.getCode(requestModelPost1, "https"), + expect( + codeGen.getCode( + CodegenLanguage.pythonRequests, requestModelPost1, "https"), expectedCode); }); test('POST 2', () { const expectedCode = r"""import requests -url = 'https://api.foss42.com/case/lower' +url = 'https://api.apidash.dev/case/lower' payload = { -"text": "I LOVE Flutter" +"text": "I LOVE Flutter", +"flag": None, +"male": True, +"female": False, +"no": 1.2, +"arr": ["null", "true", "false", None] } response = requests.post(url, json=payload) @@ -300,29 +335,205 @@ response = requests.post(url, json=payload) print('Status Code:', response.status_code) print('Response Body:', response.text) """; - expect(pythonRequestsCodeGen.getCode(requestModelPost2, "https"), + expect( + codeGen.getCode( + CodegenLanguage.pythonRequests, requestModelPost2, "https"), expectedCode); }); test('POST 3', () { const expectedCode = r"""import requests -url = 'https://api.foss42.com/case/lower' +url = 'https://api.apidash.dev/case/lower' payload = { "text": "I LOVE Flutter" } headers = { - "User-Agent": "Test Agent" - } + "User-Agent": "Test Agent" +} response = requests.post(url, json=payload, headers=headers) print('Status Code:', response.status_code) print('Response Body:', response.text) """; - expect(pythonRequestsCodeGen.getCode(requestModelPost3, "https"), + expect( + codeGen.getCode( + CodegenLanguage.pythonRequests, requestModelPost3, "https"), + expectedCode); + }); + + test('POST 4', () { + const expectedCode = r"""import requests +from requests_toolbelt.multipart.encoder import MultipartEncoder + +url = 'https://api.apidash.dev/io/form' + +payload = MultipartEncoder({ + "text": "API", + "sep": "|", + "times": "3", +}) + +headers = { + "content-type": payload.content_type +} + +response = requests.post(url, data=payload, headers=headers) + +print('Status Code:', response.status_code) +print('Response Body:', response.text) +"""; + expect( + codeGen.getCode( + CodegenLanguage.pythonRequests, requestModelPost4, "https"), + expectedCode); + }); + + test('POST 5', () { + const expectedCode = r"""import requests +from requests_toolbelt.multipart.encoder import MultipartEncoder + +url = 'https://api.apidash.dev/io/form' + +payload = MultipartEncoder({ + "text": "API", + "sep": "|", + "times": "3", +}) + +headers = { + "User-Agent": "Test Agent", + "content-type": payload.content_type +} + +response = requests.post(url, data=payload, headers=headers) + +print('Status Code:', response.status_code) +print('Response Body:', response.text) +"""; + expect( + codeGen.getCode( + CodegenLanguage.pythonRequests, requestModelPost5, "https"), + expectedCode); + }); + + test('POST 6', () { + const expectedCode = r"""import requests +from requests_toolbelt.multipart.encoder import MultipartEncoder + +url = 'https://api.apidash.dev/io/img' + +payload = MultipartEncoder({ + "token": "xyz", + "imfile": ("1.png", open("/Documents/up/1.png", "rb")), +}) + +headers = { + "content-type": payload.content_type +} + +response = requests.post(url, data=payload, headers=headers) + +print('Status Code:', response.status_code) +print('Response Body:', response.text) +"""; + expect( + codeGen.getCode( + CodegenLanguage.pythonRequests, requestModelPost6, "https"), + expectedCode); + }); + + test('POST 7', () { + const expectedCode = r"""import requests +from requests_toolbelt.multipart.encoder import MultipartEncoder + +url = 'https://api.apidash.dev/io/img' + +payload = MultipartEncoder({ + "token": "xyz", + "imfile": ("1.png", open("/Documents/up/1.png", "rb")), +}) + +headers = { + "content-type": payload.content_type +} + +response = requests.post(url, data=payload, headers=headers) + +print('Status Code:', response.status_code) +print('Response Body:', response.text) +"""; + expect( + codeGen.getCode( + CodegenLanguage.pythonRequests, requestModelPost7, "https"), + expectedCode); + }); + + test('POST 8', () { + const expectedCode = r"""import requests +from requests_toolbelt.multipart.encoder import MultipartEncoder + +url = 'https://api.apidash.dev/io/form' + +params = { + "size": "2", + "len": "3" +} + +payload = MultipartEncoder({ + "text": "API", + "sep": "|", + "times": "3", +}) + +headers = { + "content-type": payload.content_type +} + +response = requests.post(url, params=params, data=payload, headers=headers) + +print('Status Code:', response.status_code) +print('Response Body:', response.text) +"""; + expect( + codeGen.getCode( + CodegenLanguage.pythonRequests, requestModelPost8, "https"), + expectedCode); + }); + + test('POST 9', () { + const expectedCode = r"""import requests +from requests_toolbelt.multipart.encoder import MultipartEncoder + +url = 'https://api.apidash.dev/io/img' + +params = { + "size": "2", + "len": "3" +} + +payload = MultipartEncoder({ + "token": "xyz", + "imfile": ("1.png", open("/Documents/up/1.png", "rb")), +}) + +headers = { + "User-Agent": "Test Agent", + "Keep-Alive": "true", + "content-type": payload.content_type +} + +response = requests.post(url, params=params, data=payload, headers=headers) + +print('Status Code:', response.status_code) +print('Response Body:', response.text) +"""; + expect( + codeGen.getCode( + CodegenLanguage.pythonRequests, requestModelPost9, "https"), expectedCode); }); }); @@ -343,7 +554,9 @@ response = requests.put(url, json=payload) print('Status Code:', response.status_code) print('Response Body:', response.text) """; - expect(pythonRequestsCodeGen.getCode(requestModelPut1, "https"), + expect( + codeGen.getCode( + CodegenLanguage.pythonRequests, requestModelPut1, "https"), expectedCode); }); }); @@ -364,7 +577,9 @@ response = requests.patch(url, json=payload) print('Status Code:', response.status_code) print('Response Body:', response.text) """; - expect(pythonRequestsCodeGen.getCode(requestModelPatch1, "https"), + expect( + codeGen.getCode( + CodegenLanguage.pythonRequests, requestModelPatch1, "https"), expectedCode); }); }); @@ -380,7 +595,9 @@ response = requests.delete(url) print('Status Code:', response.status_code) print('Response Body:', response.text) """; - expect(pythonRequestsCodeGen.getCode(requestModelDelete1, "https"), + expect( + codeGen.getCode( + CodegenLanguage.pythonRequests, requestModelDelete1, "https"), expectedCode); }); @@ -399,7 +616,9 @@ response = requests.delete(url, json=payload) print('Status Code:', response.status_code) print('Response Body:', response.text) """; - expect(pythonRequestsCodeGen.getCode(requestModelDelete2, "https"), + expect( + codeGen.getCode( + CodegenLanguage.pythonRequests, requestModelDelete2, "https"), expectedCode); }); }); diff --git a/test/codegen/rust_actix_codegen_test.dart b/test/codegen/rust_actix_codegen_test.dart new file mode 100644 index 00000000..8e215295 --- /dev/null +++ b/test/codegen/rust_actix_codegen_test.dart @@ -0,0 +1,1094 @@ +import 'package:apidash/codegen/codegen.dart'; +import 'package:apidash/consts.dart'; +import 'package:test/test.dart'; +import '../request_models.dart'; + +void main() { + final codeGen = Codegen(); + + group('GET Request', () { + test('GET 1', () { + const expectedCode = r"""#[actix_rt::main] +async fn main() -> Result<(), Box> { + let url = "https://api.apidash.dev"; + let client = awc::Client::default(); + + let mut response = client + .get(url) + .send() + .await + .unwrap(); + + let body_bytes = response.body().await.unwrap(); + let body = std::str::from_utf8(&body_bytes).unwrap(); + println!("Response Status: {}", response.status()); + println!("Response: {:?}", body); + + Ok(()) +} +"""; + expect( + codeGen.getCode(CodegenLanguage.rustActix, requestModelGet1, "https"), + expectedCode); + }); + + test('GET 2', () { + const expectedCode = r"""#[actix_rt::main] +async fn main() -> Result<(), Box> { + let url = "https://api.apidash.dev/country/data"; + let client = awc::Client::default(); + + let mut response = client + .get(url) + .query(&[("code", "US")]) + .unwrap() + .send() + .await + .unwrap(); + + let body_bytes = response.body().await.unwrap(); + let body = std::str::from_utf8(&body_bytes).unwrap(); + println!("Response Status: {}", response.status()); + println!("Response: {:?}", body); + + Ok(()) +} +"""; + expect( + codeGen.getCode(CodegenLanguage.rustActix, requestModelGet2, "https"), + expectedCode); + }); + + test('GET 3', () { + const expectedCode = r"""#[actix_rt::main] +async fn main() -> Result<(), Box> { + let url = "https://api.apidash.dev/country/data"; + let client = awc::Client::default(); + + let mut response = client + .get(url) + .query(&[("code", "IND")]) + .unwrap() + .send() + .await + .unwrap(); + + let body_bytes = response.body().await.unwrap(); + let body = std::str::from_utf8(&body_bytes).unwrap(); + println!("Response Status: {}", response.status()); + println!("Response: {:?}", body); + + Ok(()) +} +"""; + expect( + codeGen.getCode(CodegenLanguage.rustActix, requestModelGet3, "https"), + expectedCode); + }); + + test('GET 4', () { + const expectedCode = r"""#[actix_rt::main] +async fn main() -> Result<(), Box> { + let url = "https://api.apidash.dev/humanize/social"; + let client = awc::Client::default(); + + let mut response = client + .get(url) + .query(&[("num", "8700000"), ("digits", "3"), ("system", "SS"), ("add_space", "true"), ("trailing_zeros", "true")]) + .unwrap() + .send() + .await + .unwrap(); + + let body_bytes = response.body().await.unwrap(); + let body = std::str::from_utf8(&body_bytes).unwrap(); + println!("Response Status: {}", response.status()); + println!("Response: {:?}", body); + + Ok(()) +} +"""; + expect( + codeGen.getCode(CodegenLanguage.rustActix, requestModelGet4, "https"), + expectedCode); + }); + + test('GET 5', () { + const expectedCode = r"""#[actix_rt::main] +async fn main() -> Result<(), Box> { + let url = "https://api.github.com/repos/foss42/apidash"; + let client = awc::Client::default(); + + let mut response = client + .get(url) + .insert_header(("User-Agent", "Test Agent")) + .send() + .await + .unwrap(); + + let body_bytes = response.body().await.unwrap(); + let body = std::str::from_utf8(&body_bytes).unwrap(); + println!("Response Status: {}", response.status()); + println!("Response: {:?}", body); + + Ok(()) +} +"""; + expect( + codeGen.getCode(CodegenLanguage.rustActix, requestModelGet5, "https"), + expectedCode); + }); + + test('GET 6', () { + const expectedCode = r"""#[actix_rt::main] +async fn main() -> Result<(), Box> { + let url = "https://api.github.com/repos/foss42/apidash"; + let client = awc::Client::default(); + + let mut response = client + .get(url) + .query(&[("raw", "true")]) + .unwrap() + .insert_header(("User-Agent", "Test Agent")) + .send() + .await + .unwrap(); + + let body_bytes = response.body().await.unwrap(); + let body = std::str::from_utf8(&body_bytes).unwrap(); + println!("Response Status: {}", response.status()); + println!("Response: {:?}", body); + + Ok(()) +} +"""; + expect( + codeGen.getCode(CodegenLanguage.rustActix, requestModelGet6, "https"), + expectedCode); + }); + + test('GET 7', () { + const expectedCode = r"""#[actix_rt::main] +async fn main() -> Result<(), Box> { + let url = "https://api.apidash.dev"; + let client = awc::Client::default(); + + let mut response = client + .get(url) + .send() + .await + .unwrap(); + + let body_bytes = response.body().await.unwrap(); + let body = std::str::from_utf8(&body_bytes).unwrap(); + println!("Response Status: {}", response.status()); + println!("Response: {:?}", body); + + Ok(()) +} +"""; + expect( + codeGen.getCode(CodegenLanguage.rustActix, requestModelGet7, "https"), + expectedCode); + }); + + test('GET 8', () { + const expectedCode = r"""#[actix_rt::main] +async fn main() -> Result<(), Box> { + let url = "https://api.github.com/repos/foss42/apidash"; + let client = awc::Client::default(); + + let mut response = client + .get(url) + .query(&[("raw", "true")]) + .unwrap() + .insert_header(("User-Agent", "Test Agent")) + .send() + .await + .unwrap(); + + let body_bytes = response.body().await.unwrap(); + let body = std::str::from_utf8(&body_bytes).unwrap(); + println!("Response Status: {}", response.status()); + println!("Response: {:?}", body); + + Ok(()) +} +"""; + expect( + codeGen.getCode(CodegenLanguage.rustActix, requestModelGet8, "https"), + expectedCode); + }); + + test('GET 9', () { + const expectedCode = r"""#[actix_rt::main] +async fn main() -> Result<(), Box> { + let url = "https://api.apidash.dev/humanize/social"; + let client = awc::Client::default(); + + let mut response = client + .get(url) + .query(&[("num", "8700000"), ("add_space", "true")]) + .unwrap() + .send() + .await + .unwrap(); + + let body_bytes = response.body().await.unwrap(); + let body = std::str::from_utf8(&body_bytes).unwrap(); + println!("Response Status: {}", response.status()); + println!("Response: {:?}", body); + + Ok(()) +} +"""; + expect( + codeGen.getCode(CodegenLanguage.rustActix, requestModelGet9, "https"), + expectedCode); + }); + + test('GET 10', () { + const expectedCode = r"""#[actix_rt::main] +async fn main() -> Result<(), Box> { + let url = "https://api.apidash.dev/humanize/social"; + let client = awc::Client::default(); + + let mut response = client + .get(url) + .insert_header(("User-Agent", "Test Agent")) + .send() + .await + .unwrap(); + + let body_bytes = response.body().await.unwrap(); + let body = std::str::from_utf8(&body_bytes).unwrap(); + println!("Response Status: {}", response.status()); + println!("Response: {:?}", body); + + Ok(()) +} +"""; + expect( + codeGen.getCode( + CodegenLanguage.rustActix, + requestModelGet10, + "https", + ), + expectedCode); + }); + + test('GET 11', () { + const expectedCode = r"""#[actix_rt::main] +async fn main() -> Result<(), Box> { + let url = "https://api.apidash.dev/humanize/social"; + let client = awc::Client::default(); + + let mut response = client + .get(url) + .query(&[("num", "8700000"), ("digits", "3")]) + .unwrap() + .insert_header(("User-Agent", "Test Agent")) + .send() + .await + .unwrap(); + + let body_bytes = response.body().await.unwrap(); + let body = std::str::from_utf8(&body_bytes).unwrap(); + println!("Response Status: {}", response.status()); + println!("Response: {:?}", body); + + Ok(()) +} +"""; + expect( + codeGen.getCode( + CodegenLanguage.rustActix, requestModelGet11, "https"), + expectedCode); + }); + + test('GET 12', () { + const expectedCode = r"""#[actix_rt::main] +async fn main() -> Result<(), Box> { + let url = "https://api.apidash.dev/humanize/social"; + let client = awc::Client::default(); + + let mut response = client + .get(url) + .send() + .await + .unwrap(); + + let body_bytes = response.body().await.unwrap(); + let body = std::str::from_utf8(&body_bytes).unwrap(); + println!("Response Status: {}", response.status()); + println!("Response: {:?}", body); + + Ok(()) +} +"""; + expect( + codeGen.getCode( + CodegenLanguage.rustActix, requestModelGet12, "https"), + expectedCode); + }); + }); + + group('HEAD Request', () { + test('HEAD 1', () { + const expectedCode = r"""#[actix_rt::main] +async fn main() -> Result<(), Box> { + let url = "https://api.apidash.dev"; + let client = awc::Client::default(); + + let mut response = client + .head(url) + .send() + .await + .unwrap(); + + let body_bytes = response.body().await.unwrap(); + let body = std::str::from_utf8(&body_bytes).unwrap(); + println!("Response Status: {}", response.status()); + println!("Response: {:?}", body); + + Ok(()) +} +"""; + expect( + codeGen.getCode( + CodegenLanguage.rustActix, requestModelHead1, "https"), + expectedCode); + }); + + test('HEAD 2', () { + const expectedCode = r"""#[actix_rt::main] +async fn main() -> Result<(), Box> { + let url = "http://api.apidash.dev"; + let client = awc::Client::default(); + + let mut response = client + .head(url) + .send() + .await + .unwrap(); + + let body_bytes = response.body().await.unwrap(); + let body = std::str::from_utf8(&body_bytes).unwrap(); + println!("Response Status: {}", response.status()); + println!("Response: {:?}", body); + + Ok(()) +} +"""; + expect( + codeGen.getCode(CodegenLanguage.rustActix, requestModelHead2, "http"), + expectedCode); + }); + }); + + group('POST Request', () { + test('POST 1', () { + const expectedCode = r"""#[actix_rt::main] +async fn main() -> Result<(), Box> { + let url = "https://api.apidash.dev/case/lower"; + let client = awc::Client::default(); + + let payload = r#"{ +"text": "I LOVE Flutter" +}"#; + + let mut response = client + .post(url) + .insert_header(("content-type", "text/plain")) + .send_body(payload) + .await + .unwrap(); + + let body_bytes = response.body().await.unwrap(); + let body = std::str::from_utf8(&body_bytes).unwrap(); + println!("Response Status: {}", response.status()); + println!("Response: {:?}", body); + + Ok(()) +} +"""; + expect( + codeGen.getCode( + CodegenLanguage.rustActix, requestModelPost1, "https"), + expectedCode); + }); + + test('POST 2', () { + const expectedCode = r"""#[actix_rt::main] +async fn main() -> Result<(), Box> { + let url = "https://api.apidash.dev/case/lower"; + let client = awc::Client::default(); + + let payload = serde_json::json!({ +"text": "I LOVE Flutter", +"flag": null, +"male": true, +"female": false, +"no": 1.2, +"arr": ["null", "true", "false", null] +}); + + let mut response = client + .post(url) + .send_json(&payload) + .await + .unwrap(); + + let body_bytes = response.body().await.unwrap(); + let body = std::str::from_utf8(&body_bytes).unwrap(); + println!("Response Status: {}", response.status()); + println!("Response: {:?}", body); + + Ok(()) +} +"""; + expect( + codeGen.getCode( + CodegenLanguage.rustActix, requestModelPost2, "https"), + expectedCode); + }); + + test('POST 3', () { + const expectedCode = r"""#[actix_rt::main] +async fn main() -> Result<(), Box> { + let url = "https://api.apidash.dev/case/lower"; + let client = awc::Client::default(); + + let payload = serde_json::json!({ +"text": "I LOVE Flutter" +}); + + let mut response = client + .post(url) + .insert_header(("User-Agent", "Test Agent")) + .send_json(&payload) + .await + .unwrap(); + + let body_bytes = response.body().await.unwrap(); + let body = std::str::from_utf8(&body_bytes).unwrap(); + println!("Response Status: {}", response.status()); + println!("Response: {:?}", body); + + Ok(()) +} +"""; + expect( + codeGen.getCode( + CodegenLanguage.rustActix, requestModelPost3, "https"), + expectedCode); + }); + + test('POST 4', () { + const expectedCode = r"""use std::io::Read; +#[actix_rt::main] +async fn main() -> Result<(), Box> { + let url = "https://api.apidash.dev/io/form"; + let client = awc::Client::default(); + + struct FormDataItem { + name: String, + value: String, + field_type: String, + } + + let form_data_items: Vec = vec![ + FormDataItem { + name: "text".to_string(), + value: "API".to_string(), + field_type: "text".to_string(), + }, + FormDataItem { + name: "sep".to_string(), + value: "|".to_string(), + field_type: "text".to_string(), + }, + FormDataItem { + name: "times".to_string(), + value: "3".to_string(), + field_type: "text".to_string(), + }, + ]; + + fn build_data_list(fields: Vec) -> Vec { + let mut data_list = Vec::new(); + + for field in fields { + data_list.extend_from_slice(b"--test\r\n"); + + if field.field_type == "text" { + data_list.extend_from_slice(format!("Content-Disposition: form-data; name=\"{}\"\r\n", field.name).as_bytes()); + data_list.extend_from_slice(b"Content-Type: text/plain\r\n\r\n"); + data_list.extend_from_slice(field.value.as_bytes()); + data_list.extend_from_slice(b"\r\n"); + } else if field.field_type == "file" { + data_list.extend_from_slice(format!("Content-Disposition: form-data; name=\"{}\"; filename=\"{}\"\r\n", field.name, field.value).as_bytes()); + + let mime_type = mime_guess::from_path(&field.value).first_or(mime_guess::mime::APPLICATION_OCTET_STREAM); + data_list.extend_from_slice(format!("Content-Type: {}\r\n\r\n", mime_type).as_bytes()); + + let mut file = std::fs::File::open(&field.value).unwrap(); + let mut file_contents = Vec::new(); + file.read_to_end(&mut file_contents).unwrap(); + data_list.extend_from_slice(&file_contents); + data_list.extend_from_slice(b"\r\n"); + } + } + + data_list.extend_from_slice(b"--test--\r\n"); + data_list + } + + let payload = build_data_list(form_data_items); + let mut response = client + .post(url) + .insert_header(("content-type", "multipart/form-data; boundary=test")) + .send_body(payload) + .await + .unwrap(); + + let body_bytes = response.body().await.unwrap(); + let body = std::str::from_utf8(&body_bytes).unwrap(); + println!("Response Status: {}", response.status()); + println!("Response: {:?}", body); + + Ok(()) +} +"""; + expect( + codeGen.getCode( + CodegenLanguage.rustActix, + requestModelPost4, + "https", + boundary: "test", + ), + expectedCode); + }); + test('POST 5', () { + const expectedCode = r"""use std::io::Read; +#[actix_rt::main] +async fn main() -> Result<(), Box> { + let url = "https://api.apidash.dev/io/form"; + let client = awc::Client::default(); + + struct FormDataItem { + name: String, + value: String, + field_type: String, + } + + let form_data_items: Vec = vec![ + FormDataItem { + name: "text".to_string(), + value: "API".to_string(), + field_type: "text".to_string(), + }, + FormDataItem { + name: "sep".to_string(), + value: "|".to_string(), + field_type: "text".to_string(), + }, + FormDataItem { + name: "times".to_string(), + value: "3".to_string(), + field_type: "text".to_string(), + }, + ]; + + fn build_data_list(fields: Vec) -> Vec { + let mut data_list = Vec::new(); + + for field in fields { + data_list.extend_from_slice(b"--test\r\n"); + + if field.field_type == "text" { + data_list.extend_from_slice(format!("Content-Disposition: form-data; name=\"{}\"\r\n", field.name).as_bytes()); + data_list.extend_from_slice(b"Content-Type: text/plain\r\n\r\n"); + data_list.extend_from_slice(field.value.as_bytes()); + data_list.extend_from_slice(b"\r\n"); + } else if field.field_type == "file" { + data_list.extend_from_slice(format!("Content-Disposition: form-data; name=\"{}\"; filename=\"{}\"\r\n", field.name, field.value).as_bytes()); + + let mime_type = mime_guess::from_path(&field.value).first_or(mime_guess::mime::APPLICATION_OCTET_STREAM); + data_list.extend_from_slice(format!("Content-Type: {}\r\n\r\n", mime_type).as_bytes()); + + let mut file = std::fs::File::open(&field.value).unwrap(); + let mut file_contents = Vec::new(); + file.read_to_end(&mut file_contents).unwrap(); + data_list.extend_from_slice(&file_contents); + data_list.extend_from_slice(b"\r\n"); + } + } + + data_list.extend_from_slice(b"--test--\r\n"); + data_list + } + + let payload = build_data_list(form_data_items); + let mut response = client + .post(url) + .insert_header(("User-Agent", "Test Agent")) + .insert_header(("content-type", "multipart/form-data; boundary=test")) + .send_body(payload) + .await + .unwrap(); + + let body_bytes = response.body().await.unwrap(); + let body = std::str::from_utf8(&body_bytes).unwrap(); + println!("Response Status: {}", response.status()); + println!("Response: {:?}", body); + + Ok(()) +} +"""; + expect( + codeGen.getCode(CodegenLanguage.rustActix, requestModelPost5, "https", + boundary: "test"), + expectedCode); + }); + test('POST 6', () { + const expectedCode = r"""use std::io::Read; +#[actix_rt::main] +async fn main() -> Result<(), Box> { + let url = "https://api.apidash.dev/io/img"; + let client = awc::Client::default(); + + struct FormDataItem { + name: String, + value: String, + field_type: String, + } + + let form_data_items: Vec = vec![ + FormDataItem { + name: "token".to_string(), + value: "xyz".to_string(), + field_type: "text".to_string(), + }, + FormDataItem { + name: "imfile".to_string(), + value: "/Documents/up/1.png".to_string(), + field_type: "file".to_string(), + }, + ]; + + fn build_data_list(fields: Vec) -> Vec { + let mut data_list = Vec::new(); + + for field in fields { + data_list.extend_from_slice(b"--test\r\n"); + + if field.field_type == "text" { + data_list.extend_from_slice(format!("Content-Disposition: form-data; name=\"{}\"\r\n", field.name).as_bytes()); + data_list.extend_from_slice(b"Content-Type: text/plain\r\n\r\n"); + data_list.extend_from_slice(field.value.as_bytes()); + data_list.extend_from_slice(b"\r\n"); + } else if field.field_type == "file" { + data_list.extend_from_slice(format!("Content-Disposition: form-data; name=\"{}\"; filename=\"{}\"\r\n", field.name, field.value).as_bytes()); + + let mime_type = mime_guess::from_path(&field.value).first_or(mime_guess::mime::APPLICATION_OCTET_STREAM); + data_list.extend_from_slice(format!("Content-Type: {}\r\n\r\n", mime_type).as_bytes()); + + let mut file = std::fs::File::open(&field.value).unwrap(); + let mut file_contents = Vec::new(); + file.read_to_end(&mut file_contents).unwrap(); + data_list.extend_from_slice(&file_contents); + data_list.extend_from_slice(b"\r\n"); + } + } + + data_list.extend_from_slice(b"--test--\r\n"); + data_list + } + + let payload = build_data_list(form_data_items); + let mut response = client + .post(url) + .insert_header(("content-type", "multipart/form-data; boundary=test")) + .send_body(payload) + .await + .unwrap(); + + let body_bytes = response.body().await.unwrap(); + let body = std::str::from_utf8(&body_bytes).unwrap(); + println!("Response Status: {}", response.status()); + println!("Response: {:?}", body); + + Ok(()) +} +"""; + expect( + codeGen.getCode(CodegenLanguage.rustActix, requestModelPost6, "https", + boundary: "test"), + expectedCode); + }); + test('POST 7', () { + const expectedCode = r"""use std::io::Read; +#[actix_rt::main] +async fn main() -> Result<(), Box> { + let url = "https://api.apidash.dev/io/img"; + let client = awc::Client::default(); + + struct FormDataItem { + name: String, + value: String, + field_type: String, + } + + let form_data_items: Vec = vec![ + FormDataItem { + name: "token".to_string(), + value: "xyz".to_string(), + field_type: "text".to_string(), + }, + FormDataItem { + name: "imfile".to_string(), + value: "/Documents/up/1.png".to_string(), + field_type: "file".to_string(), + }, + ]; + + fn build_data_list(fields: Vec) -> Vec { + let mut data_list = Vec::new(); + + for field in fields { + data_list.extend_from_slice(b"--test\r\n"); + + if field.field_type == "text" { + data_list.extend_from_slice(format!("Content-Disposition: form-data; name=\"{}\"\r\n", field.name).as_bytes()); + data_list.extend_from_slice(b"Content-Type: text/plain\r\n\r\n"); + data_list.extend_from_slice(field.value.as_bytes()); + data_list.extend_from_slice(b"\r\n"); + } else if field.field_type == "file" { + data_list.extend_from_slice(format!("Content-Disposition: form-data; name=\"{}\"; filename=\"{}\"\r\n", field.name, field.value).as_bytes()); + + let mime_type = mime_guess::from_path(&field.value).first_or(mime_guess::mime::APPLICATION_OCTET_STREAM); + data_list.extend_from_slice(format!("Content-Type: {}\r\n\r\n", mime_type).as_bytes()); + + let mut file = std::fs::File::open(&field.value).unwrap(); + let mut file_contents = Vec::new(); + file.read_to_end(&mut file_contents).unwrap(); + data_list.extend_from_slice(&file_contents); + data_list.extend_from_slice(b"\r\n"); + } + } + + data_list.extend_from_slice(b"--test--\r\n"); + data_list + } + + let payload = build_data_list(form_data_items); + let mut response = client + .post(url) + .insert_header(("content-type", "multipart/form-data; boundary=test")) + .send_body(payload) + .await + .unwrap(); + + let body_bytes = response.body().await.unwrap(); + let body = std::str::from_utf8(&body_bytes).unwrap(); + println!("Response Status: {}", response.status()); + println!("Response: {:?}", body); + + Ok(()) +} +"""; + expect( + codeGen.getCode(CodegenLanguage.rustActix, requestModelPost7, "https", + boundary: "test"), + expectedCode); + }); + test('POST 8', () { + const expectedCode = r"""use std::io::Read; +#[actix_rt::main] +async fn main() -> Result<(), Box> { + let url = "https://api.apidash.dev/io/form"; + let client = awc::Client::default(); + + struct FormDataItem { + name: String, + value: String, + field_type: String, + } + + let form_data_items: Vec = vec![ + FormDataItem { + name: "text".to_string(), + value: "API".to_string(), + field_type: "text".to_string(), + }, + FormDataItem { + name: "sep".to_string(), + value: "|".to_string(), + field_type: "text".to_string(), + }, + FormDataItem { + name: "times".to_string(), + value: "3".to_string(), + field_type: "text".to_string(), + }, + ]; + + fn build_data_list(fields: Vec) -> Vec { + let mut data_list = Vec::new(); + + for field in fields { + data_list.extend_from_slice(b"--test\r\n"); + + if field.field_type == "text" { + data_list.extend_from_slice(format!("Content-Disposition: form-data; name=\"{}\"\r\n", field.name).as_bytes()); + data_list.extend_from_slice(b"Content-Type: text/plain\r\n\r\n"); + data_list.extend_from_slice(field.value.as_bytes()); + data_list.extend_from_slice(b"\r\n"); + } else if field.field_type == "file" { + data_list.extend_from_slice(format!("Content-Disposition: form-data; name=\"{}\"; filename=\"{}\"\r\n", field.name, field.value).as_bytes()); + + let mime_type = mime_guess::from_path(&field.value).first_or(mime_guess::mime::APPLICATION_OCTET_STREAM); + data_list.extend_from_slice(format!("Content-Type: {}\r\n\r\n", mime_type).as_bytes()); + + let mut file = std::fs::File::open(&field.value).unwrap(); + let mut file_contents = Vec::new(); + file.read_to_end(&mut file_contents).unwrap(); + data_list.extend_from_slice(&file_contents); + data_list.extend_from_slice(b"\r\n"); + } + } + + data_list.extend_from_slice(b"--test--\r\n"); + data_list + } + + let payload = build_data_list(form_data_items); + let mut response = client + .post(url) + .query(&[("size", "2"), ("len", "3")]) + .unwrap() + .insert_header(("content-type", "multipart/form-data; boundary=test")) + .send_body(payload) + .await + .unwrap(); + + let body_bytes = response.body().await.unwrap(); + let body = std::str::from_utf8(&body_bytes).unwrap(); + println!("Response Status: {}", response.status()); + println!("Response: {:?}", body); + + Ok(()) +} +"""; + expect( + codeGen.getCode(CodegenLanguage.rustActix, requestModelPost8, "https", + boundary: "test"), + expectedCode); + }); + test('POST 9', () { + const expectedCode = r"""use std::io::Read; +#[actix_rt::main] +async fn main() -> Result<(), Box> { + let url = "https://api.apidash.dev/io/img"; + let client = awc::Client::default(); + + struct FormDataItem { + name: String, + value: String, + field_type: String, + } + + let form_data_items: Vec = vec![ + FormDataItem { + name: "token".to_string(), + value: "xyz".to_string(), + field_type: "text".to_string(), + }, + FormDataItem { + name: "imfile".to_string(), + value: "/Documents/up/1.png".to_string(), + field_type: "file".to_string(), + }, + ]; + + fn build_data_list(fields: Vec) -> Vec { + let mut data_list = Vec::new(); + + for field in fields { + data_list.extend_from_slice(b"--test\r\n"); + + if field.field_type == "text" { + data_list.extend_from_slice(format!("Content-Disposition: form-data; name=\"{}\"\r\n", field.name).as_bytes()); + data_list.extend_from_slice(b"Content-Type: text/plain\r\n\r\n"); + data_list.extend_from_slice(field.value.as_bytes()); + data_list.extend_from_slice(b"\r\n"); + } else if field.field_type == "file" { + data_list.extend_from_slice(format!("Content-Disposition: form-data; name=\"{}\"; filename=\"{}\"\r\n", field.name, field.value).as_bytes()); + + let mime_type = mime_guess::from_path(&field.value).first_or(mime_guess::mime::APPLICATION_OCTET_STREAM); + data_list.extend_from_slice(format!("Content-Type: {}\r\n\r\n", mime_type).as_bytes()); + + let mut file = std::fs::File::open(&field.value).unwrap(); + let mut file_contents = Vec::new(); + file.read_to_end(&mut file_contents).unwrap(); + data_list.extend_from_slice(&file_contents); + data_list.extend_from_slice(b"\r\n"); + } + } + + data_list.extend_from_slice(b"--test--\r\n"); + data_list + } + + let payload = build_data_list(form_data_items); + let mut response = client + .post(url) + .query(&[("size", "2"), ("len", "3")]) + .unwrap() + .insert_header(("User-Agent", "Test Agent")) + .insert_header(("Keep-Alive", "true")) + .insert_header(("content-type", "multipart/form-data; boundary=test")) + .send_body(payload) + .await + .unwrap(); + + let body_bytes = response.body().await.unwrap(); + let body = std::str::from_utf8(&body_bytes).unwrap(); + println!("Response Status: {}", response.status()); + println!("Response: {:?}", body); + + Ok(()) +} +"""; + expect( + codeGen.getCode(CodegenLanguage.rustActix, requestModelPost9, "https", + boundary: "test"), + expectedCode); + }); + }); + + group('PUT Request', () { + test('PUT 1', () { + const expectedCode = r"""#[actix_rt::main] +async fn main() -> Result<(), Box> { + let url = "https://reqres.in/api/users/2"; + let client = awc::Client::default(); + + let payload = serde_json::json!({ +"name": "morpheus", +"job": "zion resident" +}); + + let mut response = client + .put(url) + .send_json(&payload) + .await + .unwrap(); + + let body_bytes = response.body().await.unwrap(); + let body = std::str::from_utf8(&body_bytes).unwrap(); + println!("Response Status: {}", response.status()); + println!("Response: {:?}", body); + + Ok(()) +} +"""; + expect( + codeGen.getCode(CodegenLanguage.rustActix, requestModelPut1, "https"), + expectedCode); + }); + }); + + group('PATCH Request', () { + test('PATCH 1', () { + const expectedCode = r"""#[actix_rt::main] +async fn main() -> Result<(), Box> { + let url = "https://reqres.in/api/users/2"; + let client = awc::Client::default(); + + let payload = serde_json::json!({ +"name": "marfeus", +"job": "accountant" +}); + + let mut response = client + .patch(url) + .send_json(&payload) + .await + .unwrap(); + + let body_bytes = response.body().await.unwrap(); + let body = std::str::from_utf8(&body_bytes).unwrap(); + println!("Response Status: {}", response.status()); + println!("Response: {:?}", body); + + Ok(()) +} +"""; + expect( + codeGen.getCode( + CodegenLanguage.rustActix, requestModelPatch1, "https"), + expectedCode); + }); + }); + + group('DELETE Request', () { + test('DELETE 1', () { + const expectedCode = r"""#[actix_rt::main] +async fn main() -> Result<(), Box> { + let url = "https://reqres.in/api/users/2"; + let client = awc::Client::default(); + + let mut response = client + .delete(url) + .send() + .await + .unwrap(); + + let body_bytes = response.body().await.unwrap(); + let body = std::str::from_utf8(&body_bytes).unwrap(); + println!("Response Status: {}", response.status()); + println!("Response: {:?}", body); + + Ok(()) +} +"""; + expect( + codeGen.getCode( + CodegenLanguage.rustActix, requestModelDelete1, "https"), + expectedCode); + }); + + test('DELETE 2', () { + const expectedCode = r"""#[actix_rt::main] +async fn main() -> Result<(), Box> { + let url = "https://reqres.in/api/users/2"; + let client = awc::Client::default(); + + let payload = serde_json::json!({ +"name": "marfeus", +"job": "accountant" +}); + + let mut response = client + .delete(url) + .send_json(&payload) + .await + .unwrap(); + + let body_bytes = response.body().await.unwrap(); + let body = std::str::from_utf8(&body_bytes).unwrap(); + println!("Response Status: {}", response.status()); + println!("Response: {:?}", body); + + Ok(()) +} +"""; + expect( + codeGen.getCode( + CodegenLanguage.rustActix, requestModelDelete2, "https"), + expectedCode); + }); + }); +} diff --git a/test/codegen/rust_reqwest_codegen_test.dart b/test/codegen/rust_reqwest_codegen_test.dart new file mode 100644 index 00000000..c262a64e --- /dev/null +++ b/test/codegen/rust_reqwest_codegen_test.dart @@ -0,0 +1,866 @@ +import 'package:apidash/codegen/codegen.dart'; +import 'package:apidash/consts.dart'; +import 'package:test/test.dart'; +import '../request_models.dart'; + +void main() { + final codeGen = Codegen(); + + group('GET Request', () { + test('GET 1', () { + const expectedCode = + r"""fn main() -> Result<(), Box> { + let client = reqwest::blocking::Client::new(); + let url = "https://api.apidash.dev"; + + let response = client + .get(url) + .send()?; + + println!("Status Code: {}", response.status()); + println!("Response Body: {}", response.text()?); + + Ok(()) +} +"""; + expect( + codeGen.getCode( + CodegenLanguage.rustReqwest, requestModelGet1, "https"), + expectedCode); + }); + + test('GET 2', () { + const expectedCode = + r"""fn main() -> Result<(), Box> { + let client = reqwest::blocking::Client::new(); + let url = "https://api.apidash.dev/country/data"; + + let response = client + .get(url) + .query(&[("code", "US")]) + .send()?; + + println!("Status Code: {}", response.status()); + println!("Response Body: {}", response.text()?); + + Ok(()) +} +"""; + expect( + codeGen.getCode( + CodegenLanguage.rustReqwest, requestModelGet2, "https"), + expectedCode); + }); + + test('GET 3', () { + const expectedCode = + r"""fn main() -> Result<(), Box> { + let client = reqwest::blocking::Client::new(); + let url = "https://api.apidash.dev/country/data"; + + let response = client + .get(url) + .query(&[("code", "IND")]) + .send()?; + + println!("Status Code: {}", response.status()); + println!("Response Body: {}", response.text()?); + + Ok(()) +} +"""; + expect( + codeGen.getCode( + CodegenLanguage.rustReqwest, requestModelGet3, "https"), + expectedCode); + }); + + test('GET 4', () { + const expectedCode = + r"""fn main() -> Result<(), Box> { + let client = reqwest::blocking::Client::new(); + let url = "https://api.apidash.dev/humanize/social"; + + let response = client + .get(url) + .query(&[("num", "8700000"), ("digits", "3"), ("system", "SS"), ("add_space", "true"), ("trailing_zeros", "true")]) + .send()?; + + println!("Status Code: {}", response.status()); + println!("Response Body: {}", response.text()?); + + Ok(()) +} +"""; + expect( + codeGen.getCode( + CodegenLanguage.rustReqwest, requestModelGet4, "https"), + expectedCode); + }); + + test('GET 5', () { + const expectedCode = + r"""fn main() -> Result<(), Box> { + let client = reqwest::blocking::Client::new(); + let url = "https://api.github.com/repos/foss42/apidash"; + + let response = client + .get(url) + .header("User-Agent", "Test Agent") + .send()?; + + println!("Status Code: {}", response.status()); + println!("Response Body: {}", response.text()?); + + Ok(()) +} +"""; + expect( + codeGen.getCode( + CodegenLanguage.rustReqwest, requestModelGet5, "https"), + expectedCode); + }); + + test('GET 6', () { + const expectedCode = + r"""fn main() -> Result<(), Box> { + let client = reqwest::blocking::Client::new(); + let url = "https://api.github.com/repos/foss42/apidash"; + + let response = client + .get(url) + .query(&[("raw", "true")]) + .header("User-Agent", "Test Agent") + .send()?; + + println!("Status Code: {}", response.status()); + println!("Response Body: {}", response.text()?); + + Ok(()) +} +"""; + expect( + codeGen.getCode( + CodegenLanguage.rustReqwest, requestModelGet6, "https"), + expectedCode); + }); + + test('GET 7', () { + const expectedCode = + r"""fn main() -> Result<(), Box> { + let client = reqwest::blocking::Client::new(); + let url = "https://api.apidash.dev"; + + let response = client + .get(url) + .send()?; + + println!("Status Code: {}", response.status()); + println!("Response Body: {}", response.text()?); + + Ok(()) +} +"""; + expect( + codeGen.getCode( + CodegenLanguage.rustReqwest, requestModelGet7, "https"), + expectedCode); + }); + + test('GET 8', () { + const expectedCode = + r"""fn main() -> Result<(), Box> { + let client = reqwest::blocking::Client::new(); + let url = "https://api.github.com/repos/foss42/apidash"; + + let response = client + .get(url) + .query(&[("raw", "true")]) + .header("User-Agent", "Test Agent") + .send()?; + + println!("Status Code: {}", response.status()); + println!("Response Body: {}", response.text()?); + + Ok(()) +} +"""; + expect( + codeGen.getCode( + CodegenLanguage.rustReqwest, requestModelGet8, "https"), + expectedCode); + }); + + test('GET 9', () { + const expectedCode = + r"""fn main() -> Result<(), Box> { + let client = reqwest::blocking::Client::new(); + let url = "https://api.apidash.dev/humanize/social"; + + let response = client + .get(url) + .query(&[("num", "8700000"), ("add_space", "true")]) + .send()?; + + println!("Status Code: {}", response.status()); + println!("Response Body: {}", response.text()?); + + Ok(()) +} +"""; + expect( + codeGen.getCode( + CodegenLanguage.rustReqwest, requestModelGet9, "https"), + expectedCode); + }); + + test('GET 10', () { + const expectedCode = + r"""fn main() -> Result<(), Box> { + let client = reqwest::blocking::Client::new(); + let url = "https://api.apidash.dev/humanize/social"; + + let response = client + .get(url) + .header("User-Agent", "Test Agent") + .send()?; + + println!("Status Code: {}", response.status()); + println!("Response Body: {}", response.text()?); + + Ok(()) +} +"""; + expect( + codeGen.getCode( + CodegenLanguage.rustReqwest, + requestModelGet10, + "https", + ), + expectedCode); + }); + + test('GET 11', () { + const expectedCode = + r"""fn main() -> Result<(), Box> { + let client = reqwest::blocking::Client::new(); + let url = "https://api.apidash.dev/humanize/social"; + + let response = client + .get(url) + .query(&[("num", "8700000"), ("digits", "3")]) + .header("User-Agent", "Test Agent") + .send()?; + + println!("Status Code: {}", response.status()); + println!("Response Body: {}", response.text()?); + + Ok(()) +} +"""; + expect( + codeGen.getCode( + CodegenLanguage.rustReqwest, requestModelGet11, "https"), + expectedCode); + }); + + test('GET 12', () { + const expectedCode = + r"""fn main() -> Result<(), Box> { + let client = reqwest::blocking::Client::new(); + let url = "https://api.apidash.dev/humanize/social"; + + let response = client + .get(url) + .send()?; + + println!("Status Code: {}", response.status()); + println!("Response Body: {}", response.text()?); + + Ok(()) +} +"""; + expect( + codeGen.getCode( + CodegenLanguage.rustReqwest, requestModelGet12, "https"), + expectedCode); + }); + }); + + group('HEAD Request', () { + test('HEAD 1', () { + const expectedCode = + r"""fn main() -> Result<(), Box> { + let client = reqwest::blocking::Client::new(); + let url = "https://api.apidash.dev"; + + let response = client + .head(url) + .send()?; + + println!("Status Code: {}", response.status()); + println!("Response Body: {}", response.text()?); + + Ok(()) +} +"""; + expect( + codeGen.getCode( + CodegenLanguage.rustReqwest, requestModelHead1, "https"), + expectedCode); + }); + + test('HEAD 2', () { + const expectedCode = + r"""fn main() -> Result<(), Box> { + let client = reqwest::blocking::Client::new(); + let url = "http://api.apidash.dev"; + + let response = client + .head(url) + .send()?; + + println!("Status Code: {}", response.status()); + println!("Response Body: {}", response.text()?); + + Ok(()) +} +"""; + expect( + codeGen.getCode( + CodegenLanguage.rustReqwest, requestModelHead2, "http"), + expectedCode); + }); + }); + + group('POST Request', () { + test('POST 1', () { + const expectedCode = + r"""fn main() -> Result<(), Box> { + let client = reqwest::blocking::Client::new(); + let url = "https://api.apidash.dev/case/lower"; + + let payload = r#"{ +"text": "I LOVE Flutter" +}"#; + + let response = client + .post(url) + .header("content-type", "text/plain") + .body(payload) + .send()?; + + println!("Status Code: {}", response.status()); + println!("Response Body: {}", response.text()?); + + Ok(()) +} +"""; + expect( + codeGen.getCode( + CodegenLanguage.rustReqwest, requestModelPost1, "https"), + expectedCode); + }); + + test('POST 2', () { + const expectedCode = + r"""fn main() -> Result<(), Box> { + let client = reqwest::blocking::Client::new(); + let url = "https://api.apidash.dev/case/lower"; + + let payload = serde_json::json!({ +"text": "I LOVE Flutter", +"flag": null, +"male": true, +"female": false, +"no": 1.2, +"arr": ["null", "true", "false", null] +}); + + let response = client + .post(url) + .json(&payload) + .send()?; + + println!("Status Code: {}", response.status()); + println!("Response Body: {}", response.text()?); + + Ok(()) +} +"""; + expect( + codeGen.getCode( + CodegenLanguage.rustReqwest, requestModelPost2, "https"), + expectedCode); + }); + + test('POST 3', () { + const expectedCode = + r"""fn main() -> Result<(), Box> { + let client = reqwest::blocking::Client::new(); + let url = "https://api.apidash.dev/case/lower"; + + let payload = serde_json::json!({ +"text": "I LOVE Flutter" +}); + + let response = client + .post(url) + .header("User-Agent", "Test Agent") + .json(&payload) + .send()?; + + println!("Status Code: {}", response.status()); + println!("Response Body: {}", response.text()?); + + Ok(()) +} +"""; + expect( + codeGen.getCode( + CodegenLanguage.rustReqwest, requestModelPost3, "https"), + expectedCode); + }); + test('POST 4', () { + const expectedCode = + r"""fn main() -> Result<(), Box> { + let client = reqwest::blocking::Client::new(); + let url = "https://api.apidash.dev/io/form"; + + struct FormDataItem { + name: String, + value: String, + field_type: String, + } + + let form_data_items: Vec = vec![ + FormDataItem { + name: "text".to_string(), + value: "API".to_string(), + field_type: "text".to_string(), + }, + FormDataItem { + name: "sep".to_string(), + value: "|".to_string(), + field_type: "text".to_string(), + }, + FormDataItem { + name: "times".to_string(), + value: "3".to_string(), + field_type: "text".to_string(), + }, + ]; + + let mut form = reqwest::blocking::multipart::Form::new(); + + for item in form_data_items { + if item.field_type == "text" { + form = form.text(item.name, item.value); + } else if item.field_type == "file" { + form = form.file(item.name, &item.value)?; + } + } + let response = client + .post(url) + .multipart(form) + .send()?; + + println!("Status Code: {}", response.status()); + println!("Response Body: {}", response.text()?); + + Ok(()) +} +"""; + expect( + codeGen.getCode( + CodegenLanguage.rustReqwest, + requestModelPost4, + "https", + boundary: "test", + ), + expectedCode); + }); + test('POST 5', () { + const expectedCode = + r"""fn main() -> Result<(), Box> { + let client = reqwest::blocking::Client::new(); + let url = "https://api.apidash.dev/io/form"; + + struct FormDataItem { + name: String, + value: String, + field_type: String, + } + + let form_data_items: Vec = vec![ + FormDataItem { + name: "text".to_string(), + value: "API".to_string(), + field_type: "text".to_string(), + }, + FormDataItem { + name: "sep".to_string(), + value: "|".to_string(), + field_type: "text".to_string(), + }, + FormDataItem { + name: "times".to_string(), + value: "3".to_string(), + field_type: "text".to_string(), + }, + ]; + + let mut form = reqwest::blocking::multipart::Form::new(); + + for item in form_data_items { + if item.field_type == "text" { + form = form.text(item.name, item.value); + } else if item.field_type == "file" { + form = form.file(item.name, &item.value)?; + } + } + let response = client + .post(url) + .header("User-Agent", "Test Agent") + .multipart(form) + .send()?; + + println!("Status Code: {}", response.status()); + println!("Response Body: {}", response.text()?); + + Ok(()) +} +"""; + expect( + codeGen.getCode( + CodegenLanguage.rustReqwest, requestModelPost5, "https", + boundary: "test"), + expectedCode); + }); + test('POST 6', () { + const expectedCode = + r"""fn main() -> Result<(), Box> { + let client = reqwest::blocking::Client::new(); + let url = "https://api.apidash.dev/io/img"; + + struct FormDataItem { + name: String, + value: String, + field_type: String, + } + + let form_data_items: Vec = vec![ + FormDataItem { + name: "token".to_string(), + value: "xyz".to_string(), + field_type: "text".to_string(), + }, + FormDataItem { + name: "imfile".to_string(), + value: "/Documents/up/1.png".to_string(), + field_type: "file".to_string(), + }, + ]; + + let mut form = reqwest::blocking::multipart::Form::new(); + + for item in form_data_items { + if item.field_type == "text" { + form = form.text(item.name, item.value); + } else if item.field_type == "file" { + form = form.file(item.name, &item.value)?; + } + } + let response = client + .post(url) + .multipart(form) + .send()?; + + println!("Status Code: {}", response.status()); + println!("Response Body: {}", response.text()?); + + Ok(()) +} +"""; + expect( + codeGen.getCode( + CodegenLanguage.rustReqwest, requestModelPost6, "https", + boundary: "test"), + expectedCode); + }); + test('POST 7', () { + const expectedCode = + r"""fn main() -> Result<(), Box> { + let client = reqwest::blocking::Client::new(); + let url = "https://api.apidash.dev/io/img"; + + struct FormDataItem { + name: String, + value: String, + field_type: String, + } + + let form_data_items: Vec = vec![ + FormDataItem { + name: "token".to_string(), + value: "xyz".to_string(), + field_type: "text".to_string(), + }, + FormDataItem { + name: "imfile".to_string(), + value: "/Documents/up/1.png".to_string(), + field_type: "file".to_string(), + }, + ]; + + let mut form = reqwest::blocking::multipart::Form::new(); + + for item in form_data_items { + if item.field_type == "text" { + form = form.text(item.name, item.value); + } else if item.field_type == "file" { + form = form.file(item.name, &item.value)?; + } + } + let response = client + .post(url) + .multipart(form) + .send()?; + + println!("Status Code: {}", response.status()); + println!("Response Body: {}", response.text()?); + + Ok(()) +} +"""; + expect( + codeGen.getCode( + CodegenLanguage.rustReqwest, requestModelPost7, "https", + boundary: "test"), + expectedCode); + }); + test('POST 8', () { + const expectedCode = + r"""fn main() -> Result<(), Box> { + let client = reqwest::blocking::Client::new(); + let url = "https://api.apidash.dev/io/form"; + + struct FormDataItem { + name: String, + value: String, + field_type: String, + } + + let form_data_items: Vec = vec![ + FormDataItem { + name: "text".to_string(), + value: "API".to_string(), + field_type: "text".to_string(), + }, + FormDataItem { + name: "sep".to_string(), + value: "|".to_string(), + field_type: "text".to_string(), + }, + FormDataItem { + name: "times".to_string(), + value: "3".to_string(), + field_type: "text".to_string(), + }, + ]; + + let mut form = reqwest::blocking::multipart::Form::new(); + + for item in form_data_items { + if item.field_type == "text" { + form = form.text(item.name, item.value); + } else if item.field_type == "file" { + form = form.file(item.name, &item.value)?; + } + } + let response = client + .post(url) + .query(&[("size", "2"), ("len", "3")]) + .multipart(form) + .send()?; + + println!("Status Code: {}", response.status()); + println!("Response Body: {}", response.text()?); + + Ok(()) +} +"""; + expect( + codeGen.getCode( + CodegenLanguage.rustReqwest, requestModelPost8, "https", + boundary: "test"), + expectedCode); + }); + test('POST 9', () { + const expectedCode = + r"""fn main() -> Result<(), Box> { + let client = reqwest::blocking::Client::new(); + let url = "https://api.apidash.dev/io/img"; + + struct FormDataItem { + name: String, + value: String, + field_type: String, + } + + let form_data_items: Vec = vec![ + FormDataItem { + name: "token".to_string(), + value: "xyz".to_string(), + field_type: "text".to_string(), + }, + FormDataItem { + name: "imfile".to_string(), + value: "/Documents/up/1.png".to_string(), + field_type: "file".to_string(), + }, + ]; + + let mut form = reqwest::blocking::multipart::Form::new(); + + for item in form_data_items { + if item.field_type == "text" { + form = form.text(item.name, item.value); + } else if item.field_type == "file" { + form = form.file(item.name, &item.value)?; + } + } + let response = client + .post(url) + .query(&[("size", "2"), ("len", "3")]) + .header("User-Agent", "Test Agent") + .header("Keep-Alive", "true") + .multipart(form) + .send()?; + + println!("Status Code: {}", response.status()); + println!("Response Body: {}", response.text()?); + + Ok(()) +} +"""; + expect( + codeGen.getCode( + CodegenLanguage.rustReqwest, requestModelPost9, "https", + boundary: "test"), + expectedCode); + }); + }); + + group('PUT Request', () { + test('PUT 1', () { + const expectedCode = + r"""fn main() -> Result<(), Box> { + let client = reqwest::blocking::Client::new(); + let url = "https://reqres.in/api/users/2"; + + let payload = serde_json::json!({ +"name": "morpheus", +"job": "zion resident" +}); + + let response = client + .put(url) + .json(&payload) + .send()?; + + println!("Status Code: {}", response.status()); + println!("Response Body: {}", response.text()?); + + Ok(()) +} +"""; + expect( + codeGen.getCode( + CodegenLanguage.rustReqwest, requestModelPut1, "https"), + expectedCode); + }); + }); + + group('PATCH Request', () { + test('PATCH 1', () { + const expectedCode = + r"""fn main() -> Result<(), Box> { + let client = reqwest::blocking::Client::new(); + let url = "https://reqres.in/api/users/2"; + + let payload = serde_json::json!({ +"name": "marfeus", +"job": "accountant" +}); + + let response = client + .patch(url) + .json(&payload) + .send()?; + + println!("Status Code: {}", response.status()); + println!("Response Body: {}", response.text()?); + + Ok(()) +} +"""; + expect( + codeGen.getCode( + CodegenLanguage.rustReqwest, requestModelPatch1, "https"), + expectedCode); + }); + }); + + group('DELETE Request', () { + test('DELETE 1', () { + const expectedCode = + r"""fn main() -> Result<(), Box> { + let client = reqwest::blocking::Client::new(); + let url = "https://reqres.in/api/users/2"; + + let response = client + .delete(url) + .send()?; + + println!("Status Code: {}", response.status()); + println!("Response Body: {}", response.text()?); + + Ok(()) +} +"""; + expect( + codeGen.getCode( + CodegenLanguage.rustReqwest, requestModelDelete1, "https"), + expectedCode); + }); + + test('DELETE 2', () { + const expectedCode = + r"""fn main() -> Result<(), Box> { + let client = reqwest::blocking::Client::new(); + let url = "https://reqres.in/api/users/2"; + + let payload = serde_json::json!({ +"name": "marfeus", +"job": "accountant" +}); + + let response = client + .delete(url) + .json(&payload) + .send()?; + + println!("Status Code: {}", response.status()); + println!("Response Body: {}", response.text()?); + + Ok(()) +} +"""; + expect( + codeGen.getCode( + CodegenLanguage.rustReqwest, requestModelDelete2, "https"), + expectedCode); + }); + }); +} diff --git a/test/codegen/rust_ureq_codegen_test.dart b/test/codegen/rust_ureq_codegen_test.dart new file mode 100644 index 00000000..b6985f3f --- /dev/null +++ b/test/codegen/rust_ureq_codegen_test.dart @@ -0,0 +1,871 @@ +import 'package:apidash/codegen/codegen.dart'; +import 'package:apidash/consts.dart'; +import 'package:test/test.dart'; +import '../request_models.dart'; + +void main() { + final codeGen = Codegen(); + + group('GET Request', () { + test('GET 1', () { + const expectedCode = r"""fn main() -> Result<(), ureq::Error> { + let url = "https://api.apidash.dev"; + let response = ureq::get(url) + .call()?; + + println!("Response Status: {}", response.status()); + println!("Response: {}", response.into_string()?); + + Ok(()) +} +"""; + expect( + codeGen.getCode(CodegenLanguage.rustUreq, requestModelGet1, "https"), + expectedCode); + }); + + test('GET 2', () { + const expectedCode = r"""fn main() -> Result<(), ureq::Error> { + let url = "https://api.apidash.dev/country/data"; + let response = ureq::get(url) + .query("code", "US") + .call()?; + + println!("Response Status: {}", response.status()); + println!("Response: {}", response.into_string()?); + + Ok(()) +} +"""; + expect( + codeGen.getCode(CodegenLanguage.rustUreq, requestModelGet2, "https"), + expectedCode); + }); + + test('GET 3', () { + const expectedCode = r"""fn main() -> Result<(), ureq::Error> { + let url = "https://api.apidash.dev/country/data"; + let response = ureq::get(url) + .query("code", "IND") + .call()?; + + println!("Response Status: {}", response.status()); + println!("Response: {}", response.into_string()?); + + Ok(()) +} +"""; + expect( + codeGen.getCode(CodegenLanguage.rustUreq, requestModelGet3, "https"), + expectedCode); + }); + + test('GET 4', () { + const expectedCode = r"""fn main() -> Result<(), ureq::Error> { + let url = "https://api.apidash.dev/humanize/social"; + let response = ureq::get(url) + .query("num", "8700000") + .query("digits", "3") + .query("system", "SS") + .query("add_space", "true") + .query("trailing_zeros", "true") + .call()?; + + println!("Response Status: {}", response.status()); + println!("Response: {}", response.into_string()?); + + Ok(()) +} +"""; + expect( + codeGen.getCode(CodegenLanguage.rustUreq, requestModelGet4, "https"), + expectedCode); + }); + + test('GET 5', () { + const expectedCode = r"""fn main() -> Result<(), ureq::Error> { + let url = "https://api.github.com/repos/foss42/apidash"; + let response = ureq::get(url) + .set("User-Agent", "Test Agent") + .call()?; + + println!("Response Status: {}", response.status()); + println!("Response: {}", response.into_string()?); + + Ok(()) +} +"""; + expect( + codeGen.getCode(CodegenLanguage.rustUreq, requestModelGet5, "https"), + expectedCode); + }); + + test('GET 6', () { + const expectedCode = r"""fn main() -> Result<(), ureq::Error> { + let url = "https://api.github.com/repos/foss42/apidash"; + let response = ureq::get(url) + .query("raw", "true") + .set("User-Agent", "Test Agent") + .call()?; + + println!("Response Status: {}", response.status()); + println!("Response: {}", response.into_string()?); + + Ok(()) +} +"""; + expect( + codeGen.getCode(CodegenLanguage.rustUreq, requestModelGet6, "https"), + expectedCode); + }); + + test('GET 7', () { + const expectedCode = r"""fn main() -> Result<(), ureq::Error> { + let url = "https://api.apidash.dev"; + let response = ureq::get(url) + .call()?; + + println!("Response Status: {}", response.status()); + println!("Response: {}", response.into_string()?); + + Ok(()) +} +"""; + expect( + codeGen.getCode(CodegenLanguage.rustUreq, requestModelGet7, "https"), + expectedCode); + }); + + test('GET 8', () { + const expectedCode = r"""fn main() -> Result<(), ureq::Error> { + let url = "https://api.github.com/repos/foss42/apidash"; + let response = ureq::get(url) + .query("raw", "true") + .set("User-Agent", "Test Agent") + .call()?; + + println!("Response Status: {}", response.status()); + println!("Response: {}", response.into_string()?); + + Ok(()) +} +"""; + expect( + codeGen.getCode(CodegenLanguage.rustUreq, requestModelGet8, "https"), + expectedCode); + }); + + test('GET 9', () { + const expectedCode = r"""fn main() -> Result<(), ureq::Error> { + let url = "https://api.apidash.dev/humanize/social"; + let response = ureq::get(url) + .query("num", "8700000") + .query("add_space", "true") + .call()?; + + println!("Response Status: {}", response.status()); + println!("Response: {}", response.into_string()?); + + Ok(()) +} +"""; + expect( + codeGen.getCode(CodegenLanguage.rustUreq, requestModelGet9, "https"), + expectedCode); + }); + + test('GET 10', () { + const expectedCode = r"""fn main() -> Result<(), ureq::Error> { + let url = "https://api.apidash.dev/humanize/social"; + let response = ureq::get(url) + .set("User-Agent", "Test Agent") + .call()?; + + println!("Response Status: {}", response.status()); + println!("Response: {}", response.into_string()?); + + Ok(()) +} +"""; + expect( + codeGen.getCode( + CodegenLanguage.rustUreq, + requestModelGet10, + "https", + ), + expectedCode); + }); + + test('GET 11', () { + const expectedCode = r"""fn main() -> Result<(), ureq::Error> { + let url = "https://api.apidash.dev/humanize/social"; + let response = ureq::get(url) + .query("num", "8700000") + .query("digits", "3") + .set("User-Agent", "Test Agent") + .call()?; + + println!("Response Status: {}", response.status()); + println!("Response: {}", response.into_string()?); + + Ok(()) +} +"""; + expect( + codeGen.getCode(CodegenLanguage.rustUreq, requestModelGet11, "https"), + expectedCode); + }); + + test('GET 12', () { + const expectedCode = r"""fn main() -> Result<(), ureq::Error> { + let url = "https://api.apidash.dev/humanize/social"; + let response = ureq::get(url) + .call()?; + + println!("Response Status: {}", response.status()); + println!("Response: {}", response.into_string()?); + + Ok(()) +} +"""; + expect( + codeGen.getCode(CodegenLanguage.rustUreq, requestModelGet12, "https"), + expectedCode); + }); + }); + + group('HEAD Request', () { + test('HEAD 1', () { + const expectedCode = r"""fn main() -> Result<(), ureq::Error> { + let url = "https://api.apidash.dev"; + let response = ureq::head(url) + .call()?; + + println!("Response Status: {}", response.status()); + println!("Response: {}", response.into_string()?); + + Ok(()) +} +"""; + expect( + codeGen.getCode(CodegenLanguage.rustUreq, requestModelHead1, "https"), + expectedCode); + }); + + test('HEAD 2', () { + const expectedCode = r"""fn main() -> Result<(), ureq::Error> { + let url = "http://api.apidash.dev"; + let response = ureq::head(url) + .call()?; + + println!("Response Status: {}", response.status()); + println!("Response: {}", response.into_string()?); + + Ok(()) +} +"""; + expect( + codeGen.getCode(CodegenLanguage.rustUreq, requestModelHead2, "http"), + expectedCode); + }); + }); + + group('POST Request', () { + test('POST 1', () { + const expectedCode = r'''fn main() -> Result<(), ureq::Error> { + let url = "https://api.apidash.dev/case/lower"; + let payload = r#"{ +"text": "I LOVE Flutter" +}"#; + + let response = ureq::post(url) + .set("content-type", "text/plain") + .send_string(payload)?; + + println!("Response Status: {}", response.status()); + println!("Response: {}", response.into_string()?); + + Ok(()) +} +'''; + expect( + codeGen.getCode(CodegenLanguage.rustUreq, requestModelPost1, "https"), + expectedCode); + }); + + test('POST 2', () { + const expectedCode = r'''fn main() -> Result<(), ureq::Error> { + let url = "https://api.apidash.dev/case/lower"; + let payload = ureq::json!({ +"text": "I LOVE Flutter", +"flag": null, +"male": true, +"female": false, +"no": 1.2, +"arr": ["null", "true", "false", null] +}); + + let response = ureq::post(url) + .send_json(payload)?; + + println!("Response Status: {}", response.status()); + println!("Response: {}", response.into_string()?); + + Ok(()) +} +'''; + expect( + codeGen.getCode(CodegenLanguage.rustUreq, requestModelPost2, "https"), + expectedCode); + }); + + test('POST 3', () { + const expectedCode = r'''fn main() -> Result<(), ureq::Error> { + let url = "https://api.apidash.dev/case/lower"; + let payload = ureq::json!({ +"text": "I LOVE Flutter" +}); + + let response = ureq::post(url) + .set("User-Agent", "Test Agent") + .send_json(payload)?; + + println!("Response Status: {}", response.status()); + println!("Response: {}", response.into_string()?); + + Ok(()) +} +'''; + expect( + codeGen.getCode(CodegenLanguage.rustUreq, requestModelPost3, "https"), + expectedCode); + }); + + test('POST 4', () { + const expectedCode = r"""use std::io::Read; +fn main() -> Result<(), ureq::Error> { + let url = "https://api.apidash.dev/io/form"; + struct FormDataItem { + name: String, + value: String, + field_type: String, + } + + let form_data_items: Vec = vec![ + FormDataItem { + name: "text".to_string(), + value: "API".to_string(), + field_type: "text".to_string(), + }, + FormDataItem { + name: "sep".to_string(), + value: "|".to_string(), + field_type: "text".to_string(), + }, + FormDataItem { + name: "times".to_string(), + value: "3".to_string(), + field_type: "text".to_string(), + }, + ]; + + fn build_data_list(fields: Vec) -> Vec { + let mut data_list = Vec::new(); + + for field in fields { + data_list.extend_from_slice(b"--test\r\n"); + + if field.field_type == "text" { + data_list.extend_from_slice(format!("Content-Disposition: form-data; name=\"{}\"\r\n", field.name).as_bytes()); + data_list.extend_from_slice(b"Content-Type: text/plain\r\n\r\n"); + data_list.extend_from_slice(field.value.as_bytes()); + data_list.extend_from_slice(b"\r\n"); + } else if field.field_type == "file" { + data_list.extend_from_slice(format!("Content-Disposition: form-data; name=\"{}\"; filename=\"{}\"\r\n", field.name, field.value).as_bytes()); + + let mime_type = mime_guess::from_path(&field.value).first_or(mime_guess::mime::APPLICATION_OCTET_STREAM); + data_list.extend_from_slice(format!("Content-Type: {}\r\n\r\n", mime_type).as_bytes()); + + let mut file = std::fs::File::open(&field.value).unwrap(); + let mut file_contents = Vec::new(); + file.read_to_end(&mut file_contents).unwrap(); + data_list.extend_from_slice(&file_contents); + data_list.extend_from_slice(b"\r\n"); + } + } + + data_list.extend_from_slice(b"--test--\r\n"); + data_list + } + + let payload = build_data_list(form_data_items); + let response = ureq::post(url) + .set("content-type", "multipart/form-data; boundary=test") + .send_bytes(&payload)?; + + println!("Response Status: {}", response.status()); + println!("Response: {}", response.into_string()?); + + Ok(()) +} +"""; + expect( + codeGen.getCode( + CodegenLanguage.rustUreq, + requestModelPost4, + "https", + boundary: "test", + ), + expectedCode); + }); + test('POST 5', () { + const expectedCode = r"""use std::io::Read; +fn main() -> Result<(), ureq::Error> { + let url = "https://api.apidash.dev/io/form"; + struct FormDataItem { + name: String, + value: String, + field_type: String, + } + + let form_data_items: Vec = vec![ + FormDataItem { + name: "text".to_string(), + value: "API".to_string(), + field_type: "text".to_string(), + }, + FormDataItem { + name: "sep".to_string(), + value: "|".to_string(), + field_type: "text".to_string(), + }, + FormDataItem { + name: "times".to_string(), + value: "3".to_string(), + field_type: "text".to_string(), + }, + ]; + + fn build_data_list(fields: Vec) -> Vec { + let mut data_list = Vec::new(); + + for field in fields { + data_list.extend_from_slice(b"--test\r\n"); + + if field.field_type == "text" { + data_list.extend_from_slice(format!("Content-Disposition: form-data; name=\"{}\"\r\n", field.name).as_bytes()); + data_list.extend_from_slice(b"Content-Type: text/plain\r\n\r\n"); + data_list.extend_from_slice(field.value.as_bytes()); + data_list.extend_from_slice(b"\r\n"); + } else if field.field_type == "file" { + data_list.extend_from_slice(format!("Content-Disposition: form-data; name=\"{}\"; filename=\"{}\"\r\n", field.name, field.value).as_bytes()); + + let mime_type = mime_guess::from_path(&field.value).first_or(mime_guess::mime::APPLICATION_OCTET_STREAM); + data_list.extend_from_slice(format!("Content-Type: {}\r\n\r\n", mime_type).as_bytes()); + + let mut file = std::fs::File::open(&field.value).unwrap(); + let mut file_contents = Vec::new(); + file.read_to_end(&mut file_contents).unwrap(); + data_list.extend_from_slice(&file_contents); + data_list.extend_from_slice(b"\r\n"); + } + } + + data_list.extend_from_slice(b"--test--\r\n"); + data_list + } + + let payload = build_data_list(form_data_items); + let response = ureq::post(url) + .set("User-Agent", "Test Agent") + .set("content-type", "multipart/form-data; boundary=test") + .send_bytes(&payload)?; + + println!("Response Status: {}", response.status()); + println!("Response: {}", response.into_string()?); + + Ok(()) +} +"""; + expect( + codeGen.getCode(CodegenLanguage.rustUreq, requestModelPost5, "https", + boundary: "test"), + expectedCode); + }); + test('POST 6', () { + const expectedCode = r"""use std::io::Read; +fn main() -> Result<(), ureq::Error> { + let url = "https://api.apidash.dev/io/img"; + struct FormDataItem { + name: String, + value: String, + field_type: String, + } + + let form_data_items: Vec = vec![ + FormDataItem { + name: "token".to_string(), + value: "xyz".to_string(), + field_type: "text".to_string(), + }, + FormDataItem { + name: "imfile".to_string(), + value: "/Documents/up/1.png".to_string(), + field_type: "file".to_string(), + }, + ]; + + fn build_data_list(fields: Vec) -> Vec { + let mut data_list = Vec::new(); + + for field in fields { + data_list.extend_from_slice(b"--test\r\n"); + + if field.field_type == "text" { + data_list.extend_from_slice(format!("Content-Disposition: form-data; name=\"{}\"\r\n", field.name).as_bytes()); + data_list.extend_from_slice(b"Content-Type: text/plain\r\n\r\n"); + data_list.extend_from_slice(field.value.as_bytes()); + data_list.extend_from_slice(b"\r\n"); + } else if field.field_type == "file" { + data_list.extend_from_slice(format!("Content-Disposition: form-data; name=\"{}\"; filename=\"{}\"\r\n", field.name, field.value).as_bytes()); + + let mime_type = mime_guess::from_path(&field.value).first_or(mime_guess::mime::APPLICATION_OCTET_STREAM); + data_list.extend_from_slice(format!("Content-Type: {}\r\n\r\n", mime_type).as_bytes()); + + let mut file = std::fs::File::open(&field.value).unwrap(); + let mut file_contents = Vec::new(); + file.read_to_end(&mut file_contents).unwrap(); + data_list.extend_from_slice(&file_contents); + data_list.extend_from_slice(b"\r\n"); + } + } + + data_list.extend_from_slice(b"--test--\r\n"); + data_list + } + + let payload = build_data_list(form_data_items); + let response = ureq::post(url) + .set("content-type", "multipart/form-data; boundary=test") + .send_bytes(&payload)?; + + println!("Response Status: {}", response.status()); + println!("Response: {}", response.into_string()?); + + Ok(()) +} +"""; + expect( + codeGen.getCode(CodegenLanguage.rustUreq, requestModelPost6, "https", + boundary: "test"), + expectedCode); + }); + test('POST 7', () { + const expectedCode = r"""use std::io::Read; +fn main() -> Result<(), ureq::Error> { + let url = "https://api.apidash.dev/io/img"; + struct FormDataItem { + name: String, + value: String, + field_type: String, + } + + let form_data_items: Vec = vec![ + FormDataItem { + name: "token".to_string(), + value: "xyz".to_string(), + field_type: "text".to_string(), + }, + FormDataItem { + name: "imfile".to_string(), + value: "/Documents/up/1.png".to_string(), + field_type: "file".to_string(), + }, + ]; + + fn build_data_list(fields: Vec) -> Vec { + let mut data_list = Vec::new(); + + for field in fields { + data_list.extend_from_slice(b"--test\r\n"); + + if field.field_type == "text" { + data_list.extend_from_slice(format!("Content-Disposition: form-data; name=\"{}\"\r\n", field.name).as_bytes()); + data_list.extend_from_slice(b"Content-Type: text/plain\r\n\r\n"); + data_list.extend_from_slice(field.value.as_bytes()); + data_list.extend_from_slice(b"\r\n"); + } else if field.field_type == "file" { + data_list.extend_from_slice(format!("Content-Disposition: form-data; name=\"{}\"; filename=\"{}\"\r\n", field.name, field.value).as_bytes()); + + let mime_type = mime_guess::from_path(&field.value).first_or(mime_guess::mime::APPLICATION_OCTET_STREAM); + data_list.extend_from_slice(format!("Content-Type: {}\r\n\r\n", mime_type).as_bytes()); + + let mut file = std::fs::File::open(&field.value).unwrap(); + let mut file_contents = Vec::new(); + file.read_to_end(&mut file_contents).unwrap(); + data_list.extend_from_slice(&file_contents); + data_list.extend_from_slice(b"\r\n"); + } + } + + data_list.extend_from_slice(b"--test--\r\n"); + data_list + } + + let payload = build_data_list(form_data_items); + let response = ureq::post(url) + .set("content-type", "multipart/form-data; boundary=test") + .send_bytes(&payload)?; + + println!("Response Status: {}", response.status()); + println!("Response: {}", response.into_string()?); + + Ok(()) +} +"""; + expect( + codeGen.getCode(CodegenLanguage.rustUreq, requestModelPost7, "https", + boundary: "test"), + expectedCode); + }); + test('POST 8', () { + const expectedCode = r"""use std::io::Read; +fn main() -> Result<(), ureq::Error> { + let url = "https://api.apidash.dev/io/form"; + struct FormDataItem { + name: String, + value: String, + field_type: String, + } + + let form_data_items: Vec = vec![ + FormDataItem { + name: "text".to_string(), + value: "API".to_string(), + field_type: "text".to_string(), + }, + FormDataItem { + name: "sep".to_string(), + value: "|".to_string(), + field_type: "text".to_string(), + }, + FormDataItem { + name: "times".to_string(), + value: "3".to_string(), + field_type: "text".to_string(), + }, + ]; + + fn build_data_list(fields: Vec) -> Vec { + let mut data_list = Vec::new(); + + for field in fields { + data_list.extend_from_slice(b"--test\r\n"); + + if field.field_type == "text" { + data_list.extend_from_slice(format!("Content-Disposition: form-data; name=\"{}\"\r\n", field.name).as_bytes()); + data_list.extend_from_slice(b"Content-Type: text/plain\r\n\r\n"); + data_list.extend_from_slice(field.value.as_bytes()); + data_list.extend_from_slice(b"\r\n"); + } else if field.field_type == "file" { + data_list.extend_from_slice(format!("Content-Disposition: form-data; name=\"{}\"; filename=\"{}\"\r\n", field.name, field.value).as_bytes()); + + let mime_type = mime_guess::from_path(&field.value).first_or(mime_guess::mime::APPLICATION_OCTET_STREAM); + data_list.extend_from_slice(format!("Content-Type: {}\r\n\r\n", mime_type).as_bytes()); + + let mut file = std::fs::File::open(&field.value).unwrap(); + let mut file_contents = Vec::new(); + file.read_to_end(&mut file_contents).unwrap(); + data_list.extend_from_slice(&file_contents); + data_list.extend_from_slice(b"\r\n"); + } + } + + data_list.extend_from_slice(b"--test--\r\n"); + data_list + } + + let payload = build_data_list(form_data_items); + let response = ureq::post(url) + .query("size", "2") + .query("len", "3") + .set("content-type", "multipart/form-data; boundary=test") + .send_bytes(&payload)?; + + println!("Response Status: {}", response.status()); + println!("Response: {}", response.into_string()?); + + Ok(()) +} +"""; + expect( + codeGen.getCode(CodegenLanguage.rustUreq, requestModelPost8, "https", + boundary: "test"), + expectedCode); + }); + test('POST 9', () { + const expectedCode = r"""use std::io::Read; +fn main() -> Result<(), ureq::Error> { + let url = "https://api.apidash.dev/io/img"; + struct FormDataItem { + name: String, + value: String, + field_type: String, + } + + let form_data_items: Vec = vec![ + FormDataItem { + name: "token".to_string(), + value: "xyz".to_string(), + field_type: "text".to_string(), + }, + FormDataItem { + name: "imfile".to_string(), + value: "/Documents/up/1.png".to_string(), + field_type: "file".to_string(), + }, + ]; + + fn build_data_list(fields: Vec) -> Vec { + let mut data_list = Vec::new(); + + for field in fields { + data_list.extend_from_slice(b"--test\r\n"); + + if field.field_type == "text" { + data_list.extend_from_slice(format!("Content-Disposition: form-data; name=\"{}\"\r\n", field.name).as_bytes()); + data_list.extend_from_slice(b"Content-Type: text/plain\r\n\r\n"); + data_list.extend_from_slice(field.value.as_bytes()); + data_list.extend_from_slice(b"\r\n"); + } else if field.field_type == "file" { + data_list.extend_from_slice(format!("Content-Disposition: form-data; name=\"{}\"; filename=\"{}\"\r\n", field.name, field.value).as_bytes()); + + let mime_type = mime_guess::from_path(&field.value).first_or(mime_guess::mime::APPLICATION_OCTET_STREAM); + data_list.extend_from_slice(format!("Content-Type: {}\r\n\r\n", mime_type).as_bytes()); + + let mut file = std::fs::File::open(&field.value).unwrap(); + let mut file_contents = Vec::new(); + file.read_to_end(&mut file_contents).unwrap(); + data_list.extend_from_slice(&file_contents); + data_list.extend_from_slice(b"\r\n"); + } + } + + data_list.extend_from_slice(b"--test--\r\n"); + data_list + } + + let payload = build_data_list(form_data_items); + let response = ureq::post(url) + .query("size", "2") + .query("len", "3") + .set("User-Agent", "Test Agent") + .set("Keep-Alive", "true") + .set("content-type", "multipart/form-data; boundary=test") + .send_bytes(&payload)?; + + println!("Response Status: {}", response.status()); + println!("Response: {}", response.into_string()?); + + Ok(()) +} +"""; + expect( + codeGen.getCode(CodegenLanguage.rustUreq, requestModelPost9, "https", + boundary: "test"), + expectedCode); + }); + }); + + group('PUT Request', () { + test('PUT 1', () { + const expectedCode = r'''fn main() -> Result<(), ureq::Error> { + let url = "https://reqres.in/api/users/2"; + let payload = ureq::json!({ +"name": "morpheus", +"job": "zion resident" +}); + + let response = ureq::put(url) + .send_json(payload)?; + + println!("Response Status: {}", response.status()); + println!("Response: {}", response.into_string()?); + + Ok(()) +} +'''; + expect( + codeGen.getCode(CodegenLanguage.rustUreq, requestModelPut1, "https"), + expectedCode); + }); + }); + + group('PATCH Request', () { + test('PATCH 1', () { + const expectedCode = r'''fn main() -> Result<(), ureq::Error> { + let url = "https://reqres.in/api/users/2"; + let payload = ureq::json!({ +"name": "marfeus", +"job": "accountant" +}); + + let response = ureq::patch(url) + .send_json(payload)?; + + println!("Response Status: {}", response.status()); + println!("Response: {}", response.into_string()?); + + Ok(()) +} +'''; + expect( + codeGen.getCode( + CodegenLanguage.rustUreq, requestModelPatch1, "https"), + expectedCode); + }); + }); + + group('DELETE Request', () { + test('DELETE 1', () { + const expectedCode = r"""fn main() -> Result<(), ureq::Error> { + let url = "https://reqres.in/api/users/2"; + let response = ureq::delete(url) + .call()?; + + println!("Response Status: {}", response.status()); + println!("Response: {}", response.into_string()?); + + Ok(()) +} +"""; + expect( + codeGen.getCode( + CodegenLanguage.rustUreq, requestModelDelete1, "https"), + expectedCode); + }); + + test('DELETE 2', () { + const expectedCode = r'''fn main() -> Result<(), ureq::Error> { + let url = "https://reqres.in/api/users/2"; + let payload = ureq::json!({ +"name": "marfeus", +"job": "accountant" +}); + + let response = ureq::delete(url) + .send_json(payload)?; + + println!("Response Status: {}", response.status()); + println!("Response: {}", response.into_string()?); + + Ok(()) +} +'''; + expect( + codeGen.getCode( + CodegenLanguage.rustUreq, requestModelDelete2, "https"), + expectedCode); + }); + }); +} diff --git a/test/models/request_model_test.dart b/test/models/request_model_test.dart index 626727de..b7dbb413 100644 --- a/test/models/request_model_test.dart +++ b/test/models/request_model_test.dart @@ -52,7 +52,7 @@ void main() { RequestModel requestModel = RequestModel( id: '1', method: HTTPVerb.post, - url: 'api.foss42.com/case/lower', + url: 'api.apidash.dev/case/lower', name: 'foss42 api', requestHeaders: const [ NameValueModel(name: 'content-length', value: '18'), @@ -69,7 +69,7 @@ void main() { RequestModel requestModelDup = const RequestModel( id: '1', method: HTTPVerb.post, - url: 'api.foss42.com/case/lower', + url: 'api.apidash.dev/case/lower', name: 'foss42 api', requestHeaders: [ NameValueModel(name: 'content-length', value: '18'), @@ -84,7 +84,7 @@ void main() { RequestModel requestModelCopy = const RequestModel( id: '1', method: HTTPVerb.post, - url: 'api.foss42.com/case/lower', + url: 'api.apidash.dev/case/lower', name: 'foss42 api (copy)', requestHeaders: [ NameValueModel(name: 'content-length', value: '18'), @@ -99,7 +99,7 @@ void main() { Map requestModelAsJson = { "id": '1', "method": 'post', - "url": 'api.foss42.com/case/lower', + "url": 'api.apidash.dev/case/lower', "name": 'foss42 api', 'description': '', "requestHeaders": { @@ -138,7 +138,7 @@ void main() { final requestModeDupString = [ "Request Id: 1", "Request Method: post", - "Request URL: api.foss42.com/case/lower", + "Request URL: api.apidash.dev/case/lower", "Request Name: foss42 api", "Request Description: ", "Request Tab Index: 0", @@ -175,7 +175,7 @@ void main() { }); expect(requestModel.paramsMap, {}); expect(requestModel.formDataMapList, []); - expect(requestModel.isFormDataRequest, false); + expect(requestModel.hasFormData, false); expect(requestModel.hasContentTypeHeader, true); }); diff --git a/test/models/response_model_test.dart b/test/models/response_model_test.dart index 1122b833..d3553a27 100644 --- a/test/models/response_model_test.dart +++ b/test/models/response_model_test.dart @@ -81,19 +81,19 @@ void main() { test('Testing fromResponse', () async { final response = await http.get( - Uri.parse('https://api.foss42.com/'), + Uri.parse('https://api.apidash.dev/'), ); final responseData = responseModel.fromResponse(response: response); expect(responseData.statusCode, 200); expect(responseData.body, - '{"message":"Check out https://foss42.com for API docs to get started."}'); + '{"data":"Check out https://api.apidash.dev/docs to get started."}'); expect(responseData.formattedBody, '''{ - "message": "Check out https://foss42.com for API docs to get started." + "data": "Check out https://api.apidash.dev/docs to get started." }'''); }); test('Testing fromResponse for contentType not Json', () async { final response = await http.get( - Uri.parse('https://foss42.com/'), + Uri.parse('https://apidash.dev/'), ); final responseData = responseModel.fromResponse(response: response); expect(responseData.statusCode, 200); diff --git a/test/request_models.dart b/test/request_models.dart index adf7e0e8..67ff2835 100644 --- a/test/request_models.dart +++ b/test/request_models.dart @@ -1,17 +1,18 @@ -import 'package:apidash/models/models.dart' show NameValueModel, RequestModel; +import 'package:apidash/models/models.dart' + show FormDataModel, NameValueModel, RequestModel; import 'package:apidash/consts.dart'; /// Basic GET request model const requestModelGet1 = RequestModel( id: 'get1', - url: 'https://api.foss42.com', + url: 'https://api.apidash.dev', method: HTTPVerb.get, ); /// GET request model with query params const requestModelGet2 = RequestModel( id: 'get2', - url: 'https://api.foss42.com/country/data', + url: 'https://api.apidash.dev/country/data', method: HTTPVerb.get, requestParams: [ NameValueModel(name: 'code', value: 'US'), @@ -21,7 +22,7 @@ const requestModelGet2 = RequestModel( /// GET request model with override query params const requestModelGet3 = RequestModel( id: 'get3', - url: 'https://api.foss42.com/country/data?code=US', + url: 'https://api.apidash.dev/country/data?code=US', method: HTTPVerb.get, requestParams: [ NameValueModel(name: 'code', value: 'IND'), @@ -31,7 +32,7 @@ const requestModelGet3 = RequestModel( /// GET request model with different types of query params const requestModelGet4 = RequestModel( id: 'get4', - url: 'https://api.foss42.com/humanize/social', + url: 'https://api.apidash.dev/humanize/social', method: HTTPVerb.get, requestParams: [ NameValueModel(name: 'num', value: '8700000'), @@ -68,7 +69,7 @@ const requestModelGet6 = RequestModel( /// GET request model with body const requestModelGet7 = RequestModel( id: 'get7', - url: 'https://api.foss42.com', + url: 'https://api.apidash.dev', method: HTTPVerb.get, requestBodyContentType: ContentType.text, requestBody: @@ -92,8 +93,8 @@ const requestModelGet8 = RequestModel( /// GET request model with some params enabled const requestModelGet9 = RequestModel( - id: 'enabledParams', - url: 'https://api.foss42.com/humanize/social', + id: 'get9', + url: 'https://api.apidash.dev/humanize/social', method: HTTPVerb.get, requestParams: [ NameValueModel(name: 'num', value: '8700000'), @@ -111,8 +112,8 @@ const requestModelGet9 = RequestModel( /// GET Request model with some headers enabled const requestModelGet10 = RequestModel( - id: 'enabledParams', - url: 'https://api.foss42.com/humanize/social', + id: 'get10', + url: 'https://api.apidash.dev/humanize/social', method: HTTPVerb.get, requestHeaders: [ NameValueModel(name: 'User-Agent', value: 'Test Agent'), @@ -126,8 +127,8 @@ const requestModelGet10 = RequestModel( /// GET Request model with some headers & URL parameters enabled const requestModelGet11 = RequestModel( - id: 'enabledRows', - url: 'https://api.foss42.com/humanize/social', + id: 'get11', + url: 'https://api.apidash.dev/humanize/social', method: HTTPVerb.get, requestParams: [ NameValueModel(name: 'num', value: '8700000'), @@ -153,8 +154,8 @@ const requestModelGet11 = RequestModel( /// Request model with all headers & URL parameters disabled const requestModelGet12 = RequestModel( - id: 'disabledRows', - url: 'https://api.foss42.com/humanize/social', + id: 'get12', + url: 'https://api.apidash.dev/humanize/social', method: HTTPVerb.get, requestParams: [ NameValueModel(name: 'num', value: '8700000'), @@ -181,21 +182,21 @@ const requestModelGet12 = RequestModel( /// Basic HEAD request model const requestModelHead1 = RequestModel( id: 'head1', - url: 'https://api.foss42.com', + url: 'https://api.apidash.dev', method: HTTPVerb.head, ); /// Without URI Scheme (pass default as http) const requestModelHead2 = RequestModel( id: 'head2', - url: 'api.foss42.com', + url: 'api.apidash.dev', method: HTTPVerb.head, ); /// Basic POST request model (txt body) const requestModelPost1 = RequestModel( id: 'post1', - url: 'https://api.foss42.com/case/lower', + url: 'https://api.apidash.dev/case/lower', method: HTTPVerb.post, requestBody: r"""{ "text": "I LOVE Flutter" @@ -205,17 +206,22 @@ const requestModelPost1 = RequestModel( /// POST request model with JSON body const requestModelPost2 = RequestModel( id: 'post2', - url: 'https://api.foss42.com/case/lower', + url: 'https://api.apidash.dev/case/lower', method: HTTPVerb.post, requestBody: r"""{ -"text": "I LOVE Flutter" +"text": "I LOVE Flutter", +"flag": null, +"male": true, +"female": false, +"no": 1.2, +"arr": ["null", "true", "false", null] }""", ); /// POST request model with headers const requestModelPost3 = RequestModel( id: 'post3', - url: 'https://api.foss42.com/case/lower', + url: 'https://api.apidash.dev/case/lower', method: HTTPVerb.post, requestBody: r"""{ "text": "I LOVE Flutter" @@ -226,6 +232,105 @@ const requestModelPost3 = RequestModel( ], ); +/// POST request model with multipart body(text) +const requestModelPost4 = RequestModel( + id: 'post4', + url: 'https://api.apidash.dev/io/form', + method: HTTPVerb.post, + requestFormDataList: [ + FormDataModel(name: "text", value: "API", type: FormDataType.text), + FormDataModel(name: "sep", value: "|", type: FormDataType.text), + FormDataModel(name: "times", value: "3", type: FormDataType.text), + ], + requestBodyContentType: ContentType.formdata, +); + +/// POST request model with multipart body and headers +const requestModelPost5 = RequestModel( + id: 'post5', + url: 'https://api.apidash.dev/io/form', + method: HTTPVerb.post, + requestFormDataList: [ + FormDataModel(name: "text", value: "API", type: FormDataType.text), + FormDataModel(name: "sep", value: "|", type: FormDataType.text), + FormDataModel(name: "times", value: "3", type: FormDataType.text), + ], + requestHeaders: [ + NameValueModel(name: 'User-Agent', value: 'Test Agent'), + ], + requestBodyContentType: ContentType.formdata, +); + +/// POST request model with multipart body(text, file) +const requestModelPost6 = RequestModel( + id: 'post6', + url: 'https://api.apidash.dev/io/img', + method: HTTPVerb.post, + requestFormDataList: [ + FormDataModel(name: "token", value: "xyz", type: FormDataType.text), + FormDataModel( + name: "imfile", value: "/Documents/up/1.png", type: FormDataType.file), + ], + requestBodyContentType: ContentType.formdata, +); + +/// POST request model with multipart body and requestBody (the requestBody shouldn't be in codegen) +const requestModelPost7 = RequestModel( + id: 'post7', + url: 'https://api.apidash.dev/io/img', + method: HTTPVerb.post, + requestBody: r"""{ +"text": "I LOVE Flutter" +}""", + requestFormDataList: [ + FormDataModel(name: "token", value: "xyz", type: FormDataType.text), + FormDataModel( + name: "imfile", value: "/Documents/up/1.png", type: FormDataType.file), + ], + requestBodyContentType: ContentType.formdata, +); + +/// POST request model with multipart body and requestParams +const requestModelPost8 = RequestModel( + id: 'post8', + url: 'https://api.apidash.dev/io/form', + method: HTTPVerb.post, + requestFormDataList: [ + FormDataModel(name: "text", value: "API", type: FormDataType.text), + FormDataModel(name: "sep", value: "|", type: FormDataType.text), + FormDataModel(name: "times", value: "3", type: FormDataType.text), + ], + requestParams: [ + NameValueModel(name: 'size', value: '2'), + NameValueModel(name: 'len', value: '3'), + ], + requestBodyContentType: ContentType.formdata, +); + +/// POST request model with multipart body(file and text), requestParams, requestHeaders and requestBody +const requestModelPost9 = RequestModel( + id: 'post9', + url: 'https://api.apidash.dev/io/img', + method: HTTPVerb.post, + requestBody: r"""{ +"text": "I LOVE Flutter" +}""", + requestFormDataList: [ + FormDataModel(name: "token", value: "xyz", type: FormDataType.text), + FormDataModel( + name: "imfile", value: "/Documents/up/1.png", type: FormDataType.file), + ], + requestParams: [ + NameValueModel(name: 'size', value: '2'), + NameValueModel(name: 'len', value: '3'), + ], + requestHeaders: [ + NameValueModel(name: 'User-Agent', value: 'Test Agent'), + NameValueModel(name: 'Keep-Alive', value: 'true'), + ], + requestBodyContentType: ContentType.formdata, +); + /// PUT request model const requestModelPut1 = RequestModel( id: 'put1', diff --git a/test/utils/file_utils_test.dart b/test/utils/file_utils_test.dart index 18e2816a..26e90e39 100644 --- a/test/utils/file_utils_test.dart +++ b/test/utils/file_utils_test.dart @@ -1,3 +1,4 @@ +import 'package:apidash/consts.dart'; import 'package:test/test.dart'; import 'package:apidash/utils/file_utils.dart'; @@ -11,8 +12,13 @@ void main() { }); test('Test getShortPath', () { - String path = "A/B/C/D.csv"; - expect(getShortPath(path), ".../C/D.csv"); + if (kIsWindows) { + String path = r"A\B\C\D.csv"; + expect(getShortPath(path), r"...\C\D.csv"); + } else { + String path = "A/B/C/D.csv"; + expect(getShortPath(path), ".../C/D.csv"); + } }); test('Test getTempFileName', () { diff --git a/test/utils/har_utils_test.dart b/test/utils/har_utils_test.dart index 0dd16d62..9655e7c1 100644 --- a/test/utils/har_utils_test.dart +++ b/test/utils/har_utils_test.dart @@ -68,7 +68,7 @@ void main() { }, { 'startedDateTime': 'ABC', - 'comment': 'id:enabledRows', + 'comment': 'id:get11', 'serverIPAddress': '', 'time': 0, 'timings': { @@ -101,7 +101,7 @@ void main() { 'request': { 'method': 'GET', 'url': - 'https://api.foss42.com/humanize/social?num=8700000&digits=3&system=SS&add_space=true', + 'https://api.apidash.dev/humanize/social?num=8700000&digits=3&system=SS&add_space=true', 'httpVersion': 'HTTP/1.1', 'queryString': [ {'name': 'num', 'value': '8700000', 'comment': ''}, @@ -162,7 +162,7 @@ void main() { }, 'request': { 'method': 'POST', - 'url': 'https://api.foss42.com/case/lower', + 'url': 'https://api.apidash.dev/case/lower', 'httpVersion': 'HTTP/1.1', 'queryString': [], 'headers': [ @@ -252,7 +252,7 @@ void main() { test('Test requestModelToHARJsonRequest exportMode=true', () { Map expectedResult = { 'method': 'POST', - 'url': 'https://api.foss42.com/case/lower', + 'url': 'https://api.apidash.dev/case/lower', 'httpVersion': 'HTTP/1.1', 'queryString': [], 'headers': [ @@ -261,14 +261,19 @@ void main() { 'postData': { 'mimeType': 'application/json', 'text': '{\n' - '"text": "I LOVE Flutter"\n' + '"text": "I LOVE Flutter",\n' + '"flag": null,\n' + '"male": true,\n' + '"female": false,\n' + '"no": 1.2,\n' + '"arr": ["null", "true", "false", null]\n' '}', 'comment': '' }, 'comment': '', 'cookies': [], 'headersSize': -1, - 'bodySize': 28 + 'bodySize': 124 }; expect( requestModelToHARJsonRequest( @@ -282,7 +287,7 @@ void main() { Map expectedResult = { 'method': 'GET', 'url': - 'https://api.foss42.com/humanize/social?num=8700000&digits=3&system=SS&add_space=true', + 'https://api.apidash.dev/humanize/social?num=8700000&digits=3&system=SS&add_space=true', 'httpVersion': 'HTTP/1.1', 'queryString': [ {'name': 'num', 'value': '8700000'}, @@ -301,7 +306,7 @@ void main() { test('Test requestModelToHARJsonRequest useEnabled=true', () { Map expectedResult = { 'method': 'GET', - 'url': 'https://api.foss42.com/humanize/social?num=8700000&digits=3', + 'url': 'https://api.apidash.dev/humanize/social?num=8700000&digits=3', 'httpVersion': 'HTTP/1.1', 'queryString': [ {'name': 'num', 'value': '8700000'}, diff --git a/test/utils/header_utils_test.dart b/test/utils/header_utils_test.dart index 73c15721..139ba553 100644 --- a/test/utils/header_utils_test.dart +++ b/test/utils/header_utils_test.dart @@ -115,6 +115,7 @@ void main() { String pattern = "x-"; List expected = [ "Access-Control-Max-Age", + "Max-Forwards", "X-Api-Key", "X-Content-Type-Options", "X-CSRF-Token", diff --git a/test/utils/http_utils_test.dart b/test/utils/http_utils_test.dart index 55129bcc..2b660fcb 100644 --- a/test/utils/http_utils_test.dart +++ b/test/utils/http_utils_test.dart @@ -19,14 +19,14 @@ void main() { }); test('Testing getRequestTitleFromUrl using url3', () { - String url3 = "https://api.foss42.com/country/codes"; - String title3Expected = "api.foss42.com/country/codes"; + String url3 = "https://api.apidash.dev/country/codes"; + String title3Expected = "api.apidash.dev/country/codes"; expect(getRequestTitleFromUrl(url3), title3Expected); }); test('Testing getRequestTitleFromUrl using url4', () { - String url4 = "api.foss42.com/country/data"; - String title4Expected = "api.foss42.com/country/data"; + String url4 = "api.apidash.dev/country/data"; + String title4Expected = "api.apidash.dev/country/data"; expect(getRequestTitleFromUrl(url4), title4Expected); }); @@ -175,11 +175,11 @@ void main() { group("Testing getValidRequestUri", () { test('Testing getValidRequestUri for normal values', () { - String url1 = "https://api.foss42.com/country/data"; + String url1 = "https://api.apidash.dev/country/data"; const kvRow1 = NameValueModel(name: "code", value: "US"); Uri uri1Expected = Uri( scheme: 'https', - host: 'api.foss42.com', + host: 'api.apidash.dev', path: 'country/data', queryParameters: {'code': 'US'}); expect(getValidRequestUri(url1, [kvRow1]), (uri1Expected, null)); @@ -193,11 +193,11 @@ void main() { expect(getValidRequestUri("", [kvRow3]), (null, "URL is missing!")); }); test('Testing getValidRequestUri when https is not provided in url', () { - String url4 = "api.foss42.com/country/data"; + String url4 = "api.apidash.dev/country/data"; const kvRow4 = NameValueModel(name: "code", value: "US"); Uri uri4Expected = Uri( scheme: 'https', - host: 'api.foss42.com', + host: 'api.apidash.dev', path: 'country/data', queryParameters: {'code': 'US'}); expect(getValidRequestUri(url4, [kvRow4]), (uri4Expected, null)); @@ -217,20 +217,20 @@ void main() { }); test('Testing getValidRequestUri when query params in both url and kvrow', () { - String url6 = "api.foss42.com/country/data?code=IND"; + String url6 = "api.apidash.dev/country/data?code=IND"; const kvRow6 = NameValueModel(name: "code", value: "US"); Uri uri6Expected = Uri( scheme: 'https', - host: 'api.foss42.com', + host: 'api.apidash.dev', path: 'country/data', queryParameters: {'code': 'US'}); expect(getValidRequestUri(url6, [kvRow6]), (uri6Expected, null)); }); test('Testing getValidRequestUri when kvrow is null', () { - String url7 = "api.foss42.com/country/data?code=US"; + String url7 = "api.apidash.dev/country/data?code=US"; Uri uri7Expected = Uri( scheme: 'https', - host: 'api.foss42.com', + host: 'api.apidash.dev', path: 'country/data', queryParameters: {'code': 'US'}); expect(getValidRequestUri(url7, null), (uri7Expected, null)); diff --git a/test/widget_test.dart b/test/widget_test.dart index 48eb1d93..3f806c72 100644 --- a/test/widget_test.dart +++ b/test/widget_test.dart @@ -1,3 +1,6 @@ +// ignore_for_file: unused_import +// TODO: Added ignore to calculate code coverage + import 'package:apidash/main.dart'; import 'package:apidash/app.dart'; import 'package:apidash/common/utils.dart'; diff --git a/test/widgets/buttons_test.dart b/test/widgets/buttons_test.dart index bc568308..2b961e07 100644 --- a/test/widgets/buttons_test.dart +++ b/test/widgets/buttons_test.dart @@ -36,8 +36,7 @@ void main() { theme: kThemeDataLight, home: Scaffold( body: SendRequestButton( - selectedId: '1', - sentRequestId: null, + isWorking: false, onTap: () { changedValue = 'Send'; }, @@ -55,7 +54,8 @@ void main() { expect(changedValue, 'Send'); }); - testWidgets('Testing for Send Request button when sentRequestId is not null', + testWidgets( + 'Testing for Send Request button when RequestModel is viewed and is waiting for response', (tester) async { await tester.pumpWidget( MaterialApp( @@ -63,32 +63,7 @@ void main() { theme: kThemeDataLight, home: Scaffold( body: SendRequestButton( - selectedId: '1', - sentRequestId: '2', - onTap: () {}, - ), - ), - ), - ); - - expect(find.byIcon(Icons.send), findsNothing); - expect(find.text(kLabelBusy), findsOneWidget); - final button1 = find.byType(FilledButton); - expect(button1, findsOneWidget); - - expect(tester.widget(button1).enabled, isFalse); - }); - - testWidgets('Testing for Send Request button when sentRequestId = selectedId', - (tester) async { - await tester.pumpWidget( - MaterialApp( - title: 'Send Request button', - theme: kThemeDataLight, - home: Scaffold( - body: SendRequestButton( - selectedId: '1', - sentRequestId: '1', + isWorking: true, onTap: () {}, ), ), diff --git a/test/widgets/cards_test.dart b/test/widgets/cards_test.dart index e364d5eb..ae62ef55 100644 --- a/test/widgets/cards_test.dart +++ b/test/widgets/cards_test.dart @@ -17,7 +17,7 @@ void main() { SidebarRequestCard( id: '23', selectedId: '2', - url: 'https://api.foss42.com', + url: 'https://api.apidash.dev', method: HTTPVerb.get, onTap: () { changedValue = 'Single Tapped'; @@ -34,11 +34,11 @@ void main() { expect(find.byType(InkWell), findsOneWidget); - expect(find.text('api.foss42.com'), findsOneWidget); - expect(find.widgetWithText(SizedBox, 'api.foss42.com'), findsOneWidget); - expect(find.widgetWithText(Card, 'api.foss42.com'), findsOneWidget); + expect(find.text('api.apidash.dev'), findsOneWidget); + expect(find.widgetWithText(SizedBox, 'api.apidash.dev'), findsOneWidget); + expect(find.widgetWithText(Card, 'api.apidash.dev'), findsOneWidget); await tester.pumpAndSettle(); - var tappable = find.widgetWithText(Card, 'api.foss42.com'); + var tappable = find.widgetWithText(Card, 'api.apidash.dev'); await tester.tap(tappable); await tester.pumpAndSettle(const Duration(seconds: 2)); expect(changedValue, 'Single Tapped'); @@ -63,7 +63,7 @@ void main() { id: '2', selectedId: '2', editRequestId: '2', - url: 'https://api.foss42.com', + url: 'https://api.apidash.dev', method: HTTPVerb.get, onTapOutsideNameEditor: () { changedValue = 'Tapped Outside'; diff --git a/test/widgets/code_previewer_test.dart b/test/widgets/code_previewer_test.dart index 6fd77b4f..56bb3384 100644 --- a/test/widgets/code_previewer_test.dart +++ b/test/widgets/code_previewer_test.dart @@ -9,7 +9,7 @@ void main() { String code = r'''import 'package:http/http.dart' as http; void main() async { - var uri = Uri.parse('https://api.foss42.com/country/codes'); + var uri = Uri.parse('https://api.apidash.dev/country/codes'); final response = await http.get(uri); diff --git a/test/widgets/codegen_previewer_test.dart b/test/widgets/codegen_previewer_test.dart index 8310087e..cc337d2c 100644 --- a/test/widgets/codegen_previewer_test.dart +++ b/test/widgets/codegen_previewer_test.dart @@ -9,7 +9,7 @@ void main() { String code = r'''import 'package:http/http.dart' as http; void main() async { - var uri = Uri.parse('https://api.foss42.com/country/codes'); + var uri = Uri.parse('https://api.apidash.dev/country/codes'); final response = await http.get(uri); diff --git a/test/widgets/intro_message_test.dart b/test/widgets/intro_message_test.dart index 798afad8..4e256c82 100644 --- a/test/widgets/intro_message_test.dart +++ b/test/widgets/intro_message_test.dart @@ -1,9 +1,16 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:apidash/widgets/intro_message.dart'; +import 'package:package_info_plus/package_info_plus.dart'; void main() { testWidgets('Testing Intro Message', (tester) async { + PackageInfo.setMockInitialValues( + appName: 'API Dash', + packageName: 'dev.apidash.apidash', + version: '1.0.0', + buildNumber: '1', + buildSignature: 'buildSignature'); await tester.pumpWidget( const MaterialApp( title: 'Intro Message', @@ -13,7 +20,7 @@ void main() { ), ); - await tester.pumpAndSettle(); + await tester.pump(); expect(find.text('Welcome to API Dash ⚡️'), findsOneWidget); expect(find.byType(RichText), findsAtLeastNWidgets(1)); @@ -25,5 +32,5 @@ void main() { expect(find.byIcon(Icons.star), findsOneWidget); expect(find.text('Star on GitHub'), findsOneWidget); await tester.tap(find.byIcon(Icons.star)); - }, skip: true); + }); } diff --git a/test/widgets/markdown_test.dart b/test/widgets/markdown_test.dart index 79cb579a..500dca15 100644 --- a/test/widgets/markdown_test.dart +++ b/test/widgets/markdown_test.dart @@ -1,16 +1,85 @@ import 'package:flutter/material.dart'; +import 'package:flutter_markdown/flutter_markdown.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:apidash/widgets/markdown.dart'; void main() { - testWidgets('Testing CustomMarkdown', (tester) async { - const markdown = CustomMarkdown(data: """Is a markdown ~`star on github`~ + group('CustomMarkdown Widget Tests', () { + testWidgets('Testing CustomMarkdown buttons and tags renders', + (tester) async { + const markdown = CustomMarkdown( + data: """Is a markdown ~`star on github`~ - #br - #br +#br +#br - ~`github repo`~ ~`Discord Server`~"""); - await tester.pumpWidget(markdown); - //expectTextStrings(tester.allWidgets, ['Data1']); - }, skip: true); +~`github repo`~ ~`Discord Server`~""", + ); + await tester.pumpWidget(const MaterialApp(home: markdown)); + + expect(find.byIcon(Icons.star), findsOneWidget); + expect(find.text("star on github"), findsOneWidget); + + expect(find.byIcon(Icons.discord), findsOneWidget); + expect(find.text("Discord Server"), findsOneWidget); + + expect(find.byIcon(Icons.code_rounded), findsOneWidget); + expect(find.text("github repo"), findsOneWidget); + + expect(find.text('#br'), findsNothing); + }); + + testWidgets('CustomMarkdown renders correctly', + (WidgetTester tester) async { + await tester.pumpWidget(const MaterialApp( + home: CustomMarkdown( + data: '# Hello World\nThis is some *markdown* text.', + ), + )); + + final headlineTextFinder = find.text('Hello World'); + final markdownTextFinder = find.text('This is some markdown text.'); + + expect(headlineTextFinder, findsOneWidget); + expect(markdownTextFinder, findsOneWidget); + }); + + testWidgets('CustomMarkdown has proper text rendered', + (WidgetTester tester) async { + await tester.pumpWidget(MaterialApp( + home: GestureDetector( + child: const CustomMarkdown( + data: '[Link Text](https://apidash.dev/)', + ), + ), + )); + + await tester.tap(find.text('Link Text')); + await tester.pump(); + + expect(find.text('Link Text'), findsOneWidget); + + expect(find.text('https://apidash.dev/'), findsNothing); + }); + + testWidgets('CustomMarkdown creates hyperlink', + (WidgetTester tester) async { + bool linkTapped = false; + await tester.pumpWidget(MaterialApp( + home: CustomMarkdown( + data: '[Link Text](https://apidash.dev/)', + onTapLink: (text, href, title) { + linkTapped = true; + expect(text, 'Link Text'); + expect(href, 'https://apidash.dev/'); + }, + ), + )); + expect(find.byType(Markdown), findsOneWidget); + final markdownWidget = tester.widget(find.byType(Markdown)); + expect(markdownWidget.data, '[Link Text](https://apidash.dev/)'); + await tester.tap(find.text('Link Text')); + expect(linkTapped, true); + }); + }); } diff --git a/test/widgets/previewer_test.dart b/test/widgets/previewer_test.dart index 0d2f68cd..c26793bb 100644 --- a/test/widgets/previewer_test.dart +++ b/test/widgets/previewer_test.dart @@ -231,4 +231,26 @@ void main() { await tester.pumpAndSettle(); expect(find.text(kSvgError), findsOneWidget); }); + + testWidgets('Testing when type/subtype is text/csv', (tester) async { + String csvDataString = + 'Id,Name,Age\n1,John Doe,40\n2,Dbestech,41\n3,Voldermort,71\n4,Joe Biden,80\n5,Ryo Hanamura,35'; + + await tester.pumpWidget( + MaterialApp( + home: Scaffold( + body: Previewer( + type: kTypeText, + subtype: kSubTypeCsv, + bytes: Uint8List.fromList([]), + body: csvDataString, + ), + ), + ), + ); + + expect(find.byType(DataTable), findsOneWidget); + expect(find.text('John Doe'), findsOneWidget); + expect(find.text('41'), findsOneWidget); + }); } diff --git a/test/widgets/response_widgets_test.dart b/test/widgets/response_widgets_test.dart index 1aebc539..7877a285 100644 --- a/test/widgets/response_widgets_test.dart +++ b/test/widgets/response_widgets_test.dart @@ -201,7 +201,7 @@ void main() { RequestModel requestModel = const RequestModel( id: '1', method: HTTPVerb.post, - url: 'api.foss42.com/case/lower', + url: 'api.apidash.dev/case/lower', name: 'foss42 api', requestHeaders: [ NameValueModel(name: 'content-length', value: '18'), @@ -372,7 +372,7 @@ void main() { String code = r'''import 'package:http/http.dart' as http; void main() async { - var uri = Uri.parse('https://api.foss42.com/country/codes'); + var uri = Uri.parse('https://api.apidash.dev/country/codes'); final response = await http.get(uri); diff --git a/test/widgets/textfields_test.dart b/test/widgets/textfields_test.dart index 652ec8ec..88aa6392 100644 --- a/test/widgets/textfields_test.dart +++ b/test/widgets/textfields_test.dart @@ -57,4 +57,41 @@ void main() { await tester.pumpAndSettle(); expect(find.text('entering 123 for cell field'), findsOneWidget); }); + + testWidgets('URL Field sends request on enter keystroke', (tester) async { + bool wasSubmitCalled = false; + + void testSubmit(String val) { + wasSubmitCalled = true; + } + + await tester.pumpWidget( + MaterialApp( + title: 'URL Field', + theme: kThemeDataDark, + home: Scaffold( + body: Column(children: [ + URLField( + selectedId: '2', + onFieldSubmitted: testSubmit, + ) + ]), + ), + ), + ); + + // ensure URLField is blank + expect(find.byType(TextFormField), findsOneWidget); + expect(find.textContaining('Enter API endpoint '), findsOneWidget); + expect(wasSubmitCalled, false); + + // modify value and press enter + var txtForm = find.byKey(const Key("url-2")); + await tester.enterText(txtForm, 'entering 123'); + await tester.testTextInput.receiveAction(TextInputAction.done); + await tester.pump(); + + // check if value was updated + expect(wasSubmitCalled, true); + }); }