Skip to content

Commit 27d932a

Browse files
authored
Merge pull request #366 from frictionlessdata/dollar-schema-first
Create append helper function and set $schema as first attribute
2 parents 9506648 + 953bc3c commit 27d932a

8 files changed

Lines changed: 141 additions & 13 deletions

File tree

R/upgrade_descriptor.R

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,12 @@ upgrade_descriptor <- function(package) {
1414
return(package)
1515
}
1616

17-
# Set $schema
18-
purrr::pluck(package, "$schema") <-
19-
"https://datapackage.org/profiles/2.0/datapackage.json"
17+
# Set $schema as first property
18+
package <- append_with_attributes(
19+
package,
20+
list("$schema" = "https://datapackage.org/profiles/2.0/datapackage.json"),
21+
after = 0
22+
)
2023

2124
# Set $schema to profile if URL (to custom profile)
2225
# https://datapackage.org/standard/data-package/#dollar-schema

R/upgrade_resource.R

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,12 @@ upgrade_resource <- function(resource) {
1212
return(resource)
1313
}
1414

15-
# Set $schema
16-
purrr::pluck(resource, "$schema") <-
17-
"https://datapackage.org/profiles/2.0/dataresource.json"
15+
# Set $schema as first property
16+
resource <- append_with_attributes(
17+
resource,
18+
list("$schema" = "https://datapackage.org/profiles/2.0/dataresource.json"),
19+
after = 0
20+
)
1821

1922
# Set type to table if resource is tabular
2023
# https://datapackage.org/standard/data-resource/#type

R/upgrade_schema.R

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,12 @@ upgrade_schema <- function(schema, resource_name) {
1414
return(schema)
1515
}
1616

17-
# Set $schema
18-
purrr::pluck(schema, "$schema") <-
19-
"https://datapackage.org/profiles/2.0/tableschema.json"
17+
# Set $schema as first property
18+
schema <- append_with_attributes(
19+
schema,
20+
list("$schema" = "https://datapackage.org/profiles/2.0/tableschema.json"),
21+
after = 0
22+
)
2023

2124
# Update primaryKey to array
2225
# https://datapackage.org/overview/changelog/#schemaprimarykey-updated

R/utils.R

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,3 +100,28 @@ get_dot_names <- function(...) {
100100
# Return the names that are not an empty string (no name set)
101101
return(dot_names[dot_names != ""])
102102
}
103+
104+
#' Vector merging while preserving attributes
105+
#'
106+
#' Wrapper for [base::append] that preserves attributes.
107+
#'
108+
#' @inheritParams base::append
109+
#' @returns A vector containing the values in `x` with the elements of `values`
110+
#' appended after the specified element of `x`, while preserving the
111+
#' attributes of `x`.
112+
#' @noRd
113+
append_with_attributes <- function(x, values, after = length(x)) {
114+
# Keep original attributes, except names, which length will change with append
115+
original_attributes <- attributes(x)
116+
original_attributes[["names"]] <- NULL
117+
118+
# Append values (recreates names)
119+
x <- base::append(unclass(x), values, after = after)
120+
121+
# Put original attributes back
122+
for (attribute_name in names(original_attributes)) {
123+
attr(x, attribute_name) <- original_attributes[[attribute_name]]
124+
}
125+
126+
return(x)
127+
}

tests/testthat/test-upgrade_descriptor.R

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,11 @@ test_that("upgrade_descriptor() sets $schema to default v2 value or custom
5959
expect_identical(upgrade_descriptor(p_v1)$`$schema`, v2_profile)
6060
})
6161

