pyglove 0.4.5.dev202410170809__py3-none-any.whl → 0.4.5.dev202410190807__py3-none-any.whl

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.
@@ -13,7 +13,7 @@
13
13
  # limitations under the License.
14
14
 
15
15
  import inspect
16
- from typing import Any, List, Sequence
16
+ from typing import Any
17
17
  import unittest
18
18
 
19
19
  from pyglove.core.views.html import base
@@ -85,13 +85,14 @@ class TooltipTest(TestCase):
85
85
  name='name',
86
86
  ),
87
87
  """
88
- <span class="tooltip str">&#x27;This &lt;hello&gt;&lt;world&gt;&lt;/world&gt;&lt;/hello&gt;.&#x27;</span>
88
+ <span class="tooltip">&#x27;This &lt;hello&gt;&lt;world&gt;&lt;/world&gt;&lt;/hello&gt;.&#x27;</span>
89
89
  """
90
90
  )
91
91
  self.assert_content(
92
92
  self._view.tooltip(
93
93
  1,
94
94
  content=Html.element('div', ['hello']),
95
+ css_classes=['int'],
95
96
  name='name',
96
97
  ),
97
98
  """
@@ -104,7 +105,9 @@ class SummaryTest(TestCase):
104
105
 
105
106
  def test_style(self):
106
107
  self.assert_style(
107
- self._view.summary(1, enable_summary=True),
108
+ self._view.summary(
109
+ 1, enable_summary=True,
110
+ ),
108
111
  """
109
112
  <style>
110
113
  /* Tooltip styles. */
@@ -125,29 +128,56 @@ class SummaryTest(TestCase):
125
128
  margin: -0.5em -0.5em 0;
126
129
  padding: 0.5em;
127
130
  }
