def test_check_familyname_matches_fontnames(self):
     contents = self.read_metadata_contents()
     fm = Metadata.get_family_metadata(contents)
     for font_metadata in fm.fonts:
         _ = '%s: Family name "%s" does not match font name: "%s"'
         _ = _ % (font_metadata.filename, fm.name, font_metadata.name)
         self.assertEqual(font_metadata.name, fm.name, _)
    def test_metrics_descents_equal_bbox(self):
        """ Check that descents values are same as min glyph point """
        contents = self.read_metadata_contents()
        family_metadata = Metadata.get_family_metadata(contents)

        fonts_descents_not_bbox = []
        ymin = 0

        _cache = {}
        for font_metadata in family_metadata.fonts:
            ttfont = Font.get_ttfont_from_metadata(self.path, font_metadata)

            ymin_, ymax_ = ttfont.get_bounding()
            ymin = min(ymin, ymin_)

            _cache[font_metadata.filename] = {
                'os2typo': abs(ttfont.descents.os2typo),
                'os2win': abs(ttfont.descents.os2win),
                'hhea': abs(ttfont.descents.hhea)
            }

        for filename, data in _cache.items():
            if [data['os2typo'], data['os2win'], data['hhea']] != [abs(ymin)] * 3:
                fonts_descents_not_bbox.append(filename)

        if fonts_descents_not_bbox:
            _ = '[%s] ascents differ to minimum value: %s'
            self.fail(_ % (', '.join(fonts_descents_not_bbox), ymin))
    def test_check_metadata_fields(self):
        """ Check METADATA.json "fonts" property items have required field """
        contents = self.read_metadata_contents()
        family = Metadata.get_family_metadata(contents)

        keys = [("name", str), ("postScriptName", str),
                ("fullName", str), ("style", str),
                ("weight", int), ("filename", str),
                ("copyright", str)]

        missing = set([])
        unknown = set([])

        for j, itemtype in keys:

            for font_metadata in family.fonts:
                if j not in font_metadata:
                    missing.add(j)

                for k in font_metadata:
                    if k not in map(lambda x: x[0], keys):
                        unknown.add(k)

        if unknown:
            msg = 'METADATA.json "fonts" property has unknown items [%s]'
            self.fail(msg % ', '.join(unknown))

        if missing:
            msg = 'METADATA.json "fonts" property items missed [%s] items'
            self.fail(msg % ', '.join(missing))
    def test_metadata_copyright_size(self):
        """ Copyright string should be less than 500 chars """
        contents = self.read_metadata_contents()
        fm = Metadata.get_family_metadata(contents)

        for font_metadata in fm.fonts:
            self.assertLessEqual(len(font_metadata.copyright), 500)
    def test_check_normal_style_matches_names(self):
        """ Check metadata.json font.style `italic` matches font internal """
        contents = self.read_metadata_contents()
        family = Metadata.get_family_metadata(contents)

        for font_metadata in family.fonts:
            if font_metadata.style != 'normal':
                continue

            font = Font.get_ttfont_from_metadata(self.path, font_metadata)

            if bool(font.macStyle & 0b10):
                self.fail(('Metadata style has been set to normal'
                           ' but font second bit (italic) in macStyle has'
                           ' been set'))

            style = font.familyname.split('-')[-1]
            if style.endswith('Italic'):
                self.fail(('macStyle second bit is not set but postScriptName "%s"'
                           ' is ended with "Italic"') % font.familyname)

            style = font.fullname.split('-')[-1]
            if style.endswith('Italic'):
                self.fail(('macStyle second bit is not set but fullName "%s"'
                           ' is ended with "Italic"') % font.fullname)
 def test_check_menu_contains_proper_glyphs(self):
     """ Check menu file contains proper glyphs """
     contents = self.read_metadata_contents()
     fm = Metadata.get_family_metadata(contents)
     for font_metadata in fm.fonts:
         tf = Font.get_ttfont_from_metadata(self.path, font_metadata, is_menu=True)
         self.check_retrieve_glyphs(tf, font_metadata)
 def test_check_canonical_filenames(self):
     """ Test If filename is canonical """
     contents = self.read_metadata_contents()
     family_metadata = Metadata.get_family_metadata(contents)
     for font_metadata in family_metadata.fonts:
         canonical_filename = self.create_canonical_filename(font_metadata)
         self.assertEqual(canonical_filename, font_metadata.filename)
    def test_copyright_matches_pattern(self):
        """ Copyright string matches to Copyright * 20\d\d * (*@*.*) """
        contents = self.read_metadata_contents()
        fm = Metadata.get_family_metadata(contents)

        for font_metadata in fm.fonts:
            self.assertRegexpMatches(font_metadata.copyright,
                                     r'Copyright\s+\(c\)\s+20\d{2}.*\(.*@.*.*\)')
    def test_check_metadata_matches_nametable(self):
        contents = self.read_metadata_contents()
        fm = Metadata.get_family_metadata(contents)
        for font_metadata in fm.fonts:
            ttfont = Font.get_ttfont_from_metadata(self.path, font_metadata)

            report = '%s: Family name was supposed to be "%s" but is "%s"'
            report = report % (font_metadata.name, fm.name,
                               ttfont.familyname)
            self.assertEqual(ttfont.familyname, fm.name, report)
    def test_postscriptname_contains_correct_weight(self):
        """ Metadata weight matches postScriptName """
        contents = self.read_metadata_contents()
        fm = Metadata.get_family_metadata(contents)

        for font_metadata in fm.fonts:

            if 'Reserved Font Name' not in font_metadata.copyright:
                msg = '"%s" should have "Reserved File Name"'
                self.fail(msg % font_metadata.copyright)
    def test_copyright_is_consistent_across_family(self):
        """ METADATA.json fonts copyright string is the same for all items """
        contents = self.read_metadata_contents()
        fm = Metadata.get_family_metadata(contents)

        copyright = ''
        for font_metadata in fm.fonts:
            if copyright and font_metadata.copyright != copyright:
                self.fail('Copyright is not in consistent across family')
            copyright = font_metadata.copyright
    def test_postscriptname_contains_correct_weight(self):
        """ Metadata weight matches postScriptName """
        contents = self.read_metadata_contents()
        fm = Metadata.get_family_metadata(contents)

        for font_metadata in fm.fonts:

            font = Font.get_ttfont_from_metadata(self.path, font_metadata)
            if font.OS2_usWeightClass != font_metadata.weight:
                msg = 'METADATA.JSON has weight %s but in TTF it is %s'
                self.fail(msg % (font_metadata.weight, font.OS2_usWeightClass))
