@@ -44,6 +44,70 @@ def test_configure(self):
4444 self .assertRaises (TypeError , self .font .cget )
4545 self .assertRaises (TypeError , self .font .cget , 'size' , 'weight' )
4646
47+ def test_create (self ):
48+ sizetype = int if self .wantobjects else str
49+
50+ # A new named font is created from the font description...
51+ f = font .Font (root = self .root , font = ('Times' , 20 , 'bold' ))
52+ self .assertIn (f .name , font .names (self .root ))
53+ self .assertEqual (f .actual ('weight' ), 'bold' )
54+ self .assertEqual (f .cget ('size' ), sizetype (20 ))
55+
56+ # ... or from the keyword options.
57+ f = font .Font (root = self .root , family = 'Times' , size = 20 , weight = 'bold' )
58+ self .assertIn (f .name , font .names (self .root ))
59+ self .assertEqual (f .actual ('weight' ), 'bold' )
60+ self .assertEqual (f .cget ('size' ), sizetype (20 ))
61+
62+ # Explicit options override the corresponding settings of *font*.
63+ f = font .Font (root = self .root , font = ('Times' , 20 , 'bold' ), weight = 'normal' )
64+ self .assertEqual (f .actual ('weight' ), 'normal' )
65+ self .assertEqual (f .cget ('size' ), sizetype (20 ))
66+
67+ # The new font can be given an explicit name.
68+ f = font .Font (root = self .root , name = 'testfont' , font = ('Times' , 20 ))
69+ self .assertEqual (f .name , 'testfont' )
70+ self .assertIn ('testfont' , font .names (self .root ))
71+ self .assertEqual (f .cget ('size' ), sizetype (20 ))
72+ # Reusing the name of an existing font fails.
73+ self .assertRaises (tkinter .TclError , font .Font , root = self .root ,
74+ name = 'testfont' , font = ('Times' , 10 ))
75+
76+ def test_existing (self ):
77+ sizetype = int if self .wantobjects else str
78+
79+ # With a name, refer to the existing named font.
80+ named = font .Font (root = self .root , name = 'existingfont' , family = 'Times' , size = 20 )
81+ f = font .Font (root = self .root , name = 'existingfont' , exists = True )
82+ self .assertEqual (f .name , 'existingfont' )
83+ self .assertEqual (f .cget ('size' ), sizetype (20 ))
84+ # Referring to a non-existent named font fails.
85+ self .assertRaises (tkinter .TclError , font .Font , root = self .root ,
86+ name = 'nosuchfont' , exists = True )
87+ # A name and options reconfigure the existing font.
88+ font .Font (root = self .root , name = 'existingfont' , exists = True , size = 8 )
89+ self .assertEqual (f .cget ('size' ), sizetype (8 ))
90+
91+ # With a description and no name, the description is wrapped without
92+ # creating a new named font (gh-143990), so that it is used without
93+ # loss of precision by actual(), measure() and metrics().
94+ f = font .Font (root = self .root , font = ('Times' , 20 , 'bold' ), exists = True )
95+ self .assertEqual (f .name , ('Times' , 20 , 'bold' ))
96+ self .assertEqual (str (f ), 'Times 20 bold' )
97+ self .assertNotIn (f .name , font .names (self .root ))
98+ self .assertEqual (f .actual ('weight' ), 'bold' )
99+ self .assertEqual (f .actual ('size' ), sizetype (20 ))
100+ # It can be used as a widget option, with the same effect as the
101+ # description itself (gh-143990).
102+ self .assertEqual (tkinter .Label (self .root , font = f ).cget ('font' ),
103+ tkinter .Label (self .root , font = f .name ).cget ('font' ))
104+
105+ # Options cannot be combined with a wrapped description.
106+ self .assertRaises (TypeError , font .Font , root = self .root ,
107+ font = ('Times' , 20 ), exists = True , weight = 'bold' )
108+ # A name or a description is required.
109+ self .assertRaises (TypeError , font .Font , root = self .root , exists = True )
110+
47111 def test_copy (self ):
48112 f = font .Font (root = self .root , family = 'Times' , size = 10 , weight = 'bold' )
49113 copied = f .copy ()
@@ -60,10 +124,7 @@ def test_copy(self):
60124
61125 def test_unicode_family (self ):
62126 family = 'MS \u30b4 \u30b7 \u30c3 \u30af '
63- try :
64- f = font .Font (root = self .root , family = family , exists = True )
65- except tkinter .TclError :
66- f = font .Font (root = self .root , family = family , exists = False )
127+ f = font .Font (root = self .root , family = family )
67128 self .assertEqual (f .cget ('family' ), family )
68129 del f
69130 gc_collect ()
@@ -96,6 +157,19 @@ def test_equality(self):
96157 self .assertEqual (font1 , font2 )
97158 self .assertNotEqual (font1 , font1 .copy ())
98159
160+ # Wrapped descriptions (gh-143990) compare by the description.
161+ w1 = font .Font (root = self .root , font = ('Times' , 20 , 'bold' ), exists = True )
162+ w2 = font .Font (root = self .root , font = ('Times' , 20 , 'bold' ), exists = True )
163+ self .assertIsNot (w1 , w2 )
164+ self .assertEqual (w1 , w2 )
165+ w3 = font .Font (root = self .root , font = ('Times' , 12 ), exists = True )
166+ self .assertNotEqual (w1 , w3 )
167+ # A wrapped description never equals a named font, even one whose name
168+ # is the string form of the description.
169+ named = font .Font (root = self .root , name = str (w1 ), family = 'Courier' )
170+ self .assertNotEqual (w1 , named )
171+ self .assertNotEqual (named , w1 )
172+
99173 self .assertNotEqual (font1 , 0 )
100174 self .assertEqual (font1 , ALWAYS_EQ )
101175
0 commit comments