128
- .summary_name {
131
+ .summary-name {
129
132
  display: inline;
130
- padding: 0 5px;
133
+ padding: 3px 5px 3px 5px;
134
+ margin: 0 5px;
135
+ border-radius: 3px;
131
136
  }
132
- .summary_title {
137
+ .summary-title {
133
138
  display: inline;
134
139
  }
135
- .summary_name + div.summary_title {
140
+ .summary-name + div.summary-title {
136
141
  display: inline;
137
142
  color: #aaa;
138
143
  }
139
- .summary_title:hover + span.tooltip {
144
+ .summary-title:hover + span.tooltip {
140
145
  visibility: visible;
141
146
  }
142
- /* Type-specific styles. */
143
- .pyglove.str .summary_title {
144
- color: darkred;
145
- font-style: italic;
147
+ .summary-name:hover > span.tooltip {
148
+ visibility: visible;
149
+ background-color: darkblue;
146
150
  }
147
151
  </style>
148
152
  """
149
153
  )
150
154
 
155
+ def test_summary_title(self):
156
+ self.assert_content(
157
+ self._view.summary(
158
+ 1, enable_summary=True, enable_summary_tooltip=False
159
+ ),
160
+ """
161
+ <summary><div class="summary-title">int</div></summary>
162
+ """
163
+ )
164
+ self.assert_content(
165
+ self._view.summary(
166
+ int, enable_summary=True, enable_summary_tooltip=False
167
+ ),
168
+ """
169
+ <summary><div class="summary-title">type</div></summary>
170
+ """
171
+ )
172
+ self.assert_content(
173
+ self._view.summary(
174
+ [0, 1], enable_summary=True, enable_summary_tooltip=False
175
+ ),
176
+ """
177
+ <summary><div class="summary-title">list(...)</div></summary>
178
+ """
179
+ )
180
+
151
181
  def test_enable_summary(self):
152
182
  self.assertIsNone(
153
183
  self._view.summary(1, enable_summary=None),
@@ -161,7 +191,7 @@ class SummaryTest(TestCase):
161
191
  self.assert_content(
162
192
  self._view.summary('foo', enable_summary=True),
163
193
  """
164
- <summary><div class="summary_title">&#x27;foo&#x27;</div><span class="tooltip str">&#x27;foo&#x27;</span></summary>
194
+ <summary><div class="summary-title">str</div><span class="tooltip">&#x27;foo&#x27;</span></summary>
165
195
  """
166
196
  )
167
197
  self.assert_content(
@@ -169,7 +199,22 @@ class SummaryTest(TestCase):
169
199
  'foo', enable_summary=None, max_summary_len_for_str=1
170
200
  ),
171
201
  """
172
- <summary><div class="summary_title">&#x27;f...&#x27;</div><span class="tooltip str">&#x27;foo&#x27;</span></summary>
202
+ <summary><div class="summary-title">str</div><span class="tooltip">&#x27;foo&#x27;</span></summary>
203
+ """
204
+ )
205
+ self.assertIsNone(
206
+ self._view.summary(
207
+ 'foo', enable_summary=None, enable_summary_for_str=False
208
+ ),
209
+ )
210
+
211
+ def test_css_styles(self):
212
+ self.assert_content(
213
+ self._view.summary(
214
+ 'foo', name='x', css_classes=['bar'], enable_summary=True
215
+ ),
216
+ """
217
+ <summary><div class="summary-name bar">x<span class="tooltip bar"></span></div><div class="summary-title bar">str</div><span class="tooltip bar">&#x27;foo&#x27;</span></summary>
173
218
  """
174
219
  )
175
220
 
@@ -180,15 +225,54 @@ class SummaryTest(TestCase):
180
225
  max_summary_len_for_str=5
181
226
  ),
182
227
  """
183
- <summary><div class="summary_title">&#x27;abcde...&#x27;</div><span class="tooltip str">&#x27;abcdefg&#x27;</span></summary>
228
+ <summary><div class="summary-title">str</div><span class="tooltip">&#x27;abcdefg&#x27;</span></summary>
184
229
  """
185
230
  )
186
231
 
187
- def test_render_with_name(self):
232
+ def test_name(self):
188
233
  self.assert_content(
189
234
  self._view.summary('foo', name='x'),
190
235
  """
191
- <summary><div class="summary_name">x</div><div class="summary_title">&#x27;foo&#x27;</div><span class="tooltip str">&#x27;foo&#x27;</span></summary>
236
+ <summary><div class="summary-name">x<span class="tooltip"></span></div><div class="summary-title">str</div><span class="tooltip">&#x27;foo&#x27;</span></summary>
237
+ """
238
+ )
239
+
240
+ def test_enable_key_tooltip(self):
241
+ self.assert_content(
242
+ self._view.summary(
243
+ 'foo',
244
+ name='x',
245
+ root_path=KeyPath.parse('y.a.x'),
246
+ enable_summary_tooltip=False,
247
+ enable_key_tooltip=True
248
+ ),
249
+ """
250
+ <summary><div class="summary-name">x<span class="tooltip">y.a.x</span></div><div class="summary-title">str</div></summary>
251
+ """
252
+ )
253
+ self.assert_content(
254
+ self._view.summary(
255
+ 'foo',
256
+ name='x',
257
+ root_path=KeyPath.parse('y.a.x'),
258
+ enable_summary_tooltip=False,
259
+ enable_key_tooltip=False
260
+ ),
261
+ """
262
+ <summary><div class="summary-name">x</div><div class="summary-title">str</div></summary>
263
+ """
264
+ )
265
+
266
+ def test_summary_color(self):
267
+ self.assert_content(
268
+ self._view.summary(
269
+ 'foo',
270
+ name='x',
271
+ summary_color=('white', 'red'),
272
+ enable_summary_tooltip=False
273
+ ),
274
+ """
275
+ <summary><div class="summary-name" style="color:white;background-color:red;">x<span class="tooltip"></span></div><div class="summary-title">str</div></summary>
192
276
  """
193
277
  )
194
278
 
@@ -198,7 +282,7 @@ class SummaryTest(TestCase):
198
282
  'foo', enable_summary=True, enable_summary_tooltip=True
199
283
  ),
200
284
  """
201
- <summary><div class="summary_title">&#x27;foo&#x27;</div><span class="tooltip str">&#x27;foo&#x27;</span></summary>
285
+ <summary><div class="summary-title">str</div><span class="tooltip">&#x27;foo&#x27;</span></summary>
202
286
  """
203
287
  )
204
288
  self.assert_content(
@@ -206,7 +290,7 @@ class SummaryTest(TestCase):
206
290
  'foo', enable_summary=True, enable_summary_tooltip=False
207
291
  ),
208
292
  """
209
- <summary><div class="summary_title">&#x27;foo&#x27;</div></summary>
293
+ <summary><div class="summary-title">str</div></summary>
210
294
  """
211
295
  )
212
296
 
@@ -230,51 +314,65 @@ class ContentTest(TestCase):
230
314
  position: absolute;
231
315
  z-index: 1;
232
316
  }
233
- /* Object key styles. */
234
- .object_key {
235
- margin-right: 0.25em;
317
+ /* Summary styles. */
318
+ details.pyglove summary {
319
+ font-weight: bold;
320
+ margin: -0.5em -0.5em 0;
321
+ padding: 0.5em;
236
322
  }
237
- .object_key:hover + .tooltip {
238
- visibility: visible;
239
- background-color: darkblue;
323
+ .summary-name {
324
+ display: inline;
325
+ padding: 3px 5px 3px 5px;
326
+ margin: 0 5px;
327
+ border-radius: 3px;
240
328
  }
241
- .object_key.str {
242
- color: gray;
243
- border: 1px solid lightgray;
244
- background-color: ButtonFace;
245
- border-radius: 0.2em;
246
- padding: 0.3em;
329
+ .summary-title {
330
+ display: inline;
247
331
  }
248
- .object_key.int::before{
249
- content: '[';
332
+ .summary-name + div.summary-title {
333
+ display: inline;
334
+ color: #aaa;
250
335
  }
251
- .object_key.int::after{
252
- content: ']';
336
+ .summary-title:hover + span.tooltip {
337
+ visibility: visible;
253
338
  }
254
- .object_key.int{
255
- border: 0;
256
- color: lightgray;
257
- background-color: transparent;
258
- border-radius: 0;
259
- padding: 0;
339
+ .summary-name:hover > span.tooltip {
340
+ visibility: visible;
341
+ background-color: darkblue;
260
342
  }
261
343
  /* Simple value styles. */
262
- .simple_value {
344
+ .simple-value {
263
345
  color: blue;
264
346
  display: inline-block;
265
347
  white-space: pre-wrap;
266
348
  padding: 0.2em;
267
349
  margin-top: 0.15em;
268
350
  }
269
- .simple_value.str {
351
+ .simple-value.str {
270
352
  color: darkred;
271
353
  font-style: italic;
272
354
  }
273
- .simple_value.int, .simple_value.float {
355
+ .simple-value.int, .simple-value.float {
274
356
  color: darkblue;
275
357
  }
358
+ /* Value details styles. */
359
+ details.pyglove {
360
+ border: 1px solid #aaa;
361
+ border-radius: 4px;
362
+ padding: 0.5em 0.5em 0;
363
+ margin: 0.25em 0;
364
+ }
365
+ details.pyglove[open] {
366
+ padding: 0.5em 0.5em 0.5em;
367
+ }
368
+ .highlight {
369
+ background-color: Mark;
370
+ }
371
+ .lowlight {
372
+ opacity: 0.2;
373
+ }
276
374
  /* Complex value styles. */
277
- span.empty_container::before {
375
+ span.empty-container::before {
278
376
  content: '(empty)';
279
377
  font-style: italic;
280
378
  margin-left: 0.5em;
@@ -288,31 +386,31 @@ class ContentTest(TestCase):
288
386
  self.assert_content(
289
387
  self._view.content(1),
290
388
  """
291
- <span class="simple_value int">1</span>
389
+ <span class="simple-value int">1</span>
292
390
  """
293
391
  )
294
392
  self.assert_content(
295
393
  self._view.content(1.5),
296
394
  """
297
- <span class="simple_value float">1.5</span>
395
+ <span class="simple-value float">1.5</span>
298
396
  """
299
397
  )
300
398
  self.assert_content(
301
399
  self._view.content(True),
302
400
  """
303
- <span class="simple_value bool">True</span>
401
+ <span class="simple-value bool">True</span>
304
402
  """
305
403
  )
306
404
  self.assert_content(
307
405
  self._view.content(None),
308
406
  """
309
- <span class="simple_value none-type">None</span>
407
+ <span class="simple-value none-type">None</span>
310
408
  """
311
409
  )
312
410
  self.assert_content(
313
411
  self._view.content('<foo>'),
314
412
  """
315
- <span class="simple_value str">&#x27;&lt;foo&gt;&#x27;</span>
413
+ <span class="simple-value str">&#x27;&lt;foo&gt;&#x27;</span>
316
414
  """
317
415
  )
318
416
  self.assert_content(
@@ -320,7 +418,7 @@ class ContentTest(TestCase):
320
418
  '<hello><world> \nto everyone.', max_summary_len_for_str=10
321
419
  ),
322
420
  """
323
- <span class="simple_value str">&lt;hello&gt;&lt;world&gt;
421
+ <span class="simple-value str">&lt;hello&gt;&lt;world&gt;
324
422
  to everyone.</span>
325
423
  """
326
424
  )
@@ -329,13 +427,19 @@ class ContentTest(TestCase):
329
427
  self.assert_content(
330
428
  self._view.content([1, 2, 'abc']),
331
429
  """
332
- <div class="complex_value list"><table><tr><td><span class="object_key int">0</span><span class="tooltip key-path">[0]</span></td><td><div><span class="simple_value int">1</span></div></td></tr><tr><td><span class="object_key int">1</span><span class="tooltip key-path">[1]</span></td><td><div><span class="simple_value int">2</span></div></td></tr><tr><td><span class="object_key int">2</span><span class="tooltip key-path">[2]</span></td><td><div><span class="simple_value str">&#x27;abc&#x27;</span></div></td></tr></table></div>
430
+ <div class="complex-value list"><table><tr><td><span class="object-key int">0</span><span class="tooltip">[0]</span></td><td><span class="simple-value int">1</span></td></tr><tr><td><span class="object-key int">1</span><span class="tooltip">[1]</span></td><td><span class="simple-value int">2</span></td></tr><tr><td><span class="object-key int">2</span><span class="tooltip">[2]</span></td><td><span class="simple-value str">&#x27;abc&#x27;</span></td></tr></table></div>
431
+ """
432
+ )
433
+ self.assert_content(
434
+ self._view.content([1, 2, 'abc'], key_style='label'),
435
+ """
436
+ <div class="complex-value list"><table><tr><td><span class="object-key int">0</span><span class="tooltip">[0]</span></td><td><span class="simple-value int">1</span></td></tr><tr><td><span class="object-key int">1</span><span class="tooltip">[1]</span></td><td><span class="simple-value int">2</span></td></tr><tr><td><span class="object-key int">2</span><span class="tooltip">[2]</span></td><td><span class="simple-value str">&#x27;abc&#x27;</span></td></tr></table></div>
333
437
  """
334
438
  )
335
439
  self.assert_content(
336
440
  self._view.content([]),
337
441
  """
338
- <div class="complex_value list"><span class="empty_container"></span></div>
442
+ <div class="complex-value list"><span class="empty-container"></span></div>
339
443
  """
340
444
  )
341
445
 
@@ -343,13 +447,19 @@ class ContentTest(TestCase):
343
447
  self.assert_content(
344
448
  self._view.content((1, True)),
345
449
  """
346
- <div class="complex_value tuple"><table><tr><td><span class="object_key int">0</span><span class="tooltip key-path">[0]</span></td><td><div><span class="simple_value int">1</span></div></td></tr><tr><td><span class="object_key int">1</span><span class="tooltip key-path">[1]</span></td><td><div><span class="simple_value bool">True</span></div></td></tr></table></div>
450
+ <div class="complex-value tuple"><table><tr><td><span class="object-key int">0</span><span class="tooltip">[0]</span></td><td><span class="simple-value int">1</span></td></tr><tr><td><span class="object-key int">1</span><span class="tooltip">[1]</span></td><td><span class="simple-value bool">True</span></td></tr></table></div>
451
+ """
452
+ )
453
+ self.assert_content(
454
+ self._view.content((1, True), key_style='label'),
455
+ """
456
+ <div class="complex-value tuple"><table><tr><td><span class="object-key int">0</span><span class="tooltip">[0]</span></td><td><span class="simple-value int">1</span></td></tr><tr><td><span class="object-key int">1</span><span class="tooltip">[1]</span></td><td><span class="simple-value bool">True</span></td></tr></table></div>
347
457
  """
348
458
  )
349
459
  self.assert_content(
350
460
  self._view.content(()),
351
461
  """
352
- <div class="complex_value tuple"><span class="empty_container"></span></div>
462
+ <div class="complex-value tuple"><span class="empty-container"></span></div>
353
463
  """
354
464
  )
355
465
 
@@ -357,13 +467,19 @@ class ContentTest(TestCase):
357
467
  self.assert_content(
358
468
  self._view.content(dict(x=1, y='foo')),
359
469
  """
360
- <div class="complex_value dict"><table><tr><td><span class="object_key str">x</span><span class="tooltip key-path">x</span></td><td><div><span class="simple_value int">1</span></div></td></tr><tr><td><span class="object_key str">y</span><span class="tooltip key-path">y</span></td><td><div><span class="simple_value str">&#x27;foo&#x27;</span></div></td></tr></table></div>
470
+ <div class="complex-value dict"><details open class="pyglove int"><summary><div class="summary-name">x<span class="tooltip">x</span></div><div class="summary-title">int</div><span class="tooltip">1</span></summary><span class="simple-value int">1</span></details><details open class="pyglove str"><summary><div class="summary-name">y<span class="tooltip">y</span></div><div class="summary-title">str</div><span class="tooltip">&#x27;foo&#x27;</span></summary><span class="simple-value str">&#x27;foo&#x27;</span></details></div>
471
+ """
472
+ )
473
+ self.assert_content(
474
+ self._view.content(dict(x=1, y='foo'), key_style='label'),
475
+ """
476
+ <div class="complex-value dict"><table><tr><td><span class="object-key str">x</span><span class="tooltip">x</span></td><td><span class="simple-value int">1</span></td></tr><tr><td><span class="object-key str">y</span><span class="tooltip">y</span></td><td><span class="simple-value str">&#x27;foo&#x27;</span></td></tr></table></div>
361
477
  """
362
478
  )
363
479
  self.assert_content(
364
480
  self._view.content({}),
365
481
  """
366
- <div class="complex_value dict"><span class="empty_container"></span></div>
482
+ <div class="complex-value dict"><span class="empty-container"></span></div>
367
483
  """
368
484
  )
369
485
 
@@ -376,17 +492,17 @@ class ContentTest(TestCase):
376
492
  self.assert_content(
377
493
  self._view.content(Foo()),
378
494
  """
379
- <span class="simple_value foo">&lt;Foo&gt;&lt;/Foo&gt;</span>
495
+ <span class="simple-value foo">&lt;Foo&gt;&lt;/Foo&gt;</span>
380
496
  """
381
497
  )
382
498
 
383
499
  def test_custom_key_value_render(self):
384
- def render_key(key, **kwargs):
385
- del kwargs
500
+ def render_key(view, key, **kwargs):
501
+ del view, kwargs
386
502
  return Html.element('span', [f'custom {key}'])
387
503
 
388
- def render_value(value, **kwargs):
389
- del kwargs
504
+ def render_value(view, *, value, **kwargs):
505
+ del view, kwargs
390
506
  return Html.element('span', [f'custom {value}'])
391
507
 
392
508
  self.assert_content(
@@ -398,11 +514,24 @@ class ContentTest(TestCase):
398
514
  render_value_fn=render_value,
399
515
  ),
400
516
  """
401
- <div class="complex_value none-type"><table><tr><td><span>custom x</span></td><td><div><span>custom 1</span></div></td></tr><tr><td><span>custom y</span></td><td><div><span>custom foo</span></div></td></tr></table></div>
517
+ <div class="complex-value none-type"><span>custom 1</span><span>custom foo</span></div>
518
+ """
519
+ )
520
+ self.assert_content(
521
+ self._view.complex_value(
522
+ dict(x=1, y='foo'),
523
+ parent=None,
524
+ key_style='label',
525
+ root_path=KeyPath(),
526
+ render_key_fn=render_key,
527
+ render_value_fn=render_value,
528
+ ),
529
+ """
530
+ <div class="complex-value none-type"><table><tr><td><span>custom x</span></td><td><span>custom 1</span></td></tr><tr><td><span>custom y</span></td><td><span>custom foo</span></td></tr></table></div>
402
531
  """
403
532
  )
404
533
 
405
- def test_nesting(self):
534
+ def test_key_style_with_nesting(self):
406
535
 
407
536
  class Foo:
408
537
  def __str__(self):
@@ -420,16 +549,106 @@ class ContentTest(TestCase):
420
549
  ]
421
550
  ),
422
551
  """
423
- <div class="complex_value list"><table><tr><td><span class="object_key int">0</span><span class="tooltip key-path">[0]</span></td><td><div><details class="pyglove dict"><summary><div class="summary_title">dict(...)</div><span class="tooltip dict">{
552
+ <div class="complex-value list"><table><tr><td><span class="object-key int">0</span><span class="tooltip">[0]</span></td><td><details class="pyglove dict"><summary><div class="summary-title">dict(...)</div><span class="tooltip">{
553
+ &#x27;x&#x27;: [(1, 2)],
554
+ &#x27;y&#x27;: [&#x27;b&#x27;, &lt;Foo&gt;&lt;/Foo&gt;]
555
+ }</span></summary><div class="complex-value dict"><details class="pyglove list"><summary><div class="summary-name">x<span class="tooltip">[0].x</span></div><div class="summary-title">list(...)</div><span class="tooltip">[(1, 2)]</span></summary><div class="complex-value list"><table><tr><td><span class="object-key int">0</span><span class="tooltip">[0].x[0]</span></td><td><details class="pyglove tuple"><summary><div class="summary-title">tuple(...)</div><span class="tooltip">(1, 2)</span></summary><div class="complex-value tuple"><table><tr><td><span class="object-key int">0</span><span class="tooltip">[0].x[0][0]</span></td><td><span class="simple-value int">1</span></td></tr><tr><td><span class="object-key int">1</span><span class="tooltip">[0].x[0][1]</span></td><td><span class="simple-value int">2</span></td></tr></table></div></details></td></tr></table></div></details><details class="pyglove list"><summary><div class="summary-name">y<span class="tooltip">[0].y</span></div><div class="summary-title">list(...)</div><span class="tooltip">[&#x27;b&#x27;, &lt;Foo&gt;&lt;/Foo&gt;]</span></summary><div class="complex-value list"><table><tr><td><span class="object-key int">0</span><span class="tooltip">[0].y[0]</span></td><td><span class="simple-value str">&#x27;b&#x27;</span></td></tr><tr><td><span class="object-key int">1</span><span class="tooltip">[0].y[1]</span></td><td><details class="pyglove foo"><summary><div class="summary-title">Foo(...)</div><span class="tooltip">&lt;Foo&gt;&lt;/Foo&gt;</span></summary><span class="simple-value foo">&lt;Foo&gt;&lt;/Foo&gt;</span></details></td></tr></table></div></details></div></details></td></tr><tr><td><span class="object-key int">1</span><span class="tooltip">[1]</span></td><td><span class="simple-value int">1</span></td></tr><tr><td><span class="object-key int">2</span><span class="tooltip">[2]</span></td><td><details class="pyglove list"><summary><div class="summary-title">list(...)</div><span class="tooltip">[1, {
556
+ &#x27;xx&#x27;: 1,
557
+ &#x27;yy&#x27;: &#x27;a&#x27;
558
+ }]</span></summary><div class="complex-value list"><table><tr><td><span class="object-key int">0</span><span class="tooltip">[2][0]</span></td><td><span class="simple-value int">1</span></td></tr><tr><td><span class="object-key int">1</span><span class="tooltip">[2][1]</span></td><td><details class="pyglove dict"><summary><div class="summary-title">dict(...)</div><span class="tooltip">{
559
+ &#x27;xx&#x27;: 1,
560
+ &#x27;yy&#x27;: &#x27;a&#x27;
561
+ }</span></summary><div class="complex-value dict"><details open class="pyglove int"><summary><div class="summary-name">xx<span class="tooltip">[2][1].xx</span></div><div class="summary-title">int</div><span class="tooltip">1</span></summary><span class="simple-value int">1</span></details><details open class="pyglove str"><summary><div class="summary-name">yy<span class="tooltip">[2][1].yy</span></div><div class="summary-title">str</div><span class="tooltip">&#x27;a&#x27;</span></summary><span class="simple-value str">&#x27;a&#x27;</span></details></div></details></td></tr></table></div></details></td></tr></table></div>
562
+ """
563
+ )
564
+
565
+ self.assert_content(
566
+ self._view.content(
567
+ [
568
+ dict(
569
+ x=[(1, 2)],
570
+ y=['b', Foo()],
571
+ ),
572
+ 1,
573
+ [1, dict(xx=1, yy='a')]
574
+ ],
575
+ key_style='label',
576
+ ),
577
+ """
578
+ <div class="complex-value list"><table><tr><td><span class="object-key int">0</span><span class="tooltip">[0]</span></td><td><details class="pyglove dict"><summary><div class="summary-title">dict(...)</div><span class="tooltip">{
424
579
  &#x27;x&#x27;: [(1, 2)],
425
580
  &#x27;y&#x27;: [&#x27;b&#x27;, &lt;Foo&gt;&lt;/Foo&gt;]
426
- }</span></summary><div class="complex_value dict"><table><tr><td><span class="object_key str">x</span><span class="tooltip key-path">[0].x</span></td><td><div><details class="pyglove list"><summary><div class="summary_title">list(...)</div><span class="tooltip list">[(1, 2)]</span></summary><div class="complex_value list"><table><tr><td><span class="object_key int">0</span><span class="tooltip key-path">[0].x[0]</span></td><td><div><details class="pyglove tuple"><summary><div class="summary_title">tuple(...)</div><span class="tooltip tuple">(1, 2)</span></summary><div class="complex_value tuple"><table><tr><td><span class="object_key int">0</span><span class="tooltip key-path">[0].x[0][0]</span></td><td><div><span class="simple_value int">1</span></div></td></tr><tr><td><span class="object_key int">1</span><span class="tooltip key-path">[0].x[0][1]</span></td><td><div><span class="simple_value int">2</span></div></td></tr></table></div></details></div></td></tr></table></div></details></div></td></tr><tr><td><span class="object_key str">y</span><span class="tooltip key-path">[0].y</span></td><td><div><details class="pyglove list"><summary><div class="summary_title">list(...)</div><span class="tooltip list">[&#x27;b&#x27;, &lt;Foo&gt;&lt;/Foo&gt;]</span></summary><div class="complex_value list"><table><tr><td><span class="object_key int">0</span><span class="tooltip key-path">[0].y[0]</span></td><td><div><span class="simple_value str">&#x27;b&#x27;</span></div></td></tr><tr><td><span class="object_key int">1</span><span class="tooltip key-path">[0].y[1]</span></td><td><div><details class="pyglove foo"><summary><div class="summary_title">Foo(...)</div><span class="tooltip foo">&lt;Foo&gt;&lt;/Foo&gt;</span></summary><span class="simple_value foo">&lt;Foo&gt;&lt;/Foo&gt;</span></details></div></td></tr></table></div></details></div></td></tr></table></div></details></div></td></tr><tr><td><span class="object_key int">1</span><span class="tooltip key-path">[1]</span></td><td><div><span class="simple_value int">1</span></div></td></tr><tr><td><span class="object_key int">2</span><span class="tooltip key-path">[2]</span></td><td><div><details class="pyglove list"><summary><div class="summary_title">list(...)</div><span class="tooltip list">[1, {
581
+ }</span></summary><div class="complex-value dict"><table><tr><td><span class="object-key str">x</span><span class="tooltip">[0].x</span></td><td><details class="pyglove list"><summary><div class="summary-title">list(...)</div><span class="tooltip">[(1, 2)]</span></summary><div class="complex-value list"><table><tr><td><span class="object-key int">0</span><span class="tooltip">[0].x[0]</span></td><td><details class="pyglove tuple"><summary><div class="summary-title">tuple(...)</div><span class="tooltip">(1, 2)</span></summary><div class="complex-value tuple"><table><tr><td><span class="object-key int">0</span><span class="tooltip">[0].x[0][0]</span></td><td><span class="simple-value int">1</span></td></tr><tr><td><span class="object-key int">1</span><span class="tooltip">[0].x[0][1]</span></td><td><span class="simple-value int">2</span></td></tr></table></div></details></td></tr></table></div></details></td></tr><tr><td><span class="object-key str">y</span><span class="tooltip">[0].y</span></td><td><details class="pyglove list"><summary><div class="summary-title">list(...)</div><span class="tooltip">[&#x27;b&#x27;, &lt;Foo&gt;&lt;/Foo&gt;]</span></summary><div class="complex-value list"><table><tr><td><span class="object-key int">0</span><span class="tooltip">[0].y[0]</span></td><td><span class="simple-value str">&#x27;b&#x27;</span></td></tr><tr><td><span class="object-key int">1</span><span class="tooltip">[0].y[1]</span></td><td><details class="pyglove foo"><summary><div class="summary-title">Foo(...)</div><span class="tooltip">&lt;Foo&gt;&lt;/Foo&gt;</span></summary><span class="simple-value foo">&lt;Foo&gt;&lt;/Foo&gt;</span></details></td></tr></table></div></details></td></tr></table></div></details></td></tr><tr><td><span class="object-key int">1</span><span class="tooltip">[1]</span></td><td><span class="simple-value int">1</span></td></tr><tr><td><span class="object-key int">2</span><span class="tooltip">[2]</span></td><td><details class="pyglove list"><summary><div class="summary-title">list(...)</div><span class="tooltip">[1, {
427
582
  &#x27;xx&#x27;: 1,
428
583
  &#x27;yy&#x27;: &#x27;a&#x27;
429
- }]</span></summary><div class="complex_value list"><table><tr><td><span class="object_key int">0</span><span class="tooltip key-path">[2][0]</span></td><td><div><span class="simple_value int">1</span></div></td></tr><tr><td><span class="object_key int">1</span><span class="tooltip key-path">[2][1]</span></td><td><div><details class="pyglove dict"><summary><div class="summary_title">dict(...)</div><span class="tooltip dict">{
584
+ }]</span></summary><div class="complex-value list"><table><tr><td><span class="object-key int">0</span><span class="tooltip">[2][0]</span></td><td><span class="simple-value int">1</span></td></tr><tr><td><span class="object-key int">1</span><span class="tooltip">[2][1]</span></td><td><details class="pyglove dict"><summary><div class="summary-title">dict(...)</div><span class="tooltip">{
430
585
  &#x27;xx&#x27;: 1,
431
586
  &#x27;yy&#x27;: &#x27;a&#x27;
432
- }</span></summary><div class="complex_value dict"><table><tr><td><span class="object_key str">xx</span><span class="tooltip key-path">[2][1].xx</span></td><td><div><span class="simple_value int">1</span></div></td></tr><tr><td><span class="object_key str">yy</span><span class="tooltip key-path">[2][1].yy</span></td><td><div><span class="simple_value str">&#x27;a&#x27;</span></div></td></tr></table></div></details></div></td></tr></table></div></details></div></td></tr></table></div>
587
+ }</span></summary><div class="complex-value dict"><table><tr><td><span class="object-key str">xx</span><span class="tooltip">[2][1].xx</span></td><td><span class="simple-value int">1</span></td></tr><tr><td><span class="object-key str">yy</span><span class="tooltip">[2][1].yy</span></td><td><span class="simple-value str">&#x27;a&#x27;</span></td></tr></table></div></details></td></tr></table></div></details></td></tr></table></div>
588
+ """
589
+ )
590
+
591
+ def _key_style(k, v, p):
592
+ del v, p
593
+ if k and k.key in ('x', 'xx'):
594
+ return 'label'
595
+ return 'summary'
596
+
597
+ self.assert_content(
598
+ self._view.content(
599
+ [
600
+ dict(
601
+ x=[(1, 2)],
602
+ y=['b', Foo()],
603
+ ),
604
+ 1,
605
+ [1, dict(xx=1, yy='a')]
606
+ ],
607
+ key_style=_key_style,
608
+ ),
609
+ """
610
+ <div class="complex-value list"><table><tr><td><span class="object-key int">0</span><span class="tooltip">[0]</span></td><td><details class="pyglove dict"><summary><div class="summary-title">dict(...)</div><span class="tooltip">{
611
+ &#x27;x&#x27;: [(1, 2)],
612
+ &#x27;y&#x27;: [&#x27;b&#x27;, &lt;Foo&gt;&lt;/Foo&gt;]
613
+ }</span></summary><div class="complex-value dict"><details class="pyglove list"><summary><div class="summary-name">y<span class="tooltip">[0].y</span></div><div class="summary-title">list(...)</div><span class="tooltip">[&#x27;b&#x27;, &lt;Foo&gt;&lt;/Foo&gt;]</span></summary><div class="complex-value list"><table><tr><td><span class="object-key int">0</span><span class="tooltip">[0].y[0]</span></td><td><span class="simple-value str">&#x27;b&#x27;</span></td></tr><tr><td><span class="object-key int">1</span><span class="tooltip">[0].y[1]</span></td><td><details class="pyglove foo"><summary><div class="summary-title">Foo(...)</div><span class="tooltip">&lt;Foo&gt;&lt;/Foo&gt;</span></summary><span class="simple-value foo">&lt;Foo&gt;&lt;/Foo&gt;</span></details></td></tr></table></div></details><table><tr><td><span class="object-key str">x</span><span class="tooltip">[0].x</span></td><td><details class="pyglove list"><summary><div class="summary-title">list(...)</div><span class="tooltip">[(1, 2)]</span></summary><div class="complex-value list"><table><tr><td><span class="object-key int">0</span><span class="tooltip">[0].x[0]</span></td><td><details class="pyglove tuple"><summary><div class="summary-title">tuple(...)</div><span class="tooltip">(1, 2)</span></summary><div class="complex-value tuple"><table><tr><td><span class="object-key int">0</span><span class="tooltip">[0].x[0][0]</span></td><td><span class="simple-value int">1</span></td></tr><tr><td><span class="object-key int">1</span><span class="tooltip">[0].x[0][1]</span></td><td><span class="simple-value int">2</span></td></tr></table></div></details></td></tr></table></div></details></td></tr></table></div></details></td></tr><tr><td><span class="object-key int">1</span><span class="tooltip">[1]</span></td><td><span class="simple-value int">1</span></td></tr><tr><td><span class="object-key int">2</span><span class="tooltip">[2]</span></td><td><details class="pyglove list"><summary><div class="summary-title">list(...)</div><span class="tooltip">[1, {
614
+ &#x27;xx&#x27;: 1,
615
+ &#x27;yy&#x27;: &#x27;a&#x27;
616
+ }]</span></summary><div class="complex-value list"><table><tr><td><span class="object-key int">0</span><span class="tooltip">[2][0]</span></td><td><span class="simple-value int">1</span></td></tr><tr><td><span class="object-key int">1</span><span class="tooltip">[2][1]</span></td><td><details class="pyglove dict"><summary><div class="summary-title">dict(...)</div><span class="tooltip">{
617
+ &#x27;xx&#x27;: 1,
618
+ &#x27;yy&#x27;: &#x27;a&#x27;
619
+ }</span></summary><div class="complex-value dict"><details open class="pyglove str"><summary><div class="summary-name">yy<span class="tooltip">[2][1].yy</span></div><div class="summary-title">str</div><span class="tooltip">&#x27;a&#x27;</span></summary><span class="simple-value str">&#x27;a&#x27;</span></details><table><tr><td><span class="object-key str">xx</span><span class="tooltip">[2][1].xx</span></td><td><span class="simple-value int">1</span></td></tr></table></div></details></td></tr></table></div></details></td></tr></table></div>
620
+ """
621
+ )
622
+
623
+ def test_key_color(self):
624
+ self.assert_content(
625
+ self._view.content(
626
+ dict(
627
+ x=[(1, 2)],
628
+ y=['b', dict(y=1)],
629
+ ),
630
+ key_color=('white', 'red'),
631
+ enable_summary_tooltip=False,
632
+ ),
633
+ """
634
+ <div class="complex-value dict"><details class="pyglove list"><summary><div class="summary-name">x<span class="tooltip">x</span></div><div class="summary-title">list(...)</div></summary><div class="complex-value list"><table><tr><td><span class="object-key int" style="color:white;background-color:red;">0</span><span class="tooltip">x[0]</span></td><td><details class="pyglove tuple"><summary><div class="summary-title">tuple(...)</div></summary><div class="complex-value tuple"><table><tr><td><span class="object-key int" style="color:white;background-color:red;">0</span><span class="tooltip">x[0][0]</span></td><td><span class="simple-value int">1</span></td></tr><tr><td><span class="object-key int" style="color:white;background-color:red;">1</span><span class="tooltip">x[0][1]</span></td><td><span class="simple-value int">2</span></td></tr></table></div></details></td></tr></table></div></details><details class="pyglove list"><summary><div class="summary-name">y<span class="tooltip">y</span></div><div class="summary-title">list(...)</div></summary><div class="complex-value list"><table><tr><td><span class="object-key int" style="color:white;background-color:red;">0</span><span class="tooltip">y[0]</span></td><td><span class="simple-value str">&#x27;b&#x27;</span></td></tr><tr><td><span class="object-key int" style="color:white;background-color:red;">1</span><span class="tooltip">y[1]</span></td><td><details class="pyglove dict"><summary><div class="summary-title">dict(...)</div></summary><div class="complex-value dict"><details open class="pyglove int"><summary><div class="summary-name">y<span class="tooltip">y[1].y</span></div><div class="summary-title">int</div></summary><span class="simple-value int">1</span></details></div></details></td></tr></table></div></details></div>
635
+ """
636
+ )
637
+ self.assert_content(
638
+ self._view.content(
639
+ dict(
640
+ x=[(1, 2)],
641
+ y=['b', dict(y=1)],
642
+ ),
643
+ key_style='label',
644
+ enable_summary_tooltip=False,
645
+ key_color=(
646
+ lambda k, v, p: ('white', 'red')
647
+ if k.key == 'y' else (None, None)
648
+ ),
649
+ ),
650
+ """
651
+ <div class="complex-value dict"><table><tr><td><span class="object-key str">x</span><span class="tooltip">x</span></td><td><details class="pyglove list"><summary><div class="summary-title">list(...)</div></summary><div class="complex-value list"><table><tr><td><span class="object-key int">0</span><span class="tooltip">x[0]</span></td><td><details class="pyglove tuple"><summary><div class="summary-title">tuple(...)</div></summary><div class="complex-value tuple"><table><tr><td><span class="object-key int">0</span><span class="tooltip">x[0][0]</span></td><td><span class="simple-value int">1</span></td></tr><tr><td><span class="object-key int">1</span><span class="tooltip">x[0][1]</span></td><td><span class="simple-value int">2</span></td></tr></table></div></details></td></tr></table></div></details></td></tr><tr><td><span class="object-key str" style="color:white;background-color:red;">y</span><span class="tooltip">y</span></td><td><details class="pyglove list"><summary><div class="summary-title">list(...)</div></summary><div class="complex-value list"><table><tr><td><span class="object-key int">0</span><span class="tooltip">y[0]</span></td><td><span class="simple-value str">&#x27;b&#x27;</span></td></tr><tr><td><span class="object-key int">1</span><span class="tooltip">y[1]</span></td><td><details class="pyglove dict"><summary><div class="summary-title">dict(...)</div></summary><div class="complex-value dict"><table><tr><td><span class="object-key str" style="color:white;background-color:red;">y</span><span class="tooltip">y[1].y</span></td><td><span class="simple-value int">1</span></td></tr></table></div></details></td></tr></table></div></details></td></tr></table></div>
433
652
  """
434
653
  )
435
654
 
@@ -450,30 +669,30 @@ class ContentTest(TestCase):
450
669
  self.assert_content(
451
670
  self._view.content(value, enable_summary_tooltip=False),
452
671
  """
453
- <div class="complex_value list"><table><tr><td><span class="object_key int">0</span><span class="tooltip key-path">[0]</span></td><td><div><details class="pyglove dict"><summary><div class="summary_title">dict(...)</div></summary><div class="complex_value dict"><table><tr><td><span class="object_key str">x</span><span class="tooltip key-path">[0].x</span></td><td><div><details class="pyglove list"><summary><div class="summary_title">list(...)</div></summary><div class="complex_value list"><table><tr><td><span class="object_key int">0</span><span class="tooltip key-path">[0].x[0]</span></td><td><div><details class="pyglove tuple"><summary><div class="summary_title">tuple(...)</div></summary><div class="complex_value tuple"><table><tr><td><span class="object_key int">0</span><span class="tooltip key-path">[0].x[0][0]</span></td><td><div><span class="simple_value int">1</span></div></td></tr><tr><td><span class="object_key int">1</span><span class="tooltip key-path">[0].x[0][1]</span></td><td><div><span class="simple_value int">2</span></div></td></tr></table></div></details></div></td></tr></table></div></details></div></td></tr><tr><td><span class="object_key str">y</span><span class="tooltip key-path">[0].y</span></td><td><div><details class="pyglove list"><summary><div class="summary_title">list(...)</div></summary><div class="complex_value list"><table><tr><td><span class="object_key int">0</span><span class="tooltip key-path">[0].y[0]</span></td><td><div><span class="simple_value str">&#x27;b&#x27;</span></div></td></tr><tr><td><span class="object_key int">1</span><span class="tooltip key-path">[0].y[1]</span></td><td><div><details class="pyglove foo"><summary><div class="summary_title">Foo(...)</div></summary><span class="simple_value foo">&lt;Foo&gt;&lt;/Foo&gt;</span></details></div></td></tr></table></div></details></div></td></tr></table></div></details></div></td></tr><tr><td><span class="object_key int">1</span><span class="tooltip key-path">[1]</span></td><td><div><span class="simple_value int">1</span></div></td></tr><tr><td><span class="object_key int">2</span><span class="tooltip key-path">[2]</span></td><td><div><details class="pyglove list"><summary><div class="summary_title">list(...)</div></summary><div class="complex_value list"><table><tr><td><span class="object_key int">0</span><span class="tooltip key-path">[2][0]</span></td><td><div><span class="simple_value int">1</span></div></td></tr><tr><td><span class="object_key int">1</span><span class="tooltip key-path">[2][1]</span></td><td><div><details class="pyglove dict"><summary><div class="summary_title">dict(...)</div></summary><div class="complex_value dict"><table><tr><td><span class="object_key str">xx</span><span class="tooltip key-path">[2][1].xx</span></td><td><div><span class="simple_value int">1</span></div></td></tr><tr><td><span class="object_key str">yy</span><span class="tooltip key-path">[2][1].yy</span></td><td><div><span class="simple_value str">&#x27;a&#x27;</span></div></td></tr></table></div></details></div></td></tr></table></div></details></div></td></tr></table></div>
672
+ <div class="complex-value list"><table><tr><td><span class="object-key int">0</span><span class="tooltip">[0]</span></td><td><details class="pyglove dict"><summary><div class="summary-title">dict(...)</div></summary><div class="complex-value dict"><details class="pyglove list"><summary><div class="summary-name">x<span class="tooltip">[0].x</span></div><div class="summary-title">list(...)</div></summary><div class="complex-value list"><table><tr><td><span class="object-key int">0</span><span class="tooltip">[0].x[0]</span></td><td><details class="pyglove tuple"><summary><div class="summary-title">tuple(...)</div></summary><div class="complex-value tuple"><table><tr><td><span class="object-key int">0</span><span class="tooltip">[0].x[0][0]</span></td><td><span class="simple-value int">1</span></td></tr><tr><td><span class="object-key int">1</span><span class="tooltip">[0].x[0][1]</span></td><td><span class="simple-value int">2</span></td></tr></table></div></details></td></tr></table></div></details><details class="pyglove list"><summary><div class="summary-name">y<span class="tooltip">[0].y</span></div><div class="summary-title">list(...)</div></summary><div class="complex-value list"><table><tr><td><span class="object-key int">0</span><span class="tooltip">[0].y[0]</span></td><td><span class="simple-value str">&#x27;b&#x27;</span></td></tr><tr><td><span class="object-key int">1</span><span class="tooltip">[0].y[1]</span></td><td><details class="pyglove foo"><summary><div class="summary-title">Foo(...)</div></summary><span class="simple-value foo">&lt;Foo&gt;&lt;/Foo&gt;</span></details></td></tr></table></div></details></div></details></td></tr><tr><td><span class="object-key int">1</span><span class="tooltip">[1]</span></td><td><span class="simple-value int">1</span></td></tr><tr><td><span class="object-key int">2</span><span class="tooltip">[2]</span></td><td><details class="pyglove list"><summary><div class="summary-title">list(...)</div></summary><div class="complex-value list"><table><tr><td><span class="object-key int">0</span><span class="tooltip">[2][0]</span></td><td><span class="simple-value int">1</span></td></tr><tr><td><span class="object-key int">1</span><span class="tooltip">[2][1]</span></td><td><details class="pyglove dict"><summary><div class="summary-title">dict(...)</div></summary><div class="complex-value dict"><details open class="pyglove int"><summary><div class="summary-name">xx<span class="tooltip">[2][1].xx</span></div><div class="summary-title">int</div></summary><span class="simple-value int">1</span></details><details open class="pyglove str"><summary><div class="summary-name">yy<span class="tooltip">[2][1].yy</span></div><div class="summary-title">str</div></summary><span class="simple-value str">&#x27;a&#x27;</span></details></div></details></td></tr></table></div></details></td></tr></table></div>
454
673
  """
455
674
  )
456
675
  self.assert_content(
457
676
  self._view.content(value, enable_key_tooltip=False),
458
677
  """
459
- <div class="complex_value list"><table><tr><td><span class="object_key int">0</span></td><td><div><details class="pyglove dict"><summary><div class="summary_title">dict(...)</div><span class="tooltip dict">{
678
+ <div class="complex-value list"><table><tr><td><span class="object-key int">0</span></td><td><details class="pyglove dict"><summary><div class="summary-title">dict(...)</div><span class="tooltip">{
460
679
  &#x27;x&#x27;: [(1, 2)],
461
680
  &#x27;y&#x27;: [&#x27;b&#x27;, &lt;Foo&gt;&lt;/Foo&gt;]
462
- }</span></summary><div class="complex_value dict"><table><tr><td><span class="object_key str">x</span></td><td><div><details class="pyglove list"><summary><div class="summary_title">list(...)</div><span class="tooltip list">[(1, 2)]</span></summary><div class="complex_value list"><table><tr><td><span class="object_key int">0</span></td><td><div><details class="pyglove tuple"><summary><div class="summary_title">tuple(...)</div><span class="tooltip tuple">(1, 2)</span></summary><div class="complex_value tuple"><table><tr><td><span class="object_key int">0</span></td><td><div><span class="simple_value int">1</span></div></td></tr><tr><td><span class="object_key int">1</span></td><td><div><span class="simple_value int">2</span></div></td></tr></table></div></details></div></td></tr></table></div></details></div></td></tr><tr><td><span class="object_key str">y</span></td><td><div><details class="pyglove list"><summary><div class="summary_title">list(...)</div><span class="tooltip list">[&#x27;b&#x27;, &lt;Foo&gt;&lt;/Foo&gt;]</span></summary><div class="complex_value list"><table><tr><td><span class="object_key int">0</span></td><td><div><span class="simple_value str">&#x27;b&#x27;</span></div></td></tr><tr><td><span class="object_key int">1</span></td><td><div><details class="pyglove foo"><summary><div class="summary_title">Foo(...)</div><span class="tooltip foo">&lt;Foo&gt;&lt;/Foo&gt;</span></summary><span class="simple_value foo">&lt;Foo&gt;&lt;/Foo&gt;</span></details></div></td></tr></table></div></details></div></td></tr></table></div></details></div></td></tr><tr><td><span class="object_key int">1</span></td><td><div><span class="simple_value int">1</span></div></td></tr><tr><td><span class="object_key int">2</span></td><td><div><details class="pyglove list"><summary><div class="summary_title">list(...)</div><span class="tooltip list">[1, {
681
+ }</span></summary><div class="complex-value dict"><details class="pyglove list"><summary><div class="summary-name">x</div><div class="summary-title">list(...)</div><span class="tooltip">[(1, 2)]</span></summary><div class="complex-value list"><table><tr><td><span class="object-key int">0</span></td><td><details class="pyglove tuple"><summary><div class="summary-title">tuple(...)</div><span class="tooltip">(1, 2)</span></summary><div class="complex-value tuple"><table><tr><td><span class="object-key int">0</span></td><td><span class="simple-value int">1</span></td></tr><tr><td><span class="object-key int">1</span></td><td><span class="simple-value int">2</span></td></tr></table></div></details></td></tr></table></div></details><details class="pyglove list"><summary><div class="summary-name">y</div><div class="summary-title">list(...)</div><span class="tooltip">[&#x27;b&#x27;, &lt;Foo&gt;&lt;/Foo&gt;]</span></summary><div class="complex-value list"><table><tr><td><span class="object-key int">0</span></td><td><span class="simple-value str">&#x27;b&#x27;</span></td></tr><tr><td><span class="object-key int">1</span></td><td><details class="pyglove foo"><summary><div class="summary-title">Foo(...)</div><span class="tooltip">&lt;Foo&gt;&lt;/Foo&gt;</span></summary><span class="simple-value foo">&lt;Foo&gt;&lt;/Foo&gt;</span></details></td></tr></table></div></details></div></details></td></tr><tr><td><span class="object-key int">1</span></td><td><span class="simple-value int">1</span></td></tr><tr><td><span class="object-key int">2</span></td><td><details class="pyglove list"><summary><div class="summary-title">list(...)</div><span class="tooltip">[1, {
463
682
  &#x27;xx&#x27;: 1,
464
683
  &#x27;yy&#x27;: &#x27;a&#x27;
465
- }]</span></summary><div class="complex_value list"><table><tr><td><span class="object_key int">0</span></td><td><div><span class="simple_value int">1</span></div></td></tr><tr><td><span class="object_key int">1</span></td><td><div><details class="pyglove dict"><summary><div class="summary_title">dict(...)</div><span class="tooltip dict">{
684
+ }]</span></summary><div class="complex-value list"><table><tr><td><span class="object-key int">0</span></td><td><span class="simple-value int">1</span></td></tr><tr><td><span class="object-key int">1</span></td><td><details class="pyglove dict"><summary><div class="summary-title">dict(...)</div><span class="tooltip">{
466
685
  &#x27;xx&#x27;: 1,
467
686
  &#x27;yy&#x27;: &#x27;a&#x27;
468
- }</span></summary><div class="complex_value dict"><table><tr><td><span class="object_key str">xx</span></td><td><div><span class="simple_value int">1</span></div></td></tr><tr><td><span class="object_key str">yy</span></td><td><div><span class="simple_value str">&#x27;a&#x27;</span></div></td></tr></table></div></details></div></td></tr></table></div></details></div></td></tr></table></div>
469
- """
687
+ }</span></summary><div class="complex-value dict"><details open class="pyglove int"><summary><div class="summary-name">xx</div><div class="summary-title">int</div><span class="tooltip">1</span></summary><span class="simple-value int">1</span></details><details open class="pyglove str"><summary><div class="summary-name">yy</div><div class="summary-title">str</div><span class="tooltip">&#x27;a&#x27;</span></summary><span class="simple-value str">&#x27;a&#x27;</span></details></div></details></td></tr></table></div></details></td></tr></table></div>
688
+ """
470
689
  )
