danger-compose_compiler_metrics 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -2,45 +2,413 @@
2
2
 
3
3
  require File.expand_path("spec_helper", __dir__)
4
4
 
5
- module Danger
6
- describe Danger::DangerComposeCompilerMetrics do
7
- it "should be a plugin" do
8
- expect(Danger::DangerComposeCompilerMetrics.new(nil)).to be_a Danger::Plugin
5
+ describe Danger::DangerComposeCompilerMetrics do
6
+ let(:dangerfile) { testing_dangerfile }
7
+ let(:plugin) { dangerfile.compose_compiler_metrics }
8
+
9
+ describe "#new" do
10
+ subject { plugin }
11
+
12
+ it { is_expected.to be_a Danger::Plugin }
13
+ end
14
+
15
+ describe "#report_difference" do
16
+ subject { plugin.report_difference(metrics_path, reference_metrics_path) }
17
+
18
+ let(:file_timestamp) { Time.new(2024, 1, 1, 0, 0, 0) }
19
+ let(:metrics_path) { "#{File.dirname(__FILE__)}/support/fixtures/compose_compiler_metrics" }
20
+ let(:reference_metrics_path) { "#{File.dirname(__FILE__)}/support/fixtures/compose_compiler_metrics_baseline" }
21
+
22
+ before do
23
+ [
24
+ metrics_path,
25
+ reference_metrics_path
26
+ ].each do |dir|
27
+ Dir.glob("#{dir}/*").each do |file|
28
+ FileUtils.touch(file, mtime: file_timestamp)
29
+ end
30
+ end
9
31
  end
10
32
 
