From 08ff36fa0ca365000197341b9540ff7126711497 Mon Sep 17 00:00:00 2001 From: Uchida Mizuki Date: Sun, 6 Aug 2023 05:42:27 +0900 Subject: [PATCH] Fix bug in `str_trunc()` (#515) Fixes #512 --- NEWS.md | 3 +++ R/trunc.R | 7 ++++--- tests/testthat/test-trunc.R | 41 ++++++++++++++++++++++++++++++++----- 3 files changed, 43 insertions(+), 8 deletions(-) diff --git a/NEWS.md b/NEWS.md index 5c539c63..28b85b61 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,8 @@ # stringr (development version) +* `str_trunc()` now correctly truncates strings when `side` is `"left"` or + `"center"` (@UchidaMizuki, #512). + # stringr 1.5.0 ## Breaking changes diff --git a/R/trunc.R b/R/trunc.R index b48c78bf..4a0a7106 100644 --- a/R/trunc.R +++ b/R/trunc.R @@ -23,7 +23,8 @@ str_trunc <- function(string, width, side = c("right", "left", "center"), side <- arg_match(side) check_string(ellipsis) - too_long <- !is.na(string) & str_length(string) > width + len <- str_length(string) + too_long <- !is.na(string) & len > width width... <- width - str_length(ellipsis) if (width... < 0) { @@ -34,11 +35,11 @@ str_trunc <- function(string, width, side = c("right", "left", "center"), string[too_long] <- switch(side, right = str_c(str_sub(string[too_long], 1, width...), ellipsis), - left = str_c(ellipsis, str_sub(string[too_long], -width..., -1)), + left = str_c(ellipsis, str_sub(string[too_long], len[too_long] - width... + 1, -1)), center = str_c( str_sub(string[too_long], 1, ceiling(width... / 2)), ellipsis, - str_sub(string[too_long], -floor(width... / 2), -1) + str_sub(string[too_long], len[too_long] - floor(width... / 2) + 1, -1) ) ) string diff --git a/tests/testthat/test-trunc.R b/tests/testthat/test-trunc.R index 1bb80614..58c0a58d 100644 --- a/tests/testthat/test-trunc.R +++ b/tests/testthat/test-trunc.R @@ -18,15 +18,27 @@ test_that("truncations work for all elements of a vector", { test_that("truncations work for all sides", { - trunc <- function(direction) str_trunc( + trunc <- function(direction, width) str_trunc( "This string is moderately long", direction, - width = 20 + width = width ) - expect_equal(trunc("right"), "This string is mo...") - expect_equal(trunc("left"), "...s moderately long") - expect_equal(trunc("center"), "This stri...ely long") + expect_equal(trunc("right", 20), "This string is mo...") + expect_equal(trunc("left", 20), "...s moderately long") + expect_equal(trunc("center", 20), "This stri...ely long") + + expect_equal(trunc("right", 3), "...") + expect_equal(trunc("left", 3), "...") + expect_equal(trunc("center", 3), "...") + + expect_equal(trunc("right", 4), "T...") + expect_equal(trunc("left", 4), "...g") + expect_equal(trunc("center", 4), "T...") + + expect_equal(trunc("right", 5), "Th...") + expect_equal(trunc("left", 5), "...ng") + expect_equal(trunc("center", 5), "T...g") }) test_that("does not truncate to a length shorter than elipsis", { @@ -35,3 +47,22 @@ test_that("does not truncate to a length shorter than elipsis", { str_trunc("foobar", 3, ellipsis = "....") }) }) + +test_that("str_trunc correctly snips rhs-of-ellipsis for truncated strings", { + trunc <- function(width, side) { + str_trunc(c("", "a", "aa", "aaa", "aaaa", "aaaaaaa"), width, side, + ellipsis = "..") + } + + expect_equal(trunc(4, "right"), c("", "a", "aa", "aaa", "aaaa", "aa..")) + expect_equal(trunc(4, "left"), c("", "a", "aa", "aaa", "aaaa", "..aa")) + expect_equal(trunc(4, "center"), c("", "a", "aa", "aaa", "aaaa", "a..a")) + + expect_equal(trunc(3, "right"), c("", "a", "aa", "aaa", "a..", "a..")) + expect_equal(trunc(3, "left"), c("", "a", "aa", "aaa", "..a", "..a")) + expect_equal(trunc(3, "center"), c("", "a", "aa", "aaa", "a..", "a..")) + + expect_equal(trunc(2, "right"), c("", "a", "aa", "..", "..", "..")) + expect_equal(trunc(2, "left"), c("", "a", "aa", "..", "..", "..")) + expect_equal(trunc(2, "center"), c("", "a", "aa", "..", "..", "..")) +})