471
690
  self.assert_content(
472
691
  self._view.content(
473
692
  value, enable_summary_tooltip=False, enable_key_tooltip=False
474
693
  ),
475
694
  """
476
- <div class="complex_value list"><table><tr><td><span class="object_key int">0</span></td><td><div><details class="pyglove dict"><summary><div class="summary_title">dict(...)</div></summary><div class="complex_value dict"><table><tr><td><span class="object_key str">x</span></td><td><div><details class="pyglove list"><summary><div class="summary_title">list(...)</div></summary><div class="complex_value list"><table><tr><td><span class="object_key int">0</span></td><td><div><details class="pyglove tuple"><summary><div class="summary_title">tuple(...)</div></summary><div class="complex_value tuple"><table><tr><td><span class="object_key int">0</span></td><td><div><span class="simple_value int">1</span></div></td></tr><tr><td><span class="object_key int">1</span></td><td><div><span class="simple_value int">2</span></div></td></tr></table></div></details></div></td></tr></table></div></details></div></td></tr><tr><td><span class="object_key str">y</span></td><td><div><details class="pyglove list"><summary><div class="summary_title">list(...)</div></summary><div class="complex_value list"><table><tr><td><span class="object_key int">0</span></td><td><div><span class="simple_value str">&#x27;b&#x27;</span></div></td></tr><tr><td><span class="object_key int">1</span></td><td><div><details class="pyglove foo"><summary><div class="summary_title">Foo(...)</div></summary><span class="simple_value foo">&lt;Foo&gt;&lt;/Foo&gt;</span></details></div></td></tr></table></div></details></div></td></tr></table></div></details></div></td></tr><tr><td><span class="object_key int">1</span></td><td><div><span class="simple_value int">1</span></div></td></tr><tr><td><span class="object_key int">2</span></td><td><div><details class="pyglove list"><summary><div class="summary_title">list(...)</div></summary><div class="complex_value list"><table><tr><td><span class="object_key int">0</span></td><td><div><span class="simple_value int">1</span></div></td></tr><tr><td><span class="object_key int">1</span></td><td><div><details class="pyglove dict"><summary><div class="summary_title">dict(...)</div></summary><div class="complex_value dict"><table><tr><td><span class="object_key str">xx</span></td><td><div><span class="simple_value int">1</span></div></td></tr><tr><td><span class="object_key str">yy</span></td><td><div><span class="simple_value str">&#x27;a&#x27;</span></div></td></tr></table></div></details></div></td></tr></table></div></details></div></td></tr></table></div>
695
+ <div class="complex-value list"><table><tr><td><span class="object-key int">0</span></td><td><details class="pyglove dict"><summary><div class="summary-title">dict(...)</div></summary><div class="complex-value dict"><details class="pyglove list"><summary><div class="summary-name">x</div><div class="summary-title">list(...)</div></summary><div class="complex-value list"><table><tr><td><span class="object-key int">0</span></td><td><details class="pyglove tuple"><summary><div class="summary-title">tuple(...)</div></summary><div class="complex-value tuple"><table><tr><td><span class="object-key int">0</span></td><td><span class="simple-value int">1</span></td></tr><tr><td><span class="object-key int">1</span></td><td><span class="simple-value int">2</span></td></tr></table></div></details></td></tr></table></div></details><details class="pyglove list"><summary><div class="summary-name">y</div><div class="summary-title">list(...)</div></summary><div class="complex-value list"><table><tr><td><span class="object-key int">0</span></td><td><span class="simple-value str">&#x27;b&#x27;</span></td></tr><tr><td><span class="object-key int">1</span></td><td><details class="pyglove foo"><summary><div class="summary-title">Foo(...)</div></summary><span class="simple-value foo">&lt;Foo&gt;&lt;/Foo&gt;</span></details></td></tr></table></div></details></div></details></td></tr><tr><td><span class="object-key int">1</span></td><td><span class="simple-value int">1</span></td></tr><tr><td><span class="object-key int">2</span></td><td><details class="pyglove list"><summary><div class="summary-title">list(...)</div></summary><div class="complex-value list"><table><tr><td><span class="object-key int">0</span></td><td><span class="simple-value int">1</span></td></tr><tr><td><span class="object-key int">1</span></td><td><details class="pyglove dict"><summary><div class="summary-title">dict(...)</div></summary><div class="complex-value dict"><details open class="pyglove int"><summary><div class="summary-name">xx</div><div class="summary-title">int</div></summary><span class="simple-value int">1</span></details><details open class="pyglove str"><summary><div class="summary-name">yy</div><div class="summary-title">str</div></summary><span class="simple-value str">&#x27;a&#x27;</span></details></div></details></td></tr></table></div></details></td></tr></table></div>
477
696
  """
478
697
  )
