File: candidates_test.rb

package info (click to toggle)
ruby-friendly-id 5.6.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 436 kB
  • sloc: ruby: 3,248; makefile: 3
file content (142 lines) | stat: -rw-r--r-- 3,497 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
require "helper"

class CandidatesTest < TestCaseClass
  include FriendlyId::Test

  class Airport
    def initialize(code)
      @code = code
    end
    attr_reader :code
    alias_method :to_s, :code
  end

  class City < ActiveRecord::Base
    extend FriendlyId
    friendly_id :slug_candidates, use: :slugged
    alias_attribute :slug_candidates, :name
  end

  def model_class
    City
  end

  def with_instances_of(klass = model_class, &block)
    transaction do
      city1 = klass.create! name: "New York", code: "JFK"
      city2 = klass.create! name: "New York", code: "EWR"
      yield city1, city2
    end
  end
  alias_method :with_instances, :with_instances_of

  test "resolves conflict with candidate" do
    with_instances do |city1, city2|
      assert_equal "new-york", city1.slug
      assert_match(/\Anew-york-([a-z0-9]+-){4}[a-z0-9]+\z/, city2.slug)
    end
  end

  test "accepts candidate as symbol" do
    klass = Class.new model_class do
      def slug_candidates
        :name
      end
    end
    with_instances_of klass do |_, city|
      assert_match(/\Anew-york-([a-z0-9]+-){4}[a-z0-9]+\z/, city.slug)
    end
  end

  test "accepts multiple candidates" do
    klass = Class.new model_class do
      def slug_candidates
        [name, code]
      end
    end
    with_instances_of klass do |_, city|
      assert_equal "ewr", city.slug
    end
  end

  test "ignores blank candidate" do
    klass = Class.new model_class do
      def slug_candidates
        [name, ""]
      end
    end
    with_instances_of klass do |_, city|
      assert_match(/\Anew-york-([a-z0-9]+-){4}[a-z0-9]+\z/, city.slug)
    end
  end

  test "ignores nil candidate" do
    klass = Class.new model_class do
      def slug_candidates
        [name, nil]
      end
    end
    with_instances_of klass do |_, city|
      assert_match(/\Anew-york-([a-z0-9]+-){4}[a-z0-9]+\z/, city.slug)
    end
  end

  test "accepts candidate with nested array" do
    klass = Class.new model_class do
      def slug_candidates
        [name, [name, code]]
      end
    end
    with_instances_of klass do |_, city|
      assert_equal "new-york-ewr", city.slug
    end
  end

  test "accepts candidate with lambda" do
    klass = Class.new City do
      def slug_candidates
        [name, [name, -> { rand 1000 }]]
      end
    end
    with_instances_of klass do |_, city|
      assert_match(/\Anew-york-\d{,3}\z/, city.friendly_id)
    end
  end

  test "accepts candidate with object" do
    klass = Class.new City do
      def slug_candidates
        [name, [name, Airport.new(code)]]
      end
    end
    with_instances_of klass do |_, city|
      assert_equal "new-york-ewr", city.friendly_id
    end
  end

  test "allows to iterate through candidates without passing block" do
    klass = Class.new model_class do
      def slug_candidates
        :name
      end
    end
    with_instances_of klass do |_, city|
      candidates = FriendlyId::Candidates.new(city, city.slug_candidates)
      assert_equal candidates.each, ["new-york"]
    end
  end

  test "iterates through candidates with passed block" do
    klass = Class.new model_class do
      def slug_candidates
        :name
      end
    end
    with_instances_of klass do |_, city|
      collected_candidates = []
      candidates = FriendlyId::Candidates.new(city, city.slug_candidates)
      candidates.each { |candidate| collected_candidates << candidate }
      assert_equal collected_candidates, ["new-york"]
    end
  end
end