229 lines · 6.9 KB · Ruby
RawDownload
require_relative '../../../test_helper'require_relative '../../../../lib/docs' class DocsEntryIndexTest < Minitest::Spec  let :entry do    Docs::Entry.new 'name', 'path', 'type'  end   let :index do    Docs::EntryIndex.new  end   describe "#entries" do    it "returns an Array" do      assert_instance_of Array, index.entries    end  end   describe "#types" do    it "returns a hash" do      assert_instance_of Hash, index.types    end  end   describe "#add" do    it "stores an entry" do      index.add(entry)      assert_includes index.entries, entry    end     it "stores an array of entries" do      entries = [        Docs::Entry.new('one', 'path', 'type'),        Docs::Entry.new('two', 'path', 'type')      ]       index.add(entries)      assert_equal entries, index.entries    end     it "duplicates the entry" do      index.add(entry)      refute_same entry, index.entries.first    end     it "doesn't store the root entry" do      mock(entry).root? { true }      index.add(entry)      assert_empty index.entries      assert_empty index.types    end     it "doesn't store the same entry twice" do      2.times { index.add(entry.dup) }      assert_equal [entry], index.entries    end     it "creates and indexes the type" do      index.add Docs::Entry.new('one', 'path', 'a')      index.add Docs::Entry.new('two', 'path', 'b')      index.add Docs::Entry.new('three', 'path', 'b')      assert_equal ['a', 'b'], index.types.keys      assert_instance_of Docs::Type, index.types['a']    end     it "doesn't index the nil type" do      entry.type = nil; index.add(entry)      assert_empty index.types    end     it "increments the type's count" do      index.add Docs::Entry.new('one', 'path', 'type')      index.add Docs::Entry.new('two', 'path', 'type')      assert_equal 2, index.types['type'].count    end  end   describe "#empty? / #blank? / #present?" do    it "is #empty? and #blank? when no entries have been added" do      assert index.empty?      assert index.blank?      refute index.present?    end     it "is #present? when an entry has been added" do      index.add(entry)      refute index.empty?      refute index.blank?      assert index.present?    end  end   describe "#as_json" do    it "returns a Hash" do      assert_instance_of Hash, index.as_json    end     describe ":entries" do      it "is an empty array by default" do        assert_instance_of Array, index.as_json[:entries]      end       it "includes the json representation of the #entries" do        index.add one = Docs::Entry.new('one', 'path', 'type')        index.add two = Docs::Entry.new('two', 'path', 'type')        assert_equal [one.as_json, two.as_json], index.as_json[:entries]      end       it "is sorted by name, case-insensitive" do        entry.name = 'B'; index.add(entry)        entry.name = 'a'; index.add(entry)        entry.name = 'c'; index.add(entry)        assert_equal ['a', 'B', 'c'], index.as_json[:entries].map { |e| e[:name] }      end       it "sorts numbered names" do        entry.name = '4.2.2. Test'; index.add(entry)        entry.name = '4.20. Test'; index.add(entry)        entry.name = '4.3. Test'; index.add(entry)        entry.name = '4. Test'; index.add(entry)        entry.name = '2 Test'; index.add(entry)        entry.name = 'Test'; index.add(entry)        assert_equal ['4. Test', '4.2.2. Test', '4.3. Test', '4.20. Test', '2 Test', 'Test'], index.as_json[:entries].map { |e| e[:name] }      end    end     describe ":types" do      it "is an empty array by default" do        assert_instance_of Array, index.as_json[:types]      end       it "includes the json representation of the #types" do        type = Docs::Type.new 'one', 1        entry.type = 'one'; index.add(entry)        assert_equal type.as_json, index.as_json[:types].first      end       it "is sorted by name, case-insensitive" do        entry.type = 'B'; index.add(entry)        entry.type = 'a'; index.add(entry)        entry.type = 'c'; index.add(entry)        assert_equal ['a', 'B', 'c'], index.as_json[:types].map { |e| e[:name] }      end       it "sorts numbered names" do        entry.type = '1.8.2. Test'; index.add(entry)        entry.type = '1.90. Test'; index.add(entry)        entry.type = '1.9. Test'; index.add(entry)        entry.type = '9. Test'; index.add(entry)        entry.type = '1 Test'; index.add(entry)        entry.type = 'Test'; index.add(entry)        assert_equal ['1.8.2. Test', '1.9. Test', '1.90. Test', '9. Test', '1 Test', 'Test'], index.as_json[:types].map { |e| e[:name] }      end    end  end   describe "#sort_fn" do    def sort(a, b)      index.send(:sort_fn, a, b)    end     context "when neither string starts with a digit 1-9" do      it "uses case-insensitive string comparison" do        assert_operator sort('apple', 'banana'), :<, 0        assert_operator sort('banana', 'apple'), :>, 0      end       it "returns 0 for case-insensitive equal strings" do        assert_equal 0, sort('Apple', 'apple')      end       it "treats strings starting with '0' as non-numeric" do        assert_equal '0apple'.casecmp('banana'), sort('0apple', 'banana')      end    end     context "when at least one string starts with 1-9 but neither contains version dots" do      it "uses case-insensitive string comparison" do        # lexicographic: '1' < '2', so '10 Test' < '2 Test'        assert_operator sort('10 Test', '2 Test'), :<, 0      end       it "returns 0 for case-insensitive equal strings" do        assert_equal 0, sort('2 Test', '2 test')      end    end     context "when one string has version dots and the other does not" do      it "sorts the dotted string before the undotted one" do        assert_operator sort('1.2. Test', '2 Test'), :<, 0      end       it "sorts the undotted string after the dotted one" do        assert_operator sort('2 Test', '1.2. Test'), :>, 0      end       it "sorts the dotted string before a non-numeric string" do        assert_operator sort('1.2. Test', 'abc'), :<, 0      end    end     context "when both strings have version dots" do      it "sorts numerically rather than lexicographically" do        assert_operator sort('1.9. Test', '1.10. Test'), :<, 0        assert_operator sort('4.20. Test', '4.3. Test'), :>, 0      end       it "pads shorter version depths with zeros before comparing" do        assert_operator sort('4. Test', '4.2. Test'), :<, 0        assert_operator sort('4.2. Test', '4. Test'), :>, 0      end       it "compares multi-level versions against shorter ones correctly" do        assert_operator sort('4.2.2. Test', '4.3. Test'), :<, 0      end       it "returns 0 for identical version strings" do        assert_equal 0, sort('1.2. Test', '1.2. Test')      end    end  end   describe "#to_json" do    it "returns the JSON string for #as_json" do      stub(index).as_json { { entries: [1], types: [2] } }      assert_equal '{"entries":[1],"types":[2]}', index.to_json    end  endend