479
698
 
@@ -485,45 +704,36 @@ class ContentTest(TestCase):
485
704
  exclude_keys=['c', 'e'],
486
705
  enable_summary_tooltip=False,
487
706
  enable_key_tooltip=False,
707
+ key_style='label',
488
708
  ),
489
- 'object_key',
709
+ 'object-key',
490
710
  3 + 1 # 'a', 'b', 'd' at the first level and 'e' at the second level.
491
711
  )
492
712
 
493
- def test_special_keys(self):
494
- self.assert_content(
495
- self._view.content(
496
- dict(a='x', b=dict(e='y'), c='z', d='w', e='v', f='u'),
497
- special_keys=['c', 'b'],
498
- enable_summary_tooltip=False,
499
- enable_key_tooltip=False,
500
- ),
501
- """
502
- <div class="complex_value dict"><div class="special_value"><details class="pyglove str"><summary><div class="summary_name">c</div><div class="summary_title">&#x27;z&#x27;</div></summary><span class="simple_value str">&#x27;z&#x27;</span></details></div><div class="special_value"><details class="pyglove dict"><summary><div class="summary_name">b</div><div class="summary_title">dict(...)</div></summary><div class="complex_value dict"><table><tr><td><span class="object_key str">e</span></td><td><div><span class="simple_value str">&#x27;y&#x27;</span></div></td></tr></table></div></details></div><table><tr><td><span class="object_key str">a</span></td><td><div><span class="simple_value str">&#x27;x&#x27;</span></div></td></tr><tr><td><span class="object_key str">d</span></td><td><div><span class="simple_value str">&#x27;w&#x27;</span></div></td></tr><tr><td><span class="object_key str">e</span></td><td><div><span class="simple_value str">&#x27;v&#x27;</span></div></td></tr><tr><td><span class="object_key str">f</span></td><td><div><span class="simple_value str">&#x27;u&#x27;</span></div></td></tr></table></div>
503
- """
504
- )
713
+ def test_include_nodes_in_subtree(self):
505
714
  self.assert_count(
506
715
  self._view.content(
507
716
  dict(a='x', b=dict(e='y'), c='z', d='w', e='v', f='u'),
508
- special_keys=['b', 'd'],
717
+ include_keys=(lambda k, v, p: k.key == 'e' or isinstance(v, dict)),
509
718
  enable_summary_tooltip=False,
510
719
  enable_key_tooltip=False,
720
+ key_style='label',
511
721
  ),
512
- 'special_value',
513
- 2
722
+ 'object-key',
723
+ 3 # 'b', 'b.e', 'e'.
514
724
  )
