mirror of
https://github.com/freeCodeCamp/devdocs
synced 2024-11-16 19:48:10 +01:00
Improve ordering of entries and types
This commit is contained in:
parent
f9dfcf4504
commit
82d0725747
6 changed files with 52 additions and 57 deletions
|
@ -46,11 +46,40 @@ module Docs
|
|||
end
|
||||
|
||||
def entries_as_json
|
||||
@entries.sort!.map { |entry| entry.as_json }
|
||||
@entries.sort! { |a, b| sort_fn(a.name, b.name) }.map(&:as_json)
|
||||
end
|
||||
|
||||
def types_as_json
|
||||
@types.values.sort!.map { |type| type.as_json }
|
||||
@types.values.sort! { |a, b| sort_fn(a.name, b.name) }.map(&:as_json)
|
||||
end
|
||||
|
||||
SPLIT_INTS = /(?<=\d)\.(?=[\s\d])/.freeze
|
||||
|
||||
def sort_fn(a, b)
|
||||
if (a.getbyte(0) >= 49 && a.getbyte(0) <= 57) || (b.getbyte(0) >= 49 && b.getbyte(0) <= 57)
|
||||
a_split = a.split(SPLIT_INTS)
|
||||
b_split = b.split(SPLIT_INTS)
|
||||
|
||||
a_length = a_split.length
|
||||
b_length = b_split.length
|
||||
|
||||
return a.casecmp(b) if a_length == 1 && b_length == 1
|
||||
return 1 if a_length == 1
|
||||
return -1 if b_length == 1
|
||||
|
||||
a_split.each_with_index { |s, i| a_split[i] = s.to_i unless i == a_length - 1 }
|
||||
b_split.each_with_index { |s, i| b_split[i] = s.to_i unless i == b_length - 1 }
|
||||
|
||||
if b_length > a_length
|
||||
(b_length - a_length).times { a_split.insert(-2, 0) }
|
||||
elsif a_length > b_length
|
||||
(a_length - b_length).times { b_split.insert(-2, 0) }
|
||||
end
|
||||
|
||||
a_split <=> b_split
|
||||
else
|
||||
a.casecmp(b)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -22,10 +22,6 @@ module Docs
|
|||
other.name == name && other.path == path && other.type == type
|
||||
end
|
||||
|
||||
def <=>(other)
|
||||
name.to_s.casecmp(other.name.to_s)
|
||||
end
|
||||
|
||||
def name=(value)
|
||||
@name = value.try :strip
|
||||
end
|
||||
|
|
|
@ -7,16 +7,6 @@ module Docs
|
|||
self.count ||= 0
|
||||
end
|
||||
|
||||
STARTS_WITH_INTEGER = /\A\d/
|
||||
|
||||
def <=>(other)
|
||||
if name && other && name =~ STARTS_WITH_INTEGER && other.name =~ STARTS_WITH_INTEGER
|
||||
name.to_i <=> other.name.to_i
|
||||
else
|
||||
name.to_s.casecmp(other.name.to_s)
|
||||
end
|
||||
end
|
||||
|
||||
def slug
|
||||
name.parameterize
|
||||
end
|
||||
|
|
|
@ -110,8 +110,17 @@ class DocsEntryIndexTest < MiniTest::Spec
|
|||
entry.name = 'B'; index.add(entry)
|
||||
entry.name = 'a'; index.add(entry)
|
||||
entry.name = 'c'; index.add(entry)
|
||||
entry.name = nil; index.add(entry)
|
||||
assert_equal [nil, 'a', 'B', 'c'], index.as_json[:entries].map { |e| e[:name] }
|
||||
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
|
||||
|
||||
|
@ -132,6 +141,16 @@ class DocsEntryIndexTest < MiniTest::Spec
|
|||
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
|
||||
|
||||
|
|
|
@ -82,24 +82,6 @@ class DocsEntryTest < MiniTest::Spec
|
|||
end
|
||||
end
|
||||
|
||||
describe "#<=>" do
|
||||
it "returns 1 when the other's name is less" do
|
||||
assert_equal 1, build_entry('b') <=> build_entry('a')
|
||||
end
|
||||
|
||||
it "returns -1 when the other's name is greater" do
|
||||
assert_equal -1, build_entry('a') <=> build_entry('b')
|
||||
end
|
||||
|
||||
it "returns 0 when the other's name is equal" do
|
||||
assert_equal 0, build_entry('a') <=> build_entry('a')
|
||||
end
|
||||
|
||||
it "is case-insensitive" do
|
||||
assert_equal 0, build_entry('a') <=> build_entry('A')
|
||||
end
|
||||
end
|
||||
|
||||
describe "#root?" do
|
||||
it "returns true when #path is 'index'" do
|
||||
entry.path = 'index'
|
||||
|
|
|
@ -18,27 +18,6 @@ class DocsTypeTest < MiniTest::Spec
|
|||
end
|
||||
end
|
||||
|
||||
describe "#<=>" do
|
||||
it "returns 1 when the other type's name is less" do
|
||||
assert_equal 1, Type.new('b') <=> Type.new('a')
|
||||
assert_equal 1, Type.new('15 a') <=> Type.new('4 b')
|
||||
end
|
||||
|
||||
it "returns -1 when the other type's name is greater" do
|
||||
assert_equal -1, Type.new('a') <=> Type.new('b')
|
||||
assert_equal -1, Type.new('8 a') <=> Type.new('16 b')
|
||||
end
|
||||
|
||||
it "returns 0 when the other type's name is equal" do
|
||||
assert_equal 0, Type.new('a') <=> Type.new('a')
|
||||
assert_equal 0, Type.new('23 a') <=> Type.new('23 b')
|
||||
end
|
||||
|
||||
it "is case-insensitive" do
|
||||
assert_equal 0, Type.new('a') <=> Type.new('A')
|
||||
end
|
||||
end
|
||||
|
||||
describe "#slug" do
|
||||
it "parameterizes the #name" do
|
||||
name = 'a.b c\/%?#'
|
||||
|
|
Loading…
Reference in a new issue