Exemple #13
0
 def test_family_metadata_is_loaded(self):
     """ Check if Metadata can read family metadata correctly """
     fm = Metadata.get_family_metadata('{"name": "Family Name"}')
     self.assertEqual(type(fm), FamilyMetadata)
     self.assertEqual(fm.name, "Family Name")
     self.assertEqual(fm.designer, "")
     self.assertEqual(fm.license, "")
     self.assertEqual(fm.visibility, "Sandbox")
     self.assertEqual(fm.category, "")
     self.assertEqual(fm.size, 0)
     self.assertEqual(fm.date_added, "")
     self.assertEqual(fm.subsets, [])
    def test_fontname_not_in_camel_case(self):
        """ Check if fontname is not camel cased """
        contents = self.read_metadata_contents()
        familymetadata = Metadata.get_family_metadata(contents)

        camelcased_fontnames = []
        for font_metadata in familymetadata.fonts:
            if bool(re.match(r'([A-Z][a-z]+){2,}', font_metadata.name)):
                camelcased_fontnames.append(font_metadata.name)

        if camelcased_fontnames:
            self.fail(('%s are camel cased names. To solve this check just '
                       'use spaces in names.'))
    def test_menu_file_agreement(self):
        """ Check fonts have corresponding menu files """
        contents = self.read_metadata_contents()
        fm = Metadata.get_family_metadata(contents)
        for font_metadata in fm.fonts:
            menufile = self.menufile(font_metadata)
            path = op.join(op.dirname(self.path), menufile)

            if not op.exists(path):
                self.fail('%s does not exist' % menufile)

            if magic.from_file(path) != 'TrueType font data':
                self.fail('%s is not actual TTF file' % menufile)