11
- #
12
- # You should test your custom attributes and methods here
13
- #
14
- describe "with Dangerfile" do
15
- before do
16
- @dangerfile = testing_dangerfile
17
- @my_plugin = @dangerfile.compose_compiler_metrics
33
+ let(:expect_report_list) do
34
+ [
35
+ "# Compose Compiler Metrics Difference Report",
36
+ "## app - debug",
37
+ <<~MARKDOWN,
38
+ <details>
39
+ <summary>
40
+
41
+ ### Metrics Summary
42
+
43
+ </summary>
44
+
45
+ #### Composables
46
+
47
+ | name | reference | new | diff |
48
+ | --- | --- | --- | --- |
49
+ | skippableComposables | 5 | 6 | +1 |
50
+ | unskippableComposables | 3 | 1 | -2 |
51
+ | restartableComposables | 8 | 7 | -1 |
52
+ | unrestartableComposables | 0 | 0 | |
53
+ | readonlyComposables | 0 | 0 | |
54
+ | totalComposables | 8 | 7 | -1 |
55
+
56
+ #### Groups
57
+
58
+ | name | reference | new | diff |
59
+ | --- | --- | --- | --- |
60
+ | restartGroups | 8 | 7 | -1 |
61
+ | totalGroups | 11 | 7 | -4 |
62
+
63
+ #### Arguments
64
+
65
+ | name | reference | new | diff |
66
+ | --- | --- | --- | --- |
67
+ | staticArguments | 5 | 4 | -1 |
68
+ | certainArguments | 5 | 4 | -1 |
69
+ | knownStableArguments | 50 | 47 | -3 |
70
+ | knownUnstableArguments | 2 | 0 | -2 |
71
+ | unknownStableArguments | 0 | 0 | |
72
+ | totalArguments | 52 | 47 | -5 |
73
+
74
+ #### Classes
75
+
76
+ | name | reference | new | diff |
77
+ | --- | --- | --- | --- |
78
+ | markedStableClasses | 0 | 0 | |
79
+ | inferredStableClasses | 1 | 2 | +1 |
80
+ | inferredUnstableClasses | 1 | 0 | -1 |
81
+ | inferredUncertainClasses | 0 | 0 | |
82
+ | effectivelyStableClasses | 1 | 2 | +1 |
83
+ | totalClasses | 2 | 2 | |
84
+
85
+ #### Lambdas
86
+
87
+ | name | reference | new | diff |
88
+ | --- | --- | --- | --- |
89
+ | memoizedLambdas | 4 | 4 | |
90
+ | singletonLambdas | 0 | 0 | |
91
+ | singletonComposableLambdas | 3 | 3 | |
92
+ | composableLambdas | 3 | 3 | |
93
+ | totalLambdas | 5 | 4 | -1 |
94
+
95
+ </details>
96
+ MARKDOWN
97
+ <<~MARKDOWN,
98
+ <details>
99
+ <summary>
100
+
101
+ ### Metrics
102
+
103
+ </summary>
104
+
105
+ ```diff
106
+ --- #{File.dirname(__FILE__)}/support/fixtures/compose_compiler_metrics_baseline/app_debug-module.json #{file_timestamp.strftime('%F %T.%N %z')}
107
+ +++ #{File.dirname(__FILE__)}/support/fixtures/compose_compiler_metrics/app_debug-module.json #{file_timestamp.strftime('%F %T.%N %z')}
108
+ @@ -1,25 +1,25 @@
109
+ {
110
+ - "skippableComposables": 5,
111
+ - "restartableComposables": 8,
112
+ + "skippableComposables": 6,
113
+ + "restartableComposables": 7,
114
+ "readonlyComposables": 0,
115
+ - "totalComposables": 8,
116
+ - "restartGroups": 8,
117
+ - "totalGroups": 11,
118
+ - "staticArguments": 5,
119
+ - "certainArguments": 5,
120
+ - "knownStableArguments": 50,
121
+ - "knownUnstableArguments": 2,
122
+ + "totalComposables": 7,
123
+ + "restartGroups": 7,
124
+ + "totalGroups": 7,
125
+ + "staticArguments": 4,
126
+ + "certainArguments": 4,
127
+ + "knownStableArguments": 47,
128
+ + "knownUnstableArguments": 0,
129
+ "unknownStableArguments": 0,
130
+ - "totalArguments": 52,
131
+ + "totalArguments": 47,
132
+ "markedStableClasses": 0,
133
+ - "inferredStableClasses": 1,
134
+ - "inferredUnstableClasses": 1,
135
+ + "inferredStableClasses": 2,
136
+ + "inferredUnstableClasses": 0,
137
+ "inferredUncertainClasses": 0,
138
+ - "effectivelyStableClasses": 1,
139
+ + "effectivelyStableClasses": 2,
140
+ "totalClasses": 2,
141
+ "memoizedLambdas": 4,
142
+ "singletonLambdas": 0,
143
+ "singletonComposableLambdas": 3,
144
+ "composableLambdas": 3,
145
+ - "totalLambdas": 5
146
+ + "totalLambdas": 4
147
+ }
148
+ \
149
+
150
+ ```
151
+
152
+
153
+ </details>
154
+ MARKDOWN
155
+ <<~MARKDOWN,
156
+ <details>
157
+ <summary>
158
+
159
+ ### Composable Stats Report
160
+
161
+ </summary>
162
+
163
+ ```diff
164
+ --- #{File.dirname(__FILE__)}/support/fixtures/compose_compiler_metrics_baseline/app_debug-composables.csv #{file_timestamp.strftime('%F %T.%N %z')}
165
+ +++ #{File.dirname(__FILE__)}/support/fixtures/compose_compiler_metrics/app_debug-composables.csv #{file_timestamp.strftime('%F %T.%N %z')}
166
+ @@ -1,5 +1,4 @@
167
+ package,name,composable,skippable,restartable,readonly,inline,isLambda,hasDefaults,defaultsGroup,groups,calls,
168
+ -com.example.android.ContactRow,ContactRow,1,0,1,0,0,0,0,0,1,2,
169
+ +com.example.android.ContactRow,ContactRow,1,1,1,0,0,0,0,0,1,2,
170
+ com.example.android.ToggleButton,ToggleButton,1,1,1,0,0,0,0,0,1,1,
171
+ -com.example.android.ContactDetails,ContactDetails,1,0,1,0,0,0,0,0,1,1,
172
+ -com.example.android.ui.theme.ExampleTheme,ExampleTheme,1,1,1,0,0,0,1,0,4,5,
173
+ +com.example.android.ContactDetails,ContactDetails,1,1,1,0,0,0,0,0,1,1,
174
+
175
+ ```
176
+
177
+
178
+ </details>
179
+ MARKDOWN
180
+ <<~MARKDOWN,
181
+ <details>
182
+ <summary>
183
+
184
+ ### Composable Report
185
+
186
+ </summary>
187
+
188
+ ```diff
189
+ --- #{File.dirname(__FILE__)}/support/fixtures/compose_compiler_metrics_baseline/app_debug-composables.txt #{file_timestamp.strftime('%F %T.%N %z')}
190
+ +++ #{File.dirname(__FILE__)}/support/fixtures/compose_compiler_metrics/app_debug-composables.txt #{file_timestamp.strftime('%F %T.%N %z')}
191
+ @@ -1,16 +1,11 @@
192
+ -restartable scheme("[androidx.compose.ui.UiComposable]") fun ContactRow(
193
+ - unstable contact: Contact
194
+ +restartable skippable scheme("[androidx.compose.ui.UiComposable]") fun ContactRow(
195
+ + stable contact: Contact
196
+ stable modifier: Modifier? = @static Companion
197
+ )
198
+ restartable skippable scheme("[androidx.compose.ui.UiComposable]") fun ToggleButton(
199
+ stable selected: Boolean
200
+ stable onToggled: Function1<Boolean, Unit>
201
+ )
202
+ -restartable scheme("[androidx.compose.ui.UiComposable]") fun ContactDetails(
203
+ - unstable contact: Contact
204
+ -)
205
+ -restartable skippable scheme("[0, [0]]") fun ExampleTheme(
206
+ - stable darkTheme: Boolean = @dynamic isSystemInDarkTheme($composer, 0)
207
+ - stable dynamicColor: Boolean = @static true
208
+ - stable content: Function2<Composer, Int, Unit>
209
+ +restartable skippable scheme("[androidx.compose.ui.UiComposable]") fun ContactDetails(
210
+ + stable contact: Contact
211
+ )
212
+
213
+ ```
214
+
18
215
 
19
- # mock the PR data
20
- # you can then use this, eg. github.pr_author, later in the spec
21
- json = File.read("#{File.dirname(__FILE__)}/support/fixtures/github_pr.json") # example json: `curl https://api.github.com/repos/danger/danger-plugin-template/pulls/18 > github_pr.json`
22
- allow(@my_plugin.github).to receive(:pr_json).and_return(json)
216
+ </details>
217
+ MARKDOWN
218
+ <<~MARKDOWN
219
+ <details>
220
+ <summary>
221
+
222
+ ### Class Report
223
+
224
+ </summary>
225
+
226
+ ```diff
227
+ --- #{File.dirname(__FILE__)}/support/fixtures/compose_compiler_metrics_baseline/app_debug-classes.txt #{file_timestamp.strftime('%F %T.%N %z')}
228
+ +++ #{File.dirname(__FILE__)}/support/fixtures/compose_compiler_metrics/app_debug-classes.txt #{file_timestamp.strftime('%F %T.%N %z')}
229
+ @@ -1,8 +1,8 @@
230
+ stable class MainActivity {
231
+ <runtime stability> = Stable
232
+ }
233
+ -unstable class Contact {
234
+ - stable var name: String
235
+ +stable class Contact {
236
+ + stable val name: String
237
+ stable val number: String
238
+ - <runtime stability> = Unstable
239
+ + <runtime stability> = Stable
240
+ }
241
+
242
+ ```
243
+
244
+
245
+ </details>
246
+ MARKDOWN
247
+ ]
248
+ end
249
+
250
+ it "output markdown summary" do
251
+ subject
252
+
253
+ dangerfile.status_report[:markdowns].map(&:message).each_with_index do |message, index|
254
+ expect(message).to eq(expect_report_list[index])
23
255
  end
