Skip to content

Commit 466d392

Browse files
committed
Add some tests for CRD generation for enums
1 parent 15be6f1 commit 466d392

File tree

4 files changed

+247
-12
lines changed

4 files changed

+247
-12
lines changed

kube-derive/src/custom_resource.rs

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -904,15 +904,16 @@ mod tests {
904904

905905
#[test]
906906
fn test_derive_crd() {
907-
let path = env::current_dir().unwrap().join("tests").join("crd_enum_test.rs");
908-
let file = fs::File::open(path).unwrap();
909-
runtime_macros::emulate_derive_macro_expansion(file, &[("CustomResource", derive)]).unwrap();
910-
911-
let path = env::current_dir()
912-
.unwrap()
913-
.join("tests")
914-
.join("crd_schema_test.rs");
915-
let file = fs::File::open(path).unwrap();
916-
runtime_macros::emulate_derive_macro_expansion(file, &[("CustomResource", derive)]).unwrap();
907+
let files = [
908+
"crd_mixed_enum_test.rs",
909+
"crd_schema_test.rs",
910+
"crd_top_level_enum_test.rs",
911+
];
912+
913+
for file in files {
914+
let path = env::current_dir().unwrap().join("tests").join(file);
915+
let file = fs::File::open(path).unwrap();
916+
runtime_macros::emulate_derive_macro_expansion(file, &[("CustomResource", derive)]).unwrap();
917+
}
917918
}
918919
}
Lines changed: 234 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,234 @@
1+
#![allow(missing_docs)]
2+
use assert_json_diff::assert_json_eq;
3+
use kube::{CustomResource, CustomResourceExt};
4+
use schemars::JsonSchema;
5+
use serde::{Deserialize, Serialize};
6+
use serde_json::json;
7+
8+
/// This enum is invalid, as "plain" (string) variants are mixed with object variants
9+
#[derive(CustomResource, Serialize, Deserialize, Debug, Clone, JsonSchema)]
10+
#[kube(group = "clux.dev", version = "v1", kind = "InvalidEnum1")]
11+
enum InvalidEnum1Spec {
12+
/// Unit variant (represented as string)
13+
A,
14+
/// Takes an [`u32`] (represented as object)
15+
B(u32),
16+
}
17+
18+
/// This enum is invalid, as "plain" (string) variants are mixed with object variants
19+
#[derive(CustomResource, Serialize, Deserialize, Debug, Clone, JsonSchema)]
20+
#[kube(group = "clux.dev", version = "v1", kind = "InvalidEnum2")]
21+
enum InvalidEnum2Spec {
22+
/// Unit variant (represented as string)
23+
A,
24+
/// Takes a single field (represented as object)
25+
B { inner: u32 },
26+
}
27+
28+
/// This enum is valid, as all variants are objects
29+
#[derive(CustomResource, Serialize, Deserialize, Debug, Clone, JsonSchema)]
30+
#[kube(group = "clux.dev", version = "v1", kind = "ValidEnum3")]
31+
enum ValidEnum3Spec {
32+
/// Takes an [`String`] (represented as object)
33+
A(String),
34+
/// Takes an [`u32`] (represented as object)
35+
B(u32),
36+
}
37+
38+
// This enum intentionally has no documentation to increase test coverage!
39+
#[derive(CustomResource, Serialize, Deserialize, Debug, Clone, JsonSchema)]
40+
#[kube(group = "clux.dev", version = "v1", kind = "ValidEnum4")]
41+
enum ValidEnum4Spec {
42+
A(String),
43+
B { inner: u32 },
44+
}
45+
46+
/// Use `cargo test --package kube-derive print_valid_crds -- --nocapture` to get the CRDs as YAML.
47+
/// Afterwards you can use `kubectl apply -f -` to see if they are valid.
48+
#[test]
49+
fn print_valid_crds() {
50+
println!("{}", serde_yaml::to_string(&ValidEnum3::crd()).unwrap());
51+
println!("---");
52+
println!("{}", serde_yaml::to_string(&ValidEnum4::crd()).unwrap());
53+
}
54+
55+
#[test]
56+
#[should_panic = "Enum variant set [String(\"A\")] has type Single(String) but was already defined as Some(Single(Object)). The instance type must be equal for all subschema variants."]
57+
fn invalid_enum_1() {
58+
InvalidEnum1::crd();
59+
}
60+
61+
#[test]
62+
#[should_panic = "Enum variant set [String(\"A\")] has type Single(String) but was already defined as Some(Single(Object)). The instance type must be equal for all subschema variants."]
63+
fn invalid_enum_2() {
64+
InvalidEnum2::crd();
65+
}
66+
67+
#[test]
68+
fn valid_enum_3() {
69+
assert_json_eq!(
70+
ValidEnum3::crd(),
71+
json!(
72+
{
73+
"apiVersion": "apiextensions.k8s.io/v1",
74+
"kind": "CustomResourceDefinition",
75+
"metadata": {
76+
"name": "validenum3s.clux.dev"
77+
},
78+
"spec": {
79+
"group": "clux.dev",
80+
"names": {
81+
"categories": [],
82+
"kind": "ValidEnum3",
83+
"plural": "validenum3s",
84+
"shortNames": [],
85+
"singular": "validenum3"
86+
},
87+
"scope": "Cluster",
88+
"versions": [
89+
{
90+
"additionalPrinterColumns": [],
91+
"name": "v1",
92+
"schema": {
93+
"openAPIV3Schema": {
94+
"description": "Auto-generated derived type for ValidEnum3Spec via `CustomResource`",
95+
"properties": {
96+
"spec": {
97+
"description": "This enum is valid, as all variants are objects",
98+
"oneOf": [
99+
{
100+
"required": [
101+
"A"
102+
]
103+
},
104+
{
105+
"required": [
106+
"B"
107+
]
108+
}
109+
],
110+
"properties": {
111+
"A": {
112+
"description": "Takes an [`String`] (represented as object)",
113+
"type": "string"
114+
},
115+
"B": {
116+
"description": "Takes an [`u32`] (represented as object)",
117+
"format": "uint32",
118+
"minimum": 0.0,
119+
"type": "integer"
120+
}
121+
},
122+
"type": "object"
123+
}
124+
},
125+
"required": [
126+
"spec"
127+
],
128+
"title": "ValidEnum3",
129+
"type": "object"
130+
}
131+
},
132+
"served": true,
133+
"storage": true,
134+
"subresources": {}
135+
}
136+
]
137+
}
138+
}
139+
)
140+
);
141+
}
142+
143+
#[test]
144+
fn valid_enum_4() {
145+
assert_json_eq!(
146+
ValidEnum4::crd(),
147+
json!(
148+
{
149+
"apiVersion": "apiextensions.k8s.io/v1",
150+
"kind": "CustomResourceDefinition",
151+
"metadata": {
152+
"name": "validenum4s.clux.dev"
153+
},
154+
"spec": {
155+
"group": "clux.dev",
156+
"names": {
157+
"categories": [],
158+
"kind": "ValidEnum4",
159+
"plural": "validenum4s",
160+
"shortNames": [],
161+
"singular": "validenum4"
162+
},
163+
"scope": "Cluster",
164+
"versions": [
165+
{
166+
"additionalPrinterColumns": [],
167+
"name": "v1",
168+
"schema": {
169+
"openAPIV3Schema": {
170+
"description": "Auto-generated derived type for ValidEnum4Spec via `CustomResource`",
171+
"properties": {
172+
"spec": {
173+
"oneOf": [
174+
{
175+
"required": [
176+
"A"
177+
]
178+
},
179+
{
180+
"required": [
181+
"B"
182+
]
183+
}
184+
],
185+
"properties": {
186+
"A": {
187+
"type": "string"
188+
},
189+
"B": {
190+
"properties": {
191+
"inner": {
192+
"format": "uint32",
193+
"minimum": 0.0,
194+
"type": "integer"
195+
}
196+
},
197+
"required": [
198+
"inner"
199+
],
200+
"type": "object"
201+
}
202+
},
203+
"type": "object"
204+
}
205+
},
206+
"required": [
207+
"spec"
208+
],
209+
"title": "ValidEnum4",
210+
"type": "object"
211+
}
212+
},
213+
"served": true,
214+
"storage": true,
215+
"subresources": {}
216+
}
217+
]
218+
}
219+
}
220+
)
221+
);
222+
}
223+
224+
#[test]
225+
#[should_panic = "Enum variant set [String(\"A\")] has type Single(String) but was already defined as Some(Single(Object)). The instance type must be equal for all subschema variants."]
226+
fn struct_with_enum_1() {
227+
#[derive(CustomResource, Serialize, Deserialize, Debug, Clone, JsonSchema)]
228+
#[kube(group = "clux.dev", version = "v1", kind = "Foo", shortname = "foo")]
229+
struct FooSpec {
230+
foo: InvalidEnum1,
231+
}
232+
233+
Foo::crd();
234+
}
File renamed without changes.

kube-derive/tests/ui/union_fails.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ error: Unions can not #[derive(CustomResource)]
77
error: Serde does not support derive for unions
88
--> tests/ui/union_fails.rs:8:1
99
|
10-
8 | / union FooSpec {
11-
9 | | int: u32,
10+
8 | / union FooSpec {
11+
9 | | int: u32,
1212
10 | | }
1313
| |_^

0 commit comments

Comments
 (0)