Skip to content

Commit b6f233c

Browse files
authored
Merge pull request #18 from duckduckgo/dominik/user-defaults-wrapper
Add Danger check for @UserDefaultsWrapper additions
2 parents e6b3ebd + fd7fdc7 commit b6f233c

File tree

2 files changed

+146
-8
lines changed

2 files changed

+146
-8
lines changed

org/allPRs.ts

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -111,11 +111,6 @@ export const singletons = async () => {
111111
...danger.git.created_files
112112
].filter(file => file.endsWith(".swift"));
113113

114-
// If no files to check after filtering, exit early
115-
if (changedFiles.length === 0) {
116-
return;
117-
}
118-
119114
for (const file of changedFiles) {
120115
let diff = await danger.git.diffForFile(file);
121116
let addedLines = diff?.added.split(/\n/);
@@ -129,15 +124,30 @@ export const singletons = async () => {
129124
}
130125
}
131126

132-
export const remoteReleasableFeatureWarning = async () => {
127+
export const userDefaultsWrapper = async () => {
133128
const changedFiles = [
134129
...danger.git.modified_files,
135130
...danger.git.created_files
136131
].filter(file => file.endsWith(".swift"));
137132

138-
if (changedFiles.length === 0) {
139-
return;
133+
for (const file of changedFiles) {
134+
let diff = await danger.git.diffForFile(file);
135+
let addedLines = diff?.added.split(/\n/);
136+
const foundOccurrence = addedLines?.find(value => /^\+(?!\s*\/\/)\s*@UserDefaultsWrapper(?:\((?:.*\))?)?$/.test(value));
137+
if (foundOccurrence) {
138+
// trim leading + and whitespace
139+
const cleanLine = foundOccurrence.replace(/^\+\s*/, '').trim();
140+
fail(`New \`@UserDefaultsWrapper\` definitions are not allowed. Please use \`KeyedStoring\` protocol instead.\nFound this line:\n\`\`\`swift\n${cleanLine}\n\`\`\``);
141+
return;
142+
}
140143
}
144+
}
145+
146+
export const remoteReleasableFeatureWarning = async () => {
147+
const changedFiles = [
148+
...danger.git.modified_files,
149+
...danger.git.created_files
150+
].filter(file => file.endsWith(".swift"));
141151

142152
for (const file of changedFiles) {
143153
let diff = await danger.git.diffForFile(file);
@@ -284,6 +294,7 @@ export default async () => {
284294
await xcodeprojConfiguration_macOS()
285295
await xcodeprojObjectVersion_macOS()
286296
await singletons()
297+
await userDefaultsWrapper()
287298
await remoteReleasableFeatureWarning()
288299
await localizedStrings()
289300
await licensedFonts()
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
jest.mock("danger", () => jest.fn())
2+
import danger from 'danger'
3+
const dm = danger as any;
4+
5+
import { userDefaultsWrapper } from '../org/allPRs'
6+
7+
beforeEach(() => {
8+
dm.addedLines = ""
9+
dm.fail = jest.fn().mockReturnValue(true);
10+
11+
dm.danger = {
12+
git: {
13+
diffForFile: async (_filename) => {
14+
return { added: dm.addedLines }
15+
},
16+
modified_files: [
17+
"ModifiedFile.swift"
18+
],
19+
created_files: [
20+
"CreatedFile.swift"
21+
]
22+
}
23+
}
24+
})
25+
26+
describe("@UserDefaultsWrapper checks", () => {
27+
it("does not fail with no changes to Swift files", async () => {
28+
dm.danger.git.modified_files = []
29+
30+
await userDefaultsWrapper()
31+
expect(dm.fail).not.toHaveBeenCalled()
32+
})
33+
34+
it("does not fail with no diff in Swift files", async () => {
35+
dm.danger.git.diffForFile = async (_filename) => {}
36+
37+
await userDefaultsWrapper()
38+
expect(dm.fail).not.toHaveBeenCalled()
39+
})
40+
41+
it("does not fail with no additions", async () => {
42+
await userDefaultsWrapper()
43+
expect(dm.fail).not.toHaveBeenCalled()
44+
})
45+
46+
it("does not fail with non-@UserDefaultsWrapper additions", async () => {
47+
dm.addedLines = `
48+
+ let subscription = PrivacyProSubscription(status: .inactive)
49+
+ let isSubscribed: Bool
50+
+ var billingPeriod: String?
51+
+ public let startedAt: Int?
52+
+ internal let expiresOrRenewsAt: Int?
53+
+ private var paymentPlatform: String?
54+
+ let status: String?
55+
`
56+
57+
await userDefaultsWrapper()
58+
expect(dm.fail).not.toHaveBeenCalled()
59+
})
60+
61+
it("does not fail with UserDefaultsWrapper usage additions", async () => {
62+
dm.addedLines = `
63+
+ let userDefaults: UserDefaults = UserDefaultsWrapper<Any>.sharedDefaults
64+
`
65+
66+
await userDefaultsWrapper()
67+
expect(dm.fail).not.toHaveBeenCalled()
68+
})
69+
70+
it("does not fail with commented out @UserDefaultsWrapper additions", async () => {
71+
dm.addedLines = `
72+
+ // @UserDefaultsWrapper(key: .homePageIsFavoriteVisible, defaultValue: true)
73+
`
74+
75+
await userDefaultsWrapper()
76+
expect(dm.fail).not.toHaveBeenCalled()
77+
})
78+
79+
it("fails with @UserDefaultsWrapper additions", async () => {
80+
dm.addedLines = `
81+
+ @UserDefaultsWrapper(key: .homePageIsFavoriteVisible, defaultValue: true)
82+
`
83+
84+
await userDefaultsWrapper()
85+
expect(dm.fail).toHaveBeenCalled()
86+
})
87+
88+
it("fails with @UserDefaultsWrapper additions with open bracket only", async () => {
89+
dm.addedLines = `
90+
+ @UserDefaultsWrapper(
91+
+ key: .homePageIsFavoriteVisible,
92+
+ defaultValue: true
93+
+ )
94+
`
95+
96+
await userDefaultsWrapper()
97+
expect(dm.fail).toHaveBeenCalled()
98+
})
99+
100+
it("fails with @UserDefaultsWrapper additions without parameters", async () => {
101+
dm.addedLines = `
102+
+ @UserDefaultsWrapper
103+
+ private var didCrashDuringCrashHandlersSetUp: Bool
104+
`
105+
106+
await userDefaultsWrapper()
107+
expect(dm.fail).toHaveBeenCalled()
108+
})
109+
110+
it("does not fail with @UserDefaultsWrapper deletions", async () => {
111+
dm.addedLines = `
112+
- @UserDefaultsWrapper
113+
- private var didCrashDuringCrashHandlersSetUp: Bool
114+
-
115+
- @UserDefaultsWrapper(
116+
- key: .homePageIsFavoriteVisible,
117+
- defaultValue: true
118+
- )
119+
-
120+
- @UserDefaultsWrapper(key: .homePageIsFavoriteVisible, defaultValue: true)
121+
- var isFavoriteVisible: Bool
122+
`
123+
124+
await userDefaultsWrapper()
125+
expect(dm.fail).not.toHaveBeenCalled()
126+
})
127+
})

0 commit comments

Comments
 (0)