256
+ end
24
257
 
25
- # Some examples for writing tests
26
- # You should replace these with your own.
258
+ context "when missing diff command" do
259
+ before do
260
+ allow_any_instance_of(Helper).to receive(:installed?).with("diff").and_return(false)
261
+ end
27
262
 
28
- xit "Warns on a monday" do
29
- monday_date = Date.parse("2016-07-11")
30
- allow(Date).to receive(:today).and_return monday_date
263
+ it do
264
+ within_block_is_expected.to change {
265
+ dangerfile.status_report[:errors]
266
+ }.from(
267
+ be_empty
268
+ ).to(
269
+ ["diff command not found. Please install diff command."]
270
+ )
271
+ end
272
+ end
31
273
 
32
- @my_plugin.warn_on_mondays
274
+ context "when missing reference metrics file" do
275
+ let(:reference_metrics_path) { "#{File.dirname(__FILE__)}/support/fixtures/compose_compiler_metrics_missing" }
33
276
 
34
- expect(@dangerfile.status_report[:warnings]).to eq(["Trying to merge code on a Monday"])
277
+ it do
278
+ within_block_is_expected.to change {
279
+ dangerfile.status_report[:warnings]
280
+ }.from(
281
+ be_empty
282
+ ).to(
283
+ [
284
+ "DangerComposeCompilerMetrics: reference file not found at #{File.dirname(__FILE__)}/support/fixtures/compose_compiler_metrics_missing/app_debug-module.json. Skipping file difference report.",
285
+ "DangerComposeCompilerMetrics: reference file not found at #{File.dirname(__FILE__)}/support/fixtures/compose_compiler_metrics_missing/app_debug-module.json. Skipping file difference report.",
286
+ "DangerComposeCompilerMetrics: reference file not found at #{File.dirname(__FILE__)}/support/fixtures/compose_compiler_metrics_missing/app_debug-composables.csv. Skipping file difference report.",
287
+ "DangerComposeCompilerMetrics: reference file not found at #{File.dirname(__FILE__)}/support/fixtures/compose_compiler_metrics_missing/app_debug-composables.txt. Skipping file difference report.",
288
+ "DangerComposeCompilerMetrics: reference file not found at #{File.dirname(__FILE__)}/support/fixtures/compose_compiler_metrics_missing/app_debug-classes.txt. Skipping file difference report."
289
+ ]
290
+ )
35
291
  end