515
725
 
516
- def test_filter(self):
517
- self.assert_content(
726
+ def test_exclude_nodes_in_subtree(self):
727
+ self.assert_count(
518
728
  self._view.content(
519
729
  dict(a='x', b=dict(e='y'), c='z', d='w', e='v', f='u'),
730
+ exclude_keys=(lambda k, v, p: k.key == 'e'),
520
731
  enable_summary_tooltip=False,
521
732
  enable_key_tooltip=False,
522
- filter=(lambda k, v, p: len(k) > 1 or isinstance(v, dict))
733
+ key_style='label',
523
734
  ),
524
- """
525
- <div class="complex_value dict"><table><tr><td><span class="object_key str">b</span></td><td><div><details class="pyglove dict"><summary><div class="summary_title">dict(...)</div></summary><div class="complex_value dict"><table><tr><td><span class="object_key str">e</span></td><td><div><span class="simple_value str">&#x27;y&#x27;</span></div></td></tr></table></div></details></div></td></tr></table></div>
526
- """
735
+ 'object-key',
736
+ 5 # 'a', 'b', 'c', 'd', 'f'.
527
737
  )
528
738
 
529
739
  def test_highlight_lowlight(self):
@@ -532,11 +742,11 @@ class ContentTest(TestCase):
532
742
  dict(a=1, b=dict(e='y'), c=2, d='w', e=3, f='u'),
533
743
  enable_summary_tooltip=False,
534
744
  enable_key_tooltip=False,
535
- highlight_keys=(lambda k, v, p: isinstance(v, int)),
536
- lowlight_keys=(lambda k, v, p: isinstance(v, str)),
745
+ highlight=(lambda k, v, p: isinstance(v, int)),
746
+ lowlight=(lambda k, v, p: isinstance(v, str)),
537
747
  ),
538
748
  """
539
- <div class="complex_value dict"><table><tr><td><span class="object_key str">a</span></td><td><div><span class="simple_value int">1</span></div></td></tr><tr><td><span class="object_key str">b</span></td><td><div><details class="pyglove dict"><summary><div class="summary_title">dict(...)</div></summary><div class="complex_value dict"><table><tr><td><span class="object_key str">e</span></td><td><div><span class="simple_value str">&#x27;y&#x27;</span></div></td></tr></table></div></details></div></td></tr><tr><td><span class="object_key str">c</span></td><td><div><span class="simple_value int">2</span></div></td></tr><tr><td><span class="object_key str">d</span></td><td><div><span class="simple_value str">&#x27;w&#x27;</span></div></td></tr><tr><td><span class="object_key str">e</span></td><td><div><span class="simple_value int">3</span></div></td></tr><tr><td><span class="object_key str">f</span></td><td><div><span class="simple_value str">&#x27;u&#x27;</span></div></td></tr></table></div>
749
+ <div class="complex-value dict"><div class="highlight"><details open class="pyglove int"><summary><div class="summary-name">a</div><div class="summary-title">int</div></summary><span class="simple-value int">1</span></details></div><details class="pyglove dict"><summary><div class="summary-name">b</div><div class="summary-title">dict(...)</div></summary><div class="complex-value dict"><div class="lowlight"><details open class="pyglove str"><summary><div class="summary-name">e</div><div class="summary-title">str</div></summary><span class="simple-value str">&#x27;y&#x27;</span></details></div></div></details><div class="highlight"><details open class="pyglove int"><summary><div class="summary-name">c</div><div class="summary-title">int</div></summary><span class="simple-value int">2</span></details></div><div class="lowlight"><details open class="pyglove str"><summary><div class="summary-name">d</div><div class="summary-title">str</div></summary><span class="simple-value str">&#x27;w&#x27;</span></details></div><div class="highlight"><details open class="pyglove int"><summary><div class="summary-name">e</div><div class="summary-title">int</div></summary><span class="simple-value int">3</span></details></div><div class="lowlight"><details open class="pyglove str"><summary><div class="summary-name">f</div><div class="summary-title">str</div></summary><span class="simple-value str">&#x27;u&#x27;</span></details></div></div>
540
750
  """
541
751
  )
542
752
 
@@ -578,18 +788,16 @@ class ContentTest(TestCase):
578
788
  'open',
579
789
  4
580
790
  )
581
- with base.HtmlView.preset_args(collapse_level=4):
582
- self.assert_count(
583
- self._view.content(x),
584
- 'open',
585
- 6
586
- )
587
- with base.HtmlView.preset_args(collapse_level=None):
588
- self.assert_count(
589
- self._view.content(x),
590
- 'open',
591
- 8
592
- )
791
+ self.assert_count(
792
+ self._view.content(x, collapse_level=4),
793
+ 'open',
794
+ 6
795
+ )
796
+ self.assert_count(
797
+ self._view.content(x, collapse_level=None),
798
+ 'open',
799
+ 8
800
+ )
593
801
 
594
802
  def test_uncollapse(self):
595
803
  x = dict(
@@ -652,7 +860,7 @@ class RenderTest(TestCase):
652
860
  ],
653
861
  ),
