From b5a76b6fc2f399af7baec0f2f689613c0ede82f2 Mon Sep 17 00:00:00 2001 From: Osose Ewaleifoh <83099348+osose-e@users.noreply.github.com> Date: Tue, 30 Aug 2022 10:39:39 -0700 Subject: [PATCH] Updates to refiners and writers (#1795) * Updates to refiners and writers * adding accept field to header of http request * Updated tests * Fixed passing field deserializer items * fixes null request configuration * Updated changelog --- CHANGELOG.md | 5 +- .../net_http_request_adapter.rb | 5 +- .../json_parse_node.rb | 2 +- .../spec/files/email_address.rb | 4 +- .../spec/files/entity.rb | 2 +- .../spec/files/item_body.rb | 4 +- .../spec/files/message.rb | 46 +++++++++---------- .../spec/files/messages_response.rb | 4 +- .../spec/files/outlook_item.rb | 8 ++-- .../spec/files/recipient.rb | 2 +- .../CodeRenderers/CodeRenderer.cs | 2 +- src/Kiota.Builder/Refiners/RubyRefiner.cs | 4 +- .../Ruby/CodeClassDeclarationWriter.cs | 4 +- .../Writers/Ruby/CodeMethodWriter.cs | 21 ++++++--- .../Writers/Ruby/CodeMethodWriterTests.cs | 2 +- 15 files changed, 62 insertions(+), 53 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 61de114c1b..aafdf7e961 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,11 +10,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Added none output formatter to CLI commons. (Shell) +- Added 'Accept' field of http request header in Ruby. [#1660](https://github.com/microsoft/kiota/issues/1660) ### Changed - Fixed a bug to properly add request headers to Nethttp requests in Ruby. - Fixed a bug to properly reject invalid URLs in Ruby. - +- Fixed an issue with require statements being generated instead of require relative in Ruby. +- Updated AdditionDataHolder with the correct namespace. (Ruby) +- Removed/fixed passing in the current instance to fields deserializers in Ruby. [#1663](https://github.com/microsoft/kiota/issues/1663) - Fix issue with duplicate variable declaration in command handlers (Shell) - Update namespace qualification algorithm (helps in resolving when a type name appears in multiple namespaces) to use case insensitive string comparison (CSharp). diff --git a/http/ruby/nethttp/microsoft_kiota_nethttplibrary/lib/microsoft_kiota_nethttplibrary/net_http_request_adapter.rb b/http/ruby/nethttp/microsoft_kiota_nethttplibrary/lib/microsoft_kiota_nethttplibrary/net_http_request_adapter.rb index c2380746d7..791b904363 100644 --- a/http/ruby/nethttp/microsoft_kiota_nethttplibrary/lib/microsoft_kiota_nethttplibrary/net_http_request_adapter.rb +++ b/http/ruby/nethttp/microsoft_kiota_nethttplibrary/lib/microsoft_kiota_nethttplibrary/net_http_request_adapter.rb @@ -49,10 +49,7 @@ def send_async(request_info, type, response_handler) http = @client.new(uri.host, uri.port) http.use_ssl = true http.verify_mode = OpenSSL::SSL::VERIFY_PEER - - request.add_field 'Authorization', request_info.headers['Authorization'] - request.add_field 'Content-Type', 'application/json' - request.add_field 'Accept', 'application/json' + request.headers = request_info.headers response = http.request(request) if response_handler diff --git a/serialization/ruby/json/microsoft_kiota_serialization/lib/microsoft_kiota_serialization/json_parse_node.rb b/serialization/ruby/json/microsoft_kiota_serialization/lib/microsoft_kiota_serialization/json_parse_node.rb index e98e17ee5c..131bfe5d2b 100644 --- a/serialization/ruby/json/microsoft_kiota_serialization/lib/microsoft_kiota_serialization/json_parse_node.rb +++ b/serialization/ruby/json/microsoft_kiota_serialization/lib/microsoft_kiota_serialization/json_parse_node.rb @@ -98,7 +98,7 @@ def assign_field_values(item) @current_node.each do |k, v| deserializer = fields[k] if deserializer - deserializer.call(item, JsonParseNode.new(v)) + deserializer.call(JsonParseNode.new(v)) elsif item.additional_data item.additional_data[k] = v else diff --git a/serialization/ruby/json/microsoft_kiota_serialization/spec/files/email_address.rb b/serialization/ruby/json/microsoft_kiota_serialization/spec/files/email_address.rb index be9ea47754..ffd7563295 100644 --- a/serialization/ruby/json/microsoft_kiota_serialization/spec/files/email_address.rb +++ b/serialization/ruby/json/microsoft_kiota_serialization/spec/files/email_address.rb @@ -39,8 +39,8 @@ def name ## def get_field_deserializers() return { - "address" => lambda {|o, n| o.address = n.get_string_value() }, - "name" => lambda {|o, n| o.name = n.get_string_value() }, + "address" => lambda {|n| @address = n.get_string_value() }, + "name" => lambda {|n| @name = n.get_string_value() }, } end ## diff --git a/serialization/ruby/json/microsoft_kiota_serialization/spec/files/entity.rb b/serialization/ruby/json/microsoft_kiota_serialization/spec/files/entity.rb index f510c04d59..fe3131c6e2 100644 --- a/serialization/ruby/json/microsoft_kiota_serialization/spec/files/entity.rb +++ b/serialization/ruby/json/microsoft_kiota_serialization/spec/files/entity.rb @@ -29,7 +29,7 @@ def id ## def get_field_deserializers() return { - "id" => lambda {|o, n| o.id = n.get_string_value() }, + "id" => lambda {|n| @id = n.get_string_value() }, } end ## diff --git a/serialization/ruby/json/microsoft_kiota_serialization/spec/files/item_body.rb b/serialization/ruby/json/microsoft_kiota_serialization/spec/files/item_body.rb index f0b0c9d03f..1ce32c9e94 100644 --- a/serialization/ruby/json/microsoft_kiota_serialization/spec/files/item_body.rb +++ b/serialization/ruby/json/microsoft_kiota_serialization/spec/files/item_body.rb @@ -37,8 +37,8 @@ def content_type ## def get_field_deserializers() return { - "content" => lambda {|o, n| o.content = n.get_string_value() }, - "contentType" => lambda {|o, n| o.content_type = n.get_enum_value(Files::BodyType) }, + "content" => lambda {|n| @content = n.get_string_value() }, + "contentType" => lambda {|n| @content_type = n.get_enum_value(Files::BodyType) }, } end ## diff --git a/serialization/ruby/json/microsoft_kiota_serialization/spec/files/message.rb b/serialization/ruby/json/microsoft_kiota_serialization/spec/files/message.rb index a5b6699050..ee7e92699c 100644 --- a/serialization/ruby/json/microsoft_kiota_serialization/spec/files/message.rb +++ b/serialization/ruby/json/microsoft_kiota_serialization/spec/files/message.rb @@ -300,29 +300,29 @@ def web_link ## def get_field_deserializers() return super.merge({ - "guidId" => lambda {|o, n| o.guid_id = n.get_guid_value() }, - "bccRecipients" => lambda {|o, n| o.bcc_recipients = n.get_collection_of_object_values(Files::Recipient) }, - "body" => lambda {|o, n| o.body = n.get_object_value(Files::ItemBody) }, - "bodyPreview" => lambda {|o, n| o.body_preview = n.get_string_value() }, - "ccRecipients" => lambda {|o, n| o.cc_recipients = n.get_collection_of_object_values(Files::Recipient) }, - "conversationId" => lambda {|o, n| o.conversation_id = n.get_string_value() }, - "conversationIndex" => lambda {|o, n| o.conversation_index = n.get_string_value() }, - "from" => lambda {|o, n| o.from = n.get_object_value(Files::Recipient) }, - "hasAttachments" => lambda {|o, n| o.has_attachments = n.get_boolean_value() }, - "internetMessageId" => lambda {|o, n| o.internet_message_id = n.get_string_value() }, - "isDeliveryReceiptRequested" => lambda {|o, n| o.is_delivery_receipt_requested = n.get_boolean_value() }, - "isDraft" => lambda {|o, n| o.is_draft = n.get_boolean_value() }, - "isRead" => lambda {|o, n| o.is_read = n.get_boolean_value() }, - "isReadReceiptRequested" => lambda {|o, n| o.is_read_receipt_requested = n.get_boolean_value() }, - "parentFolderId" => lambda {|o, n| o.parent_folder_id = n.get_string_value() }, - "receivedDateTime" => lambda {|o, n| o.received_date_time = n.get_date_time_value() }, - "replyTo" => lambda {|o, n| o.reply_to = n.get_collection_of_object_values(Files::Recipient) }, - "sender" => lambda {|o, n| o.sender = n.get_object_value(Files::Recipient) }, - "sentDateTime" => lambda {|o, n| o.sent_date_time = n.get_date_time_value() }, - "subject" => lambda {|o, n| o.subject = n.get_string_value() }, - "toRecipients" => lambda {|o, n| o.to_recipients = n.get_collection_of_object_values(Files::Recipient) }, - "uniqueBody" => lambda {|o, n| o.unique_body = n.get_object_value(Files::ItemBody) }, - "webLink" => lambda {|o, n| o.web_link = n.get_string_value() }, + "guidId" => lambda {|n| @guid_id = n.get_guid_value() }, + "bccRecipients" => lambda {|n| @bcc_recipients = n.get_collection_of_object_values(Files::Recipient) }, + "body" => lambda {|n| @body = n.get_object_value(Files::ItemBody) }, + "bodyPreview" => lambda {|n| @body_preview = n.get_string_value() }, + "ccRecipients" => lambda {|n| @cc_recipients = n.get_collection_of_object_values(Files::Recipient) }, + "conversationId" => lambda {|n| @conversation_id = n.get_string_value() }, + "conversationIndex" => lambda {|n| @conversation_index = n.get_string_value() }, + "from" => lambda {|n| @from = n.get_object_value(Files::Recipient) }, + "hasAttachments" => lambda {|n| @has_attachments = n.get_boolean_value() }, + "internetMessageId" => lambda {|n| @internet_message_id = n.get_string_value() }, + "isDeliveryReceiptRequested" => lambda {|n| @is_delivery_receipt_requested = n.get_boolean_value() }, + "isDraft" => lambda {|n| @is_draft = n.get_boolean_value() }, + "isRead" => lambda {|n| @is_read = n.get_boolean_value() }, + "isReadReceiptRequested" => lambda {|n| @is_read_receipt_requested = n.get_boolean_value() }, + "parentFolderId" => lambda {|n| @parent_folder_id = n.get_string_value() }, + "receivedDateTime" => lambda {|n| @received_date_time = n.get_date_time_value() }, + "replyTo" => lambda {|n| @reply_to = n.get_collection_of_object_values(Files::Recipient) }, + "sender" => lambda {|n| @sender = n.get_object_value(Files::Recipient) }, + "sentDateTime" => lambda {|n| @sent_date_time = n.get_date_time_value() }, + "subject" => lambda {|n| @subject = n.get_string_value() }, + "toRecipients" => lambda {|n| @to_recipients = n.get_collection_of_object_values(Files::Recipient) }, + "uniqueBody" => lambda {|n| @unique_body = n.get_object_value(Files::ItemBody) }, + "webLink" => lambda {|n| @web_link = n.get_string_value() }, }) end ## diff --git a/serialization/ruby/json/microsoft_kiota_serialization/spec/files/messages_response.rb b/serialization/ruby/json/microsoft_kiota_serialization/spec/files/messages_response.rb index d260e0bb9f..cc94434c4d 100644 --- a/serialization/ruby/json/microsoft_kiota_serialization/spec/files/messages_response.rb +++ b/serialization/ruby/json/microsoft_kiota_serialization/spec/files/messages_response.rb @@ -35,8 +35,8 @@ def value ## def get_field_deserializers() return { - "@odata.nextLink" => lambda {|o, n| o.next_link = n.get_string_value() }, - "value" => lambda {|o, n| o.value = n.get_collection_of_object_values(Files::Message) }, + "@odata.nextLink" => lambda {|n| @next_link = n.get_string_value() }, + "value" => lambda {|n| @value = n.get_collection_of_object_values(Files::Message) }, } end ## diff --git a/serialization/ruby/json/microsoft_kiota_serialization/spec/files/outlook_item.rb b/serialization/ruby/json/microsoft_kiota_serialization/spec/files/outlook_item.rb index bc2062c7b7..d22b6f518b 100644 --- a/serialization/ruby/json/microsoft_kiota_serialization/spec/files/outlook_item.rb +++ b/serialization/ruby/json/microsoft_kiota_serialization/spec/files/outlook_item.rb @@ -50,10 +50,10 @@ def last_modified_date_time ## def get_field_deserializers() return super.merge({ - "categories" => lambda {|o, n| o.categories = n.get_collection_of_primitive_values(String) }, - "changeKey" => lambda {|o, n| o.change_key = n.get_string_value() }, - "createdDateTime" => lambda {|o, n| o.created_date_time = n.get_date_value() }, - "lastModifiedDateTime" => lambda {|o, n| o.last_modified_date_time = n.get_date_value() }, + "categories" => lambda {|n| @categories = n.get_collection_of_primitive_values(String) }, + "changeKey" => lambda {|n| @change_key = n.get_string_value() }, + "createdDateTime" => lambda {|n| @created_date_time = n.get_date_value() }, + "lastModifiedDateTime" => lambda {|n| @last_modified_date_time = n.get_date_value() }, }) end ## diff --git a/serialization/ruby/json/microsoft_kiota_serialization/spec/files/recipient.rb b/serialization/ruby/json/microsoft_kiota_serialization/spec/files/recipient.rb index 229b6c9a46..a384ab235f 100644 --- a/serialization/ruby/json/microsoft_kiota_serialization/spec/files/recipient.rb +++ b/serialization/ruby/json/microsoft_kiota_serialization/spec/files/recipient.rb @@ -27,7 +27,7 @@ def email_address ## def get_field_deserializers() return { - "emailAddress" => lambda {|o, n| o.email_address = n.get_object_value(Files::EmailAddress) }, + "emailAddress" => lambda {|n| @email_address = n.get_object_value(Files::EmailAddress) }, } end ## diff --git a/src/Kiota.Builder/CodeRenderers/CodeRenderer.cs b/src/Kiota.Builder/CodeRenderers/CodeRenderer.cs index b19c34d869..32ce98ed97 100644 --- a/src/Kiota.Builder/CodeRenderers/CodeRenderer.cs +++ b/src/Kiota.Builder/CodeRenderers/CodeRenderer.cs @@ -52,7 +52,7 @@ private async Task RenderBarrel(LanguageWriter writer, CodeNamespace root, CodeN if (!string.IsNullOrEmpty(codeNamespace.Name) && !string.IsNullOrEmpty(root.Name) && _configuration.ShouldWriteNamespaceIndices && - !_configuration.ClientNamespaceName.Contains(codeNamespace.Name, StringComparison.OrdinalIgnoreCase) && + !_configuration.ClientNamespaceName.StartsWith(codeNamespace.Name, StringComparison.OrdinalIgnoreCase) && ShouldRenderNamespaceFile(codeNamespace)) { await RenderCodeNamespaceToSingleFileAsync(writer, codeNamespace, writer.PathSegmenter.GetPath(root, codeNamespace), cancellationToken); diff --git a/src/Kiota.Builder/Refiners/RubyRefiner.cs b/src/Kiota.Builder/Refiners/RubyRefiner.cs index 7cae312c41..e8e32063a7 100644 --- a/src/Kiota.Builder/Refiners/RubyRefiner.cs +++ b/src/Kiota.Builder/Refiners/RubyRefiner.cs @@ -157,7 +157,7 @@ protected void AddNamespaceModuleImports(CodeElement current, string clientNames currentClass.AddUsing(new CodeUsing { Name = usingName, Declaration = new CodeType { - IsExternal = true, + IsExternal = false, Name = $"{(string.IsNullOrEmpty(prefix) ? "./" : prefix)}{usingName}", } }); @@ -167,7 +167,7 @@ protected void AddNamespaceModuleImports(CodeElement current, string clientNames CrawlTree(current, c => AddNamespaceModuleImports(c, clientNamespaceName)); } private static void CorrectImplements(ProprietableBlockDeclaration block) { - block.Implements.Where(x => "IAdditionalDataHolder".Equals(x.Name, StringComparison.OrdinalIgnoreCase)).ToList().ForEach(x => x.Name = x.Name[1..]); // skipping the I + block.Implements.Where(x => "IAdditionalDataHolder".Equals(x.Name, StringComparison.OrdinalIgnoreCase)).ToList().ForEach(x => x.Name = "MicrosoftKiotaAbstractions::AdditionalDataHolder"); } } } diff --git a/src/Kiota.Builder/Writers/Ruby/CodeClassDeclarationWriter.cs b/src/Kiota.Builder/Writers/Ruby/CodeClassDeclarationWriter.cs index fbd09213b3..b5bf37d539 100644 --- a/src/Kiota.Builder/Writers/Ruby/CodeClassDeclarationWriter.cs +++ b/src/Kiota.Builder/Writers/Ruby/CodeClassDeclarationWriter.cs @@ -26,7 +26,9 @@ public override void WriteCodeElement(ClassDeclaration codeElement, LanguageWrit foreach (var relativePath in codeElement.Usings .Where(x => !x.IsExternal) - .Select(x => relativeImportManager.GetRelativeImportPathForUsing(x, currentNamespace)) + .Select(x => x.Declaration?.Name?.StartsWith('.') ?? false ? + (string.Empty, string.Empty, x.Declaration.Name) : + relativeImportManager.GetRelativeImportPathForUsing(x, currentNamespace)) .Select(x => x.Item3) .Distinct() .OrderBy(x => x)) diff --git a/src/Kiota.Builder/Writers/Ruby/CodeMethodWriter.cs b/src/Kiota.Builder/Writers/Ruby/CodeMethodWriter.cs index e5f5699259..2765084272 100644 --- a/src/Kiota.Builder/Writers/Ruby/CodeMethodWriter.cs +++ b/src/Kiota.Builder/Writers/Ruby/CodeMethodWriter.cs @@ -136,7 +136,7 @@ private void WriteDeserializerBody(CodeClass parentClass, LanguageWriter writer) writer.WriteLine($"return {{"); writer.IncreaseIndent(); foreach(var otherProp in parentClass.GetPropertiesOfKind(CodePropertyKind.Custom)) { - writer.WriteLine($"\"{otherProp.SerializationName ?? otherProp.Name.ToFirstCharacterLowerCase()}\" => lambda {{|o, n| o.{otherProp.Name.ToSnakeCase()} = n.{GetDeserializationMethodName(otherProp.Type)} }},"); + writer.WriteLine($"\"{otherProp.SerializationName ?? otherProp.Name.ToFirstCharacterLowerCase()}\" => lambda {{|n| @{otherProp.Name.ToSnakeCase()} = n.{GetDeserializationMethodName(otherProp.Type)} }},"); } writer.DecreaseIndent(); if(parentClass.StartBlock.Inherits != null) @@ -172,7 +172,7 @@ private void WriteRequestExecutorBody(CodeMethod codeElement, RequestParams requ writer.WriteLine(")"); var isStream = conventions.StreamTypeName.Equals(StringComparison.OrdinalIgnoreCase); var genericTypeForSendMethod = GetSendRequestMethodName(isStream); - writer.WriteLine($"return @http_core.{genericTypeForSendMethod}(request_info, {returnType}, response_handler)"); + writer.WriteLine($"return @request_adapter.{genericTypeForSendMethod}(request_info, {returnType}, response_handler)"); } private void WriteRequestGeneratorBody(CodeMethod codeElement, RequestParams requestParams, CodeClass parentClass, LanguageWriter writer) { @@ -185,15 +185,22 @@ private void WriteRequestGeneratorBody(CodeMethod codeElement, RequestParams req $"request_info.url_template = {GetPropertyCall(urlTemplateProperty, "''")}", $"request_info.path_parameters = {GetPropertyCall(urlTemplateParamsProperty, "''")}", $"request_info.http_method = :{codeElement.HttpMethod?.ToString().ToUpperInvariant()}"); + if(codeElement.AcceptedResponseTypes.Any()) + writer.WriteLine($"request_info.headers['Accept'] = '{string.Join(", ", codeElement.AcceptedResponseTypes)}'"); if (requestParams.requestConfiguration != null) { var queryString = requestParams.QueryParameters; var headers = requestParams.Headers; // TODO add options handling - if(headers != null) - writer.WriteLine($"request_info.set_headers_from_raw_object({requestParams.requestConfiguration.Name.ToSnakeCase()}.{headers.Name.ToSnakeCase()})"); - if(queryString != null) - writer.WriteLines($"request_info.set_query_string_parameters_from_raw_object({requestParams.requestConfiguration.Name.ToSnakeCase()}.{queryString.Name.ToSnakeCase()})"); + if(headers != null || queryString != null) { + writer.WriteLine($"unless {requestParams.requestConfiguration.Name.ToSnakeCase()}.nil?"); + writer.IncreaseIndent(); + if(headers != null) + writer.WriteLine($"request_info.set_headers_from_raw_object({requestParams.requestConfiguration.Name.ToSnakeCase()}.{headers.Name.ToSnakeCase()})"); + if(queryString != null) + writer.WriteLines($"request_info.set_query_string_parameters_from_raw_object({requestParams.requestConfiguration.Name.ToSnakeCase()}.{queryString.Name.ToSnakeCase()})"); + writer.CloseBlock("end"); + } if(requestParams.requestBody != null) { if(requestParams.requestBody.Type.Name.Equals(conventions.StreamTypeName, StringComparison.OrdinalIgnoreCase)) writer.WriteLine($"request_info.set_stream_content({requestParams.requestBody.Name})"); @@ -201,7 +208,7 @@ private void WriteRequestGeneratorBody(CodeMethod codeElement, RequestParams req writer.WriteLine($"request_info.set_content_from_parsable(self.{requestAdapterProperty.Name.ToSnakeCase()}, \"{codeElement.RequestBodyContentType}\", {requestParams.requestBody.Name})"); } } - writer.WriteLine("return request_info;"); + writer.WriteLine("return request_info"); } private static string GetPropertyCall(CodeProperty property, string defaultValue) => property == null ? defaultValue : $"@{property.Name.ToSnakeCase()}"; private void WriteSerializerBody(CodeClass parentClass, LanguageWriter writer) { diff --git a/tests/Kiota.Builder.Tests/Writers/Ruby/CodeMethodWriterTests.cs b/tests/Kiota.Builder.Tests/Writers/Ruby/CodeMethodWriterTests.cs index dbbcd8cc54..372d0c316c 100644 --- a/tests/Kiota.Builder.Tests/Writers/Ruby/CodeMethodWriterTests.cs +++ b/tests/Kiota.Builder.Tests/Writers/Ruby/CodeMethodWriterTests.cs @@ -208,7 +208,7 @@ public void WritesRequestGeneratorBody() { Assert.Contains("http_method = :GET", result); Assert.Contains("set_query_string_parameters_from_raw_object", result); Assert.Contains("set_content_from_parsable", result); - Assert.Contains("return request_info;", result); + Assert.Contains("return request_info", result); } [Fact] public void WritesInheritedDeSerializerBody() {