Exemple #16
0
 def test_font_metadata_is_loaded(self):
     """ Check if font metadata can be read from family metadata """
     fm = Metadata.get_family_metadata('{"name": "Family Name", "fonts": [{"name": "FontName"}]}')
     fonts_metadata = fm.fonts
     self.assertEqual(type(fonts_metadata), types.GeneratorType)
     fm = fonts_metadata.next()
     self.assertEqual(type(fm), FontMetadata)
     self.assertEqual(fm.name, "FontName")
     self.assertEqual(fm.post_script_name, "")
     self.assertEqual(fm.full_name, "")
     self.assertEqual(fm.style, "normal")
     self.assertEqual(fm.weight, 400)
     self.assertEqual(fm.filename, "")
     self.assertEqual(fm.copyright, "")
    def test_metrics_linegaps_are_zero(self):
        """ Check that linegaps in tables are zero """
        contents = self.read_metadata_contents()
        family_metadata = Metadata.get_family_metadata(contents)

        fonts_gaps_are_not_zero = []
        for font_metadata in family_metadata.fonts:
            ttfont = Font.get_ttfont_from_metadata(self.path, font_metadata)
            if bool(ttfont.linegaps.os2typo) or bool(ttfont.linegaps.hhea):
                fonts_gaps_are_not_zero.append(font_metadata.filename)

        if fonts_gaps_are_not_zero:
            _ = '[%s] have not zero linegaps'
            self.fail(_ % ', '.join(fonts_gaps_are_not_zero))
 def test_check_canonical_styles(self):
     """ Test If font styles are canonical """
     contents = self.read_metadata_contents()
     fm = Metadata.get_family_metadata(contents)
     for font_metadata in fm.fonts:
         self.assertIn(font_metadata.style, self.CANONICAL_STYLE_VALUES)
         if self.is_italic(font_metadata):
             if font_metadata.style != 'italic':
                 _ = "%s: The font style is %s but it should be italic"
                 self.fail(_ % (font_metadata.filename, font_metadata.style))
         else:
             if font_metadata.style != 'normal':
                 _ = "%s: The font style is %s but it should be normal"
                 self.fail(_ % (font_metadata.filename, font_metadata.style))
    def test_check_subsets_exists(self):
        contents = self.read_metadata_contents()
        fm = Metadata.get_family_metadata(contents)
        for font_metadata in fm.fonts:
            for subset in fm.subsets:
                subset_filename = self.get_subset_filename(font_metadata.filename, subset)

                error = "The subset file for the %s subset does not exist"
                error = error % subset_filename
                self.assertTrue(self.f.exists(subset_filename), error)

                error = "The subset file %s is bigger than the original file"
                error = error % subset_filename
                self.assertLessEqual(self.f.size(subset_filename),
                                     self.f.size(font_metadata.filename),
                                     error)
    def test_check_nbsp_width_matches_sp_width(self):
        contents = self.read_metadata_contents()
        fm = Metadata.get_family_metadata(contents)
        for font_metadata in fm.fonts:
            tf = Font.get_ttfont_from_metadata(self.path, font_metadata)
            space_advance_width = tf.advanceWidth('space')
            nbsp_advance_width = tf.advanceWidth('uni00A0')

            _ = "%s: The font does not contain a sp glyph"
            self.assertTrue(space_advance_width, _ % font_metadata.filename)
            _ = "%s: The font does not contain a nbsp glyph"
            self.assertTrue(nbsp_advance_width, _ % font_metadata.filename)

            _ = ("%s: The nbsp advance width does not match "
                 "the sp advance width") % font_metadata.filename
            self.assertEqual(space_advance_width, nbsp_advance_width, _)
    def test_check_subsets_exists(self):
        """ Check that corresponding subset files exist for fonts """
        contents = self.read_metadata_contents()
        fm = Metadata.get_family_metadata(contents)
        for font_metadata in fm.fonts:
            for subset in fm.subsets:
                subset_filename = self.get_subset_filename(font_metadata.filename, subset)

                error = "The subset file for the %s subset does not exist"
                error = error % subset_filename
                self.assertTrue(self.f.exists(subset_filename), error)

                error = "The subset file %s is bigger than the original file"
                error = error % subset_filename
                self.assertLessEqual(self.f.size(subset_filename),
                                     self.f.size(font_metadata.filename),
                                     error)

                self.assertEqual(self.f.mime(subset_filename),
                                 'application/x-font-ttf')
    def test_postscriptname_contains_correct_weight(self):
        """ Metadata weight matches postScriptName """
        contents = self.read_metadata_contents()
        fm = Metadata.get_family_metadata(contents)

        for font_metadata in fm.fonts:
            pair = []
            for k, weight in weights.items():
                if weight == font_metadata.weight:
                    pair.append((k, weight))

            if not pair:
                self.fail('Font weight does not match for "postScriptName"')

            if not (font_metadata.post_script_name.endswith('-%s' % pair[0][0])
                    or font_metadata.post_script_name.endswith('-%s' % pair[1][0])):

                _ = ('postScriptName with weight %s must be '
                     'ended with "%s" or "%s"')
                self.fail(_ % (pair[0][1], pair[0][0], pair[1][0]))
    def test_check_canonical_weights(self):
        """ Check that weights have canonical value """
        contents = self.read_metadata_contents()
        fm = Metadata.get_family_metadata(contents)
        for font_metadata in fm.fonts:
            weight = font_metadata.weight
            first_digit = weight / 100
            is_invalid = (weight % 100) != 0 or (first_digit < 1
                                                 or first_digit > 9)
            _ = ("%s: The weight is %d which is not a "
                 "multiple of 100 between 1 and 9")

            self.assertFalse(is_invalid, _ % (op.basename(self.path),
                                              font_metadata.weight))

            tf = Font.get_ttfont_from_metadata(self.path, font_metadata)
            _ = ("%s: METADATA.json overwrites the weight. "
                 " The METADATA.json weight is %d and the font"
                 " file %s weight is %d")
            _ = _ % (font_metadata.filename, font_metadata.weight,
                     font_metadata.filename, tf.OS2_usWeightClass)

            self.assertEqual(tf.OS2_usWeightClass, font_metadata.weight)
    def test_metadata_contains_current_font(self):
        """ METADATA.json should contains testing font, under canonic name"""

        contents = self.read_metadata_contents()
        fm = Metadata.get_family_metadata(contents)

        for font_metadata in fm.fonts:
            font = Font.get_ttfont_from_metadata(self.path, font_metadata)

            _weights = []
            for value, intvalue in weights.items():
                if intvalue == font.OS2_usWeightClass:
                    _weights.append(value)

            for w in _weights:
                current_font = "%s %s" % (font.familyname, w)
                if font_metadata.full_name != current_font:
                    is_canonical = True

            if not is_canonical:
                v = map(lambda x: font.familyname + ' ' + x, _weights)
                msg = 'Canonical name in font expected: [%s] but %s'
                self.fail(msg % (v, font_metadata.full_name))
 def setUp(self):
     contents = self.read_metadata_contents()
     self.familymetadata = Metadata.get_family_metadata(contents)