<commit_before>require "spec_helper"

require "sequel_mapper/association_proxy"

RSpec.describe SequelMapper::AssociationProxy do
  let(:proxy) {
    SequelMapper::AssociationProxy.new(lazy_enum)
  }

  let(:lazy_enum) { data_set.each.lazy }
  let(:data_set) { (0..9) }

  def id
    ->(x) { x }
  end

  it "is Enumerable" do
    expect(proxy).to be_a(Enumerable)
  end

  describe "#to_a" do
    it "is equivalent to the original enumeration" do
      expect(proxy.map(&id)).to eq(data_set.to_a)
    end
  end

  describe "#each" do
    context "when called with a block" do
      it "returns self" do
        expect(proxy.each(&id)).to eq(proxy)
      end

      it "yields each element to the block" do
        yielded = []

        proxy.each do |element|
          yielded.push(element)
        end

        expect(yielded).to eq(data_set.to_a)
      end

      context "when calling each more than once" do
        before do
          proxy.each { |x| nil }
          proxy.each { |x| nil }
        end

        it "rewinds the enumeration on each call" do
          expect(proxy.map(&id)).to eq(data_set.to_a)
        end
      end
    end

    context "when called without a block" do
      it "returns an enumerator" do
        expect(proxy.each).to be_a(Enumerator)
      end
    end
  end

  describe "#remove" do
    it "returns self" do
      expect(proxy.remove(3)).to be(proxy)
    end

    context "after removing a element from the enumeration" do
      before do
        proxy.remove(3)
      end

      it "skips that element in the enumeration" do
        expect(proxy.map(&id)).to eq([0,1,2,4,5,6,7,8,9])
      end
    end
  end

  describe "#push" do
    context "after pushing another element into the enumeration" do
      before do
        proxy.push(new_value)
      end

      let(:new_value) { double(:new_value) }

      it "does not alter the other elements" do
        expect(proxy.map(&id)[0..-2]).to eq([0,1,2,3,4,5,6,7,8,9])
      end

      it "appends the element to the enumeration" do
        expect(proxy.map(&id).last).to eq(new_value)
      end
    end
  end

  describe "#loaded?" do
    context "before an item in the collection has been yielded" do
      it "is not loaded" do
        expect(proxy.loaded?).to be(false)
      end
    end

    context "after the collection has been mapped" do
      before do
        proxy.map(&id)
      end

      # TODO: This seems like a bug :(
      it "is loaded" do
        expect(proxy.loaded?).to be(true)
      end
    end

    context "after calling first" do
      before do
        proxy.first
      end

      it "is loaded" do
        expect(proxy.loaded?).to be(true)
      end
    end

    context "after iterating over the collection" do
      before do
        proxy.each do |obj|
          # NO OP
        end
      end

      it "is loaded" do
        expect(proxy.loaded?).to be(true)
      end
    end
  end<commit_msg>Association proxies are not lazy to the consumer<commit_after>require "spec_helper"

require "sequel_mapper/association_proxy"

RSpec.describe SequelMapper::AssociationProxy do
  let(:proxy) {
    SequelMapper::AssociationProxy.new(lazy_enum)
  }

  let(:lazy_enum) { data_set.each.lazy }
  let(:data_set) { (0..9) }

  def id
    ->(x) { x }
  end

  it "is Enumerable" do
    expect(proxy).to be_a(Enumerable)
  end

  describe "#to_a" do
    it "is equivalent to the original enumeration" do
      expect(proxy.map(&id)).to eq(data_set.to_a)
    end
  end

  describe "#each" do
    context "when called with a block" do
      it "returns self" do
        expect(proxy.each(&id)).to eq(proxy)
      end

      it "yields each element to the block" do
        yielded = []

        proxy.each do |element|
          yielded.push(element)
        end

        expect(yielded).to eq(data_set.to_a)
      end

      context "when calling each more than once" do
        before do
          proxy.each { |x| nil }
          proxy.each { |x| nil }
        end

        it "rewinds the enumeration on each call" do
          expect(proxy.map(&id)).to eq(data_set.to_a)
        end
      end
    end

    context "when called without a block" do
      it "returns an enumerator" do
        expect(proxy.each).to be_a(Enumerator)
      end
    end
  end

  describe "#remove" do
    it "returns self" do
      expect(proxy.remove(3)).to be(proxy)
    end

    context "after removing a element from the enumeration" do
      before do
        proxy.remove(3)
      end

      it "skips that element in the enumeration" do
        expect(proxy.map(&id)).to eq([0,1,2,4,5,6,7,8,9])
      end
    end
  end

  describe "#push" do
    context "after pushing another element into the enumeration" do
      before do
        proxy.push(new_value)
      end

      let(:new_value) { double(:new_value) }

      it "does not alter the other elements" do
        expect(proxy.map(&id)[0..-2]).to eq([0,1,2,3,4,5,6,7,8,9])
      end

      it "appends the element to the enumeration" do
        expect(proxy.map(&id).last).to eq(new_value)
      end
    end
  end

  describe "#loaded?" do
    context "before an item in the collection has been yielded" do
      it "is not loaded" do
        expect(proxy.loaded?).to be(false)
      end
    end

    context "after the collection has been mapped" do
      before do
        proxy.map(&id)
      end

      it "is loaded" do
        expect(proxy.loaded?).to be(true)
      end
    end

    context "after calling first" do
      before do
        proxy.first
      end

      it "is loaded" do
        expect(proxy.loaded?).to be(true)
      end
    end

    context "after iterating over the collection" do
      before do
        proxy.each do |obj|
          # NO OP
        end
      end

      it "is loaded" do
        expect(proxy.loaded?).to be(true)
      end
    end
  end
{'fraction_non_alphanumeric': 0.09766963673749143, 'fraction_numerical': 0.008567511994516792, 'mean_word_length': 2.0401041666666666, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1359915', 'n_tokens_mistral': 1919, 'n_tokens_neox': 1833, 'n_words': 580}