|
| 1 | +require 'aireview/output_schemas' |
| 2 | + |
| 3 | +RSpec.describe 'Aireview output schemas' do |
| 4 | + def schema_for(schema_class) |
| 5 | + schema_class.new.to_json_schema.fetch(:schema) |
| 6 | + end |
| 7 | + |
| 8 | + it 'defines generate fields, enums, nullable line, and candidate limit' do |
| 9 | + schema = schema_for(Aireview::GenerateOutputSchema) |
| 10 | + candidates = schema.dig(:properties, :candidates) |
| 11 | + candidate = candidates.fetch(:items) |
| 12 | + properties = candidate.fetch(:properties) |
| 13 | + |
| 14 | + expect(schema.fetch(:required)).to contain_exactly(:summary, :candidates) |
| 15 | + expect(schema.fetch(:additionalProperties)).to be(false) |
| 16 | + expect(schema.dig(:properties, :summary, :type)).to eq('string') |
| 17 | + expect(candidates.fetch(:type)).to eq('array') |
| 18 | + expect(candidates.fetch(:maxItems)).to eq(3) |
| 19 | + expect(candidate.fetch(:required)).to contain_exactly( |
| 20 | + :id, :file, :line, :quoted_code, :problem, :why, :suggestion, :category, :severity |
| 21 | + ) |
| 22 | + expect(candidate.fetch(:additionalProperties)).to be(false) |
| 23 | + expect(properties.values_at(:id, :file, :quoted_code, :problem, :why, :suggestion).map { |field| field[:type] }) |
| 24 | + .to all(eq('string')) |
| 25 | + expect(properties.dig(:line, :anyOf).map { |type| type.fetch(:type) }).to contain_exactly('integer', 'null') |
| 26 | + expect(properties.dig(:category, :enum)).to eq(Aireview::OutputSchemaValues::CATEGORIES) |
| 27 | + expect(properties.dig(:severity, :enum)).to eq(Aireview::OutputSchemaValues::SEVERITIES) |
| 28 | + end |
| 29 | + |
| 30 | + it 'defines critique decision and optional refinement constraints' do |
| 31 | + schema = schema_for(Aireview::CritiqueOutputSchema) |
| 32 | + verdict = schema.dig(:properties, :verdicts, :items) |
| 33 | + properties = verdict.fetch(:properties) |
| 34 | + refinement = properties.fetch(:refinement) |
| 35 | + |
| 36 | + expect(schema.fetch(:required)).to contain_exactly(:verdicts) |
| 37 | + expect(schema.fetch(:additionalProperties)).to be(false) |
| 38 | + expect(schema.dig(:properties, :verdicts, :type)).to eq('array') |
| 39 | + expect(verdict.fetch(:required)).to contain_exactly(:id, :decision, :reason) |
| 40 | + expect(verdict.fetch(:additionalProperties)).to be(false) |
| 41 | + expect(properties.values_at(:id, :decision, :reason).map { |field| field[:type] }).to all(eq('string')) |
| 42 | + expect(properties.dig(:decision, :enum)).to eq(Aireview::OutputSchemaValues::DECISIONS) |
| 43 | + expect(refinement.fetch(:additionalProperties)).to be(false) |
| 44 | + expect(refinement.fetch(:required)).to contain_exactly(:problem, :why, :suggestion, :category, :severity) |
| 45 | + expect(refinement.dig(:properties, :category, :enum)).to eq(Aireview::OutputSchemaValues::CATEGORIES) |
| 46 | + expect(refinement.dig(:properties, :severity, :enum)).to eq(Aireview::OutputSchemaValues::SEVERITIES) |
| 47 | + end |
| 48 | +end |
0 commit comments