654
862
  """
655
- <details open class="pyglove list"><summary><div class="summary_title">list(...)</div><span class="tooltip list">[
863
+ <details open class="pyglove list"><summary><div class="summary-title">list(...)</div><span class="tooltip">[
656
864
  {
657
865
  &#x27;x&#x27;: [(1, 2)],
658
866
  &#x27;y&#x27;: [&#x27;b&#x27;, &lt;Foo&gt;&lt;/Foo&gt;]
@@ -662,16 +870,78 @@ class RenderTest(TestCase):
662
870
  &#x27;xx&#x27;: 1,
663
871
  &#x27;yy&#x27;: &#x27;a&#x27;
664
872
  }]
665
- ]</span></summary><div class="complex_value list"><table><tr><td><span class="object_key int">0</span><span class="tooltip key-path">[0]</span></td><td><div><details class="pyglove dict"><summary><div class="summary_title">dict(...)</div><span class="tooltip dict">{
873
+ ]</span></summary><div class="complex-value list"><table><tr><td><span class="object-key int">0</span><span class="tooltip">[0]</span></td><td><details class="pyglove dict"><summary><div class="summary-title">dict(...)</div><span class="tooltip">{
666
874
  &#x27;x&#x27;: [(1, 2)],
667
875
  &#x27;y&#x27;: [&#x27;b&#x27;, &lt;Foo&gt;&lt;/Foo&gt;]
668
- }</span></summary><div class="complex_value dict"><table><tr><td><span class="object_key str">x</span><span class="tooltip key-path">[0].x</span></td><td><div><details class="pyglove list"><summary><div class="summary_title">list(...)</div><span class="tooltip list">[(1, 2)]</span></summary><div class="complex_value list"><table><tr><td><span class="object_key int">0</span><span class="tooltip key-path">[0].x[0]</span></td><td><div><details class="pyglove tuple"><summary><div class="summary_title">tuple(...)</div><span class="tooltip tuple">(1, 2)</span></summary><div class="complex_value tuple"><table><tr><td><span class="object_key int">0</span><span class="tooltip key-path">[0].x[0][0]</span></td><td><div><span class="simple_value int">1</span></div></td></tr><tr><td><span class="object_key int">1</span><span class="tooltip key-path">[0].x[0][1]</span></td><td><div><span class="simple_value int">2</span></div></td></tr></table></div></details></div></td></tr></table></div></details></div></td></tr><tr><td><span class="object_key str">y</span><span class="tooltip key-path">[0].y</span></td><td><div><details class="pyglove list"><summary><div class="summary_title">list(...)</div><span class="tooltip list">[&#x27;b&#x27;, &lt;Foo&gt;&lt;/Foo&gt;]</span></summary><div class="complex_value list"><table><tr><td><span class="object_key int">0</span><span class="tooltip key-path">[0].y[0]</span></td><td><div><span class="simple_value str">&#x27;b&#x27;</span></div></td></tr><tr><td><span class="object_key int">1</span><span class="tooltip key-path">[0].y[1]</span></td><td><div><details class="pyglove foo"><summary><div class="summary_title">Foo(...)</div><span class="tooltip foo">&lt;Foo&gt;&lt;/Foo&gt;</span></summary><span class="simple_value foo">&lt;Foo&gt;&lt;/Foo&gt;</span></details></div></td></tr></table></div></details></div></td></tr></table></div></details></div></td></tr><tr><td><span class="object_key int">1</span><span class="tooltip key-path">[1]</span></td><td><div><span class="simple_value int">1</span></div></td></tr><tr><td><span class="object_key int">2</span><span class="tooltip key-path">[2]</span></td><td><div><details class="pyglove list"><summary><div class="summary_title">list(...)</div><span class="tooltip list">[1, {
876
+ }</span></summary><div class="complex-value dict"><details class="pyglove list"><summary><div class="summary-name">x<span class="tooltip">[0].x</span></div><div class="summary-title">list(...)</div><span class="tooltip">[(1, 2)]</span></summary><div class="complex-value list"><table><tr><td><span class="object-key int">0</span><span class="tooltip">[0].x[0]</span></td><td><details class="pyglove tuple"><summary><div class="summary-title">tuple(...)</div><span class="tooltip">(1, 2)</span></summary><div class="complex-value tuple"><table><tr><td><span class="object-key int">0</span><span class="tooltip">[0].x[0][0]</span></td><td><span class="simple-value int">1</span></td></tr><tr><td><span class="object-key int">1</span><span class="tooltip">[0].x[0][1]</span></td><td><span class="simple-value int">2</span></td></tr></table></div></details></td></tr></table></div></details><details class="pyglove list"><summary><div class="summary-name">y<span class="tooltip">[0].y</span></div><div class="summary-title">list(...)</div><span class="tooltip">[&#x27;b&#x27;, &lt;Foo&gt;&lt;/Foo&gt;]</span></summary><div class="complex-value list"><table><tr><td><span class="object-key int">0</span><span class="tooltip">[0].y[0]</span></td><td><span class="simple-value str">&#x27;b&#x27;</span></td></tr><tr><td><span class="object-key int">1</span><span class="tooltip">[0].y[1]</span></td><td><details class="pyglove foo"><summary><div class="summary-title">Foo(...)</div><span class="tooltip">&lt;Foo&gt;&lt;/Foo&gt;</span></summary><span class="simple-value foo">&lt;Foo&gt;&lt;/Foo&gt;</span></details></td></tr></table></div></details></div></details></td></tr><tr><td><span class="object-key int">1</span><span class="tooltip">[1]</span></td><td><span class="simple-value int">1</span></td></tr><tr><td><span class="object-key int">2</span><span class="tooltip">[2]</span></td><td><details class="pyglove list"><summary><div class="summary-title">list(...)</div><span class="tooltip">[1, {
669
877
  &#x27;xx&#x27;: 1,
670
878
  &#x27;yy&#x27;: &#x27;a&#x27;
671
- }]</span></summary><div class="complex_value list"><table><tr><td><span class="object_key int">0</span><span class="tooltip key-path">[2][0]</span></td><td><div><span class="simple_value int">1</span></div></td></tr><tr><td><span class="object_key int">1</span><span class="tooltip key-path">[2][1]</span></td><td><div><details class="pyglove dict"><summary><div class="summary_title">dict(...)</div><span class="tooltip dict">{
879
+ }]</span></summary><div class="complex-value list"><table><tr><td><span class="object-key int">0</span><span class="tooltip">[2][0]</span></td><td><span class="simple-value int">1</span></td></tr><tr><td><span class="object-key int">1</span><span class="tooltip">[2][1]</span></td><td><details class="pyglove dict"><summary><div class="summary-title">dict(...)</div><span class="tooltip">{
672
880
  &#x27;xx&#x27;: 1,
673
881
  &#x27;yy&#x27;: &#x27;a&#x27;
674
- }</span></summary><div class="complex_value dict"><table><tr><td><span class="object_key str">xx</span><span class="tooltip key-path">[2][1].xx</span></td><td><div><span class="simple_value int">1</span></div></td></tr><tr><td><span class="object_key str">yy</span><span class="tooltip key-path">[2][1].yy</span></td><td><div><span class="simple_value str">&#x27;a&#x27;</span></div></td></tr></table></div></details></div></td></tr></table></div></details></div></td></tr></table></div></details>
882
+ }</span></summary><div class="complex-value dict"><details open class="pyglove int"><summary><div class="summary-name">xx<span class="tooltip">[2][1].xx</span></div><div class="summary-title">int</div><span class="tooltip">1</span></summary><span class="simple-value int">1</span></details><details open class="pyglove str"><summary><div class="summary-name">yy<span class="tooltip">[2][1].yy</span></div><div class="summary-title">str</div><span class="tooltip">&#x27;a&#x27;</span></summary><span class="simple-value str">&#x27;a&#x27;</span></details></div></details></td></tr></table></div></details></td></tr></table></div></details>
883
+ """
884
+ )
885
+
886
+ def test_debug(self):
887
+ self.assertIn(
888
+ inspect.cleandoc(
889
+ """
890
+ .debug-info-trigger {
891
+ display: inline-flex;
892
+ cursor: pointer;
893
+ font-size: 0.6em;
894
+ background-color: red;
895
+ color: white;
896
+ padding: 5px;
897
+ border-radius: 3px;
898
+ margin: 5px 0 5px 0;
899
+ }
900
+ .debug-info-trigger:hover + span.tooltip {
901
+ visibility: visible;
902
+ }
903
+ """
904
+ ),
905
+ self._view.render(dict(x=dict(y=1)), debug=True).style_section,
906
+ )
907
+ self.assert_content(
908
+ self._view.render(dict(x=1), debug=True),
909
+ """
910
+ <details open class="pyglove dict"><summary><div class="summary-title">dict(...)</div><span class="tooltip">{
911
+ &#x27;x&#x27;: 1
912
+ }</span></summary><div><span class="debug-info-trigger">DEBUG</span><span class="tooltip debug-info">{
913
+ &#x27;css_classes&#x27;: None,
914
+ &#x27;collapse_level&#x27;: 1,
915
+ &#x27;uncollapse&#x27;: KeyPathSet(),
916
+ &#x27;extra_flags&#x27;: {},
917
+ &#x27;child_config&#x27;: {},
918
+ &#x27;key_style&#x27;: &#x27;summary&#x27;,
919
+ &#x27;key_color&#x27;: None,
920
+ &#x27;include_keys&#x27;: None,
921
+ &#x27;exclude_keys&#x27;: None,
922
+ &#x27;summary_color&#x27;: None,
923
+ &#x27;enable_summary&#x27;: None,
924
+ &#x27;enable_summary_for_str&#x27;: True,
925
+ &#x27;max_summary_len_for_str&#x27;: 80,
926
+ &#x27;enable_summary_tooltip&#x27;: True,
927
+ &#x27;enable_key_tooltip&#x27;: True
928
+ }</span></div><div class="complex-value dict"><details open class="pyglove int"><summary><div class="summary-name">x<span class="tooltip">x</span></div><div class="summary-title">int</div><span class="tooltip">1</span></summary><div><span class="debug-info-trigger">DEBUG</span><span class="tooltip debug-info">{
929
+ &#x27;css_classes&#x27;: None,
930
+ &#x27;collapse_level&#x27;: 0,
931
+ &#x27;uncollapse&#x27;: KeyPathSet(),
932
+ &#x27;extra_flags&#x27;: {},
933
+ &#x27;child_config&#x27;: {},
934
+ &#x27;key_style&#x27;: &#x27;summary&#x27;,
935
+ &#x27;key_color&#x27;: None,
936
+ &#x27;include_keys&#x27;: None,
937
+ &#x27;exclude_keys&#x27;: None,
938
+ &#x27;summary_color&#x27;: None,
939
+ &#x27;enable_summary&#x27;: None,
940
+ &#x27;enable_summary_for_str&#x27;: True,
941
+ &#x27;max_summary_len_for_str&#x27;: 80,
942
+ &#x27;enable_summary_tooltip&#x27;: True,
943
+ &#x27;enable_key_tooltip&#x27;: True
944
+ }</span></div><span class="simple-value int">1</span></details></div></details>
675
945
  """
676
946
  )
677
947
 
@@ -690,10 +960,10 @@ class ExtensionTest(TestCase):
690
960
  Foo(),
691
961
  enable_summary=True,
692
962
  max_summary_len_for_str=10,
693
- enable_tooltip=True,
963
+ enable_summary_tooltip=True,
694
964
  ),
695
965
  """
696
- <summary><div class="summary_title">Foo(...)</div><span class="tooltip foo">Foo()</span></summary>
966
+ <summary><div class="summary-title">Foo(...)</div><span class="tooltip">Foo()</span></summary>
697
967
  """
698
968
  )
699
969
  self.assert_content(
@@ -701,41 +971,47 @@ class ExtensionTest(TestCase):
701
971
  Foo(),
702
972
  ),
703
973
  """
704
- <span class="simple_value foo">Foo()</span>
974
+ <span class="simple-value foo">Foo()</span>
705
975
  """
706
976
  )
707
977
 
708
- def test_options_overrides(self):
978
+ def test_config_override(self):
709
979
 
710
980
  class Foo(tree_view.HtmlTreeView.Extension):
711
981
 
712
982
  def __str__(self):
713
983
  return 'Foo()'
714
984
 
715
- def _html_style(self) -> List[str]:
985
+ @classmethod
986
+ def _html_tree_view_css_styles(cls) -> list[str]:
716
987
  return [
717
988
  """
718
989
  /* Foo style */
719
990
  """
720
991
  ]
721
992
 
722
- def _html_element_class(self) -> List[str]:
723
- return ['foo', 'bar']
724
-
725
- def _html_tree_view_special_keys(self) -> Sequence[str]:
726
- return ['x']
727
-
728
- def _html_tree_view_include_keys(self) -> Sequence[str]:
729
- return ['x', 'y', 'z', 'w']
730
-
731
- def _html_tree_view_exclude_keys(self) -> Sequence[str]:
732
- return ['z']
733
-
734
- def _html_tree_view_uncollapse_level(self) -> int:
735
- return 2
736
-
737
- def _html_tree_view_uncollapse(self) -> KeyPathSet:
738
- return KeyPathSet(['x.a', 'y.b'], include_intermediate=True)
993
+ @classmethod
994
+ def _html_tree_view_config(cls) -> dict[str, Any]:
995
+ return dict(
996
+ css_classes=['foo', 'bar'],
997
+ include_keys=['x', 'y', 'z', 'w'],
998
+ exclude_keys=['z'],
999
+ key_style='label',
1000
+ key_color=('white', 'red'),
1001
+ collapse_level=2,
1002
+ uncollapse=KeyPathSet(['x.a'], include_intermediate=True),
1003
+ child_config={
1004
+ 'x': dict(
1005
+ summary_color=('white', 'blue'),
1006
+ key_style='label',
1007
+ key_color=('white', 'blue'),
1008
+ collapse_level=1,
1009
+ ),
1010
+ 'y': dict(
1011
+ uncollapse=KeyPathSet(['e']),
1012
+ )
1013
+ }
1014
+ )
739
1015
 
