Skip to content

Commit 0aef7fa

Browse files
tkropSmilyOrgePaul
authored
feat: adjust date time property convention rule (#1536)
Signed-off-by: Tronje Krop <[email protected]> Co-authored-by: Miha Lunar <[email protected]> Co-authored-by: Paŭlo Ebermann <[email protected]>
1 parent 5092bfc commit 0aef7fa

File tree

3 files changed

+110
-49
lines changed

3 files changed

+110
-49
lines changed

server/zally-ruleset-zalando/src/main/kotlin/org/zalando/zally/ruleset/zalando/DateTimePropertiesSuffixRule.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import org.zalando.zally.rule.api.Violation
1313
ruleSet = ZalandoRuleSet::class,
1414
id = "235",
1515
severity = Severity.SHOULD,
16-
title = "Name date/time properties using the \"_at\" suffix"
16+
title = "Name date/time properties using the common conventions"
1717
)
1818
class DateTimePropertiesSuffixRule(rulesConfig: Config) {
1919

@@ -22,7 +22,7 @@ class DateTimePropertiesSuffixRule(rulesConfig: Config) {
2222
.map { Regex(it) }
2323
.toSet()
2424

25-
private val propertyFormats = setOf("date", "date-time")
25+
private val propertyFormats = setOf("date", "time", "date-time")
2626

2727
@Check(severity = Severity.SHOULD)
2828
fun validate(context: Context): List<Violation> {

server/zally-ruleset-zalando/src/main/resources/reference.conf

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,10 @@ ProprietaryHeadersRule {
216216

217217
DateTimePropertiesSuffixRule {
218218
patterns: [
219-
".*_at"
219+
".+_at",
220+
"(.+_)*time(stamp)?(_.+)?",
221+
"(.+_)*date(_.+)*",
222+
"(.+_)*day(_.+)*"
220223
]
221224
}
222225

server/zally-ruleset-zalando/src/test/kotlin/org/zalando/zally/ruleset/zalando/DateTimePropertiesSuffixRuleTest.kt

Lines changed: 104 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
package org.zalando.zally.ruleset.zalando
44

5-
import com.typesafe.config.ConfigValueFactory
65
import org.assertj.core.api.Assertions.assertThat
76
import org.intellij.lang.annotations.Language
87
import org.junit.jupiter.api.Test
@@ -14,7 +13,7 @@ class DateTimePropertiesSuffixRuleTest {
1413
private val rule = DateTimePropertiesSuffixRule(rulesConfig)
1514

1615
@Test
17-
fun `rule should pass with correct 'date-time' fields`() {
16+
fun `should pass with correct format and suffix`() {
1817
@Language("YAML")
1918
val content = """
2019
openapi: '3.0.1'
@@ -25,25 +24,28 @@ class DateTimePropertiesSuffixRuleTest {
2524
schemas:
2625
Pet:
2726
properties:
28-
created_at:
27+
was_created_at:
2928
type: string
3029
format: date-time
31-
modified_at:
30+
was_modified_time:
3231
type: string
33-
format: date-time
34-
occurred_at:
32+
format: time
33+
has_occurred_timestamp:
3534
type: string
3635
format: date-time
37-
returned_at:
36+
was_returned_date:
3837
type: string
39-
format: date-time
38+
format: date
39+
was_delivered_day:
40+
type: string
41+
format: date
4042
""".trimIndent()
4143
val violations = rule.validate(DefaultContextFactory().getOpenApiContext(content))
4244
assertThat(violations).isEmpty()
4345
}
4446

4547
@Test
46-
fun `rule should pass with correct 'date' fields`() {
48+
fun `should ignore fields with non-date and time types`() {
4749
@Language("YAML")
4850
val content = """
4951
openapi: '3.0.1'
@@ -54,25 +56,58 @@ class DateTimePropertiesSuffixRuleTest {
5456
schemas:
5557
Car:
5658
properties:
57-
created_at:
59+
was_created:
5860
type: string
59-
format: date
60-
modified_at:
61+
was_modified:
62+
type: enum
63+
enum: [ "yes", "no" ]
64+
has_occurred:
65+
type: string
66+
was_returned:
67+
type: string
68+
was_delivered:
69+
type: int
70+
""".trimIndent()
71+
val violations = rule.validate(DefaultContextFactory().getOpenApiContext(content))
72+
assertThat(violations).isEmpty()
73+
}
74+
75+
@Test
76+
fun `should fail on suffix _at and succeed on infix patterns`() {
77+
@Language("YAML")
78+
val content = """
79+
openapi: '3.0.1'
80+
info:
81+
title: Test API
82+
version: 1.0.0
83+
components:
84+
schemas:
85+
Car:
86+
properties:
87+
was_created_at_suffix:
88+
type: string
89+
format: date-time
90+
was_modified_time_suffix:
6191
type: string
62-
format: date
63-
occurred_at:
92+
format: time
93+
has_occurred_timestamp_suffix:
6494
type: string
65-
format: date
66-
returned_at:
95+
format: date-time
96+
was_returned_date_suffix:
97+
type: string
98+
format: date
99+
was_delivered_day_suffix:
67100
type: string
68-
format: date
101+
format: date
69102
""".trimIndent()
70103
val violations = rule.validate(DefaultContextFactory().getOpenApiContext(content))
71-
assertThat(violations).isEmpty()
104+
assertThat(violations.map { it.description }).containsExactly(
105+
rule.generateMessage("was_created_at_suffix", "string", "date-time")
106+
)
72107
}
73108

74109
@Test
75-
fun `should ignore fields with non-date and time types`() {
110+
fun `should fail on prefix at_ and succeed on prefix patterns`() {
76111
@Language("YAML")
77112
val content = """
78113
openapi: '3.0.1'
@@ -83,21 +118,30 @@ class DateTimePropertiesSuffixRuleTest {
83118
schemas:
84119
Car:
85120
properties:
86-
created:
87-
type: string
88-
occurred:
89-
type: string
90-
returned:
91-
type: string
92-
modified:
93-
type: int
121+
at_created:
122+
type: string
123+
format: date-time
124+
time_modified_suffix:
125+
type: string
126+
format: time
127+
timestamp_occurred_suffix:
128+
type: string
129+
format: date-time
130+
date_returned_suffix:
131+
type: string
132+
format: date
133+
day_delivered_suffix:
134+
type: string
135+
format: date
94136
""".trimIndent()
95137
val violations = rule.validate(DefaultContextFactory().getOpenApiContext(content))
96-
assertThat(violations).isEmpty()
138+
assertThat(violations.map { it.description }).containsExactly(
139+
rule.generateMessage("at_created", "string", "date-time")
140+
)
97141
}
98142

99143
@Test
100-
fun `rule should fail to validate schema`() {
144+
fun `should fail on leading _`() {
101145
@Language("YAML")
102146
val content = """
103147
openapi: '3.0.1'
@@ -108,30 +152,34 @@ class DateTimePropertiesSuffixRuleTest {
108152
schemas:
109153
Car:
110154
properties:
111-
created:
155+
_at:
112156
type: string
113157
format: date-time
114-
occurred:
158+
_time:
115159
type: string
116-
format: date
117-
returned:
160+
format: time
161+
_timestamp:
118162
type: string
119163
format: date-time
120-
modified:
164+
_date:
165+
type: string
166+
format: date
167+
_day:
121168
type: string
122169
format: date
123170
""".trimIndent()
124171
val violations = rule.validate(DefaultContextFactory().getOpenApiContext(content))
125172
assertThat(violations.map { it.description }).containsExactly(
126-
rule.generateMessage("created", "string", "date-time"),
127-
rule.generateMessage("occurred", "string", "date"),
128-
rule.generateMessage("returned", "string", "date-time"),
129-
rule.generateMessage("modified", "string", "date")
173+
rule.generateMessage("_at", "string", "date-time"),
174+
rule.generateMessage("_time", "string", "time"),
175+
rule.generateMessage("_timestamp", "string", "date-time"),
176+
rule.generateMessage("_date", "string", "date"),
177+
rule.generateMessage("_day", "string", "date")
130178
)
131179
}
132180

133181
@Test
134-
fun `rule should support different patterns`() {
182+
fun `should fail on trailing _`() {
135183
@Language("YAML")
136184
val content = """
137185
openapi: '3.0.1'
@@ -142,19 +190,29 @@ class DateTimePropertiesSuffixRuleTest {
142190
schemas:
143191
Car:
144192
properties:
145-
created:
193+
at_:
194+
type: string
195+
format: date-time
196+
time_:
197+
type: string
198+
format: time
199+
timestamp_:
146200
type: string
147201
format: date-time
148-
modified:
202+
date_:
203+
type: string
204+
format: date
205+
day_:
149206
type: string
150207
format: date
151208
""".trimIndent()
152-
val newConfig = rulesConfig.withValue("DateTimePropertiesSuffixRule/patterns", ConfigValueFactory.fromIterable(listOf("was_.*")))
153-
val customRule = DateTimePropertiesSuffixRule(newConfig)
154-
val violations = customRule.validate(DefaultContextFactory().getOpenApiContext(content))
209+
val violations = rule.validate(DefaultContextFactory().getOpenApiContext(content))
155210
assertThat(violations.map { it.description }).containsExactly(
156-
customRule.generateMessage("created", "string", "date-time"),
157-
customRule.generateMessage("modified", "string", "date")
211+
rule.generateMessage("at_", "string", "date-time"),
212+
rule.generateMessage("time_", "string", "time"),
213+
rule.generateMessage("timestamp_", "string", "date-time"),
214+
rule.generateMessage("date_", "string", "date"),
215+
rule.generateMessage("day_", "string", "date")
158216
)
159217
}
160218
}

0 commit comments

Comments
 (0)