62+
test_that("upgrade_resource() sets $schema as first property", {
63+
p_v1 <- example_package(version = "1.0")
64+
expect_identical(names(upgrade_descriptor(p_v1))[[1]], "$schema")
65+
})
66+
6267
test_that("upgrade_descriptor() updates contributor role to roles", {
6368
p_v1 <- example_package(version = "1.0")
6469

tests/testthat/test-upgrade_resource.R

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,11 @@ test_that("upgrade_resource() sets $schema to default v2 value", {
5454
expect_identical(upgrade_resource(resource_v1)$`$schema`, v2_profile)
5555
})
5656

57+
test_that("upgrade_resource() sets $schema as first property", {
58+
resource_v1 <- resource(example_package(version = "1.0"), "deployments")
59+
expect_identical(names(upgrade_resource(resource_v1))[[1]], "$schema")
60+
})
61+
5762
test_that("upgrade_resource() sets type for tabular resources", {
5863
resource_v1 <- resource(example_package(version = "1.0"), "deployments")
5964

tests/testthat/test-upgrade_schema.R

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,14 @@ test_that("upgrade_schema() sets $schema to default v2 value", {
2323
)
2424
})
2525

26+
test_that("upgrade_schema() sets $schema as first property", {
27+
schema_v1 <- schema(example_package(version = "1.0"), "deployments")
28+
expect_identical(
29+
names(upgrade_schema(schema_v1, "deployments"))[[1]],
30+
"$schema"
31+
)
32+
})
33+
2634
test_that("upgrade_schema() updates primaryKey", {
2735
schema_v1 <- schema(example_package(version = "1.0"), "deployments")
2836

@@ -33,11 +41,11 @@ test_that("upgrade_schema() updates primaryKey", {
3341
list("deployment_id")
3442
)
3543

36-
# Leave undefined
44+
# Undefined
3745
schema_v1$primaryKey <- NULL
3846
expect_null(upgrade_schema(schema_v1, "deployments")$primaryKey)
3947

40-
# Leave list
48+
# List
4149
schema_v1$primaryKey <- list("deployment_id", "other_id")
4250
expect_identical(
4351
upgrade_schema(schema_v1, "deployments")$primaryKey,
@@ -55,11 +63,11 @@ test_that("upgrade_schema() updates foreignKeys", {
5563
schema(example_package(version = "2.0"), "media")$foreignKeys,
5664
)
5765

58-
# Leave undefined
66+
# Undefined
5967
schema_v1$foreignKeys <- NULL
6068
expect_null(upgrade_schema(schema_v1, "media")$foreignKeys)
6169

62-
# Extensive example
70+
# Custom properties + self-referential resource
6371
provided_keys <- list(
6472
fields = "not_in_list", # Ignore
6573
list(

tests/testthat/test-utils.R

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,3 +87,79 @@ test_that("get_dot_names() does not return empty strings for unnamed args passed
8787
expect_identical(test_fn(a = "1", "2", b = "3", c = "4"), c("a", "b", "c"))
8888
expect_length(test_fn(a = "1", "2", b = "3", c = "4"), 3)
8989
})
90+
91+
# append_with_attributes() ----
92+
test_that("append_with_attributes() supports base::append() functionality", {
93+
list_1 <- list(a = 1, b = 2)
94+
list_2 <- list(c = 3, d = 4)
95+
list_nested <- list(c = list(d = 3))
96+
expect_identical(
97+
append_with_attributes(1:5, 0:1, after = 3),
98+
append(1:5, 0:1, after = 3)
99+
)
100+
expect_identical(
101+
append_with_attributes(list_1, list_2, after = 0),
102+
append(list_1, list_2, after = 0)
103+
)
104+
expect_identical(
105+
append_with_attributes(list_1, list_nested),
106+
append(list_1, list_nested)
107+
)
108+
})
109+
110+
test_that("append_with_attributes() preserves attributes and classes", {
111+
object <- head(letters, -1L) # a, b, ... y
112+
# Add custom attributes
113+
attr(object, "title") <- "Letters"
114+
attr(object, "description") <- "Lowercase letters in alphabetical order"
115+
# Add custom class
116+
class(object) <- c("letters")
117+
class(object) <- c("series", class(object))
118+
119+
expect_identical(
120+
attributes(append_with_attributes(object, "z")),
121+
attributes(object)
122+
)
123+
expect_s3_class(
124+
append_with_attributes(object, "z"),
125+
c("series", "letters")
126+
)
127+
})
128+
129+
test_that("append_with_attributes() preserves names", {
130+
object <- head(letters, -1L) # a, b, ... y
131+
# Add names
132+
object <- purrr::set_names(object, toupper(object))
133+
expect_named(
134+
append_with_attributes(object, c("Z" = "z")),
135+
toupper(letters)
136+
)
137+
})
138+
139+
test_that("append_with_attributes() can return a valid package", {
140+
p <- create_package()
141+
p_appended <- append_with_attributes(
142+
p,
143+
list(custom_property = "custom_value"),
144+
0
145+
)
146+
expect_no_error(check_package(p_appended))
147+
expect_identical(names(p_appended)[[1]], "custom_property")
148+
})
149+
150+
test_that("append_with_attributes() can return a valid resource", {
151+
resource <- resource(example_package(), "deployments")
152+
resource_appended <- append_with_attributes(
153+
resource,
154+
list(custom_property = "custom_value"),
155+
0
156+
)
157+
# Resource attributes are kept
158+
expect_identical(
159+
attr(resource_appended, "data_location"),
160+
attr(resource, "data_location")
161+
)
162+
expect_identical(names(resource_appended)[[1]], "custom_property")
163+
})
164+
165+

0 commit comments

Comments
 (0)