Skip to content

Commit 250c51a

Browse files
authored
Harden tests (#49)
* Enable reserved words being converted. Add check for NA and enforce character Avoid appending suffix is it's empty * Improve unit tests * Update website URLs based on new results * Add AI service prompts to README
1 parent b80f474 commit 250c51a

File tree

5 files changed

+158
-34
lines changed

5 files changed

+158
-34
lines changed

R/utilities.R

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ open_web_browser = function(url) { # nocov start
7373
#' [utils::URLencode()]
7474
#' @noRd
7575
encode_url = function(base, unencoded_query, encoded_query = "") {
76-
paste0(base, utils::URLencode(unencoded_query), encoded_query)
76+
paste0(base, utils::URLencode(unencoded_query, reserved = TRUE), encoded_query)
7777
}
7878

7979
#' Validate search query
@@ -94,10 +94,10 @@ encode_url = function(base, unencoded_query, encoded_query = "") {
9494
#' valid_query()
9595
#' valid_query(NULL)
9696
#' valid_query("")
97-
#' valid_query(c(1,2))
97+
#' valid_query(c(1, 2))
9898
#' @noRd
9999
valid_query = function(query) {
100-
if(missing(query) || is.null(query) || length(query) != 1 || query == "") {
100+
if(missing(query) || anyNA(query) || !is.character(query) || length(query) != 1 || query == "") {
101101
FALSE
102102
} else {
103103
TRUE
@@ -126,7 +126,7 @@ valid_query = function(query) {
126126
#' @noRd
127127
append_search_term_suffix = function(query, rlang = TRUE, suffix = "r programming") {
128128

129-
if (rlang && !is.null(suffix))
129+
if (rlang && !is.null(suffix) && suffix != "")
130130
paste(query, suffix)
131131
else
132132
query

README.Rmd

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -269,12 +269,14 @@ Presently, the following options are available:
269269
viewer pane instead of a web browser. Default is `FALSE`.
270270
- `searcher.default_keyword`: Suffix keyword to focus search results
271271
between either `"base"` or `"tidyverse"`. Default is `"base"`.
272-
- `searcher.chatgpt_prompt`: Default prompt for ChatGPT queries, used if no specific prompt is provided.
273-
- `searcher.claude_prompt`: Default prompt for Claude queries.
274-
- `searcher.perplexity_prompt`: Default prompt for Perplexity queries.
275-
- `searcher.mistral_prompt`: Default prompt for Mistral AI queries.
276-
- `searcher.bing_copilot_prompt`: Default prompt for Bing Copilot queries.
277-
- `searcher.meta_ai_prompt`: Default prompt for Meta AI queries.
272+
- AI service prompts:
273+
- `searcher.chatgpt_prompt`: Default prompt for OpenAI's ChatGPT queries.
274+
- `searcher.claude_prompt`: Default prompt for Anthropic's Claude queries.
275+
- `searcher.perplexity_prompt`: Default prompt for Perplexity AI queries.
276+
- `searcher.mistral_prompt`: Default prompt for Mistral AI queries.
277+
- `searcher.bing_copilot_prompt`: Default prompt for Bing Copilot queries.
278+
- `searcher.grok_prompt`: Default prompt for xAI's Grok AI queries.
279+
- `searcher.meta_ai_prompt`: Default prompt for Meta AI queries.
278280

279281
To set one of these options, please create the `.Rprofile` by typing into _R_:
280282

README.md

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -165,8 +165,9 @@ ask_chatgpt(
165165
)
166166
```
167167

168-
See `vignette("search-with-ai-assistants", package = "searcher")` for
169-
more details on using AI assistants in searches through `searcher`.
168+
See
169+
`vignette("using-ai-assistants-with-searcher", package = "searcher")`
170+
for more details on using AI assistants in searches through `searcher`.
170171

171172
## AI Prompt Management
172173

@@ -280,14 +281,18 @@ Presently, the following options are available:
280281
viewer pane instead of a web browser. Default is `FALSE`.
281282
- `searcher.default_keyword`: Suffix keyword to focus search results
282283
between either `"base"` or `"tidyverse"`. Default is `"base"`.
283-
- `searcher.chatgpt_prompt`: Default prompt for ChatGPT queries, used if
284-
no specific prompt is provided.
285-
- `searcher.claude_prompt`: Default prompt for Claude queries.
286-
- `searcher.perplexity_prompt`: Default prompt for Perplexity queries.
287-
- `searcher.mistral_prompt`: Default prompt for Mistral AI queries.
288-
- `searcher.bing_copilot_prompt`: Default prompt for Bing Copilot
289-
queries.
290-
- `searcher.meta_ai_prompt`: Default prompt for Meta AI queries.
284+
- AI service prompts:
285+
- `searcher.chatgpt_prompt`: Default prompt for OpenAI’s ChatGPT
286+
queries.
287+
- `searcher.claude_prompt`: Default prompt for Anthropic’s Claude
288+
queries.
289+
- `searcher.perplexity_prompt`: Default prompt for Perplexity AI
290+
queries.
291+
- `searcher.mistral_prompt`: Default prompt for Mistral AI queries.
292+
- `searcher.bing_copilot_prompt`: Default prompt for Bing Copilot
293+
queries.
294+
- `searcher.grok_prompt`: Default prompt for xAI’s Grok AI queries.
295+
- `searcher.meta_ai_prompt`: Default prompt for Meta AI queries.
291296

292297
To set one of these options, please create the `.Rprofile` by typing
293298
into *R*:

tests/testthat/test-search-functions.R

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ test_that("Check link generation - rseek", {
7272

7373
expect_identical(
7474
search_rseek("toad"),
75-
"https://rseek.org/?q=toad%20"
75+
"https://rseek.org/?q=toad"
7676
)
7777

7878
expect_identical(
@@ -174,7 +174,7 @@ test_that("Check link generation - stackoverflow", {
174174

175175
expect_identical(
176176
search_stackoverflow("toad"),
177-
"https://stackoverflow.com/search?q=toad%20[r]"
177+
"https://stackoverflow.com/search?q=toad%20%5Br%5D"
178178
)
179179

180180
expect_identical(
@@ -188,7 +188,7 @@ test_that("Check link generation - github", {
188188

189189
expect_identical(
190190
search_github("toad"),
191-
"https://github.com/search?q=toad%20language:r%20type:issue&type=Issues"
191+
"https://github.com/search?q=toad%20language%3Ar%20type%3Aissue&type=Issues"
192192
)
193193

194194
expect_identical(
@@ -202,7 +202,7 @@ test_that("Check link generation - bitbucket", {
202202

203203
expect_identical(
204204
search_bitbucket("toad"),
205-
"https://bitbucket.com/search?q=toad%20lang:r"
205+
"https://bitbucket.com/search?q=toad%20lang%3Ar"
206206
)
207207

208208
expect_identical(

tests/testthat/test-utilities.R

Lines changed: 127 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,131 @@
1-
test_that("Detect RStudio", {
2-
# Obtain value
3-
before = Sys.getenv("RSTUDIO")
1+
# Tests for Utility Functions
42

5-
# Modify check environment variable
6-
Sys.setenv("RSTUDIO" = 1)
7-
expect_true(is_rstudio(), info = "Within RStudio")
3+
## Test is_rstudio() ----
4+
test_that("is_rstudio(): detects RStudio environment correctly", {
5+
# Save original environment variable
6+
original_rstudio <- Sys.getenv("RSTUDIO")
87

9-
Sys.setenv("RSTUDIO" = 0)
10-
expect_false(is_rstudio(), info = "Not in RStudio")
8+
# Test when in RStudio
9+
Sys.setenv("RSTUDIO" = "1")
10+
expect_true(is_rstudio(), info = "Should detect RStudio when RSTUDIO=1")
1111

12-
# Restore
13-
Sys.setenv("RSTUDIO" = before)
12+
# Test when not in RStudio
13+
Sys.setenv("RSTUDIO" = "0")
14+
expect_false(is_rstudio(), info = "Should not detect RStudio when RSTUDIO=0")
15+
16+
# Test with empty environment variable
17+
Sys.setenv("RSTUDIO" = "")
18+
expect_false(is_rstudio(), info = "Should not detect RStudio when RSTUDIO is empty")
19+
20+
# Restore original environment
21+
Sys.setenv("RSTUDIO" = original_rstudio)
22+
})
23+
24+
25+
## Test valid_query() ----
26+
test_that("valid_query validates queries correctly", {
27+
# Valid queries
28+
expect_true(valid_query("valid query"))
29+
expect_true(valid_query("a"))
30+
expect_true(valid_query("query with spaces and numbers 123"))
31+
expect_true(valid_query("special chars: !@#$%^&*()"))
32+
33+
# Invalid queries
34+
expect_false(valid_query(""))
35+
expect_false(valid_query(NULL))
36+
expect_false(valid_query(c("multiple", "elements")))
37+
expect_false(valid_query(character(0)))
38+
expect_false(valid_query(NA_character_))
39+
expect_false(valid_query(123)) # Not a character
40+
41+
# Test missing argument
42+
expect_false(valid_query())
43+
})
44+
45+
## Test encode_url() ----
46+
test_that("encode_url() creates properly formatted URLs", {
47+
base_url <- "https://example.com/search?q="
48+
49+
# Test basic encoding
50+
result <- encode_url(base_url, "simple query")
51+
expect_equal(result, "https://example.com/search?q=simple%20query")
52+
53+
# Test with special characters
54+
result <- encode_url(base_url, "query with & and + symbols")
55+
expect_true(grepl("%26", result)) # & becomes %26
56+
expect_true(grepl("%2B", result)) # + becomes %2B
57+
expect_true(grepl("%20", result)) # space becomes %20
58+
59+
# Test with encoded query suffix
60+
result <- encode_url(base_url, "query", "&type=test")
61+
expect_equal(result, "https://example.com/search?q=query&type=test")
62+
63+
# Test with empty query
64+
result <- encode_url(base_url, "")
65+
expect_equal(result, "https://example.com/search?q=")
66+
67+
# Test with complex characters
68+
result <- encode_url(base_url, "R [language] test")
69+
expect_true(grepl("%5B", result)) # [ becomes %5B
70+
expect_true(grepl("%5D", result)) # ] becomes %5D
71+
})
72+
73+
# Test append_search_term_suffix() ----
74+
test_that("append_search_term_suffix(): works correctly", {
75+
# Test with rlang = TRUE (default behavior)
76+
result <- append_search_term_suffix("test query", rlang = TRUE, suffix = "r programming")
77+
expect_equal(result, "test query r programming")
78+
79+
# Test with rlang = FALSE
80+
result <- append_search_term_suffix("test query", rlang = FALSE, suffix = "r programming")
81+
expect_equal(result, "test query")
82+
83+
# Test with NULL suffix
84+
result <- append_search_term_suffix("test query", rlang = TRUE, suffix = NULL)
85+
expect_equal(result, "test query")
86+
87+
# Test with empty suffix
88+
result <- append_search_term_suffix("test query", rlang = TRUE, suffix = "")
89+
expect_equal(result, "test query")
90+
91+
# Test with custom suffix
92+
result <- append_search_term_suffix("test", rlang = TRUE, suffix = "custom")
93+
expect_equal(result, "test custom")
94+
95+
# Test edge cases
96+
result <- append_search_term_suffix("", rlang = TRUE, suffix = "r programming")
97+
expect_equal(result, " r programming")
98+
99+
result <- append_search_term_suffix("test", rlang = FALSE, suffix = "ignored")
100+
expect_equal(result, "test")
101+
})
102+
103+
# Test browse_url() ----
104+
test_that("browse_url(): generates correct URLs without opening browser", {
105+
base_url <- "https://example.com/search?q="
106+
query <- "test query"
107+
108+
# Test basic URL generation (open_browser = FALSE)
109+
expect_message(
110+
result <- browse_url(base_url, query, open_browser = FALSE),
111+
"Please type into your browser"
112+
)
113+
expect_equal(result, "https://example.com/search?q=test%20query")
114+
115+
# Test with encoded suffix
116+
expect_message(
117+
result <- browse_url(base_url, query, "&type=issues", open_browser = FALSE),
118+
"Please type into your browser"
119+
)
120+
expect_equal(result, "https://example.com/search?q=test%20query&type=issues")
121+
122+
# Test with special characters
123+
special_query <- "R [language] & symbols"
124+
expect_message(
125+
result <- browse_url(base_url, special_query, open_browser = FALSE),
126+
"Please type into your browser"
127+
)
128+
expect_true(grepl("%5B", result)) # [ is encoded
129+
expect_true(grepl("%5D", result)) # ] is encoded
130+
expect_true(grepl("%26", result)) # & is encoded
14131
})

0 commit comments

Comments
 (0)