740
1016
  def _html_tree_view_content(
741
1017
  self,
@@ -747,7 +1023,7 @@ class ExtensionTest(TestCase):
747
1023
  return view.complex_value(
748
1024
  kv=dict(
749
1025
  x=dict(a=dict(foo=2)),
750
- y=dict(b=dict(bar=3)),
1026
+ y=dict(b=dict(bar=3), e=dict(srt=6)),
751
1027
  z=dict(c=dict(baz=4)),
752
1028
  w=dict(d=dict(qux=5)),
753
1029
  ),
@@ -773,7 +1049,7 @@ class ExtensionTest(TestCase):
773
1049
  collapse_level=0,
774
1050
  ),
775
1051
  """
776
- <details class="pyglove list"><summary><div class="summary_title">list(...)</div></summary><div class="complex_value list"><table><tr><td><span class="object_key int">0</span></td><td><div><details open class="pyglove foo bar"><summary><div class="summary_title">Foo(...)</div></summary><div class="complex_value foo bar"><div class="special_value"><details open class="pyglove dict"><summary><div class="summary_name">x</div><div class="summary_title">dict(...)</div></summary><div class="complex_value dict"><table><tr><td><span class="object_key str">a</span></td><td><div><details open class="pyglove dict"><summary><div class="summary_title">dict(...)</div></summary><div class="complex_value dict"><table><tr><td><span class="object_key str">foo</span></td><td><div><span class="simple_value int">2</span></div></td></tr></table></div></details></div></td></tr></table></div></details></div><table><tr><td><span class="object_key str">y</span></td><td><div><details open class="pyglove dict"><summary><div class="summary_title">dict(...)</div></summary><div class="complex_value dict"><table><tr><td><span class="object_key str">b</span></td><td><div><details open class="pyglove dict"><summary><div class="summary_title">dict(...)</div></summary><div class="complex_value dict"><table><tr><td><span class="object_key str">bar</span></td><td><div><span class="simple_value int">3</span></div></td></tr></table></div></details></div></td></tr></table></div></details></div></td></tr><tr><td><span class="object_key str">w</span></td><td><div><details open class="pyglove dict"><summary><div class="summary_title">dict(...)</div></summary><div class="complex_value dict"><table><tr><td><span class="object_key str">d</span></td><td><div><details class="pyglove dict"><summary><div class="summary_title">dict(...)</div></summary><div class="complex_value dict"><table><tr><td><span class="object_key str">qux</span></td><td><div><span class="simple_value int">5</span></div></td></tr></table></div></details></div></td></tr></table></div></details></div></td></tr></table></div></details></div></td></tr></table></div></details>
1052
+ <details class="pyglove list"><summary><div class="summary-title">list(...)</div></summary><div class="complex-value list"><table><tr><td><span class="object-key int">0</span></td><td><details open class="pyglove foo bar"><summary><div class="summary-title foo bar">Foo(...)</div></summary><div class="complex-value foo"><table><tr><td><span class="object-key str" style="color:white;background-color:blue;">x</span></td><td><details open class="pyglove dict"><summary><div class="summary-title">dict(...)</div></summary><div class="complex-value dict"><table><tr><td><span class="object-key str" style="color:white;background-color:blue;">a</span></td><td><details open class="pyglove dict"><summary><div class="summary-title">dict(...)</div></summary><div class="complex-value dict"><table><tr><td><span class="object-key str" style="color:white;background-color:blue;">foo</span></td><td><span class="simple-value int">2</span></td></tr></table></div></details></td></tr></table></div></details></td></tr><tr><td><span class="object-key str" style="color:white;background-color:red;">y</span></td><td><details open class="pyglove dict"><summary><div class="summary-title">dict(...)</div></summary><div class="complex-value dict"><table><tr><td><span class="object-key str" style="color:white;background-color:red;">b</span></td><td><details class="pyglove dict"><summary><div class="summary-title">dict(...)</div></summary><div class="complex-value dict"><table><tr><td><span class="object-key str" style="color:white;background-color:red;">bar</span></td><td><span class="simple-value int">3</span></td></tr></table></div></details></td></tr><tr><td><span class="object-key str" style="color:white;background-color:red;">e</span></td><td><details open class="pyglove dict"><summary><div class="summary-title">dict(...)</div></summary><div class="complex-value dict"><table><tr><td><span class="object-key str" style="color:white;background-color:red;">srt</span></td><td><span class="simple-value int">6</span></td></tr></table></div></details></td></tr></table></div></details></td></tr><tr><td><span class="object-key str" style="color:white;background-color:red;">w</span></td><td><details open class="pyglove dict"><summary><div class="summary-title">dict(...)</div></summary><div class="complex-value dict"><table><tr><td><span class="object-key str" style="color:white;background-color:red;">d</span></td><td><details class="pyglove dict"><summary><div class="summary-title">dict(...)</div></summary><div class="complex-value dict"><table><tr><td><span class="object-key str" style="color:white;background-color:red;">qux</span></td><td><span class="simple-value int">5</span></td></tr></table></div></details></td></tr></table></div></details></td></tr></table></div></details></td></tr></table></div></details>
777
1053
  """
778
1054
  )
779
1055
  self.assert_content(
@@ -784,7 +1060,7 @@ class ExtensionTest(TestCase):
784
1060
  collapse_level=1,
785
1061
  ),
786
1062
  """
787
- <details open class="pyglove list"><summary><div class="summary_title">list(...)</div></summary><div class="complex_value list"><table><tr><td><span class="object_key int">0</span></td><td><div><details open class="pyglove foo bar"><summary><div class="summary_title">Foo(...)</div></summary><div class="complex_value foo bar"><div class="special_value"><details open class="pyglove dict"><summary><div class="summary_name">x</div><div class="summary_title">dict(...)</div></summary><div class="complex_value dict"><table><tr><td><span class="object_key str">a</span></td><td><div><details open class="pyglove dict"><summary><div class="summary_title">dict(...)</div></summary><div class="complex_value dict"><table><tr><td><span class="object_key str">foo</span></td><td><div><span class="simple_value int">2</span></div></td></tr></table></div></details></div></td></tr></table></div></details></div><table><tr><td><span class="object_key str">y</span></td><td><div><details open class="pyglove dict"><summary><div class="summary_title">dict(...)</div></summary><div class="complex_value dict"><table><tr><td><span class="object_key str">b</span></td><td><div><details open class="pyglove dict"><summary><div class="summary_title">dict(...)</div></summary><div class="complex_value dict"><table><tr><td><span class="object_key str">bar</span></td><td><div><span class="simple_value int">3</span></div></td></tr></table></div></details></div></td></tr></table></div></details></div></td></tr><tr><td><span class="object_key str">w</span></td><td><div><details open class="pyglove dict"><summary><div class="summary_title">dict(...)</div></summary><div class="complex_value dict"><table><tr><td><span class="object_key str">d</span></td><td><div><details class="pyglove dict"><summary><div class="summary_title">dict(...)</div></summary><div class="complex_value dict"><table><tr><td><span class="object_key str">qux</span></td><td><div><span class="simple_value int">5</span></div></td></tr></table></div></details></div></td></tr></table></div></details></div></td></tr></table></div></details></div></td></tr></table></div></details>
1063
+ <details open class="pyglove list"><summary><div class="summary-title">list(...)</div></summary><div class="complex-value list"><table><tr><td><span class="object-key int">0</span></td><td><details open class="pyglove foo bar"><summary><div class="summary-title foo bar">Foo(...)</div></summary><div class="complex-value foo"><table><tr><td><span class="object-key str" style="color:white;background-color:blue;">x</span></td><td><details open class="pyglove dict"><summary><div class="summary-title">dict(...)</div></summary><div class="complex-value dict"><table><tr><td><span class="object-key str" style="color:white;background-color:blue;">a</span></td><td><details open class="pyglove dict"><summary><div class="summary-title">dict(...)</div></summary><div class="complex-value dict"><table><tr><td><span class="object-key str" style="color:white;background-color:blue;">foo</span></td><td><span class="simple-value int">2</span></td></tr></table></div></details></td></tr></table></div></details></td></tr><tr><td><span class="object-key str" style="color:white;background-color:red;">y</span></td><td><details open class="pyglove dict"><summary><div class="summary-title">dict(...)</div></summary><div class="complex-value dict"><table><tr><td><span class="object-key str" style="color:white;background-color:red;">b</span></td><td><details class="pyglove dict"><summary><div class="summary-title">dict(...)</div></summary><div class="complex-value dict"><table><tr><td><span class="object-key str" style="color:white;background-color:red;">bar</span></td><td><span class="simple-value int">3</span></td></tr></table></div></details></td></tr><tr><td><span class="object-key str" style="color:white;background-color:red;">e</span></td><td><details open class="pyglove dict"><summary><div class="summary-title">dict(...)</div></summary><div class="complex-value dict"><table><tr><td><span class="object-key str" style="color:white;background-color:red;">srt</span></td><td><span class="simple-value int">6</span></td></tr></table></div></details></td></tr></table></div></details></td></tr><tr><td><span class="object-key str" style="color:white;background-color:red;">w</span></td><td><details open class="pyglove dict"><summary><div class="summary-title">dict(...)</div></summary><div class="complex-value dict"><table><tr><td><span class="object-key str" style="color:white;background-color:red;">d</span></td><td><details class="pyglove dict"><summary><div class="summary-title">dict(...)</div></summary><div class="complex-value dict"><table><tr><td><span class="object-key str" style="color:white;background-color:red;">qux</span></td><td><span class="simple-value int">5</span></td></tr></table></div></details></td></tr></table></div></details></td></tr></table></div></details></td></tr></table></div></details>
788
1064
  """
789
1065
  )
790
1066
  self.assert_content(
@@ -795,7 +1071,7 @@ class ExtensionTest(TestCase):
795
1071
  collapse_level=None,
796
1072
  ),
797
1073
  """
798
- <details open class="pyglove list"><summary><div class="summary_title">list(...)</div></summary><div class="complex_value list"><table><tr><td><span class="object_key int">0</span></td><td><div><details open class="pyglove foo bar"><summary><div class="summary_title">Foo(...)</div></summary><div class="complex_value foo bar"><div class="special_value"><details open class="pyglove dict"><summary><div class="summary_name">x</div><div class="summary_title">dict(...)</div></summary><div class="complex_value dict"><table><tr><td><span class="object_key str">a</span></td><td><div><details open class="pyglove dict"><summary><div class="summary_title">dict(...)</div></summary><div class="complex_value dict"><table><tr><td><span class="object_key str">foo</span></td><td><div><span class="simple_value int">2</span></div></td></tr></table></div></details></div></td></tr></table></div></details></div><table><tr><td><span class="object_key str">y</span></td><td><div><details open class="pyglove dict"><summary><div class="summary_title">dict(...)</div></summary><div class="complex_value dict"><table><tr><td><span class="object_key str">b</span></td><td><div><details open class="pyglove dict"><summary><div class="summary_title">dict(...)</div></summary><div class="complex_value dict"><table><tr><td><span class="object_key str">bar</span></td><td><div><span class="simple_value int">3</span></div></td></tr></table></div></details></div></td></tr></table></div></details></div></td></tr><tr><td><span class="object_key str">w</span></td><td><div><details open class="pyglove dict"><summary><div class="summary_title">dict(...)</div></summary><div class="complex_value dict"><table><tr><td><span class="object_key str">d</span></td><td><div><details open class="pyglove dict"><summary><div class="summary_title">dict(...)</div></summary><div class="complex_value dict"><table><tr><td><span class="object_key str">qux</span></td><td><div><span class="simple_value int">5</span></div></td></tr></table></div></details></div></td></tr></table></div></details></div></td></tr></table></div></details></div></td></tr></table></div></details>
1074
+ <details open class="pyglove list"><summary><div class="summary-title">list(...)</div></summary><div class="complex-value list"><table><tr><td><span class="object-key int">0</span></td><td><details open class="pyglove foo bar"><summary><div class="summary-title foo bar">Foo(...)</div></summary><div class="complex-value foo"><table><tr><td><span class="object-key str" style="color:white;background-color:blue;">x</span></td><td><details open class="pyglove dict"><summary><div class="summary-title">dict(...)</div></summary><div class="complex-value dict"><table><tr><td><span class="object-key str" style="color:white;background-color:blue;">a</span></td><td><details open class="pyglove dict"><summary><div class="summary-title">dict(...)</div></summary><div class="complex-value dict"><table><tr><td><span class="object-key str" style="color:white;background-color:blue;">foo</span></td><td><span class="simple-value int">2</span></td></tr></table></div></details></td></tr></table></div></details></td></tr><tr><td><span class="object-key str" style="color:white;background-color:red;">y</span></td><td><details open class="pyglove dict"><summary><div class="summary-title">dict(...)</div></summary><div class="complex-value dict"><table><tr><td><span class="object-key str" style="color:white;background-color:red;">b</span></td><td><details open class="pyglove dict"><summary><div class="summary-title">dict(...)</div></summary><div class="complex-value dict"><table><tr><td><span class="object-key str" style="color:white;background-color:red;">bar</span></td><td><span class="simple-value int">3</span></td></tr></table></div></details></td></tr><tr><td><span class="object-key str" style="color:white;background-color:red;">e</span></td><td><details open class="pyglove dict"><summary><div class="summary-title">dict(...)</div></summary><div class="complex-value dict"><table><tr><td><span class="object-key str" style="color:white;background-color:red;">srt</span></td><td><span class="simple-value int">6</span></td></tr></table></div></details></td></tr></table></div></details></td></tr><tr><td><span class="object-key str" style="color:white;background-color:red;">w</span></td><td><details open class="pyglove dict"><summary><div class="summary-title">dict(...)</div></summary><div class="complex-value dict"><table><tr><td><span class="object-key str" style="color:white;background-color:red;">d</span></td><td><details open class="pyglove dict"><summary><div class="summary-title">dict(...)</div></summary><div class="complex-value dict"><table><tr><td><span class="object-key str" style="color:white;background-color:red;">qux</span></td><td><span class="simple-value int">5</span></td></tr></table></div></details></td></tr></table></div></details></td></tr></table></div></details></td></tr></table></div></details>
799
1075
  """
