File: test-sort_linter.R

package info (click to toggle)
r-cran-lintr 3.2.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 4,396 kB
  • sloc: sh: 13; xml: 10; makefile: 2
file content (134 lines) | stat: -rw-r--r-- 3,629 bytes parent folder | download
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
test_that("sort_linter skips allowed usages", {
  linter <- sort_linter()

  expect_lint("order(y)", NULL, linter)

  expect_lint("y[order(x)]", NULL, linter)

  # If another function is intercalated, don't fail
  expect_lint("x[c(order(x))]", NULL, linter)

  expect_lint("x[order(y, x)]", NULL, linter)
  expect_lint("x[order(x, y)]", NULL, linter)
  # pretty sure this never makes sense, but test anyway
  expect_lint("x[order(y, na.last = x)]", NULL, linter)
})


test_that("sort_linter blocks simple disallowed usages", {
  linter <- sort_linter()
  lint_message <- rex::rex("sort(", anything, ") is better than")

  expect_lint("x[order(x)]", lint_message, linter)

  # Works with extra args in order()
  expect_lint("x[order(x, decreasing = TRUE)]", lint_message, linter)

  # ...even in disorder
  expect_lint("x[order(decreasing = TRUE, x)]", lint_message, linter)
})

test_that("sort_linter produces customized warning message", {
  linter <- sort_linter()

  expect_lint(
    "y[order(y)]",
    rex::rex("sort(y, na.last = TRUE) is better than y[order(y)]."),
    linter
  )

  # We capture the correct variable symbol
  expect_lint(
    "y + x[order(x)]",
    rex::rex("sort(x, na.last = TRUE) is better than x[order(x)]."),
    linter
  )

  # Default na.last = TRUE is overwritten if na.last is already provided
  expect_lint(
    "x[order(x, na.last = FALSE)]",
    rex::rex("sort(x, na.last = FALSE) is better than x[order(x, na.last = FALSE)]."),
    linter
  )

  expect_lint(
    "x[order(x, decreasing = FALSE)]",
    rex::rex("sort(x, decreasing = FALSE, na.last = TRUE) is better than x[order(x, decreasing = FALSE)]."),
    linter
  )

  expect_lint(
    "f()[order(f())]",
    rex::rex("sort(f(), na.last = TRUE) is better than f()[order(f())]"),
    linter
  )
})

test_that("sort_linter works with multiple lints in a single expression", {
  linter <- sort_linter()

  expect_lint(
    "c(
      x[order(x)],
      y[order(y, decreasing = TRUE, na.last = FALSE)]
    )",
    list(
      rex::rex("sort(x, na.last = TRUE) is better than x[order(x)]."),
      rex::rex(
        "sort(y, decreasing = TRUE, na.last = FALSE)",
        anything,
        "y[order(y, decreasing = TRUE, na.last = FALSE)]."
      )
    ),
    linter
  )

})

test_that("sort_linter skips usages calling sort arguments", {
  linter <- sort_linter()

  # any arguments to sort --> not compatible
  expect_lint("sort(x, decreasing = TRUE) == x", NULL, linter)
  expect_lint("sort(x, na.last = TRUE) != x", NULL, linter)
  expect_lint("sort(x, method_arg = TRUE) == x", NULL, linter)
})

test_that("sort_linter skips when inputs don't match", {
  linter <- sort_linter()

  expect_lint("sort(x) == y", NULL, linter)
  expect_lint("sort(x) == foo(x)", NULL, linter)
  expect_lint("sort(foo(x)) == x", NULL, linter)
})

test_that("sort_linter blocks simple disallowed usages", {
  linter <- sort_linter()
  unsorted_msg <- rex::rex("Use is.unsorted(x) to test the unsortedness of a vector.")
  sorted_msg <- rex::rex("Use !is.unsorted(x) to test the sortedness of a vector.")

  expect_lint("sort(x) == x", sorted_msg, linter)

  # argument order doesn't matter
  expect_lint("x == sort(x)", sorted_msg, linter)

  # inverted version
  expect_lint("sort(x) != x", unsorted_msg, linter)

  # expression matching
  expect_lint("sort(foo(x)) == foo(x)", sorted_msg, linter)
})

test_that("lints vectorize", {
  expect_lint(
    trim_some("{
      x == sort(x)
      y[order(y)]
    }"),
    list(
      list(rex::rex("is.unsorted(x)"), line_number = 2L),
      list(rex::rex("sort(y"), line_number = 3L)
    ),
    sort_linter()
  )
})