11import plotly .graph_objects as go
22
33
4- class TestTraceAsDict :
5- """Test _as_dict =True on trace constructors."""
4+ class TestTraceRaw :
5+ """Test raw =True on trace constructors."""
66
77 def test_returns_dict_with_type (self ):
8- result = go .Scatter (x = [1 , 2 ], y = [3 , 4 ], mode = "lines" , _as_dict = True )
8+ result = go .Scatter (x = [1 , 2 ], y = [3 , 4 ], mode = "lines" , raw = True )
99 assert isinstance (result , dict )
1010 assert result == {"type" : "scatter" , "x" : [1 , 2 ], "y" : [3 , 4 ], "mode" : "lines" }
1111
1212 def test_preserves_nested_dicts (self ):
13- result = go .Scatter (
14- x = [1 ], y = [2 ], line = dict (color = "red" , width = 2 ), _as_dict = True
15- )
13+ result = go .Scatter (x = [1 ], y = [2 ], line = dict (color = "red" , width = 2 ), raw = True )
1614 assert result ["line" ] == {"color" : "red" , "width" : 2 }
1715
1816 def test_default_unchanged (self ):
19- """Without _as_dict , constructors must return graph objects as before."""
17+ """Without raw , constructors must return graph objects as before."""
2018 assert not isinstance (go .Scatter (x = [1 ], y = [2 ]), dict )
21- assert not isinstance (go .Scatter (x = [1 ], y = [2 ], _as_dict = False ), dict )
19+ assert not isinstance (go .Scatter (x = [1 ], y = [2 ], raw = False ), dict )
2220
2321
24- class TestFigureAsDict :
25- """Test _as_dict =True on go.Figure construction and methods."""
22+ class TestFigureRaw :
23+ """Test raw =True on go.Figure construction and methods."""
2624
2725 def test_construction (self ):
2826 fig = go .Figure (
29- data = [go .Scatter (x = [1 ], y = [2 ], _as_dict = True )],
27+ data = [go .Scatter (x = [1 ], y = [2 ], raw = True )],
3028 layout = {"title" : "T" },
31- _as_dict = True ,
29+ raw = True ,
3230 )
3331 assert isinstance (fig , go .Figure )
34- assert fig ._as_dict_mode is True
35- # data stored as list of dicts, layout as raw dict
32+ assert fig ._raw_mode is True
3633 assert fig ._data == [{"type" : "scatter" , "x" : [1 ], "y" : [2 ]}]
3734 assert fig ._layout == {"title" : "T" }
38- # Property getters return raw containers
3935 assert isinstance (fig .data , tuple )
4036 assert fig .layout is fig ._layout
4137
4238 def test_construction_from_dict (self ):
4339 """Accept figure-like dict input (e.g. from to_dict())."""
4440 fig = go .Figure (
4541 data = {"data" : [{"type" : "bar" , "x" : [1 ]}], "layout" : {"height" : 400 }},
46- _as_dict = True ,
42+ raw = True ,
4743 )
4844 assert fig ._data == [{"type" : "bar" , "x" : [1 ]}]
4945 assert fig ._layout == {"height" : 400 }
5046
5147 def test_add_traces (self ):
52- fig = go .Figure (_as_dict = True )
53- # Single item (not list)
54- fig .add_traces (go .Scatter (x = [1 ], y = [2 ], _as_dict = True ))
55- # List of items
56- fig .add_traces ([go .Bar (x = ["a" ], y = [1 ], _as_dict = True )])
48+ fig = go .Figure (raw = True )
49+ fig .add_traces (go .Scatter (x = [1 ], y = [2 ], raw = True ))
50+ fig .add_traces ([go .Bar (x = ["a" ], y = [1 ], raw = True )])
5751 assert len (fig ._data ) == 2
5852 assert fig ._data [0 ]["type" ] == "scatter"
5953 assert fig ._data [1 ]["type" ] == "bar"
6054
6155 def test_update_layout (self ):
62- fig = go .Figure (_as_dict = True )
63- # kwargs path
56+ fig = go .Figure (raw = True )
6457 fig .update_layout (title = {"text" : "Hello" })
65- # dict1 path — recursive merge
6658 fig .update_layout ({"title" : {"font" : {"size" : 20 }}})
6759 assert fig ._layout ["title" ] == {"text" : "Hello" , "font" : {"size" : 20 }}
68- # overwrite=True
6960 fig .update_layout (title = {"text" : "New" }, overwrite = True )
7061 assert fig ._layout ["title" ] == {"text" : "New" }
7162
63+ def test_update_traces (self ):
64+ fig = go .Figure (raw = True )
65+ fig .add_traces (
66+ [
67+ go .Scatter (x = [1 ], y = [2 ], mode = "lines" , raw = True ),
68+ go .Bar (x = ["a" ], y = [1 ], raw = True ),
69+ ]
70+ )
71+ fig .update_traces (patch = {"opacity" : 0.5 })
72+ assert fig ._data [0 ]["opacity" ] == 0.5
73+ assert fig ._data [1 ]["opacity" ] == 0.5
74+
75+ def test_update_traces_with_selector (self ):
76+ fig = go .Figure (raw = True )
77+ fig .add_traces (
78+ [
79+ go .Scatter (x = [1 ], y = [2 ], raw = True ),
80+ go .Bar (x = ["a" ], y = [1 ], raw = True ),
81+ ]
82+ )
83+ fig .update_traces (patch = {"opacity" : 0.5 }, selector = {"type" : "scatter" })
84+ assert fig ._data [0 ]["opacity" ] == 0.5
85+ assert "opacity" not in fig ._data [1 ]
86+
87+ def test_for_each_trace (self ):
88+ fig = go .Figure (raw = True )
89+ fig .add_traces ([go .Scatter (x = [1 ], y = [2 ], raw = True )])
90+ visited = []
91+ fig .for_each_trace (lambda t : visited .append (t ["type" ]))
92+ assert visited == ["scatter" ]
93+
7294 def test_add_annotation_and_shape (self ):
73- fig = go .Figure (_as_dict = True )
95+ fig = go .Figure (raw = True )
7496 fig .add_annotation (text = "Note" , x = 1 , y = 2 , showarrow = False )
7597 fig .add_shape (type = "rect" , x0 = 0 , y0 = 0 , x1 = 1 , y1 = 1 )
7698 assert fig ._layout ["annotations" ][0 ]["text" ] == "Note"
7799 assert fig ._layout ["shapes" ][0 ]["type" ] == "rect"
78100
101+ def test_update_annotations (self ):
102+ fig = go .Figure (raw = True )
103+ fig .add_annotation (text = "A" , x = 0 , y = 0 , showarrow = False )
104+ fig .add_annotation (text = "B" , x = 1 , y = 1 , showarrow = False )
105+ fig .update_annotations (patch = {"font" : {"size" : 14 }})
106+ for ann in fig ._layout ["annotations" ]:
107+ assert ann ["font" ] == {"size" : 14 }
108+
109+ def test_update_shapes (self ):
110+ fig = go .Figure (raw = True )
111+ fig .add_shape (type = "rect" , x0 = 0 , y0 = 0 , x1 = 1 , y1 = 1 )
112+ fig .update_shapes (patch = {"opacity" : 0.3 })
113+ assert fig ._layout ["shapes" ][0 ]["opacity" ] == 0.3
114+
79115 def test_add_vline_and_hline (self ):
80- fig = go .Figure (_as_dict = True )
116+ fig = go .Figure (raw = True )
81117 fig .add_vline (x = 5 )
82118 fig .add_hline (y = 3 )
83119 shapes = fig ._layout ["shapes" ]
84120 assert len (shapes ) == 2
85- # vline: x fixed, yref is domain
86121 assert shapes [0 ]["x0" ] == 5 and shapes [0 ]["x1" ] == 5
87122 assert "y domain" in shapes [0 ]["yref" ]
88- # hline: y fixed, xref is domain
89123 assert shapes [1 ]["y0" ] == 3 and shapes [1 ]["y1" ] == 3
90124 assert "x domain" in shapes [1 ]["xref" ]
91125
92- def test_add_vline_with_annotation (self ):
93- fig = go .Figure (_as_dict = True )
94- fig .add_vline (x = 5 , annotation = dict (text = "Limit" ))
95- assert len (fig ._layout ["shapes" ]) == 1
96- assert fig ._layout ["annotations" ][0 ]["text" ] == "Limit"
97-
98- def test_bulk_annotations (self ):
99- """Annotations use list.append (O(N)), not tuple concat."""
100- fig = go .Figure (_as_dict = True )
101- for i in range (100 ):
102- fig .add_annotation (text = f"L{ i } " , x = i , y = i , showarrow = False )
103- assert len (fig ._layout ["annotations" ]) == 100
104-
105126 def test_serialization (self ):
106127 fig = go .Figure (
107- data = [go .Scatter (x = [1 , 2 ], y = [3 , 4 ], _as_dict = True )],
108- _as_dict = True ,
128+ data = [go .Scatter (x = [1 , 2 ], y = [3 , 4 ], raw = True )],
129+ raw = True ,
109130 )
110131 fig .update_layout (title = "Test" )
111132 d = fig .to_dict ()
@@ -115,24 +136,24 @@ def test_serialization(self):
115136 assert isinstance (j , str ) and '"scatter"' in j
116137
117138 def test_default_figure_unchanged (self ):
118- """Without _as_dict , Figure must behave exactly as before."""
139+ """Without raw , Figure must behave exactly as before."""
119140 fig = go .Figure (data = [go .Scatter (x = [1 ], y = [2 ])])
120141 assert hasattr (fig .data [0 ], "to_plotly_json" )
121- assert not getattr (fig , "_as_dict_mode " , False )
142+ assert not getattr (fig , "_raw_mode " , False )
122143
123144
124145class TestOutputEquivalence :
125146 """Fast-path output must match standard path for explicit properties."""
126147
127148 def test_trace_equivalence (self ):
128149 default = go .Scatter (x = [1 ], y = [2 ], mode = "lines" )
129- fast = go .Scatter (x = [1 ], y = [2 ], mode = "lines" , _as_dict = True )
150+ fast = go .Scatter (x = [1 ], y = [2 ], mode = "lines" , raw = True )
130151 for key in ["x" , "y" , "mode" , "type" ]:
131152 assert default .to_plotly_json ()[key ] == fast [key ]
132153
133154 def test_figure_data_equivalence (self ):
134155 default = go .Figure (data = [go .Scatter (x = [1 ], y = [2 ])])
135- fast = go .Figure (data = [go .Scatter (x = [1 ], y = [2 ], _as_dict = True )], _as_dict = True )
156+ fast = go .Figure (data = [go .Scatter (x = [1 ], y = [2 ], raw = True )], raw = True )
136157 dd , fd = default .to_dict ()["data" ][0 ], fast .to_dict ()["data" ][0 ]
137158 for key in ["type" , "x" , "y" ]:
138159 assert dd [key ] == fd [key ]
0 commit comments