moduleOasRailsmoduleExtractors# Extracts and processes render responses from a given source.moduleRenderResponseExtractorclass<<self# Extracts responses from the provided source string.## @param source [String] The source string containing render calls.# @return [Array<Response>] An array of Response objects extracted from the source.defextract_responses_from_source(specification,source:)render_calls=extract_render_calls(source)return[Builders::ResponseBuilder.new(specification).with_description("No content").with_code(204).build]ifrender_calls.empty?render_calls.map{|render_content,status|process_render_content(specification,render_content.strip,status)}endprivate# Extracts render calls from the source string.## @param source [String] The source string containing render calls.# @return [Array<Array<String, String>>] An array of arrays, each containing render content and status.defextract_render_calls(source)source.scan(/render json: ((?:\{.*?\}|\S+))(?:, status: :(\w+))?(?:,.*?)?$/m)end# Processes the render content and status to build a Response object.## @param content [String] The content extracted from the render call.# @param status [String] The status code associated with the render call.# @return [Response] A Response object based on the processed content and status.defprocess_render_content(specification,content,status)schema,examples=build_schema_and_examples(content)status_int=Utils.status_to_integer(status)content=Builders::ContentBuilder.new(specification,:outgoing).with_schema(schema).with_examples(examples).buildBuilders::ResponseBuilder.new(specification).with_code(status_int).with_description(Utils.get_definition(status_int)).with_content(content).buildend# Builds schema and examples based on the content type.## @param content [String] The content extracted from the render call.# @return [Array<Hash, Hash>] An array where the first element is the schema and the second is the examples.defbuild_schema_and_examples(content)ifcontent.start_with?('{')[Utils.hash_to_json_schema(parse_hash_structure(content)),{}]elseprocess_non_hash_content(content)endrescueStandardError=>eRails.logger.debug("Error building schema: #{e.message}")[{}]end# Processes non-hash content (e.g., model or method calls) to build schema and examples.## @param content [String] The content extracted from the render call.# @return [Array<Hash, Hash>] An array where the first element is the schema and the second is the examples.defprocess_non_hash_content(content)maybe_a_model,errors=content.gsub('@',"").split(".")klass=maybe_a_model.singularize.camelize(:upper).constantizeifklass.ancestors.include?(ActiveRecord::Base)schema=Builders::EsquemaBuilder.build_outgoing_schema(klass:)iftest_singularity(maybe_a_model)build_singular_model_schema_and_examples(maybe_a_model,errors,klass,schema)elsebuild_array_model_schema_and_examples(maybe_a_model,klass,schema)endelse[{}]endend# Builds schema and examples for singular models.## @param maybe_a_model [String] The model name or variable.# @param errors [String, nil] Errors related to the model.# @param klass [Class] The class associated with the model.# @param schema [Hash] The schema for the model.# @return [Array<Hash, Hash>] An array where the first element is the schema and the second is the examples.defbuild_singular_model_schema_and_examples(_maybe_a_model,errors,klass,schema)iferrors.nil?[schema,Spec::MediaType.search_for_examples_in_tests(klass,context: :outgoing)]else# TODO: this is not building the real schema.[{type: "object",properties: {success: {type: "boolean"},errors: {type: "object",additionalProperties: {type: "array",items: {type: "string"}}}}},{}]endend# Builds schema and examples for array models.## @param maybe_a_model [String] The model name or variable.# @param klass [Class] The class associated with the model.# @param schema [Hash] The schema for the model.# @return [Array<Hash, Hash>] An array where the first element is the schema and the second is the examples.defbuild_array_model_schema_and_examples(maybe_a_model,klass,schema)examples={maybe_a_model=>{value: Spec::MediaType.search_for_examples_in_tests(klass,context: :outgoing).values.map{|p|p.dig(:value,maybe_a_model.singularize.to_sym)}}}[{type: "array",items: schema},examples]end# Determines if a string represents a singular model.## @param str [String] The string to test.# @return [Boolean] True if the string is a singular model, false otherwise.deftest_singularity(str)str.pluralize!=str&&str.singularize==strend# Parses a hash literal to determine its structure.## @param hash_literal [String] The hash literal string.# @return [Hash<Symbol, String>] A hash representing the structure of the input.defparse_hash_structure(hash_literal)structure={}hash_literal.scan(/(\w+):\s*(\S+)/)do|key,value|structure[key.to_sym]=casevaluewhen'true','false''Boolean'when/^\d+$/'Number'else'Object'endendstructureendendendendend