danger-compose_compiler_metrics 0.0.2 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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,