describe Fakeit::Openapi::Example do
  let(:schema) { load_schema("array_schema") }

  let(:use_static) { double("lambda", :[] => false) }
  let(:example_options) { {use_static:, depth: 0, property: "static_array"} }

  it "calls use_static" do
    expect(use_static).to receive(:[]).with(type: "array", property: "static_array")

    schema.properties["array"].to_example(example_options)
  end

  context "static" do
    let(:use_static) { double("lambda", :[] => true) }

    it "default array example" do
      array = schema.properties["array"].to_example(example_options)

      expect(array).to be_a_kind_of(Array)
      expect(array.size).to be(1)
    end

    it "minItems and maxItems example" do
      array = schema.properties["array_min_max"].to_example(example_options)

      expect(array.size).to be(5)
    end

    it "generates at least 1 item" do
      array = schema.properties["array_unique_min_0"].to_example(example_options)

      expect(array.size).to be(1)
    end
  end

  context "random" do
    it "first level array example" do
      expect(Faker::Number).to receive(:between).with(from: 1, to: 10).and_return(3)

      array = schema.properties["array"].to_example(example_options)

      expect(array).to be_a_kind_of(Array)
      expect(array.size).to be(3)
    end

    it "nested level array example" do
      expect(Faker::Number).to receive(:between).with(from: 1, to: 3).and_return(1)

      array = schema.properties["array"].to_example(**example_options, depth: 1)

      expect(array).to be_a_kind_of(Array)
      expect(array.size).to be(1)
    end

    it "minItems and maxItems example" do
      expect(Faker::Number).to receive(:between).with(from: 5, to: 10).and_return(5)

      array = schema.properties["array_min_max"].to_example(example_options)

      expect(array.size).to be(5)
    end

    context "uniqueItems" do
      it "tries to generate minimum items to avoid duplication" do
        array = schema.properties["array_unique"].to_example(example_options)

        expect(array.size).to be(2)
      end

      it "retries for unique results" do
        array_schema = schema.properties["array_unique"]
        allow(array_schema.items).to receive(:to_example).and_return(1, 1, 2)

        array = array_schema.to_example(example_options)

        expect(array).to eq([1, 2])
      end

      it "retries for double of the expected size at most" do
        array_schema = schema.properties["array_unique"]
        allow(array_schema.items).to receive(:to_example).and_return(1, 1, 1, 1)

        array = array_schema.to_example(example_options)

        expect(array).to eq([1, 1])
      end

      it "tries to generate at least 1 item" do
        array = schema.properties["array_unique_min_0"].to_example(example_options)

        expect(array.size).to be(1)
      end
    end
  end
end
