1test_that("throws on invalid output dir", { 2 local_temp_cache() 3 4 # Prime the cache 5 sass("div { border: 1px solid black; }") 6 7 # Cache 8 expect_error( 9 sass( 10 "div { border: 1px solid black; }", 11 output = file.path("not", "a", "path.css") 12 ) 13 ) 14}) 15 16test_that("reads from and writes to cache", { 17 local_temp_cache() 18 expected <- read_utf8("test-unicode-var-expected.css") 19 20 css <- sass(sass_file("test-unicode-var-input.scss")) 21 expect_equal(as.character(css), expected) 22 23 css <- sass(sass_file("test-unicode-var-input.scss")) 24 expect_equal(as.character(css), expected) 25 26 expect_equal(sass_cache_get()$size(), 1) 27 28 # Modifying the file busts the cache (even it if has the same contents) 29 Sys.setFileTime("test-unicode-var-input.scss", Sys.time() + 5) 30 css <- sass(sass_file("test-unicode-var-input.scss")) 31 expect_equal(as.character(css), expected) 32 expect_equal(sass_cache_get()$size(), 2) 33}) 34 35test_that("writes to cache", { 36 37 expect_cached <- function(input, css) { 38 local_temp_cache() 39 cache <- sass_cache_get() 40 # Allow input to be an expression, like layer(), that can generate 41 # different input everytime it gets evaluated 42 input_code <- substitute(input) 43 # Did we get the right CSS result? 44 expect_css(eval(input_code), css) 45 # Did a cache entry get added? 46 expect_equal(cache$size(), 1) 47 # Compile again, now with an output file 48 out_file <- tempfile(fileext = ".css") 49 expect_css(eval(input_code), css, output = out_file) 50 # If there was a cache hit, the size should be the same 51 expect_equal(cache$size(), 1) 52 # Now manipulate the cache directly to make sure it is actually being read 53 # from. We'll change the value in the cache and see if sass() reads from it. 54 cache$set_content(cache$keys(), "foo") 55 expect_css(eval(input_code), "foo") 56 } 57 58 expect_cached( 59 list( 60 list(text_color = "#313131"), 61 list("body { color: $text_color; }") 62 ), 63 "body{color:#313131;}" 64 ) 65 66 # Make sure cache key doesn't change with new/temporary HTML dependencies 67 my_layer <- function() { 68 src <- tempfile() 69 dir.create(src) 70 sass_layer( 71 "@function fib($x) { 72 @if $x <= 1 { 73 @return $x 74 } 75 @return fib($x - 2) + fib($x - 1); 76 } 77 body { width: fib(27);}", 78 html_deps = htmltools::htmlDependency("foo", "1.0", src) 79 ) 80 } 81 82 expect_cached( 83 my_layer(), 84 "body{width:196418;}" 85 ) 86 87}) 88 89test_that("unicode characters work OK after caching", { 90 local_temp_cache() 91 expected <- read_utf8("test-unicode-var-expected.css") 92 class(expected) <- c("css", "html", "character") 93 attr(expected, "html") <- TRUE 94 95 css <- sass(sass_file("test-unicode-var-input.scss")) 96 expect_equal(css, expected) 97 98 css <- sass(sass_file("test-unicode-var-input.scss")) 99 expect_equal(css, expected) 100 101 expect_equal(sass_cache_get()$size(), 1) 102}) 103 104test_that("cache isn't written if a compilation error occurs", { 105 local_temp_cache() 106 107 input <- list( 108 list(text_color = "#a0a0a0"), 109 list("body { color is: $text_color; }") 110 ) 111 options <- sass_options(output_style = "compact") 112 113 expect_error(sass(input, options), "must be followed") 114 115 expect_equal(sass_cache_get()$size(), 0) 116}) 117 118test_that("cache key components", { 119 tmpfile <- tempfile(fileext = ".tmp") 120 file.create(tmpfile) 121 old_mtime <- file.mtime(tmpfile) 122 123 input <- list(sass_file(tmpfile)) 124 options <- sass_options() 125 126 key1 <- sass_hash(list(input, options)) 127 while (file.mtime(tmpfile) == old_mtime) { 128 # Force timestamp to change 129 Sys.sleep(0.1) 130 file.remove(tmpfile) 131 file.create(tmpfile) 132 } 133 134 # Files differing by mtime should have different keys 135 key2 <- sass_hash(list(input, options)) 136 expect_true(key1 != key2) 137 138 # Options that are identical should have same key 139 options3 <- sass_options() 140 key3 <- sass_hash(list(input, options3)) 141 expect_true(key2 == key3) 142 143 # Options that are different should have different keys 144 options4 <- sass_options(output_style = "compact") 145 key4 <- sass_hash(list(input, options4)) 146 expect_true(key3 != key4) 147}) 148 149 150 151test_that("output_template() is cache and options aware", { 152 local_temp_cache() 153 154 input <- list( 155 list(color = "red"), 156 "body{color:red}" 157 ) 158 opts <- sass_options(output_style = "compressed") 159 expect_red <- function(file) { 160 expect_equal( 161 "body{color:red}", 162 gsub("(\\s+)|(\t)|(;)", "", paste(readLines(file), collapse = "")) 163 ) 164 } 165 166 # File is exactly the same with the same input+options 167 output1 <- sass(input, output = output_template(), options = opts) 168 output2 <- sass(input, output = output_template(), options = opts) 169 expect_true(output1 == output2) 170 expect_match(output1, ".min.css$") 171 expect_red(output1) 172 expect_red(output2) 173 174 # If cache is different, should get a different output file 175 output3 <- sass(input, output = output_template(), options = opts, cache_key_extra = "foo") 176 expect_true(output1 != output3) 177 expect_red(output3) 178 179 # Not minimized by default (because output_style = "expanded") 180 output4 <- sass(input, output = output_template()) 181 expect_false(grepl(".min.css$", output4)) 182 expect_red(output4) 183 184 # If no caching, should get a different output files 185 output5 <- sass(input, output = output_template(), cache = FALSE) 186 output6 <- sass(input, output = output_template(), cache = FALSE) 187 expect_true(dirname(output5) != dirname(output6)) 188 expect_red(output5) 189 expect_red(output6) 190 191 # File can be written in another dir and still be cache aware 192 temp_dir <- withr::local_tempdir() 193 output7 <- sass(input, output = output_template(path = temp_dir), options = opts) 194 expect_true(basename(dirname(dirname(output7))) == basename(temp_dir)) 195 expect_true(basename(dirname(output7)) == basename(dirname(output1))) 196}) 197 198test_that("Cache directory getting/setting", { 199 cache_dir <- tempfile("sass-cache-test-") 200 cache <- sass_file_cache(dir = cache_dir) 201 202 # Can normalize path _after_ dir is created. 203 cache_dir <- normalizePath(cache_dir) 204 expect_identical(normalizePath(cache$dir()), cache_dir) 205 206 # Setting the cache for a directory works 207 sass_cache_set_dir(cache_dir, cache) 208 expect_identical(sass_cache_get_dir(cache_dir), cache) 209 210 # It checks that the specified dir and the cache's dir match 211 expect_error(sass_cache_set_dir(file.path(cache_dir, "foo"), cache)) 212 213 # Check that the path is normalized. Create another cache object and set 214 # it as the cache for this path. Then fetching the cache for the path should 215 # return the new one. 216 cache2 <- sass_file_cache(dir = cache_dir) 217 expect_false(identical(cache, cache2)) 218 sass_cache_set_dir( 219 file.path(cache_dir, "..", basename(cache_dir)), 220 cache2 221 ) 222 expect_identical(sass_cache_get_dir(cache_dir), cache2) 223 224 # Can unset cache for a given directory 225 sass_cache_set_dir(cache_dir, NULL) 226 expect_false(exists(cache_dir, envir = .caches)) 227 228 # Calling sass_cache_get_dir() when it doesn't exist should error 229 cache_dir <- tempfile("sass-cache-test-") 230 expect_error(sass_cache_get_dir(cache_dir)) 231 232 # Calling sass_cache_get_dir() when the dir exists but no cache object has 233 # been registered returns NULL 234 dir.create(cache_dir) 235 expect_null(sass_cache_get_dir(cache_dir)) 236 237 238 # Calling sass_cache_get_dir() when the dir doesn't exist (and cache object 239 # isn't registered) with create=TRUE should create the dir and the cache 240 # object. 241 cache_dir <- tempfile("sass-cache-test-") 242 cache_obj <- sass_cache_get_dir(cache_dir, create = TRUE) 243 expect_true(dir.exists(cache_dir)) 244 expect_true(inherits(cache_obj, "FileCache")) 245 246 # Calling sass_cache_get_dir() when the dir exists but cache object does not 247 # with create=TRUE should create the cache object. 248 cache_dir <- tempfile("sass-cache-test-") 249 dir.create(cache_dir) 250 cache_obj <- sass_cache_get_dir(cache_dir, create = TRUE) 251 expect_true(dir.exists(cache_dir)) 252 expect_true(inherits(cache_obj, "FileCache")) 253}) 254 255 256test_that("Can pass a cache directory to sass()", { 257 cache_dir <- tempfile() 258 sass("body {color: red; }", cache = cache_dir) 259 260 # Cache directory should have been created 261 cache_obj <- sass_cache_get_dir(cache_dir, create = FALSE) 262 expect_true(inherits(cache_obj, "FileCache")) 263}) 264