calculations_test.rb 40.4 KB
Newer Older
1 2
# frozen_string_literal: true

3
require "cases/helper"
4
require "models/book"
5 6
require "models/club"
require "models/company"
7
require "models/contract"
8 9 10 11 12
require "models/edge"
require "models/organization"
require "models/possession"
require "models/topic"
require "models/reply"
13
require "models/numeric_data"
14 15 16 17 18
require "models/minivan"
require "models/speedometer"
require "models/ship_part"
require "models/treasure"
require "models/developer"
19
require "models/post"
20 21
require "models/comment"
require "models/rating"
22
require "support/stubs/strong_parameters"
23

24
class CalculationsTest < ActiveRecord::TestCase
25
  fixtures :companies, :accounts, :topics, :speedometers, :minivans, :books, :posts, :comments
26 27

  def test_should_sum_field
28
    assert_equal 318, Account.sum(:credit_limit)
29 30
  end

31 32 33 34
  def test_should_sum_arel_attribute
    assert_equal 318, Account.sum(Account.arel_table[:credit_limit])
  end

35 36
  def test_should_average_field
    value = Account.average(:credit_limit)
37
    assert_equal 53.0, value
38 39
  end

40 41 42 43 44
  def test_should_average_arel_attribute
    value = Account.average(Account.arel_table[:credit_limit])
    assert_equal 53.0, value
  end

45 46 47 48
  def test_should_resolve_aliased_attributes
    assert_equal 318, Account.sum(:available_credit)
  end

49 50 51 52 53
  def test_should_return_decimal_average_of_integer_field
    value = Account.average(:id)
    assert_equal 3.5, value
  end

54
  def test_should_return_integer_average_if_db_returns_such
A
Aaron Patterson 已提交
55
    ShipPart.delete_all
56
    ShipPart.create!(id: 3, name: "foo")
A
Aaron Patterson 已提交
57
    value = ShipPart.average(:id)
58 59 60
    assert_equal 3, value
  end

61 62
  def test_should_return_nil_as_average
    assert_nil NumericData.average(:bank_balance)
63
  end
64

65 66 67 68
  def test_should_get_maximum_of_field
    assert_equal 60, Account.maximum(:credit_limit)
  end

69 70 71 72
  def test_should_get_maximum_of_arel_attribute
    assert_equal 60, Account.maximum(Account.arel_table[:credit_limit])
  end

73
  def test_should_get_maximum_of_field_with_include
J
Jon Leighton 已提交
74
    assert_equal 55, Account.where("companies.name != 'Summit'").references(:companies).includes(:firm).maximum(:credit_limit)
75 76
  end

77 78 79 80
  def test_should_get_maximum_of_arel_attribute_with_include
    assert_equal 55, Account.where("companies.name != 'Summit'").references(:companies).includes(:firm).maximum(Account.arel_table[:credit_limit])
  end

81 82 83 84
  def test_should_get_minimum_of_field
    assert_equal 50, Account.minimum(:credit_limit)
  end

85 86 87 88
  def test_should_get_minimum_of_arel_attribute
    assert_equal 50, Account.minimum(Account.arel_table[:credit_limit])
  end

89
  def test_should_group_by_field
J
Jon Leighton 已提交
90
    c = Account.group(:firm_id).sum(:credit_limit)
91
    [1, 6, 2].each do |firm_id|
92
      assert_includes c.keys, firm_id, "Group #{c.inspect} does not contain firm_id #{firm_id}"
93
    end
94
  end
95

96
  def test_should_group_by_arel_attribute
97
    c = Account.group(Account.arel_table[:firm_id]).sum(:credit_limit)
98
    [1, 6, 2].each do |firm_id|
99
      assert_includes c.keys, firm_id, "Group #{c.inspect} does not contain firm_id #{firm_id}"
100
    end
101 102
  end

103
  def test_should_group_by_multiple_fields
104
    c = Account.group("firm_id", :credit_limit).count(:all)
105
    [ [nil, 50], [1, 50], [6, 50], [6, 55], [9, 53], [2, 60] ].each { |firm_and_limit| assert_includes c.keys, firm_and_limit }
106 107 108
  end

  def test_should_group_by_multiple_fields_having_functions
109
    c = Topic.group(:author_name, "COALESCE(type, title)").count(:all)
110 111 112 113 114
    assert_equal 1, c[["Carl", "The Third Topic of the day"]]
    assert_equal 1, c[["Mary", "Reply"]]
    assert_equal 1, c[["David", "The First Topic"]]
    assert_equal 1, c[["Carl", "Reply"]]
  end
115 116

  def test_should_group_by_summed_field
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
    expected = { nil => 50, 1 => 50, 2 => 60, 6 => 105, 9 => 53 }
    assert_equal expected, Account.group(:firm_id).sum(:credit_limit)
  end

  def test_group_by_multiple_same_field
    accounts = Account.group(:firm_id)

    expected = {
      nil => 50,
      1 => 50,
      2 => 60,
      6 => 105,
      9 => 53
    }
    assert_equal expected, accounts.sum(:credit_limit)

    expected = {
      [nil, nil] => 50,
      [1, 1] => 50,
      [2, 2] => 60,
      [6, 6] => 55,
      [9, 9] => 53
    }
    assert_equal expected, accounts.merge!(accounts).maximum(:credit_limit)

    expected = {
      [nil, nil, nil, nil] => 50,
      [1, 1, 1, 1] => 50,
      [2, 2, 2, 2] => 60,
      [6, 6, 6, 6] => 50,
      [9, 9, 9, 9] => 53
    }
    assert_equal expected, accounts.merge!(accounts).minimum(:credit_limit)
150 151
  end

152
  def test_should_generate_valid_sql_with_joins_and_group
153
    assert_nothing_raised do
154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170
      AuditLog.joins(:developer).group(:id).count
    end
  end

  def test_should_calculate_against_given_relation
    developer = Developer.create!(name: "developer")
    developer.audit_logs.create!(message: "first log")
    developer.audit_logs.create!(message: "second log")

    c = developer.audit_logs.joins(:developer).group(:id).count

    assert_equal developer.audit_logs.count, c.size
    developer.audit_logs.each do |log|
      assert_equal 1, c[log.id]
    end
  end

