File: identifier_mangling_spec.rb

package info (click to toggle)
ruby-sequel 5.63.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 10,408 kB
  • sloc: ruby: 113,747; makefile: 3
file content (201 lines) | stat: -rw-r--r-- 10,218 bytes parent folder | download | duplicates (3)
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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
require_relative "spec_helper"

describe "identifier_mangling extension" do
  it "should respect the :quote_identifiers option" do
    db = Sequel::Database.new(:quote_identifiers=>false).extension(:identifier_mangling)
    db.quote_identifiers?.must_equal false
    db = Sequel::Database.new(:quote_identifiers=>true).extension(:identifier_mangling)
    db.quote_identifiers?.must_equal true
  end

  it "should respect the :quote_identifiers setting" do
    db = Sequel::Database.new.extension(:identifier_mangling)
    db.quote_identifiers?.must_equal true
    db.quote_identifiers = false
    db.quote_identifiers?.must_equal false
  end

  it "should upcase on input and downcase on output by default" do
    db = Sequel::Database.new.extension(:identifier_mangling)
    db.send(:identifier_input_method_default).must_equal :upcase
    db.send(:identifier_output_method_default).must_equal :downcase
  end

  it "should respect the :identifier_input_method option" do
    db = Sequel::Database.new.extension(:identifier_mangling)
    db.identifier_input_method.must_equal :upcase
    db.identifier_input_method = nil
    db.identifier_input_method.must_be_nil
    db = Sequel::Database.new(:identifier_input_method=>nil).extension(:identifier_mangling)
    db.identifier_input_method.must_be_nil
    db.identifier_input_method = :downcase
    db.identifier_input_method.must_equal :downcase
    db = Sequel::Database.new(:identifier_input_method=>:upcase).extension(:identifier_mangling)
    db.identifier_input_method.must_equal :upcase
    db.identifier_input_method = nil
    db.identifier_input_method.must_be_nil
  end
  
  it "should respect the :identifier_output_method option" do
    db = Sequel::Database.new.extension(:identifier_mangling)
    db.identifier_output_method.must_equal :downcase
    db.identifier_output_method = nil
    db.identifier_output_method.must_be_nil
    db = Sequel::Database.new(:identifier_output_method=>nil).extension(:identifier_mangling)
    db.identifier_output_method.must_be_nil
    db.identifier_output_method = :downcase
    db.identifier_output_method.must_equal :downcase
    db = Sequel::Database.new(:identifier_output_method=>:upcase).extension(:identifier_mangling)
    db.identifier_output_method.must_equal :upcase
    db.identifier_output_method = nil
    db.identifier_output_method.must_be_nil
  end

  it "should respect the identifier_input_method_default method if Sequel.identifier_input_method is not called" do
    class Sequel::Database
      @identifier_input_method = nil
    end
    x = Class.new(Sequel::Database){private; def dataset_class_default; Sequel::Dataset end; def identifier_input_method_default; :downcase end}
    x.new.extension(:identifier_mangling).identifier_input_method.must_equal :downcase
    y = Class.new(Sequel::Database){private; def dataset_class_default; Sequel::Dataset end; def identifier_input_method_default; :camelize end}
    y.new.extension(:identifier_mangling).identifier_input_method.must_equal :camelize
  end
  
  it "should respect the identifier_output_method_default method if Sequel.identifier_output_method is not called" do
    class Sequel::Database
      @identifier_output_method = nil
    end
    x = Class.new(Sequel::Database){private; def dataset_class_default; Sequel::Dataset end; def identifier_output_method_default; :upcase end}
    x.new.extension(:identifier_mangling).identifier_output_method.must_equal :upcase
    y = Class.new(Sequel::Database){private; def dataset_class_default; Sequel::Dataset end; def identifier_output_method_default; :underscore end}
    y.new.extension(:identifier_mangling).identifier_output_method.must_equal :underscore
  end
end

describe "Database#input_identifier_meth" do
  it "should be the input_identifer method of a default dataset for this database" do
    db = Sequel::Database.new.extension(:identifier_mangling)
    db.identifier_input_method = nil
    db.send(:input_identifier_meth).call(:a).must_equal 'a'
    db.identifier_input_method = :upcase
    db.send(:input_identifier_meth).call(:a).must_equal 'A'
  end
end

describe "Database#output_identifier_meth" do
  it "should be the output_identifer method of a default dataset for this database" do
    db = Sequel::Database.new.extension(:identifier_mangling)
    db.identifier_output_method = nil
    db.send(:output_identifier_meth).call('A').must_equal :A
    db.identifier_output_method = :downcase
    db.send(:output_identifier_meth).call('A').must_equal :a
  end
end

describe "Database#metadata_dataset" do
  it "should be a dataset with the default settings for identifier_mangling" do
    ds = Sequel::Database.new.extension(:identifier_mangling).send(:metadata_dataset)
    ds.literal(:a).must_equal "\"A\""
    ds.send(:output_identifier, 'A').must_equal :a
  end
end