292
+ end
293
+ end
294
+
295
+ describe "#report" do
296
+ subject { plugin.report(metrics_path) }
297
+
298
+ let(:metrics_path) { "#{File.dirname(__FILE__)}/support/fixtures/compose_compiler_metrics" }
299
+ let(:expect_report_list) do
300
+ [
301
+ "# Compose Compiler Metrics Report",
302
+ "## app - debug",
303
+ <<~MARKDOWN,
304
+ <details>
305
+ <summary>
306
+
307
+ ### Metrics
36
308
 
37
- xit "Does nothing on a tuesday" do
38
- monday_date = Date.parse("2016-07-12")
39
- allow(Date).to receive(:today).and_return monday_date
309
+ </summary>
310
+
311
+ | name | value |
312
+ | --- | --- |
313
+ | skippableComposables | 6 |
314
+ | restartableComposables | 7 |
315
+ | readonlyComposables | 0 |
316
+ | totalComposables | 7 |
317
+ | restartGroups | 7 |
318
+ | totalGroups | 7 |
319
+ | staticArguments | 4 |
320
+ | certainArguments | 4 |
321
+ | knownStableArguments | 47 |
322
+ | knownUnstableArguments | 0 |
323
+ | unknownStableArguments | 0 |
324
+ | totalArguments | 47 |
325
+ | markedStableClasses | 0 |
326
+ | inferredStableClasses | 2 |
327
+ | inferredUnstableClasses | 0 |
328
+ | inferredUncertainClasses | 0 |
329
+ | effectivelyStableClasses | 2 |
330
+ | totalClasses | 2 |
331
+ | memoizedLambdas | 4 |
332
+ | singletonLambdas | 0 |
333
+ | singletonComposableLambdas | 3 |
334
+ | composableLambdas | 3 |
335
+ | totalLambdas | 4 |
336
+
337
+ </details>
338
+ MARKDOWN
339
+ <<~MARKDOWN,
340
+ <details>
341
+ <summary>
342
+
343
+ ### Composable Stats Report
344
+
345
+ </summary>
346
+
347
+ | package | name | composable | skippable | restartable | readonly | inline | isLambda | hasDefaults | defaultsGroup | groups | calls | |
348
+ | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
349
+ | com.example.android.ContactRow | ContactRow | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 2 | |
350
+ | com.example.android.ToggleButton | ToggleButton | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | |
351
+ | com.example.android.ContactDetails | ContactDetails | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | |
352
+
353
+ </details>
354
+ MARKDOWN
355
+ <<~MARKDOWN,
356
+ <details>
357
+ <summary>
358
+
359
+ ### Composable Report
360
+
361
+ </summary>
362
+
363
+ ```kotlin
364
+ restartable skippable scheme("[androidx.compose.ui.UiComposable]") fun ContactRow(
365
+ stable contact: Contact
366
+ stable modifier: Modifier? = @static Companion
367
+ )
368
+ restartable skippable scheme("[androidx.compose.ui.UiComposable]") fun ToggleButton(
369
+ stable selected: Boolean
370
+ stable onToggled: Function1<Boolean, Unit>
371
+ )
372
+ restartable skippable scheme("[androidx.compose.ui.UiComposable]") fun ContactDetails(
373
+ stable contact: Contact
374
+ )
375
+
376
+ ```
377
+
378
+
379
+ </details>
380
+ MARKDOWN
381
+ <<~MARKDOWN
382
+ <details>
383
+ <summary>
384
+
385
+ ### Class Report
386
+
387
+ </summary>
388
+
389
+ ```kotlin
390
+ stable class MainActivity {
391
+ <runtime stability> = Stable
392
+ }
393
+ stable class Contact {
394
+ stable val name: String
395
+ stable val number: String
396
+ <runtime stability> = Stable
397
+ }
398
+
399
+ ```
400
+
401
+
402
+ </details>
403
+ MARKDOWN
404
+ ]
405
+ end
40
406
 