171 172 173 174 175 176 177
  def test_should_not_use_alias_for_grouped_field
    assert_sql(/GROUP BY #{Regexp.escape(Account.connection.quote_table_name("accounts.firm_id"))}/i) do
      c = Account.group(:firm_id).order("accounts_firm_id").sum(:credit_limit)
      assert_equal [1, 2, 6, 9], c.keys.compact
    end
  end

178
  def test_should_order_by_grouped_field
179
    c = Account.group(:firm_id).order("firm_id").sum(:credit_limit)
180
    assert_equal [1, 2, 6, 9], c.keys.compact
181 182 183
  end

  def test_should_order_by_calculation
B
Ben Toews 已提交
184
    c = Account.group(:firm_id).order("sum_credit_limit desc, firm_id").sum(:credit_limit)
185 186
    assert_equal [105, 60, 53, 50, 50], c.keys.collect { |k| c[k] }
    assert_equal [6, 2, 9, 1], c.keys.compact
187 188
  end

189
  def test_should_limit_calculation
190
    c = Account.where("firm_id IS NOT NULL").group(:firm_id).order("firm_id").limit(2).sum(:credit_limit)
191 192 193 194
    assert_equal [1, 2], c.keys.compact
  end

  def test_should_limit_calculation_with_offset
195 196
    c = Account.where("firm_id IS NOT NULL").group(:firm_id).order("firm_id").
     limit(2).offset(1).sum(:credit_limit)
197 198 199
    assert_equal [2, 6], c.keys.compact
  end

200
  def test_limit_should_apply_before_count
201
    accounts = Account.order(:id).limit(4)
202 203 204 205 206

    assert_equal 3, accounts.count(:firm_id)
    assert_equal 3, accounts.select(:firm_id).count
  end

207
  def test_limit_should_apply_before_count_arel_attribute
208
    accounts = Account.order(:id).limit(4)
209 210 211 212 213 214

    firm_id_attribute = Account.arel_table[:firm_id]
    assert_equal 3, accounts.count(firm_id_attribute)
    assert_equal 3, accounts.select(firm_id_attribute).count
  end

215 216 217 218 219 220 221
  def test_count_should_shortcut_with_limit_zero
    accounts = Account.limit(0)

    assert_no_queries { assert_equal 0, accounts.count }
  end

  def test_limit_is_kept
A
Aaron Patterson 已提交
222 223
    return if current_adapter?(:OracleAdapter)

224
    queries = capture_sql { Account.limit(1).count }
225 226 227 228
    assert_equal 1, queries.length
    assert_match(/LIMIT/, queries.first)
  end

229 230 231
  def test_offset_is_kept
    return if current_adapter?(:OracleAdapter)

232
    queries = capture_sql { Account.offset(1).count }
233
    assert_equal 1, queries.length
234
    assert_match(/OFFSET/, queries.first)
235 236
  end

237 238 239
  def test_limit_with_offset_is_kept
    return if current_adapter?(:OracleAdapter)

240
    queries = capture_sql { Account.limit(1).offset(1).count }
241
    assert_equal 1, queries.length
242 243
    assert_match(/LIMIT/, queries.first)
    assert_match(/OFFSET/, queries.first)
244 245 246
  end

  def test_no_limit_no_offset
247
    queries = capture_sql { Account.count }
248 249 250 251 252
    assert_equal 1, queries.length
    assert_no_match(/LIMIT/, queries.first)
    assert_no_match(/OFFSET/, queries.first)
  end

253 254 255 256 257
  def test_count_on_invalid_columns_raises
    e = assert_raises(ActiveRecord::StatementInvalid) {
      Account.select("credit_limit, firm_name").count
    }

G
Gannon McGibbon 已提交
258 259
    assert_match %r{accounts}i, e.sql
    assert_match "credit_limit, firm_name", e.sql
260 261
  end

262
  def test_apply_distinct_in_count
263
    queries = capture_sql do
264 265 266 267 268 269 270 271 272
      Account.distinct.count
      Account.group(:firm_id).distinct.count
    end

    queries.each do |query|
      assert_match %r{\ASELECT(?! DISTINCT) COUNT\(DISTINCT\b}, query
    end
  end

273 274 275 276 277 278
  def test_count_with_eager_loading_and_custom_order
    posts = Post.includes(:comments).order("comments.id")
    assert_queries(1) { assert_equal 11, posts.count }
    assert_queries(1) { assert_equal 11, posts.count(:all) }
  end

279 280 281 282 283 284
  def test_count_with_eager_loading_and_custom_select_and_order
    posts = Post.includes(:comments).order("comments.id").select(:type)
    assert_queries(1) { assert_equal 11, posts.count }
    assert_queries(1) { assert_equal 11, posts.count(:all) }
  end

285 286 287 288 289 290
  def test_count_with_eager_loading_and_custom_order_and_distinct
    posts = Post.includes(:comments).order("comments.id").distinct
    assert_queries(1) { assert_equal 11, posts.count }
    assert_queries(1) { assert_equal 11, posts.count(:all) }
  end

291 292 293 294 295 296
  def test_distinct_count_all_with_custom_select_and_order
    accounts = Account.distinct.select("credit_limit % 10").order(Arel.sql("credit_limit % 10"))
    assert_queries(1) { assert_equal 3, accounts.count(:all) }
    assert_queries(1) { assert_equal 3, accounts.load.size }
  end

297 298 299 300 301 302 303 304 305 306 307 308
  def test_distinct_count_with_order_and_limit
    assert_equal 4, Account.distinct.order(:firm_id).limit(4).count
  end

  def test_distinct_count_with_order_and_offset
    assert_equal 4, Account.distinct.order(:firm_id).offset(2).count
  end

  def test_distinct_count_with_order_and_limit_and_offset
    assert_equal 4, Account.distinct.order(:firm_id).limit(4).offset(2).count
  end

309 310 311 312 313 314 315 316 317 318 319 320
  def test_distinct_joins_count_with_order_and_limit
    assert_equal 3, Account.joins(:firm).distinct.order(:firm_id).limit(3).count
  end

  def test_distinct_joins_count_with_order_and_offset
    assert_equal 3, Account.joins(:firm).distinct.order(:firm_id).offset(2).count
  end

  def test_distinct_joins_count_with_order_and_limit_and_offset
    assert_equal 3, Account.joins(:firm).distinct.order(:firm_id).limit(3).offset(2).count
  end

321 322 323 324 325 326 327 328 329 330 331 332
  def test_distinct_joins_count_with_group_by
    expected = { nil => 4, 1 => 1, 2 => 1, 4 => 1, 5 => 1, 7 => 1 }
    assert_equal expected, Post.left_joins(:comments).group(:post_id).distinct.count(:author_id)
    assert_equal expected, Post.left_joins(:comments).group(:post_id).distinct.select(:author_id).count
    assert_equal expected, Post.left_joins(:comments).group(:post_id).count("DISTINCT posts.author_id")
    assert_equal expected, Post.left_joins(:comments).group(:post_id).select("DISTINCT posts.author_id").count

    expected = { nil => 6, 1 => 1, 2 => 1, 4 => 1, 5 => 1, 7 => 1 }
    assert_equal expected, Post.left_joins(:comments).group(:post_id).distinct.count(:all)
    assert_equal expected, Post.left_joins(:comments).group(:post_id).distinct.select(:author_id).count(:all)
  end

333 334 335 336
  def test_distinct_count_with_group_by_and_order_and_limit
    assert_equal({ 6 => 2 }, Account.group(:firm_id).distinct.order("1 DESC").limit(1).count)
  end

337
  def test_should_group_by_summed_field_having_condition
338
    c = Account.group(:firm_id).having("sum(credit_limit) > 50").sum(:credit_limit)
339 340 341 342 343
    assert_nil        c[1]
    assert_equal 105, c[6]
    assert_equal 60,  c[2]
  end

344
  def test_should_group_by_summed_field_having_condition_from_select
345
    skip unless current_adapter?(:Mysql2Adapter, :SQLite3Adapter)
346
    c = Account.select("MIN(credit_limit) AS min_credit_limit").group(:firm_id).having("min_credit_limit > 50").sum(:credit_limit)
347 348 349 350 351
    assert_nil       c[1]
    assert_equal 60, c[2]
    assert_equal 53, c[9]
  end

352
  def test_should_group_by_summed_association
J
Jon Leighton 已提交
353
    c = Account.group(:firm).sum(:credit_limit)
354 355 356 357
    assert_equal 50,   c[companies(:first_firm)]
    assert_equal 105,  c[companies(:rails_core)]
    assert_equal 60,   c[companies(:first_client)]
  end
J
Jeremy Kemper 已提交
358

359
  def test_should_sum_field_with_conditions
360
    assert_equal 105, Account.where("firm_id = 6").sum(:credit_limit)
361 362
  end

363
  def test_should_return_zero_if_sum_conditions_return_nothing
364 365
    assert_equal 0, Account.where("1 = 2").sum(:credit_limit)
    assert_equal 0, companies(:rails_core).companies.where("1 = 2").sum(:id)
366 367
  end

368
  def test_sum_should_return_valid_values_for_decimals
369
    NumericData.create(bank_balance: 19.83)
370 371 372
    assert_equal 19.83, NumericData.sum(:bank_balance)
  end

373
  def test_should_return_type_casted_values_with_group_and_expression
374
    assert_equal 0.5, Account.group(:firm_name).sum("0.01 * credit_limit")["37signals"]
375 376
  end

377
  def test_should_group_by_summed_field_with_conditions
378
    c = Account.where("firm_id > 1").group(:firm_id).sum(:credit_limit)
379 380 381
    assert_nil        c[1]
    assert_equal 105, c[6]
    assert_equal 60,  c[2]
382
  end
J
Jeremy Kemper 已提交
383

384
  def test_should_group_by_summed_field_with_conditions_and_having
385 386
    c = Account.where("firm_id > 1").group(:firm_id).
     having("sum(credit_limit) > 60").sum(:credit_limit)
387 388 389
    assert_nil        c[1]
    assert_equal 105, c[6]
    assert_nil        c[2]
390 391 392
  end

  def test_should_group_by_fields_with_table_alias
393
    c = Account.group("accounts.firm_id").sum(:credit_limit)
394 395 396
    assert_equal 50,  c[1]
    assert_equal 105, c[6]
    assert_equal 60,  c[2]
397
  end
J
Jeremy Kemper 已提交
398

399 400 401 402 403 404 405 406 407 408 409
  def test_should_calculate_grouped_with_longer_field
    field = "a" * Account.connection.max_identifier_length

    Account.update_all("#{field} = credit_limit")

    c = Account.group(:firm_id).sum(field)
    assert_equal 50,  c[1]
    assert_equal 105, c[6]
    assert_equal 60,  c[2]
  end

410
  def test_should_calculate_with_invalid_field
411
    assert_equal 6, Account.calculate(:count, "*")
412
    assert_equal 6, Account.calculate(:count, :all)
413
  end
J
Jeremy Kemper 已提交
414

415
  def test_should_calculate_grouped_with_invalid_field
416
    c = Account.group("accounts.firm_id").count(:all)
417 418 419
    assert_equal 1, c[1]
    assert_equal 2, c[6]
    assert_equal 1, c[2]
420
  end
J
Jeremy Kemper 已提交
421

422
  def test_should_calculate_grouped_association_with_invalid_field
J
Jon Leighton 已提交
423
    c = Account.group(:firm).count(:all)
424 425 426 427
    assert_equal 1, c[companies(:first_firm)]
    assert_equal 2, c[companies(:rails_core)]
    assert_equal 1, c[companies(:first_client)]
  end
428

429
  def test_should_group_by_association_with_non_numeric_foreign_key
430 431
    Speedometer.create! id: "ABC"
    Minivan.create! id: "OMG", speedometer_id: "ABC"
432

433
    c = Minivan.group(:speedometer).count(:all)
434
    first_key = c.keys.first
435
    assert_equal Speedometer, first_key.class
436
    assert_equal 1, c[first_key]
437
  end
J
Jeremy Kemper 已提交
438

439
  def test_should_calculate_grouped_association_with_foreign_key_option
440
    Account.belongs_to :another_firm, class_name: "Firm", foreign_key: "firm_id"
J
Jon Leighton 已提交
441
    c = Account.group(:another_firm).count(:all)
442 443 444 445 446
    assert_equal 1, c[companies(:first_firm)]
    assert_equal 2, c[companies(:rails_core)]
    assert_equal 1, c[companies(:first_client)]
  end

447
  def test_should_calculate_grouped_by_function
J
Jon Leighton 已提交
448
    c = Company.group("UPPER(#{QUOTED_TYPE})").count(:all)
449
    assert_equal 2, c[nil]
450 451 452
    assert_equal 1, c["DEPENDENTFIRM"]
    assert_equal 5, c["CLIENT"]
    assert_equal 2, c["FIRM"]
453
  end
J
Jeremy Kemper 已提交
454

455
  def test_should_calculate_grouped_by_function_with_table_alias
J
Jon Leighton 已提交
456
    c = Company.group("UPPER(companies.#{QUOTED_TYPE})").count(:all)
457
    assert_equal 2, c[nil]
458 459 460
    assert_equal 1, c["DEPENDENTFIRM"]
    assert_equal 5, c["CLIENT"]
    assert_equal 2, c["FIRM"]
461
  end
J
Jeremy Kemper 已提交
462

463 464 465
  def test_should_not_overshadow_enumerable_sum
    assert_equal 6, [1, 2, 3].sum(&:abs)
  end
466 467 468 469 470

  def test_should_sum_scoped_field
    assert_equal 15, companies(:rails_core).companies.sum(:id)
  end

471 472 473 474
  def test_should_sum_scoped_field_with_from
    assert_equal Club.count, Organization.clubs.count
  end

475
  def test_should_sum_scoped_field_with_conditions
476
    assert_equal 8,  companies(:rails_core).companies.where("id > 7").sum(:id)
477 478 479
  end

  def test_should_group_by_scoped_field
J
Jon Leighton 已提交
480
    c = companies(:rails_core).companies.group(:name).sum(:id)
481 482
    assert_equal 7, c["Leetsoft"]
    assert_equal 8, c["Jadedpixel"]
483 484
  end

E
Emilio Tagua 已提交
485
  def test_should_group_by_summed_field_through_association_and_having
486 487 488
    c = companies(:rails_core).companies.group(:name).having("sum(id) > 7").sum(:id)
    assert_nil      c["Leetsoft"]
    assert_equal 8, c["Jadedpixel"]
489
  end
490

491
  def test_should_count_selected_field_with_include
492 493
    assert_equal 6, Account.includes(:firm).distinct.count
    assert_equal 4, Account.includes(:firm).distinct.select(:credit_limit).count
494 495
    assert_equal 4, Account.includes(:firm).distinct.count("DISTINCT credit_limit")
    assert_equal 4, Account.includes(:firm).distinct.count("DISTINCT(credit_limit)")
496
  end
J
Jeremy Kemper 已提交
497

498 499
  def test_should_not_perform_joined_include_by_default
    assert_equal Account.count, Account.includes(:firm).count
500
    queries = capture_sql { Account.includes(:firm).count }
501 502 503 504
    assert_no_match(/join/i, queries.last)
  end

  def test_should_perform_joined_include_when_referencing_included_tables
505
    joined_count = Account.includes(:firm).where(companies: { name: "37signals" }).count
506 507 508
    assert_equal 1, joined_count
  end

509
  def test_should_count_scoped_select
510
    Account.update_all("credit_limit = NULL")
511
    assert_equal 0, Account.select("credit_limit").count
512 513 514
  end

  def test_should_count_scoped_select_with_options
515
    Account.update_all("credit_limit = NULL")
516 517
    Account.last.update_columns("credit_limit" => 49)
    Account.first.update_columns("credit_limit" => 51)
518

519
    assert_equal 1, Account.select("credit_limit").where("credit_limit >= 50").count
520 521
  end

522
  def test_should_count_manual_select_with_include
523
    assert_equal 6, Account.select("DISTINCT accounts.id").includes(:firm).count
524 525
  end

526 527 528 529 530
  def test_should_count_manual_select_with_count_all
    assert_equal 5, Account.select("DISTINCT accounts.firm_id").count(:all)
  end

  def test_should_count_with_manual_distinct_select_and_distinct
531
    assert_equal 4, Account.select("DISTINCT accounts.firm_id").distinct(true).count
532 533 534 535 536 537 538 539 540 541 542 543
  end

  def test_should_count_manual_select_with_group_with_count_all
    expected = { nil => 1, 1 => 1, 2 => 1, 6 => 2, 9 => 1 }
    actual = Account.select("DISTINCT accounts.firm_id").group("accounts.firm_id").count(:all)
    assert_equal expected, actual
  end

  def test_should_count_manual_with_count_all
    assert_equal 6, Account.count(:all)
  end

544 545 546 547 548
  def test_count_selected_arel_attribute
    assert_equal 5, Account.select(Account.arel_table[:firm_id]).count
    assert_equal 4, Account.distinct.select(Account.arel_table[:firm_id]).count
  end

549 550 551
  def test_count_with_column_parameter
    assert_equal 5, Account.count(:firm_id)
  end
J
Jeremy Kemper 已提交
552

553 554 555 556 557 558 559 560
  def test_count_with_arel_attribute
    assert_equal 5, Account.count(Account.arel_table[:firm_id])
  end

  def test_count_with_arel_star
    assert_equal 6, Account.count(Arel.star)
  end

561 562
  def test_count_with_distinct
    assert_equal 4, Account.select(:credit_limit).distinct.count
563 564
  end

565 566 567 568
  def test_count_with_aliased_attribute
    assert_equal 6, Account.count(:available_credit)
  end

569
  def test_count_with_column_and_options_parameter
J
Jon Leighton 已提交
570
    assert_equal 2, Account.where("credit_limit = 50 AND firm_id IS NOT NULL").count(:firm_id)
571
  end
J
Jeremy Kemper 已提交
572

O
oleg dashevskii 已提交
573
  def test_should_count_field_in_joined_table
574 575
    assert_equal 5, Account.joins(:firm).count("companies.id")
    assert_equal 4, Account.joins(:firm).distinct.count("companies.id")
O
oleg dashevskii 已提交
576 577
  end

578 579 580 581 582 583 584 585 586 587
  def test_count_arel_attribute_in_joined_table_with
    assert_equal 5, Account.joins(:firm).count(Company.arel_table[:id])
    assert_equal 4, Account.joins(:firm).distinct.count(Company.arel_table[:id])
  end

  def test_count_selected_arel_attribute_in_joined_table
    assert_equal 5, Account.joins(:firm).select(Company.arel_table[:id]).count
    assert_equal 4, Account.joins(:firm).distinct.select(Company.arel_table[:id]).count
  end

O
oleg dashevskii 已提交
588
  def test_should_count_field_in_joined_table_with_group_by
589
    c = Account.group("accounts.firm_id").joins(:firm).count("companies.id")
O
oleg dashevskii 已提交
590

591
    [1, 6, 2, 9].each { |firm_id| assert_includes c.keys, firm_id }
O
oleg dashevskii 已提交
592 593
  end

594
  def test_should_count_field_of_root_table_with_conflicting_group_by_column
595 596 597 598
    expected = { 1 => 2, 2 => 1, 4 => 5, 5 => 2, 7 => 1 }
    assert_equal expected, Post.joins(:comments).group(:post_id).count
    assert_equal expected, Post.joins(:comments).group("comments.post_id").count
    assert_equal expected, Post.joins(:comments).group(:post_id).select("DISTINCT posts.author_id").count(:all)
599 600
  end

601 602 603 604 605 606 607
  def test_count_with_no_parameters_isnt_deprecated
    assert_not_deprecated { Account.count }
  end

  def test_count_with_too_many_parameters_raises
    assert_raise(ArgumentError) { Account.count(1, 2, 3) }
  end
608

L
Lauro Caetano 已提交
609 610 611 612 613 614 615 616 617
  def test_count_with_order
    assert_equal 6, Account.order(:credit_limit).count
  end

  def test_count_with_reverse_order
    assert_equal 6, Account.order(:credit_limit).reverse_order.count
  end

  def test_count_with_where_and_order
618 619 620
    assert_equal 1, Account.where(firm_name: "37signals").count
    assert_equal 1, Account.where(firm_name: "37signals").order(:firm_name).count
    assert_equal 1, Account.where(firm_name: "37signals").order(:firm_name).reverse_order.count
L
Lauro Caetano 已提交
621 622
  end

623 624 625 626
  def test_count_with_block
    assert_equal 4, Account.count { |account| account.credit_limit.modulo(10).zero? }
  end

627
  def test_should_sum_expression
628
    assert_equal 636, Account.sum("2 * credit_limit")
629
  end
630

631
  def test_sum_expression_returns_zero_when_no_records_to_sum
632
    assert_equal 0, Account.where("1 = 2").sum("2 * credit_limit")
633 634
  end

635
  def test_count_with_from_option
636
    assert_equal Company.count(:all), Company.from("companies").count(:all)
J
Jon Leighton 已提交
637
    assert_equal Account.where("credit_limit = 50").count(:all),
638
        Account.from("accounts").where("credit_limit = 50").count(:all)
639 640
    assert_equal Company.where(type: "Firm").count(:type),
        Company.where(type: "Firm").from("companies").count(:type)
641 642 643
  end

  def test_sum_with_from_option
644
    assert_equal Account.sum(:credit_limit), Account.from("accounts").sum(:credit_limit)
J
Jon Leighton 已提交
645
    assert_equal Account.where("credit_limit > 50").sum(:credit_limit),
646
        Account.where("credit_limit > 50").from("accounts").sum(:credit_limit)
647 648 649
  end

  def test_average_with_from_option
650
    assert_equal Account.average(:credit_limit), Account.from("accounts").average(:credit_limit)
J
Jon Leighton 已提交
651
    assert_equal Account.where("credit_limit > 50").average(:credit_limit),
652
        Account.where("credit_limit > 50").from("accounts").average(:credit_limit)
653 654 655
  end

  def test_minimum_with_from_option
656
    assert_equal Account.minimum(:credit_limit), Account.from("accounts").minimum(:credit_limit)
J
Jon Leighton 已提交
657
    assert_equal Account.where("credit_limit > 50").minimum(:credit_limit),
658
        Account.where("credit_limit > 50").from("accounts").minimum(:credit_limit)
659 660 661
  end

  def test_maximum_with_from_option
662
    assert_equal Account.maximum(:credit_limit), Account.from("accounts").maximum(:credit_limit)
J
Jon Leighton 已提交
663
    assert_equal Account.where("credit_limit > 50").maximum(:credit_limit),
664
        Account.where("credit_limit > 50").from("accounts").maximum(:credit_limit)
665 666
  end

667
  def test_maximum_with_not_auto_table_name_prefix_if_column_included
668
    Company.create!(name: "test", contracts: [Contract.new(developer_id: 7)])
669

A
Aaron Patterson 已提交
670
    assert_equal 7, Company.includes(:contracts).maximum(:developer_id)
671 672 673
  end

  def test_minimum_with_not_auto_table_name_prefix_if_column_included
674
    Company.create!(name: "test", contracts: [Contract.new(developer_id: 7)])
675

A
Aaron Patterson 已提交
676
    assert_equal 7, Company.includes(:contracts).minimum(:developer_id)
677 678 679
  end

  def test_sum_with_not_auto_table_name_prefix_if_column_included
680
    Company.create!(name: "test", contracts: [Contract.new(developer_id: 7)])
681

A
Aaron Patterson 已提交
682
    assert_equal 7, Company.includes(:contracts).sum(:developer_id)
683 684
  end

R
Ryuta Kamizono 已提交
685 686
  if current_adapter?(:Mysql2Adapter)
    def test_from_option_with_specified_index
687 688 689
      assert_equal Edge.count(:all), Edge.from("edges USE INDEX(unique_edge_index)").count(:all)
      assert_equal Edge.where("sink_id < 5").count(:all),
          Edge.from("edges USE INDEX(unique_edge_index)").where("sink_id < 5").count(:all)
690 691 692 693
    end
  end

  def test_from_option_with_table_different_than_class
694
    assert_equal Account.count(:all), Company.from("accounts").count(:all)
695
  end
696 697 698 699

  def test_distinct_is_honored_when_used_with_count_operation_after_group
    # Count the number of authors for approved topics
    approved_topics_count = Topic.group(:approved).count(:author_name)[true]
700
    assert_equal approved_topics_count, 4
701
    # Count the number of distinct authors for approved Topics
702
    distinct_authors_for_approved_count = Topic.group(:approved).distinct.count(:author_name)[true]
703
    assert_equal distinct_authors_for_approved_count, 3
704
  end
705 706

  def test_pluck
707
    assert_equal [1, 2, 3, 4, 5], Topic.order(:id).pluck(:id)
708 709
  end

710 711 712 713 714 715 716
  def test_pluck_with_empty_in
    Topic.send(:load_schema)
    assert_no_queries do
      assert_equal [], Topic.where(id: []).pluck(:id)
    end
  end

717
  def test_pluck_without_column_names
718 719 720 721 722
    if current_adapter?(:OracleAdapter)
      assert_equal [[1, "Firm", 1, nil, "37signals", nil, 1, nil, nil]], Company.order(:id).limit(1).pluck
    else
      assert_equal [[1, "Firm", 1, nil, "37signals", nil, 1, nil, ""]], Company.order(:id).limit(1).pluck
    end
723 724
  end

725 726
  def test_pluck_type_cast
    topic = topics(:first)
727
    relation = Topic.where(id: topic.id)
728 729 730 731 732
    assert_equal [ topic.approved ], relation.pluck(:approved)
    assert_equal [ topic.last_read ], relation.pluck(:last_read)
    assert_equal [ topic.written_on ], relation.pluck(:written_on)
  end

733 734 735 736 737 738 739 740 741 742 743 744
  def test_pluck_with_type_cast_does_not_corrupt_the_query_cache
    topic = topics(:first)
    relation = Topic.where(id: topic.id)
    assert_queries 1 do
      Topic.cache do
        kind = relation.select(:written_on).load.first.read_attribute_before_type_cast(:written_on).class
        relation.pluck(:written_on)
        assert_kind_of kind, relation.select(:written_on).load.first.read_attribute_before_type_cast(:written_on)
      end
    end
  end

745 746
  def test_pluck_and_distinct
    assert_equal [50, 53, 55, 60], Account.order(:credit_limit).distinct.pluck(:credit_limit)
747 748 749 750 751 752 753 754
  end

  def test_pluck_in_relation
    company = Company.first
    contract = company.contracts.create!
    assert_equal [contract.id], company.contracts.pluck(:id)
  end

755
  def test_pluck_on_aliased_attribute
756
    assert_equal "The First Topic", Topic.order(:id).pluck(:heading).first
757 758
  end

759
  def test_pluck_with_serialization
760
    t = Topic.create!(content: { foo: :bar })
761
    assert_equal [{ foo: :bar }], Topic.where(id: t.id).pluck(:content)
762 763 764
  end

  def test_pluck_with_qualified_column_name
B
Ben Toews 已提交
765
    assert_equal [1, 2, 3, 4, 5], Topic.order(:id).pluck("topics.id")
766
  end
767 768

  def test_pluck_auto_table_name_prefix
769
    c = Company.create!(name: "test", contracts: [Contract.new])
770 771 772
    assert_equal [c.id], Company.joins(:contracts).pluck(:id)
  end

773
  def test_pluck_if_table_included
774
    c = Company.create!(name: "test", contracts: [Contract.new(developer_id: 7)])
775 776 777
    assert_equal [c.id], Company.includes(:contracts).where("contracts.id" => c.contracts.first).pluck(:id)
  end

778
  def test_pluck_not_auto_table_name_prefix_if_column_joined
779 780 781
    company = Company.create!(name: "test", contracts: [Contract.new(developer_id: 7)])
    metadata = company.contracts.first.metadata
    assert_equal [metadata], Company.joins(:contracts).pluck(:metadata)
782
  end
T
twinturbo 已提交
783

784
  def test_pluck_with_selection_clause
B
Ben Toews 已提交
785 786 787
    assert_equal [50, 53, 55, 60], Account.pluck(Arel.sql("DISTINCT credit_limit")).sort
    assert_equal [50, 53, 55, 60], Account.pluck(Arel.sql("DISTINCT accounts.credit_limit")).sort
    assert_equal [50, 53, 55, 60], Account.pluck(Arel.sql("DISTINCT(credit_limit)")).sort
788
    assert_equal [50 + 53 + 55 + 60], Account.pluck(Arel.sql("SUM(DISTINCT(credit_limit))"))
789 790
  end

T
twinturbo 已提交
791
  def test_plucks_with_ids
J
Jon Leighton 已提交
792
    assert_equal Company.all.map(&:id).sort, Company.ids.sort
T
twinturbo 已提交
793
  end
794

795 796
  def test_pluck_with_includes_limit_and_empty_result
    assert_equal [], Topic.includes(:replies).limit(0).pluck(:id)
797
    assert_equal [], Topic.includes(:replies).limit(1).where("0 = 1").pluck(:id)
798 799
  end

800 801 802 803 804
  def test_pluck_with_includes_offset
    assert_equal [5], Topic.includes(:replies).order(:id).offset(4).pluck(:id)
    assert_equal [], Topic.includes(:replies).order(:id).offset(5).pluck(:id)
  end

805
  def test_pluck_with_join
806
    assert_equal [[2, 2], [4, 4]], Reply.includes(:topic).order(:id).pluck(:id, :"topics.id")
807 808
  end

809 810 811 812 813 814
  def test_group_by_with_order_by_virtual_count_attribute
    expected = { "SpecialPost" => 1, "StiPost" => 2 }
    actual = Post.group(:type).order(:count).limit(2).maximum(:comments_count)
    assert_equal expected, actual
  end if current_adapter?(:PostgreSQLAdapter)

815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832
  def test_group_by_with_limit
    expected = { "Post" => 8, "SpecialPost" => 1 }
    actual = Post.includes(:comments).group(:type).order(:type).limit(2).count("comments.id")
    assert_equal expected, actual
  end

  def test_group_by_with_offset
    expected = { "SpecialPost" => 1, "StiPost" => 2 }
    actual = Post.includes(:comments).group(:type).order(:type).offset(1).count("comments.id")
    assert_equal expected, actual
  end

  def test_group_by_with_limit_and_offset
    expected = { "SpecialPost" => 1 }
    actual = Post.includes(:comments).group(:type).order(:type).offset(1).limit(1).count("comments.id")
    assert_equal expected, actual
  end

C
Carlos Antonio da Silva 已提交
833
  def test_group_by_with_quoted_count_and_order_by_alias
834 835 836 837 838 839
    quoted_posts_id = Post.connection.quote_table_name("posts.id")
    expected = { "SpecialPost" => 1, "StiPost" => 1, "Post" => 9 }
    actual = Post.group(:type).order("count_posts_id").count(quoted_posts_id)
    assert_equal expected, actual
  end

840
  def test_pluck_not_auto_table_name_prefix_if_column_included
841
    Company.create!(name: "test", contracts: [Contract.new(developer_id: 7)])
B
Ben Toews 已提交
842
    ids = Company.includes(:contracts).pluck(:developer_id)
843 844 845
    assert_equal Company.count, ids.length
    assert_equal [7], ids.compact
  end
846 847 848 849

  def test_pluck_multiple_columns
    assert_equal [
      [1, "The First Topic"], [2, "The Second Topic of the day"],
850 851
      [3, "The Third Topic of the day"], [4, "The Fourth Topic of the day"],
      [5, "The Fifth Topic of the day"]
852
    ], Topic.order(:id).pluck(:id, :title)
853 854
    assert_equal [
      [1, "The First Topic", "David"], [2, "The Second Topic of the day", "Mary"],
855 856
      [3, "The Third Topic of the day", "Carl"], [4, "The Fourth Topic of the day", "Carl"],
      [5, "The Fifth Topic of the day", "Jason"]
857 858 859 860 861
    ], Topic.order(:id).pluck(:id, :title, :author_name)
  end

  def test_pluck_with_multiple_columns_and_selection_clause
    assert_equal [[1, 50], [2, 50], [3, 50], [4, 60], [5, 55], [6, 53]],
862
      Account.order(:id).pluck("id, credit_limit")
863 864 865
  end

  def test_pluck_with_multiple_columns_and_includes
866
    Company.create!(name: "test", contracts: [Contract.new(developer_id: 7)])
B
Ben Toews 已提交
867
    companies_and_developers = Company.order("companies.id").includes(:contracts).pluck(:name, :developer_id)
868 869 870 871

    assert_equal Company.count, companies_and_developers.length
    assert_equal ["37signals", nil], companies_and_developers.first
    assert_equal ["test", 7], companies_and_developers.last
872
  end
873 874

  def test_pluck_with_reserved_words
875
    Possession.create!(where: "Over There")
876 877 878

    assert_equal ["Over There"], Possession.pluck(:where)
  end
879 880 881

  def test_pluck_replaces_select_clause
    taks_relation = Topic.select(:approved, :id).order(:id)
882
    assert_equal [1, 2, 3, 4, 5], taks_relation.pluck(:id)
883
    assert_equal [false, true, true, true, true], taks_relation.pluck(:approved)
884
  end
885 886 887

  def test_pluck_columns_with_same_name
    expected = [["The First Topic", "The Second Topic of the day"], ["The Third Topic of the day", "The Fourth Topic of the day"]]
888
    actual = Topic.joins(:replies).order(:id)
B
Ben Toews 已提交
889
      .pluck("topics.title", "replies_topics.title")
890 891
    assert_equal expected, actual
  end
892

893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914
  def test_pluck_functions_with_alias
    assert_equal [
      [1, "The First Topic"], [2, "The Second Topic of the day"],
      [3, "The Third Topic of the day"], [4, "The Fourth Topic of the day"],
      [5, "The Fifth Topic of the day"]
    ], Topic.order(:id).pluck(
      Arel.sql("COALESCE(id, 0) id"),
      Arel.sql("COALESCE(title, 'untitled') title")
    )
  end

  def test_pluck_functions_without_alias
    assert_equal [
      [1, "The First Topic"], [2, "The Second Topic of the day"],
      [3, "The Third Topic of the day"], [4, "The Fourth Topic of the day"],
      [5, "The Fifth Topic of the day"]
    ], Topic.order(:id).pluck(
      Arel.sql("COALESCE(id, 0)"),
      Arel.sql("COALESCE(title, 'untitled')")
    )
  end

915
  def test_calculation_with_polymorphic_relation
916 917 918 919
    part = ShipPart.create!(name: "has trinket")
    part.trinkets.create!

    assert_equal part.id, ShipPart.joins(:trinkets).sum(:id)
920 921
  end

S
Sean Griffin 已提交
922 923 924 925 926 927 928
  def test_pluck_joined_with_polymorphic_relation
    part = ShipPart.create!(name: "has trinket")
    part.trinkets.create!

    assert_equal [part.id], ShipPart.joins(:trinkets).pluck(:id)
  end

929 930
  def test_pluck_loaded_relation
    companies = Company.order(:id).limit(3).load
Y
yuuji.yaginuma 已提交
931

932
    assert_queries(0) do
933
      assert_equal ["37signals", "Summit", "Microsoft"], companies.pluck(:name)
934 935 936 937 938
    end
  end

  def test_pluck_loaded_relation_multiple_columns
    companies = Company.order(:id).limit(3).load
Y
yuuji.yaginuma 已提交
939

940
    assert_queries(0) do
941
      assert_equal [[1, "37signals"], [2, "Summit"], [3, "Microsoft"]], companies.pluck(:id, :name)
942 943 944 945
    end
  end

  def test_pluck_loaded_relation_sql_fragment
946
    companies = Company.order(:name).limit(3).load
Y
yuuji.yaginuma 已提交
947

948
    assert_queries(1) do
B
Ben Toews 已提交
949
      assert_equal ["37signals", "Apex", "Ex Nihilo"], companies.pluck(Arel.sql("DISTINCT name"))
950 951 952
    end
  end

953 954
  def test_pick_one
    assert_equal "The First Topic", Topic.order(:id).pick(:heading)
955 956 957 958
    assert_no_queries do
      assert_nil Topic.none.pick(:heading)
      assert_nil Topic.where(id: 9999999999999999999).pick(:heading)
    end
959 960 961 962
  end

  def test_pick_two
    assert_equal ["David", "david@loudthinking.com"], Topic.order(:id).pick(:author_name, :author_email_address)
963 964 965 966
    assert_no_queries do
      assert_nil Topic.none.pick(:author_name, :author_email_address)
      assert_nil Topic.where(id: 9999999999999999999).pick(:author_name, :author_email_address)
    end
967 968
  end

Y
Yuji Hanamura 已提交
969 970 971 972 973
  def test_pick_delegate_to_all
    cool_first = minivans(:cool_first)
    assert_equal cool_first.color, Minivan.pick(:color)
  end

974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997
  def test_pick_loaded_relation
    companies = Company.order(:id).limit(3).load

    assert_no_queries do
      assert_equal "37signals", companies.pick(:name)
    end
  end

  def test_pick_loaded_relation_multiple_columns
    companies = Company.order(:id).limit(3).load

    assert_no_queries do
      assert_equal [1, "37signals"], companies.pick(:id, :name)
    end
  end

  def test_pick_loaded_relation_sql_fragment
    companies = Company.order(:name).limit(3).load

    assert_queries 1 do
      assert_equal "37signals", companies.pick(Arel.sql("DISTINCT name"))
    end
  end

998 999 1000 1001 1002 1003
  def test_grouped_calculation_with_polymorphic_relation
    part = ShipPart.create!(name: "has trinket")
    part.trinkets.create!

    assert_equal({ "has trinket" => part.id }, ShipPart.joins(:trinkets).group("ship_parts.name").sum(:id))
  end
1004 1005 1006 1007 1008

  def test_calculation_grouped_by_association_doesnt_error_when_no_records_have_association
    Client.update_all(client_of: nil)
    assert_equal({ nil => Client.count }, Client.group(:firm).count)
  end
1009 1010

  def test_should_reference_correct_aliases_while_joining_tables_of_has_many_through_association
1011
    assert_nothing_raised do
1012
      developer = Developer.create!(name: "developer")
1013 1014 1015
      developer.ratings.includes(comment: :post).where(posts: { id: 1 }).count
    end
  end
1016 1017 1018 1019 1020 1021 1022 1023 1024 1025

  def test_sum_uses_enumerable_version_when_block_is_given
    block_called = false
    relation = Client.all.load

    assert_no_queries do
      assert_equal 0, relation.sum { block_called = true; 0 }
    end
    assert block_called
  end
1026 1027

  def test_having_with_strong_parameters
1028
    params = ProtectedParams.new(credit_limit: "50")
1029 1030 1031 1032 1033 1034 1035 1036 1037 1038

    assert_raises(ActiveModel::ForbiddenAttributesError) do
      Account.group(:id).having(params)
    end

    result = Account.group(:id).having(params.permit!)
    assert_equal 50, result[0].credit_limit
    assert_equal 50, result[1].credit_limit
    assert_equal 50, result[2].credit_limit
  end
1039 1040

  def test_group_by_attribute_with_custom_type
R
Ryuta Kamizono 已提交
1041
    assert_equal({ "proposed" => 2, "published" => 2 }, Book.group(:status).count)
1042
  end
1043

1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054
  def test_aggregate_attribute_on_custom_type
    assert_equal 4, Book.sum(:status)
    assert_equal 1, Book.sum(:difficulty)
    assert_equal 0, Book.minimum(:status)
    assert_equal 1, Book.maximum(:difficulty)
    assert_equal({ "proposed" => 0, "published" => 4 }, Book.group(:status).sum(:status))
    assert_equal({ "proposed" => 0, "published" => 1 }, Book.group(:status).sum(:difficulty))
    assert_equal({ "proposed" => 0, "published" => 2 }, Book.group(:status).minimum(:status))
    assert_equal({ "proposed" => 0, "published" => 1 }, Book.group(:status).maximum(:difficulty))
  end

1055 1056 1057 1058 1059 1060 1061
  def test_minimum_and_maximum_on_non_numeric_type
    assert_equal Date.new(2004, 4, 15), Topic.minimum(:last_read)
    assert_equal Date.new(2004, 4, 15), Topic.maximum(:last_read)
    assert_equal({ false => Date.new(2004, 4, 15), true => nil }, Topic.group(:approved).minimum(:last_read))
    assert_equal({ false => Date.new(2004, 4, 15), true => nil }, Topic.group(:approved).maximum(:last_read))
  end

1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145
  def test_select_avg_with_group_by_as_virtual_attribute_with_sql
    rails_core = companies(:rails_core)

    sql = <<~SQL
      SELECT firm_id, AVG(credit_limit) AS avg_credit_limit
      FROM accounts
      WHERE firm_id = ?
      GROUP BY firm_id
      LIMIT 1
    SQL

    account = Account.find_by_sql([sql, rails_core]).first

    # id was not selected, so it should be nil
    # (cannot select id because it wasn't used in the GROUP BY clause)
    assert_nil account.id

    # firm_id was explicitly selected, so it should be present
    assert_equal(rails_core, account.firm)

    # avg_credit_limit should be present as a virtual attribute
    assert_equal(52.5, account.avg_credit_limit)
  end

  def test_select_avg_with_group_by_as_virtual_attribute_with_ar
    rails_core = companies(:rails_core)

    account = Account
      .select(:firm_id, "AVG(credit_limit) AS avg_credit_limit")
      .where(firm: rails_core)
      .group(:firm_id)
      .take!

    # id was not selected, so it should be nil
    # (cannot select id because it wasn't used in the GROUP BY clause)
    assert_nil account.id

    # firm_id was explicitly selected, so it should be present
    assert_equal(rails_core, account.firm)

    # avg_credit_limit should be present as a virtual attribute
    assert_equal(52.5, account.avg_credit_limit)
  end

  def test_select_avg_with_joins_and_group_by_as_virtual_attribute_with_sql
    rails_core = companies(:rails_core)

    sql = <<~SQL
      SELECT companies.*, AVG(accounts.credit_limit) AS avg_credit_limit
      FROM companies
      INNER JOIN accounts ON companies.id = accounts.firm_id
      WHERE companies.id = ?
      GROUP BY companies.id
      LIMIT 1
    SQL

    firm = DependentFirm.find_by_sql([sql, rails_core]).first

    # all the DependentFirm attributes should be present
    assert_equal rails_core, firm
    assert_equal rails_core.name, firm.name

    # avg_credit_limit should be present as a virtual attribute
    assert_equal(52.5, firm.avg_credit_limit)
  end

  def test_select_avg_with_joins_and_group_by_as_virtual_attribute_with_ar
    rails_core = companies(:rails_core)

    firm = DependentFirm
      .select("companies.*", "AVG(accounts.credit_limit) AS avg_credit_limit")
      .where(id: rails_core)
      .joins(:account)
      .group(:id)
      .take!

    # all the DependentFirm attributes should be present
    assert_equal rails_core, firm
    assert_equal rails_core.name, firm.name

    # avg_credit_limit should be present as a virtual attribute
    assert_equal(52.5, firm.avg_credit_limit)
  end

1146 1147 1148
  def test_count_with_block_and_column_name_raises_an_error
    assert_raises(ArgumentError) do
      Account.count(:firm_id) { true }
1149 1150 1151
    end
  end

1152 1153 1154
  def test_sum_with_block_and_column_name_raises_an_error
    assert_raises(ArgumentError) do
      Account.sum(:firm_id) { 1 }
1155 1156
    end
  end
1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198

  test "#skip_query_cache! for #pluck" do
    Account.cache do
      assert_queries(1) do
        Account.pluck(:credit_limit)
        Account.pluck(:credit_limit)
      end

      assert_queries(2) do
        Account.all.skip_query_cache!.pluck(:credit_limit)
        Account.all.skip_query_cache!.pluck(:credit_limit)
      end
    end
  end

  test "#skip_query_cache! for a simple calculation" do
    Account.cache do
      assert_queries(1) do
        Account.calculate(:sum, :credit_limit)
        Account.calculate(:sum, :credit_limit)
      end

      assert_queries(2) do
        Account.all.skip_query_cache!.calculate(:sum, :credit_limit)
        Account.all.skip_query_cache!.calculate(:sum, :credit_limit)
      end
    end
  end

  test "#skip_query_cache! for a grouped calculation" do
    Account.cache do
      assert_queries(1) do
        Account.group(:firm_id).calculate(:sum, :credit_limit)
        Account.group(:firm_id).calculate(:sum, :credit_limit)
      end

      assert_queries(2) do
        Account.all.skip_query_cache!.group(:firm_id).calculate(:sum, :credit_limit)
        Account.all.skip_query_cache!.group(:firm_id).calculate(:sum, :credit_limit)
      end
    end
  end
1199
end