describe "Dataset" do
  before do
    @dataset = Sequel.mock.extension(:identifier_mangling).dataset
  end
  
  it "should get quote_identifiers default from database" do
    db = Sequel::Database.new(:quote_identifiers=>true).extension(:identifier_mangling)
    db[:a].quote_identifiers?.must_equal true
    db = Sequel::Database.new(:quote_identifiers=>false).extension(:identifier_mangling)
    db[:a].quote_identifiers?.must_equal false
  end

  it "should get identifier_input_method default from database" do
    db = Sequel::Database.new(:identifier_input_method=>:upcase).extension(:identifier_mangling)
    db[:a].identifier_input_method.must_equal :upcase
    db = Sequel::Database.new(:identifier_input_method=>:downcase).extension(:identifier_mangling)
    db[:a].identifier_input_method.must_equal :downcase
  end

  it "should get identifier_output_method default from database" do
    db = Sequel::Database.new(:identifier_output_method=>:upcase).extension(:identifier_mangling)
    db[:a].identifier_output_method.must_equal :upcase
    db = Sequel::Database.new(:identifier_output_method=>:downcase).extension(:identifier_mangling)
    db[:a].identifier_output_method.must_equal :downcase
  end
  
  it "should have with_quote_identifiers method which returns cloned dataset with changed literalization of identifiers" do
    @dataset.with_quote_identifiers(true).literal(:a).must_equal '"a"'
    @dataset.with_quote_identifiers(false).literal(:a).must_equal 'a'
    ds = @dataset.freeze.with_quote_identifiers(false)
    ds.literal(:a).must_equal 'a'
    ds.frozen?.must_equal true
  end
  
  it "should have with_identifier_input_method method which returns cloned dataset with changed literalization of identifiers" do
    @dataset.with_identifier_input_method(:upcase).literal(:a).must_equal 'A'
    @dataset.with_identifier_input_method(:downcase).literal(:A).must_equal 'a'
    @dataset.with_identifier_input_method(:reverse).literal(:at_b).must_equal 'b_ta'
    ds = @dataset.freeze.with_identifier_input_method(:reverse)
    ds.frozen?.must_equal true
    ds.literal(:at_b).must_equal 'b_ta'
  end
  
  it "should have with_identifier_output_method method which returns cloned dataset with changed identifiers returned from the database" do
    @dataset.send(:output_identifier, "at_b_C").must_equal :at_b_C
    @dataset.with_identifier_output_method(:upcase).send(:output_identifier, "at_b_C").must_equal :AT_B_C
    @dataset.with_identifier_output_method(:downcase).send(:output_identifier, "at_b_C").must_equal :at_b_c
    @dataset.with_identifier_output_method(:reverse).send(:output_identifier, "at_b_C").must_equal :C_b_ta
    ds = @dataset.freeze.with_identifier_output_method(:reverse)
    ds.send(:output_identifier, "at_b_C").must_equal :C_b_ta
    ds.frozen?.must_equal true
  end
  
  it "should have output_identifier handle empty identifiers" do
    @dataset.send(:output_identifier, "").must_equal :untitled
    @dataset.with_identifier_output_method(:upcase).send(:output_identifier, "").must_equal :UNTITLED
    @dataset.with_identifier_output_method(:downcase).send(:output_identifier, "").must_equal :untitled
    @dataset.with_identifier_output_method(:reverse).send(:output_identifier, "").must_equal :deltitnu
  end
end

describe "identifier_mangling extension" do
  it "should be able to load dialects based on the database name" do
    Sequel.mock(:host=>'access').select(Date.new(2011, 12, 13)).sql.must_equal 'SELECT #2011-12-13#'
    Sequel.mock(:host=>'db2').select(1).sql.must_equal 'SELECT 1 FROM "SYSIBM"."SYSDUMMY1"'
    Sequel.mock(:host=>'mssql')[:a].full_text_search(:b, 'c').sql.must_equal "SELECT * FROM [A] WHERE (CONTAINS ([B], 'c'))"
    Sequel.mock(:host=>'mysql')[:a].full_text_search(:b, 'c').sql.must_equal "SELECT * FROM `a` WHERE (MATCH (`b`) AGAINST ('c'))"
    Sequel.mock(:host=>'oracle')[:a].limit(1).sql.must_equal 'SELECT * FROM (SELECT * FROM "A") "T1" WHERE (ROWNUM <= 1)'
    Sequel.mock(:host=>'postgres')[:a].full_text_search(:b, 'c').sql.must_equal "SELECT * FROM \"a\" WHERE (to_tsvector(CAST('simple' AS regconfig), (COALESCE(\"b\", ''))) @@ to_tsquery(CAST('simple' AS regconfig), 'c'))"
    Sequel.mock(:host=>'sqlanywhere').from(:a).offset(1).sql.must_equal 'SELECT TOP 2147483647 START AT (1 + 1) * FROM "A"'
    Sequel.mock(:host=>'sqlite')[Sequel[:a].as(:b)].sql.must_equal "SELECT * FROM `a` AS 'b'"
  end
end

describe Sequel::Model, ".[] optimization" do
  before do
    @db = Sequel.mock(:quote_identifiers=>true).extension(:identifier_mangling)
    def @db.schema(*) [[:id, {:primary_key=>true}]] end
    def @db.supports_schema_parsing?() true end
    @c = Class.new(Sequel::Model(@db))
    @ds = @db.dataset.with_quote_identifiers(true)
  end

  it "should have simple_pk and simple_table respect dataset's identifier input methods" do
    ds = @db.from(:ab).with_identifier_input_method(:reverse)
    @c.set_dataset ds
    @c.simple_table.must_equal '"ba"'
    @c.set_primary_key :cd
    @c.simple_pk.must_equal '"dc"'
    @c.set_dataset ds.from(Sequel[:ef][:gh])
    @c.simple_table.must_equal '"fe"."hg"'
  end

  with_symbol_splitting "should have simple_pk and simple_table respect dataset's identifier input methods when using splittable symbols" do
    ds = @db.from(:ab).with_identifier_input_method(:reverse)
    @c.set_dataset ds.from(:ef__gh)
    @c.simple_table.must_equal '"fe"."hg"'
  end
end