41
- @my_plugin.warn_on_mondays
407
+ it "output markdown summary" do
408
+ subject
42
409
 
43
- expect(@dangerfile.status_report[:warnings]).to eq([])
410
+ dangerfile.status_report[:markdowns].map(&:message).each_with_index do |message, index|
411
+ expect(message).to eq(expect_report_list[index])
44
412
  end
45
413
  end
46
414
  end
@@ -0,0 +1,220 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "./lib/compose_compiler_metrics/metrics"
4
+ require "tempfile"
5
+
6
+ describe Metrics do
7
+ let(:metrics) { described_class.new(hash) }
8
+
9
+ let(:hash) do
10
+ {
11
+ "skippableComposables" => 5,
12
+ "unskippableComposables" => 3,
13
+ "restartableComposables" => 8,
14
+ "unrestartableComposables" => 0,
15
+ "readonlyComposables" => 0,
16
+ "totalComposables" => 8,
17
+ "restartGroups" => 8,
18
+ "totalGroups" => 11,
19
+ "staticArguments" => 5,
20
+ "certainArguments" => 5,
21
+ "knownStableArguments" => 50,
22
+ "knownUnstableArguments" => 2,
23
+ "unknownStableArguments" => 0,
24
+ "totalArguments" => 52,
25
+ "markedStableClasses" => 0,
26
+ "inferredStableClasses" => 1,
27
+ "inferredUnstableClasses" => 1,
28
+ "inferredUncertainClasses" => 0,
29
+ "effectivelyStableClasses" => 1,
30
+ "totalClasses" => 2,
31
+ "memoizedLambdas" => 4,
32
+ "singletonLambdas" => 0,
33
+ "singletonComposableLambdas" => 3,
34
+ "composableLambdas" => 3,
35
+ "totalLambdas" => 5
36
+ }
37
+ end
38
+
39
+ describe "#keys" do
40
+ subject { metrics.keys }
41
+
42
+ it do
43
+ is_expected.to eq %w(
44
+ skippableComposables
45
+ unskippableComposables
46
+ restartableComposables
47
+ unrestartableComposables
48
+ readonlyComposables
49
+ totalComposables
50
+ restartGroups
51
+ totalGroups
52
+ staticArguments
53
+ certainArguments
54
+ knownStableArguments
55
+ knownUnstableArguments
56
+ unknownStableArguments
57
+ totalArguments
58
+ markedStableClasses
59
+ inferredStableClasses
60
+ inferredUnstableClasses
61
+ inferredUncertainClasses
62
+ effectivelyStableClasses
63
+ totalClasses
64
+ memoizedLambdas
65
+ singletonLambdas
66
+ singletonComposableLambdas
67
+ composableLambdas
68
+ totalLambdas
69
+ )
70
+ end
71
+ end
72
+
73
+ describe "#grouping_keys" do
74
+ subject { metrics.grouping_keys }
75
+
76
+ it { is_expected.to eq %w(Composables Groups Arguments Classes Lambdas) }
77
+ end
78
+
79
+ describe "#grouped_metrics" do
80
+ subject { metrics.grouped_metrics }
81
+
82
+ it do
83
+ is_expected.to eq(
84
+ "Composables" => described_class.new(
85
+ "skippableComposables" => 5,
86
+ "unskippableComposables" => 3,
87
+ "restartableComposables" => 8,
88
+ "unrestartableComposables" => 0,
89
+ "readonlyComposables" => 0,
90
+ "totalComposables" => 8
91
+ ),
92
+ "Groups" => described_class.new(
93
+ "restartGroups" => 8,
94
+ "totalGroups" => 11
95
+ ),
96
+ "Arguments" => described_class.new(
97
+ "staticArguments" => 5,
98
+ "certainArguments" => 5,
99
+ "knownStableArguments" => 50,
100
+ "knownUnstableArguments" => 2,
101
+ "unknownStableArguments" => 0,
102
+ "totalArguments" => 52
103
+ ),
104
+ "Classes" => described_class.new(
105
+ "markedStableClasses" => 0,
106
+ "inferredStableClasses" => 1,
107
+ "inferredUnstableClasses" => 1,
108
+ "inferredUncertainClasses" => 0,
109
+ "effectivelyStableClasses" => 1,
110
+ "totalClasses" => 2
111
+ ),
112
+ "Lambdas" => described_class.new(
113
+ "memoizedLambdas" => 4,
114
+ "singletonLambdas" => 0,
115
+ "singletonComposableLambdas" => 3,
116
+ "composableLambdas" => 3,
117
+ "totalLambdas" => 5
118
+ )
119
+ )
120
+ end
121
+ end
122
+
123
+ describe "#skippable_composables" do
124
+ subject { metrics.skippable_composables }
125
+
126
+ it { is_expected.to eq 5 }
127
+ end
128
+
129
+ describe "#unskippable_composables" do
130
+ subject { metrics.unskippable_composables }
131
+
132
+ it { is_expected.to eq 3 }
133
+ end
134
+
135
+ describe "#total_composables" do
136
+ subject { metrics.total_composables }
137
+
138
+ it { is_expected.to eq 8 }
139
+ end
140
+
141
+ describe "#to_h" do
142
+ subject { metrics.to_h }
143
+
144
+ it { is_expected.to eq metrics.hash }
145
+ end
146
+ end
147
+
148
+ describe Metrics::Loader do
149
+ let(:loader) { described_class.new(json_file.path) }
150
+
151
+ let(:json_file) do
152
+ Tempfile.create(["compose_compiler_metrics_", ".json"]).tap do |file|
153
+ file.write(json)
154
+ file.flush
155
+ end
156
+ end
157
+
158
+ let(:json) do
159
+ {
160
+ "skippableComposables" => 5,
161
+ "restartableComposables" => 8,
162
+ "readonlyComposables" => 0,
163
+ "totalComposables" => 8,
164
+ "restartGroups" => 8,
165
+ "totalGroups" => 11,
166
+ "staticArguments" => 5,
167
+ "certainArguments" => 5,
168
+ "knownStableArguments" => 50,
169
+ "knownUnstableArguments" => 2,
170
+ "unknownStableArguments" => 0,
171
+ "totalArguments" => 52,
172
+ "markedStableClasses" => 0,
173
+ "inferredStableClasses" => 1,
174
+ "inferredUnstableClasses" => 1,
175
+ "inferredUncertainClasses" => 0,
176
+ "effectivelyStableClasses" => 1,
177
+ "totalClasses" => 2,
178
+ "memoizedLambdas" => 4,
179
+ "singletonLambdas" => 0,
180
+ "singletonComposableLambdas" => 3,
181
+ "composableLambdas" => 3,
182
+ "totalLambdas" => 5
183
+ }.to_json
184
+ end
185
+
186
+ describe "#load" do
187
+ subject { loader.load }
188
+
189
+ it do
190
+ is_expected.to have_attributes(
191
+ skippable_composables: 5,
192
+ restartable_composables: 8,
193
+ readonly_composables: 0,
194
+ total_composables: 8,
195
+ restart_groups: 8,
196
+ total_groups: 11,
197
+ static_arguments: 5,
198
+ certain_arguments: 5,
199
+ known_stable_arguments: 50,
200
+ known_unstable_arguments: 2,
201
+ unknown_stable_arguments: 0,
202
+ total_arguments: 52,
203
+ marked_stable_classes: 0,
204
+ inferred_stable_classes: 1,
205
+ inferred_unstable_classes: 1,
206
+ inferred_uncertain_classes: 0,
207
+ effectively_stable_classes: 1,
208
+ total_classes: 2,
209
+ memoized_lambdas: 4,
210
+ singleton_lambdas: 0,
211
+ singleton_composable_lambdas: 3,
212
+ composable_lambdas: 3,
213
+ total_lambdas: 5
214
+ )
215
+ end
216
+
217
+ it { is_expected.to have_attributes(unskippableComposables: 3) }
218
+ it { is_expected.to have_attributes(unrestartableComposables: 0) }
219
+ end
220
+ end
data/spec/spec_helper.rb CHANGED
@@ -17,11 +17,18 @@ if `git remote -v` == ""
17
17
  exit(0)
18
18
  end
19
19
 
20
+ module WithinBlockIsExpected
21
+ def within_block_is_expected
22
+ expect { subject }
23
+ end
24
+ end
25
+
20
26
  # Use coloured output, it's the best.
21
27
  RSpec.configure do |config|
22
28
  config.filter_gems_from_backtrace "bundler"
23
29
  config.color = true
24
30
  config.tty = true
31
+ config.include WithinBlockIsExpected
25
32
  end
26
33
 
27
34
  require "danger_plugin"
@@ -0,0 +1,8 @@
1
+ stable class MainActivity {
2
+ <runtime stability> = Stable
3
+ }
4
+ stable class Contact {
5
+ stable val name: String
6
+ stable val number: String
7
+ <runtime stability> = Stable
8
+ }
@@ -0,0 +1,4 @@
1
+ package,name,composable,skippable,restartable,readonly,inline,isLambda,hasDefaults,defaultsGroup,groups,calls,
2
+ com.example.android.ContactRow,ContactRow,1,1,1,0,0,0,0,0,1,2,
3
+ com.example.android.ToggleButton,ToggleButton,1,1,1,0,0,0,0,0,1,1,
4
+ com.example.android.ContactDetails,ContactDetails,1,1,1,0,0,0,0,0,1,1,