800
1076
  )
801
1077
 
@@ -823,26 +1099,6 @@ class ExtensionTest(TestCase):
823
1099
  del kwargs
824
1100
  return 'Content of MyFoo'
825
1101
 
826
- def _html_tree_view_tooltip(
827
- self,
828
- *,
829
- view: tree_view.HtmlTreeView,
830
- **kwargs
831
- ):
832
- del kwargs
833
- return view.tooltip(
834
- value=self,
835
- content='Tooltip <MyFoo>'
836
- )
837
-
838
- self.assert_content(
839
- self._view.render(
840
- Foo(),
841
- ),
842
- """
843
- <details open class="pyglove foo"><summary><div class="summary_title">MyFoo</div><span class="tooltip foo">Tooltip <MyFoo></span></summary>Content of MyFoo</details>
844
- """
845
- )
846
1102
  self.assert_content(
847
1103
  self._view.render(
848
1104
  Foo(),
@@ -850,7 +1106,7 @@ class ExtensionTest(TestCase):
850
1106
  enable_key_tooltip=False,
851
1107
  ),
852
1108
  """
853
- <details open class="pyglove foo"><summary><div class="summary_title">MyFoo</div></summary>Content of MyFoo</details>
1109
+ <details open class="pyglove foo"><summary><div class="summary-title">MyFoo</div></summary>Content of MyFoo</details>
854
1110
  """
855
1111
  )
856
1112
  self.assert_content(
@@ -864,5 +1120,328 @@ class ExtensionTest(TestCase):
864
1120
  )
865
1121
 
866
1122
 
1123
+ class OverrideKwargsTest(TestCase):
1124
+
1125
+ def test_override_collapse_level(self):
1126
+ def assert_collapse_level(
1127
+ call_kwargs, overriden_kwargs, expected_collapse_level
1128
+ ):
1129
+ self.assertEqual(
1130
+ tree_view.HtmlTreeView.get_kwargs(
1131
+ call_kwargs,
1132
+ overriden_kwargs,
1133
+ KeyPath(''),
1134
+ ).get('collapse_level', -1),
1135
+ expected_collapse_level,
1136
+ )
1137
+ assert_collapse_level(
1138
+ dict(),
1139
+ dict(),
1140
+ -1,
1141
+ )
1142
+ assert_collapse_level(
1143
+ dict(collapse_level=1),
1144
+ dict(),
1145
+ 1,
1146
+ )
1147
+ assert_collapse_level(
1148
+ dict(collapse_level=1),
1149
+ dict(collapse_level=None),
1150
+ None,
1151
+ )
1152
+ assert_collapse_level(
1153
+ dict(collapse_level=1),
1154
+ dict(collapse_level=2),
1155
+ 2,
1156
+ )
1157
+ assert_collapse_level(
1158
+ dict(collapse_level=2),
1159
+ dict(collapse_level=1),
1160
+ 2,
1161
+ )
1162
+
1163
+ def test_override_uncollapse(self):
1164
+ def assert_uncollapse(
1165
+ call_kwargs,
1166
+ overriden_kwargs,
1167
+ expected_uncollapse,
1168
+ root_path=KeyPath(),
1169
+ ):
1170
+ self.assertEqual(
1171
+ tree_view.HtmlTreeView.get_kwargs(
1172
+ call_kwargs,
1173
+ overriden_kwargs,
1174
+ root_path,
1175
+ ).get('uncollapse', None),
1176
+ expected_uncollapse
1177
+ )
1178
+ assert_uncollapse(
1179
+ dict(uncollapse=None),
1180
+ dict(),
1181
+ None,
1182
+ )
1183
+ assert_uncollapse(
1184
+ dict(),
1185
+ dict(uncollapse=None),
1186
+ KeyPathSet(),
1187
+ )
1188
+ assert_uncollapse(
1189
+ dict(uncollapse=KeyPathSet(['a.b'])),
1190
+ dict(),
1191
+ KeyPathSet(['a.b']),
1192
+ )
1193
+ assert_uncollapse(
1194
+ dict(uncollapse=KeyPathSet(['a.b.c'])),
1195
+ dict(uncollapse=KeyPathSet(['b'])),
1196
+ KeyPathSet(['a.b.c', 'a.b']),
1197
+ root_path=KeyPath('a'),
1198
+ )
1199
+ assert_uncollapse(
1200
+ dict(uncollapse=[]),
1201
+ dict(uncollapse=KeyPathSet(['b'])),
1202
+ KeyPathSet(['a.b']),
1203
+ root_path=KeyPath('a'),
1204
+ )
1205
+ assert_uncollapse(
1206
+ dict(uncollapse=KeyPathSet(['a.b.c'])),
1207
+ dict(uncollapse=KeyPathSet(['b'])),
1208
+ KeyPathSet(['a.b.c', 'a.b']),
1209
+ root_path=KeyPath('a'),
1210
+ )
1211
+
1212
+ def test_override_kwargs(self):
1213
+ def assert_child_config(
1214
+ call_kwargs,
1215
+ overriden_kwargs,
1216
+ expected_child_config,
1217
+ root_path=KeyPath(''),
1218
+ ):
1219
+ self.maxDiff = None
1220
+ actual = tree_view.HtmlTreeView.get_kwargs(
1221
+ call_kwargs,
1222
+ overriden_kwargs,
1223
+ root_path,
1224
+ )
1225
+ if actual != expected_child_config:
1226
+ print(actual)
1227
+ self.assertEqual(actual, expected_child_config)
1228
+
1229
+ assert_child_config(
1230
+ dict(
1231
+ child_config=dict(
1232
+ x=dict(
1233
+ enable_summary=True
1234
+ ),
1235
+ )
1236
+ ),
1237
+ dict(
1238
+ child_config=dict(
1239
+ x=dict(
1240
+ enable_summary_tooltip=False
1241
+ ),
1242
+ y=dict(
1243
+ collapse_level=None
1244
+ ),
1245
+ )
1246
+ ),
1247
+ dict(
1248
+ child_config=dict(
1249
+ x=dict(
1250
+ enable_summary=True,
1251
+ enable_summary_tooltip=False,
1252
+ ),
1253
+ y=dict(
1254
+ collapse_level=None
1255
+ ),
1256
+ ),
1257
+ ),
1258
+ )
1259
+
1260
+ def test_get_child_kwargs(self):
1261
+ def assert_child_kwargs(
1262
+ call_kwargs,
1263
+ child_key,
1264
+ root_path,
1265
+ expected_child_kwargs,
1266
+ ):
1267
+ self.maxDiff = None
1268
+ actual = tree_view.HtmlTreeView.get_child_kwargs(
1269
+ call_kwargs,
1270
+ call_kwargs.pop('child_config', {}),
1271
+ child_key,
1272
+ root_path,
1273
+ )
1274
+ if actual != expected_child_kwargs:
1275
+ print(actual)
1276
+ self.assertEqual(actual, expected_child_kwargs)
1277
+
1278
+ assert_child_kwargs(
1279
+ call_kwargs=dict(
1280
+ enable_summary=False,
1281
+ collapse_level=1,
1282
+ uncollapse=KeyPathSet(['a.y']),
1283
+ child_config=dict(
1284
+ x=dict(
1285
+ enable_summary=True,
1286
+ uncollapse=KeyPathSet(['b']),
1287
+ child_config=dict(
1288
+ y=dict(
1289
+ collapse_level=2
1290
+ ),
1291
+ ),
1292
+ ),
1293
+ )
1294
+ ),
1295
+ child_key='x',
1296
+ root_path=KeyPath(['a']),
1297
+ expected_child_kwargs=dict(
1298
+ enable_summary=True,
1299
+ collapse_level=1,
1300
+ uncollapse=KeyPathSet(['a.y', 'a.x.b']),
1301
+ child_config=dict(
1302
+ y=dict(
1303
+ collapse_level=2
1304
+ ),
1305
+ ),
1306
+ ),
1307
+ )
1308
+
1309
+
1310
+ class HelperTest(TestCase):
1311
+
1312
+ def test_get_collapse_level(self):
1313
+ self.assertIsNone(
1314
+ tree_view.HtmlTreeView.get_collapse_level(
1315
+ None,
1316
+ None
1317
+ ),
1318
+ )
1319
+ self.assertIsNone(
1320
+ tree_view.HtmlTreeView.get_collapse_level(
1321
+ 1,
1322
+ None
1323
+ ),
1324
+ )
1325
+ self.assertIsNone(
1326
+ tree_view.HtmlTreeView.get_collapse_level(
1327
+ None,
1328
+ 1
1329
+ ),
1330
+ )
1331
+ self.assertEqual(
1332
+ tree_view.HtmlTreeView.get_collapse_level(
1333
+ 2,
1334
+ 3
1335
+ ),
1336
+ 3
1337
+ )
1338
+ self.assertEqual(
1339
+ tree_view.HtmlTreeView.get_collapse_level(
1340
+ (3, -1),
1341
+ 0
1342
+ ),
1343
+ 2
1344
+ )
1345
+ self.assertEqual(
1346
+ tree_view.HtmlTreeView.get_collapse_level(
1347
+ 0,
1348
+ (2, 1)
1349
+ ),
1350
+ 3
1351
+ )
1352
+
1353
+ def test_get_color(self):
1354
+ self.assertEqual(
1355
+ tree_view.HtmlTreeView.get_color(None, KeyPath('a.b.c'), 1, None),
1356
+ (None, None)
1357
+ )
1358
+ self.assertEqual(
1359
+ tree_view.HtmlTreeView.get_color(
1360
+ ('blue', None), KeyPath('a.b.c'), 1, None
1361
+ ),
1362
+ ('blue', None)
1363
+ )
1364
+ self.assertEqual(
1365
+ tree_view.HtmlTreeView.get_color(
1366
+ lambda k, v, p: ('white', 'black'), KeyPath('a.b.c'), 1, None),
1367
+ ('white', 'black')
1368
+ )
1369
+
1370
+ def test_merge_uncollapse(self):
1371
+ self.assertEqual(
1372
+ tree_view.HtmlTreeView.merge_uncollapse(
1373
+ None,
1374
+ None,
1375
+ child_path=KeyPath.parse('a.b'),
1376
+ ),
1377
+ KeyPathSet()
1378
+ )
1379
+ self.assertEqual(
1380
+ tree_view.HtmlTreeView.merge_uncollapse(
1381
+ KeyPathSet(['a.b']),
1382
+ None,
1383
+ child_path=KeyPath.parse('x'),
1384
+ ),
1385
+ KeyPathSet(['a.b'])
1386
+ )
1387
+ path_fn = lambda k, v, p: True
1388
+ self.assertIs(
1389
+ tree_view.HtmlTreeView.merge_uncollapse(
1390
+ path_fn,
1391
+ None,
1392
+ child_path=KeyPath.parse('x'),
1393
+ ),
1394
+ path_fn
1395
+ )
1396
+ self.assertEqual(
1397
+ tree_view.HtmlTreeView.merge_uncollapse(
1398
+ KeyPathSet(),
1399
+ KeyPathSet(['d']),
1400
+ child_path=KeyPath.parse('a.b'),
1401
+ ),
1402
+ KeyPathSet(['a.b.d']),
1403
+ )
1404
+ self.assertEqual(
1405
+ tree_view.HtmlTreeView.merge_uncollapse(
1406
+ KeyPathSet(['a.b.c']),
1407
+ KeyPathSet(['d']),
1408
+ child_path=KeyPath.parse('a.b'),
1409
+ ),
1410
+ KeyPathSet(['a.b.c', 'a.b.d']),
1411
+ )
1412
+
1413
+ def test_get_passthrough_kwargs(self):
1414
+ key_filter = (lambda k, v, p: k == 'foo')
1415
+ self.assertEqual(
1416
+ tree_view.HtmlTreeView.get_passthrough_kwargs(
1417
+ name='foo',
1418
+ value=1,
1419
+ root_path=KeyPath(),
1420
+ enable_summary=False,
1421
+ include_keys=key_filter,
1422
+ ),
1423
+ {
1424
+ 'enable_summary': False,
1425
+ 'include_keys': key_filter,
1426
+ },
1427
+ )
1428
+
1429
+ self.assertEqual(
1430
+ tree_view.HtmlTreeView.get_passthrough_kwargs(
1431
+ name='foo',
1432
+ value=1,
1433
+ root_path=KeyPath(),
1434
+ enable_summary=False,
1435
+ include_keys=['a'],
1436
+ extra_flags=dict(x=1),
1437
+ exclude_keys='a',
1438
+ remove=['extra_flags']
1439
+ ),
1440
+ {
1441
+ 'enable_summary': False,
1442
+ },
1443
+ )
1444
+
1445
+
867
1446
  if __name__ == '__main__':
868
1447
  unittest.main()