@@ -12,6 +12,7 @@ var helpers = require('@src/plot_api/helpers');
12
12
var editTypes = require ( '@src/plot_api/edit_types' ) ;
13
13
var annotations = require ( '@src/components/annotations' ) ;
14
14
var images = require ( '@src/components/images' ) ;
15
+ var Registry = require ( '@src/registry' ) ;
15
16
16
17
var d3 = require ( 'd3' ) ;
17
18
var createGraphDiv = require ( '../assets/create_graph_div' ) ;
@@ -1053,14 +1054,14 @@ describe('Test plot api', function() {
1053
1054
var mlcmax1 = 6 ;
1054
1055
var mlcscl1 = 'greens' ;
1055
1056
1056
- function check ( auto , msg ) {
1057
+ function check ( auto , autocolorscale , msg ) {
1057
1058
expect ( gd . data [ 0 ] . marker . cauto ) . toBe ( auto , msg ) ;
1058
1059
expect ( gd . data [ 0 ] . marker . cmin ) . negateIf ( auto ) . toBe ( mcmin0 ) ;
1059
- expect ( gd . _fullData [ 0 ] . marker . autocolorscale ) . toBe ( auto , msg ) ;
1060
+ expect ( gd . _fullData [ 0 ] . marker . autocolorscale ) . toBe ( autocolorscale , msg ) ;
1060
1061
expect ( gd . data [ 0 ] . marker . colorscale ) . toEqual ( auto ? autocscale : mcscl0 ) ;
1061
1062
expect ( gd . data [ 1 ] . marker . line . cauto ) . toBe ( auto , msg ) ;
1062
1063
expect ( gd . data [ 1 ] . marker . line . cmax ) . negateIf ( auto ) . toBe ( mlcmax1 ) ;
1063
- expect ( gd . _fullData [ 1 ] . marker . line . autocolorscale ) . toBe ( auto , msg ) ;
1064
+ expect ( gd . _fullData [ 1 ] . marker . line . autocolorscale ) . toBe ( autocolorscale , msg ) ;
1064
1065
expect ( gd . data [ 1 ] . marker . line . colorscale ) . toEqual ( auto ? autocscale : mlcscl1 ) ;
1065
1066
}
1066
1067
@@ -1069,28 +1070,30 @@ describe('Test plot api', function() {
1069
1070
{ y : [ 2 , 1 ] , mode : 'markers' , marker : { line : { width : 2 , color : [ 3 , 4 ] } } }
1070
1071
] )
1071
1072
. then ( function ( ) {
1072
- check ( true , 'initial' ) ;
1073
+ // autocolorscale is actually true after supplyDefaults, but during calc it's set
1074
+ // to false when we push the resulting colorscale back to the input container
1075
+ check ( true , false , 'initial' ) ;
1073
1076
return Plotly . restyle ( gd , { 'marker.cmin' : mcmin0 , 'marker.colorscale' : mcscl0 } , null , [ 0 ] ) ;
1074
1077
} )
1075
1078
. then ( function ( ) {
1076
1079
return Plotly . restyle ( gd , { 'marker.line.cmax' : mlcmax1 , 'marker.line.colorscale' : mlcscl1 } , null , [ 1 ] ) ;
1077
1080
} )
1078
1081
. then ( function ( ) {
1079
- check ( false , 'set min/max/scale' ) ;
1082
+ check ( false , false , 'set min/max/scale' ) ;
1080
1083
return Plotly . restyle ( gd , { 'marker.cauto' : true , 'marker.autocolorscale' : true } , null , [ 0 ] ) ;
1081
1084
} )
1082
1085
. then ( function ( ) {
1083
1086
return Plotly . restyle ( gd , { 'marker.line.cauto' : true , 'marker.line.autocolorscale' : true } , null , [ 1 ] ) ;
1084
1087
} )
1085
1088
. then ( function ( ) {
1086
- check ( true , 'reset' ) ;
1089
+ check ( true , true , 'reset' ) ;
1087
1090
return Queue . undo ( gd ) ;
1088
1091
} )
1089
1092
. then ( function ( ) {
1090
1093
return Queue . undo ( gd ) ;
1091
1094
} )
1092
1095
. then ( function ( ) {
1093
- check ( false , 'undo' ) ;
1096
+ check ( false , false , 'undo' ) ;
1094
1097
} )
1095
1098
. catch ( failTest )
1096
1099
. then ( done ) ;
@@ -3183,6 +3186,7 @@ describe('Test plot api', function() {
3183
3186
[ 'cheater_smooth' , require ( '@mocks/cheater_smooth.json' ) ] ,
3184
3187
[ 'finance_style' , require ( '@mocks/finance_style.json' ) ] ,
3185
3188
[ 'geo_first' , require ( '@mocks/geo_first.json' ) ] ,
3189
+ [ 'gl2d_heatmapgl' , require ( '@mocks/gl2d_heatmapgl.json' ) ] ,
3186
3190
[ 'gl2d_line_dash' , require ( '@mocks/gl2d_line_dash.json' ) ] ,
3187
3191
[ 'gl2d_parcoords_2' , require ( '@mocks/gl2d_parcoords_2.json' ) ] ,
3188
3192
[ 'gl2d_pointcloud-basic' , require ( '@mocks/gl2d_pointcloud-basic.json' ) ] ,
@@ -3196,12 +3200,14 @@ describe('Test plot api', function() {
3196
3200
[ 'range_selector_style' , require ( '@mocks/range_selector_style.json' ) ] ,
3197
3201
[ 'range_slider_multiple' , require ( '@mocks/range_slider_multiple.json' ) ] ,
3198
3202
[ 'sankey_energy' , require ( '@mocks/sankey_energy.json' ) ] ,
3203
+ [ 'scattercarpet' , require ( '@mocks/scattercarpet.json' ) ] ,
3199
3204
[ 'splom_iris' , require ( '@mocks/splom_iris.json' ) ] ,
3200
3205
[ 'table_wrapped_birds' , require ( '@mocks/table_wrapped_birds.json' ) ] ,
3201
3206
[ 'ternary_fill' , require ( '@mocks/ternary_fill.json' ) ] ,
3202
3207
[ 'text_chart_arrays' , require ( '@mocks/text_chart_arrays.json' ) ] ,
3208
+ [ 'transforms' , require ( '@mocks/transforms.json' ) ] ,
3203
3209
[ 'updatemenus' , require ( '@mocks/updatemenus.json' ) ] ,
3204
- [ 'violins ' , require ( '@mocks/violins .json' ) ] ,
3210
+ [ 'violin_side-by-side ' , require ( '@mocks/violin_side-by-side .json' ) ] ,
3205
3211
[ 'world-cals' , require ( '@mocks/world-cals.json' ) ] ,
3206
3212
[ 'typed arrays' , {
3207
3213
data : [ {
@@ -3211,86 +3217,127 @@ describe('Test plot api', function() {
3211
3217
} ]
3212
3218
] ;
3213
3219
3214
- mockList . forEach ( function ( mockSpec ) {
3215
- it ( 'can redraw "' + mockSpec [ 0 ] + '" with no changes as a noop' , function ( done ) {
3216
- var mock = mockSpec [ 1 ] ;
3217
- var initialJson ;
3218
-
3219
- function fullJson ( ) {
3220
- var out = JSON . parse ( Plotly . Plots . graphJson ( {
3221
- data : gd . _fullData ,
3222
- layout : gd . _fullLayout
3223
- } ) ) ;
3224
-
3225
- // TODO: does it matter that ax.tick0/dtick/range and zmin/zmax
3226
- // are often not regenerated without a calc step?
3227
- // in as far as editor and others rely on _full, I think the
3228
- // answer must be yes, but I'm not sure about within plotly.js
3229
- [
3230
- 'xaxis' , 'xaxis2' , 'xaxis3' , 'xaxis4' , 'xaxis5' ,
3231
- 'yaxis' , 'yaxis2' , 'yaxis3' , 'yaxis4' ,
3232
- 'zaxis'
3233
- ] . forEach ( function ( axName ) {
3234
- var ax = out . layout [ axName ] ;
3220
+ // make sure we've included every trace type in this suite
3221
+ var typesTested = { } ;
3222
+ var itemType ;
3223
+ for ( itemType in Registry . modules ) { typesTested [ itemType ] = 0 ; }
3224
+ for ( itemType in Registry . transformsRegistry ) { typesTested [ itemType ] = 0 ; }
3225
+
3226
+ // Only include scattermapbox locally, see below
3227
+ delete typesTested . scattermapbox ;
3228
+
3229
+ // Not being supported? This isn't part of the main bundle, and it's pretty broken,
3230
+ // but it gets registered and used by a couple of the gl2d tests.
3231
+ delete typesTested . contourgl ;
3232
+
3233
+ function _runReactMock ( mockSpec , done ) {
3234
+ var mock = mockSpec [ 1 ] ;
3235
+ var initialJson ;
3236
+
3237
+ function fullJson ( ) {
3238
+ var out = JSON . parse ( Plotly . Plots . graphJson ( {
3239
+ data : gd . _fullData . map ( function ( trace ) { return trace . _fullInput ; } ) ,
3240
+ layout : gd . _fullLayout
3241
+ } ) ) ;
3242
+
3243
+ // TODO: does it matter that ax.tick0/dtick/range and zmin/zmax
3244
+ // are often not regenerated without a calc step?
3245
+ // in as far as editor and others rely on _full, I think the
3246
+ // answer must be yes, but I'm not sure about within plotly.js
3247
+ [
3248
+ 'xaxis' , 'xaxis2' , 'xaxis3' , 'xaxis4' , 'xaxis5' ,
3249
+ 'yaxis' , 'yaxis2' , 'yaxis3' , 'yaxis4' ,
3250
+ 'zaxis'
3251
+ ] . forEach ( function ( axName ) {
3252
+ var ax = out . layout [ axName ] ;
3253
+ if ( ax ) {
3254
+ delete ax . dtick ;
3255
+ delete ax . tick0 ;
3256
+
3257
+ // TODO this one I don't understand and can't reproduce
3258
+ // in the dashboard but it's needed here?
3259
+ delete ax . range ;
3260
+ }
3261
+ if ( out . layout . scene ) {
3262
+ ax = out . layout . scene [ axName ] ;
3235
3263
if ( ax ) {
3236
3264
delete ax . dtick ;
3237
3265
delete ax . tick0 ;
3238
-
3239
- // TODO this one I don't understand and can't reproduce
3240
- // in the dashboard but it's needed here ?
3266
+ // TODO: this is the only one now that uses '_input_' + key
3267
+ // as a hack to tell Plotly.react to ignore changes.
3268
+ // Can we kill this ?
3241
3269
delete ax . range ;
3242
3270
}
3243
- if ( out . layout . scene ) {
3244
- ax = out . layout . scene [ axName ] ;
3245
- if ( ax ) {
3246
- delete ax . dtick ;
3247
- delete ax . tick0 ;
3248
- // TODO: this is the only one now that uses '_input_' + key
3249
- // as a hack to tell Plotly.react to ignore changes.
3250
- // Can we kill this?
3251
- delete ax . range ;
3252
- }
3253
- }
3254
- } ) ;
3255
- out . data . forEach ( function ( trace ) {
3256
- if ( trace . type === 'contourcarpet' ) {
3257
- delete trace . zmin ;
3258
- delete trace . zmax ;
3259
- }
3260
- } ) ;
3271
+ }
3272
+ } ) ;
3273
+ out . data . forEach ( function ( trace ) {
3274
+ if ( trace . type === 'contourcarpet' ) {
3275
+ delete trace . zmin ;
3276
+ delete trace . zmax ;
3277
+ }
3278
+ } ) ;
3279
+
3280
+ return out ;
3281
+ }
3261
3282
3262
- return out ;
3283
+ // Make sure we define `_length` in every trace *in supplyDefaults*.
3284
+ // This is only relevant for traces that *have* a 1D concept of length,
3285
+ // and in addition to simplifying calc/plot logic later on, ths serves
3286
+ // as a signal to transforms about how they should operate. For traces
3287
+ // that do NOT have a 1D length, `_length` should be `null`.
3288
+ var mockGD = Lib . extendDeep ( { } , mock ) ;
3289
+ supplyAllDefaults ( mockGD ) ;
3290
+ expect ( mockGD . _fullData . length ) . not . toBeLessThan ( ( mock . data || [ ] ) . length , mockSpec [ 0 ] ) ;
3291
+ mockGD . _fullData . forEach ( function ( trace , i ) {
3292
+ var len = trace . _length ;
3293
+ if ( trace . visible !== false && len !== null ) {
3294
+ expect ( typeof len ) . toBe ( 'number' , mockSpec [ 0 ] + ' trace ' + i + ': type=' + trace . type ) ;
3263
3295
}
3264
3296
3265
- // Make sure we define `_length` in every trace *in supplyDefaults*.
3266
- // This is only relevant for traces that *have* a 1D concept of length,
3267
- // and in addition to simplifying calc/plot logic later on, ths serves
3268
- // as a signal to transforms about how they should operate. For traces
3269
- // that do NOT have a 1D length, `_length` should be `null`.
3270
- var mockGD = Lib . extendDeep ( { } , mock ) ;
3271
- supplyAllDefaults ( mockGD ) ;
3272
- expect ( mockGD . _fullData . length ) . not . toBeLessThan ( ( mock . data || [ ] ) . length , mockSpec [ 0 ] ) ;
3273
- mockGD . _fullData . forEach ( function ( trace , i ) {
3274
- var len = trace . _length ;
3275
- if ( trace . visible !== false && len !== null ) {
3276
- expect ( typeof len ) . toBe ( 'number' , mockSpec [ 0 ] + ' trace ' + i + ': type=' + trace . type ) ;
3277
- }
3278
- } ) ;
3297
+ typesTested [ trace . type ] ++ ;
3279
3298
3280
- Plotly . newPlot ( gd , mock )
3281
- . then ( countPlots )
3282
- . then ( function ( ) {
3283
- initialJson = fullJson ( ) ;
3284
-
3285
- return Plotly . react ( gd , mock ) ;
3286
- } )
3287
- . then ( function ( ) {
3288
- expect ( fullJson ( ) ) . toEqual ( initialJson ) ;
3289
- countCalls ( { } ) ;
3290
- } )
3291
- . catch ( failTest )
3292
- . then ( done ) ;
3299
+ if ( trace . transforms ) {
3300
+ trace . transforms . forEach ( function ( transform ) {
3301
+ typesTested [ transform . type ] ++ ;
3302
+ } ) ;
3303
+ }
3293
3304
} ) ;
3305
+
3306
+ Plotly . newPlot ( gd , mock )
3307
+ . then ( countPlots )
3308
+ . then ( function ( ) {
3309
+ initialJson = fullJson ( ) ;
3310
+
3311
+ return Plotly . react ( gd , mock ) ;
3312
+ } )
3313
+ . then ( function ( ) {
3314
+ expect ( fullJson ( ) ) . toEqual ( initialJson ) ;
3315
+ countCalls ( { } ) ;
3316
+ } )
3317
+ . catch ( failTest )
3318
+ . then ( done ) ;
3319
+ }
3320
+
3321
+ mockList . forEach ( function ( mockSpec ) {
3322
+ it ( 'can redraw "' + mockSpec [ 0 ] + '" with no changes as a noop' , function ( done ) {
3323
+ _runReactMock ( mockSpec , done ) ;
3324
+ } ) ;
3325
+ } ) ;
3326
+
3327
+ it ( '@noCI can redraw scattermapbox with no changes as a noop' , function ( done ) {
3328
+ typesTested . scattermapbox = 0 ;
3329
+
3330
+ Plotly . setPlotConfig ( {
3331
+ mapboxAccessToken : require ( '@build/credentials.json' ) . MAPBOX_ACCESS_TOKEN
3332
+ } ) ;
3333
+
3334
+ _runReactMock ( [ 'scattermapbox' , require ( '@mocks/mapbox_bubbles-text.json' ) ] , done ) ;
3335
+ } ) ;
3336
+
3337
+ it ( 'tested every trace & transform type at least once' , function ( ) {
3338
+ for ( var itemType in typesTested ) {
3339
+ expect ( typesTested [ itemType ] ) . toBeGreaterThan ( 0 , itemType + ' was not tested' ) ;
3340
+ }
3294
3341
} ) ;
3295
3342
} ) ;
3296
3343
0 commit comments