class TestVariants(unittest.TestCase):
    def setUp(self):
        self.ctx = FluentBundle(['en-US'], use_isolating=False)
        self.ctx.add_messages(
            dedent_ftl("""
            -variant = {
                [a] A
               *[b] B
             }
            foo = { -variant }
            bar = { -variant[a] }
            baz = { -variant[b] }
            qux = { -variant[c] }
        """))

    def test_returns_the_default_variant(self):
        val, errs = self.ctx.format('foo', {})
        self.assertEqual(val, 'B')
        self.assertEqual(len(errs), 0)

    def test_choose_other_variant(self):
        val, errs = self.ctx.format('bar', {})
        self.assertEqual(val, 'A')
        self.assertEqual(len(errs), 0)

    def test_choose_default_variant(self):
        val, errs = self.ctx.format('baz', {})
        self.assertEqual(val, 'B')
        self.assertEqual(len(errs), 0)

    def test_choose_missing_variant(self):
        val, errs = self.ctx.format('qux', {})
        self.assertEqual(val, 'B')
        self.assertEqual(len(errs), 1)
        self.assertEqual(errs, [FluentReferenceError("Unknown variant: c")])
Example #2
0
class TestResolving(unittest.TestCase):
    def setUp(self):
        self.args_passed = []

        def number_processor(number):
            self.args_passed.append(number)
            return number

        self.ctx = FluentBundle(
            ['en-US'],
            use_isolating=False,
            functions={'NUMBER_PROCESSOR': number_processor})

        self.ctx.add_messages(
            dedent_ftl("""
            pass-number = { NUMBER_PROCESSOR(1) }
            pass-arg = { NUMBER_PROCESSOR($arg) }
        """))

    def test_args_passed_as_numbers(self):
        val, errs = self.ctx.format('pass-arg', {'arg': 1})
        self.assertEqual(val, "1")
        self.assertEqual(len(errs), 0)
        self.assertEqual(self.args_passed, [1])

    def test_literals_passed_as_numbers(self):
        val, errs = self.ctx.format('pass-number', {})
        self.assertEqual(val, "1")
        self.assertEqual(len(errs), 0)
        self.assertEqual(self.args_passed, [1])
Example #3
0
class TestBillionLaughs(unittest.TestCase):
    def setUp(self):
        self.ctx = FluentBundle(['en-US'], use_isolating=False)
        self.ctx.add_messages(
            dedent_ftl("""
            lol0 = 01234567890123456789012345678901234567890123456789
            lol1 = {lol0}{lol0}{lol0}{lol0}{lol0}{lol0}{lol0}{lol0}{lol0}{lol0}
            lol2 = {lol1}{lol1}{lol1}{lol1}{lol1}{lol1}{lol1}{lol1}{lol1}{lol1}
            lol3 = {lol2}{lol2}{lol2}{lol2}{lol2}{lol2}{lol2}{lol2}{lol2}{lol2}
            lol4 = {lol3}{lol3}{lol3}{lol3}{lol3}{lol3}{lol3}{lol3}{lol3}{lol3}
            lolz = {lol4}

            elol0 = { "" }
            elol1 = {elol0}{elol0}{elol0}{elol0}{elol0}{elol0}{elol0}{elol0}{elol0}{elol0}
            elol2 = {elol1}{elol1}{elol1}{elol1}{elol1}{elol1}{elol1}{elol1}{elol1}{elol1}
            elol3 = {elol2}{elol2}{elol2}{elol2}{elol2}{elol2}{elol2}{elol2}{elol2}{elol2}
            elol4 = {elol3}{elol3}{elol3}{elol3}{elol3}{elol3}{elol3}{elol3}{elol3}{elol3}
            elol5 = {elol4}{elol4}{elol4}{elol4}{elol4}{elol4}{elol4}{elol4}{elol4}{elol4}
            elol6 = {elol5}{elol5}{elol5}{elol5}{elol5}{elol5}{elol5}{elol5}{elol5}{elol5}
            emptylolz = {elol6}

        """))

    def test_max_length_protection(self):
        val, errs = self.ctx.format('lolz')
        self.assertEqual(val, ('0123456789' * 1000)[0:2500])
        self.assertNotEqual(len(errs), 0)

    def test_max_expansions_protection(self):
        # Without protection, emptylolz will take a really long time to
        # evaluate, although it generates an empty message.
        val, errs = self.ctx.format('emptylolz')
        self.assertEqual(val, '???')
        self.assertEqual(len(errs), 1)
class TestNumbersInValues(unittest.TestCase):
    def setUp(self):
        self.ctx = FluentBundle(['en-US'], use_isolating=False)
        self.ctx.add_messages(
            dedent_ftl("""
            foo = Foo { $num }
            bar = { foo }
            baz =
                .attr = Baz Attribute { $num }
            qux = { "a" ->
               *[a]     Baz Variant A { $num }
             }
        """))

    def test_can_be_used_in_the_message_value(self):
        val, errs = self.ctx.format('foo', {'num': 3})
        self.assertEqual(val, 'Foo 3')
        self.assertEqual(len(errs), 0)

    def test_can_be_used_in_the_message_value_which_is_referenced(self):
        val, errs = self.ctx.format('bar', {'num': 3})
        self.assertEqual(val, 'Foo 3')
        self.assertEqual(len(errs), 0)

    def test_can_be_used_in_an_attribute(self):
        val, errs = self.ctx.format('baz.attr', {'num': 3})
        self.assertEqual(val, 'Baz Attribute 3')
        self.assertEqual(len(errs), 0)

    def test_can_be_used_in_a_variant(self):
        val, errs = self.ctx.format('qux', {'num': 3})
        self.assertEqual(val, 'Baz Variant A 3')
        self.assertEqual(len(errs), 0)
class TestAttributesWithStringValues(unittest.TestCase):

    def setUp(self):
        self.ctx = FluentBundle(['en-US'], use_isolating=False)
        self.ctx.add_messages(dedent_ftl("""
            foo = Foo
                .attr = Foo Attribute
            bar = { foo } Bar
                .attr = Bar Attribute
            ref-foo = { foo.attr }
            ref-bar = { bar.attr }
        """))

    def test_can_be_referenced_for_entities_with_string_values(self):
        val, errs = self.ctx.format('ref-foo', {})
        self.assertEqual(val, 'Foo Attribute')
        self.assertEqual(len(errs), 0)

    def test_can_be_referenced_for_entities_with_pattern_values(self):
        val, errs = self.ctx.format('ref-bar', {})
        self.assertEqual(val, 'Bar Attribute')
        self.assertEqual(len(errs), 0)

    def test_can_be_formatted_directly_for_entities_with_string_values(self):
        val, errs = self.ctx.format('foo.attr', {})
        self.assertEqual(val, 'Foo Attribute')
        self.assertEqual(len(errs), 0)

    def test_can_be_formatted_directly_for_entities_with_pattern_values(self):
        val, errs = self.ctx.format('bar.attr', {})
        self.assertEqual(val, 'Bar Attribute')
        self.assertEqual(len(errs), 0)
Example #6
0
class TestUseIsolating(unittest.TestCase):

    def setUp(self):
        self.ctx = FluentBundle(['en-US'])
        self.ctx.add_messages(dedent_ftl("""
            foo = Foo
            bar = { foo } Bar
            baz = { $arg } Baz
            qux = { bar } { baz }
        """))

    def test_isolates_interpolated_message_references(self):
        val, errs = self.ctx.format('bar', {})
        self.assertEqual(val, FSI + "Foo" + PDI + " Bar")
        self.assertEqual(len(errs), 0)

    def test_isolates_interpolated_string_typed_variable_references(self):
        val, errs = self.ctx.format('baz', {'arg': 'Arg'})
        self.assertEqual(val, FSI + "Arg" + PDI + " Baz")
        self.assertEqual(len(errs), 0)

    def test_isolates_interpolated_number_typed_variable_references(self):
        val, errs = self.ctx.format('baz', {'arg': 1})
        self.assertEqual(val, FSI + "1" + PDI + " Baz")
        self.assertEqual(len(errs), 0)

    def test_isolates_complex_interpolations(self):
        val, errs = self.ctx.format('qux', {'arg': 'Arg'})
        expected_bar = FSI + FSI + "Foo" + PDI + " Bar" + PDI
        expected_baz = FSI + FSI + "Arg" + PDI + " Baz" + PDI
        self.assertEqual(val, expected_bar + " " + expected_baz)
        self.assertEqual(len(errs), 0)
class TestSelectExpressionWithPluralCategories(unittest.TestCase):
    def setUp(self):
        self.ctx = FluentBundle(['en-US'], use_isolating=False)
        self.ctx.add_messages(
            dedent_ftl("""
            foo = { 1 ->
                [one] A
               *[other] B
             }

            bar = { 1 ->
                [1] A
               *[other] B
             }

            baz = { "not a number" ->
                [one] A
               *[other] B
             }

            qux = { $num ->
                [one] A
               *[other] B
             }
        """))

    def test_selects_the_right_category(self):
        val, errs = self.ctx.format('foo', {})
        self.assertEqual(val, "A")
        self.assertEqual(len(errs), 0)

    def test_selects_exact_match(self):
        val, errs = self.ctx.format('bar', {})
        self.assertEqual(val, "A")
        self.assertEqual(len(errs), 0)

    def test_selects_default_with_invalid_selector(self):
        val, errs = self.ctx.format('baz', {})
        self.assertEqual(val, "B")
        self.assertEqual(len(errs), 0)

    def test_with_a_missing_selector(self):
        val, errs = self.ctx.format('qux', {})
        self.assertEqual(val, "B")
        self.assertEqual(errs, [FluentReferenceError("Unknown external: num")])

    def test_with_argument_integer(self):
        val, errs = self.ctx.format('qux', {'num': 1})
        self.assertEqual(val, "A")
        self.assertEqual(len(errs), 0)

        val, errs = self.ctx.format('qux', {'num': 2})
        self.assertEqual(val, "B")
        self.assertEqual(len(errs), 0)

    def test_with_argument_float(self):
        val, errs = self.ctx.format('qux', {'num': 1.0})
        self.assertEqual(val, "A")
        self.assertEqual(len(errs), 0)
Example #8
0
class TestDatetimeBuiltin(unittest.TestCase):
    def setUp(self):
        self.ctx = FluentBundle(['en-US'], use_isolating=False)
        self.ctx.add_messages(
            dedent_ftl("""
            implicit-call    = { $date }
            explicit-call    = { DATETIME($date) }
            call-with-arg    = { DATETIME($date, dateStyle: "long") }
        """))

    def test_implicit_call_date(self):
        val, errs = self.ctx.format('implicit-call',
                                    {'date': date(2018, 2, 1)})
        self.assertEqual(val, "Feb 1, 2018")
        self.assertEqual(len(errs), 0)

    def test_implicit_call_datetime(self):
        val, errs = self.ctx.format('implicit-call',
                                    {'date': datetime(2018, 2, 1, 14, 15, 16)})
        self.assertEqual(val, "Feb 1, 2018")
        self.assertEqual(len(errs), 0)

    def test_explicit_call_date(self):
        val, errs = self.ctx.format('explicit-call',
                                    {'date': date(2018, 2, 1)})
        self.assertEqual(val, "Feb 1, 2018")
        self.assertEqual(len(errs), 0)

    def test_explicit_call_datetime(self):
        val, errs = self.ctx.format('explicit-call',
                                    {'date': datetime(2018, 2, 1, 14, 15, 16)})
        self.assertEqual(val, "Feb 1, 2018")
        self.assertEqual(len(errs), 0)

    def test_explicit_call_date_fluent_date(self):
        val, errs = self.ctx.format(
            'explicit-call',
            {'date': fluent_date(date(2018, 2, 1), dateStyle='short')})
        self.assertEqual(val, "2/1/18")
        self.assertEqual(len(errs), 0)

    def test_arg(self):
        val, errs = self.ctx.format('call-with-arg',
                                    {'date': date(2018, 2, 1)})
        self.assertEqual(val, "February 1, 2018")
        self.assertEqual(len(errs), 0)

    def test_arg_overrides_fluent_date(self):
        val, errs = self.ctx.format(
            'call-with-arg',
            {'date': fluent_date(date(2018, 2, 1), dateStyle='short')})
        self.assertEqual(val, "February 1, 2018")
        self.assertEqual(len(errs), 0)
Example #9
0
class TestFunctionCalls(unittest.TestCase):
    def setUp(self):
        self.ctx = FluentBundle(['en-US'],
                                use_isolating=False,
                                functions={'IDENTITY': lambda x: x})
        self.ctx.add_messages(
            dedent_ftl("""
            foo = Foo
                .attr = Attribute
            pass-nothing       = { IDENTITY() }
            pass-string        = { IDENTITY("a") }
            pass-number        = { IDENTITY(1) }
            pass-message       = { IDENTITY(foo) }
            pass-attr          = { IDENTITY(foo.attr) }
            pass-external      = { IDENTITY($ext) }
            pass-function-call = { IDENTITY(IDENTITY(1)) }
        """))

    def test_accepts_strings(self):
        val, errs = self.ctx.format('pass-string', {})
        self.assertEqual(val, "a")
        self.assertEqual(len(errs), 0)

    def test_accepts_numbers(self):
        val, errs = self.ctx.format('pass-number', {})
        self.assertEqual(val, "1")
        self.assertEqual(len(errs), 0)

    def test_accepts_entities(self):
        val, errs = self.ctx.format('pass-message', {})
        self.assertEqual(val, "Foo")
        self.assertEqual(len(errs), 0)

    def test_accepts_attributes(self):
        val, errs = self.ctx.format('pass-attr', {})
        self.assertEqual(val, "Attribute")
        self.assertEqual(len(errs), 0)

    def test_accepts_externals(self):
        val, errs = self.ctx.format('pass-external', {'ext': 'Ext'})
        self.assertEqual(val, "Ext")
        self.assertEqual(len(errs), 0)

    def test_accepts_function_calls(self):
        val, errs = self.ctx.format('pass-function-call', {})
        self.assertEqual(val, "1")
        self.assertEqual(len(errs), 0)

    def test_wrong_arity(self):
        val, errs = self.ctx.format('pass-nothing', {})
        self.assertEqual(val, "IDENTITY()")
        self.assertEqual(len(errs), 1)
        self.assertEqual(type(errs[0]), TypeError)
class TestStrings(unittest.TestCase):
    def setUp(self):
        self.ctx = FluentBundle(['en-US'], use_isolating=False)
        self.ctx.add_messages(
            dedent_ftl("""
            foo = { $arg }
        """))

    def test_can_be_a_string(self):
        val, errs = self.ctx.format('foo', {'arg': 'Argument'})
        self.assertEqual(val, 'Argument')
        self.assertEqual(len(errs), 0)
class TestSelectExpressionWithNumbers(unittest.TestCase):
    def setUp(self):
        self.ctx = FluentBundle(['en-US'], use_isolating=False)
        self.ctx.add_messages(
            dedent_ftl("""
            foo = { 1 ->
               *[0] A
                [1] B
             }

            bar = { 2 ->
               *[0] A
                [1] B
             }

            baz = { $num ->
               *[0] A
                [1] B
             }

            qux = { 1.0 ->
               *[0] A
                [1] B
             }
        """))

    def test_selects_the_right_variant(self):
        val, errs = self.ctx.format('foo', {})
        self.assertEqual(val, "B")
        self.assertEqual(len(errs), 0)

    def test_with_a_non_matching_selector(self):
        val, errs = self.ctx.format('bar', {})
        self.assertEqual(val, "A")
        self.assertEqual(len(errs), 0)

    def test_with_a_missing_selector(self):
        val, errs = self.ctx.format('baz', {})
        self.assertEqual(val, "A")
        self.assertEqual(errs, [FluentReferenceError("Unknown external: num")])

    def test_with_argument_int(self):
        val, errs = self.ctx.format('baz', {'num': 1})
        self.assertEqual(val, "B")

    def test_with_argument_float(self):
        val, errs = self.ctx.format('baz', {'num': 1.0})
        self.assertEqual(val, "B")

    def test_with_float(self):
        val, errs = self.ctx.format('qux', {})
        self.assertEqual(val, "B")
Example #12
0
class TestMissing(unittest.TestCase):
    def setUp(self):
        self.ctx = FluentBundle(['en-US'], use_isolating=False)
        self.ctx.add_messages(
            dedent_ftl("""
            missing = { MISSING(1) }
        """))

    def test_falls_back_to_name_of_function(self):
        val, errs = self.ctx.format("missing", {})
        self.assertEqual(val, "MISSING()")
        self.assertEqual(errs,
                         [FluentReferenceError("Unknown function: MISSING")])
Example #13
0
class Translation():

    def __init__(self):

        self.__language = 'de'

        self.__locales = None

        self.__bundle = None

    def setLanguage(self, language):

        self.__language = language

        self.setupTranslation()

    def getLanguage(self):

        return self.__language

    def setLocaleDirectory(self, locales):

        self.__locales = locales

    def setupTranslation(self):

        messages = ""

        self.__bundle = FluentBundle([self.__language])

        path = Path("{}/{}".format(self.__locales, self.__language))

        for file in path.iterdir():
            
            with open(file, "r") as f:

                messages += f.read()

        self.__bundle.add_messages(messages)

    def addMessage(self, message):

        self.__bundle.add_messages(message)

        print("Message '{}' added.".format(message))

    def getMessage(self, id, args):

        return self.__bundle.format(id, args)
class TestMessagesCalledFromTerms(unittest.TestCase):
    def setUp(self):
        self.ctx = FluentBundle(['en-US'], use_isolating=False)
        self.ctx.add_messages(
            dedent_ftl("""
            msg = Msg is {$arg}
            -foo = {msg}
            ref-foo = {-foo(arg: 1)}
        """))

    def test_messages_inherit_term_args(self):
        # This behaviour may change in future, message calls might be
        # disallowed from inside terms
        val, errs = self.ctx.format('ref-foo', {'arg': 2})
        self.assertEqual(val, 'Msg is 1')
        self.assertEqual(errs, [])
def getStruct(resource):
    pp = pprint.PrettyPrinter(indent=0)

    bundle = FluentBundle(["en-US"])
    bundle.add_messages(resource)
    parser = fs.FluentParser()
    resource = parser.parse(resource)

    thing = fs.ast.to_json(resource)

    # json.loads(thing)
    # pp.pprint(thing)
    # pp.pprint(thing['body'])

    template_data = {}

    for m in thing['body']:
        if 'id' in m:
            # print(m['id']['name'])
            template_id = m['id']['name']
            # pp.pprint(m['value']['elements'])

            new_entry = indvPieces(m, pp)

            template_data[template_id] = new_entry

    # print("FIRST OUTPUT")
    # pp.pprint(template_data)

    for k in template_data.keys():
        # print(k)
        passedVars = passUpVars(template_data, k)

        for v in passedVars:
            if v not in template_data[k]['variables']:
                template_data[k]['variables'].append(v)

        passedVariants = passUpVariants(template_data, k)

        for v in passedVariants.keys():
            if v not in template_data[k]['variants']:
                template_data[k]['variants'][v] = passedVariants[v]

    # print("SECOND OUTPUT")
    # pp.pprint(template_data)

    return template_data
class TestAttributesWithSimplePatternValues(unittest.TestCase):

    def setUp(self):
        self.ctx = FluentBundle(['en-US'], use_isolating=False)
        self.ctx.add_messages(dedent_ftl("""
            foo = Foo
            bar = Bar
                .attr = { foo } Attribute
            baz = { foo } Baz
                .attr = { foo } Attribute
            qux = Qux
                .attr = { qux } Attribute
            ref-bar = { bar.attr }
            ref-baz = { baz.attr }
            ref-qux = { qux.attr }
        """))

    def test_can_be_referenced_for_entities_with_string_values(self):
        val, errs = self.ctx.format('ref-bar', {})
        self.assertEqual(val, 'Foo Attribute')
        self.assertEqual(len(errs), 0)

    def test_can_be_formatted_directly_for_entities_with_string_values(self):
        val, errs = self.ctx.format('bar.attr', {})
        self.assertEqual(val, 'Foo Attribute')
        self.assertEqual(len(errs), 0)

    def test_can_be_referenced_for_entities_with_pattern_values(self):
        val, errs = self.ctx.format('ref-baz', {})
        self.assertEqual(val, 'Foo Attribute')
        self.assertEqual(len(errs), 0)

    def test_can_be_formatted_directly_for_entities_with_pattern_values(self):
        val, errs = self.ctx.format('baz.attr', {})
        self.assertEqual(val, 'Foo Attribute')
        self.assertEqual(len(errs), 0)

    def test_works_with_self_references(self):
        val, errs = self.ctx.format('ref-qux', {})
        self.assertEqual(val, 'Qux Attribute')
        self.assertEqual(len(errs), 0)

    def test_works_with_self_references_direct(self):
        val, errs = self.ctx.format('qux.attr', {})
        self.assertEqual(val, 'Qux Attribute')
        self.assertEqual(len(errs), 0)
class TestNestedParameterizedTerms(unittest.TestCase):
    def setUp(self):
        self.ctx = FluentBundle(['en-US'], use_isolating=False)
        self.ctx.add_messages(
            dedent_ftl("""
            -thing = { $article ->
                *[definite] { $first-letter ->
                    *[lower] the thing
                     [upper] The thing
                 }
                 [indefinite] { $first-letter ->
                    *[lower] a thing
                     [upper] A thing
                 }
             }

            both-args = { -thing(first-letter: "upper", article: "indefinite") }.
            outer-arg = This is { -thing(article: "indefinite") }.
            inner-arg = { -thing(first-letter: "upper") }.
            neither-arg = { -thing() }.
        """))

    def test_both_args(self):
        val, errs = self.ctx.format('both-args', {})
        self.assertEqual(val, 'A thing.')
        self.assertEqual(errs, [])

    def test_outer_arg(self):
        val, errs = self.ctx.format('outer-arg', {})
        self.assertEqual(val, 'This is a thing.')
        self.assertEqual(errs, [])

    def test_inner_arg(self):
        val, errs = self.ctx.format('inner-arg', {})
        self.assertEqual(val, 'The thing.')
        self.assertEqual(errs, [])

    def test_inner_arg_with_external_args(self):
        val, errs = self.ctx.format('inner-arg', {'article': 'indefinite'})
        self.assertEqual(val, 'The thing.')
        self.assertEqual(errs, [])

    def test_neither_arg(self):
        val, errs = self.ctx.format('neither-arg', {})
        self.assertEqual(val, 'the thing.')
        self.assertEqual(errs, [])
Example #18
0
class TestKeywordArgs(unittest.TestCase):
    def setUp(self):
        self.args_passed = []

        def my_function(arg, kwarg1=None, kwarg2="default"):
            self.args_passed.append((arg, kwarg1, kwarg2))
            return arg

        self.ctx = FluentBundle(['en-US'],
                                use_isolating=False,
                                functions={'MYFUNC': my_function})
        self.ctx.add_messages(
            dedent_ftl("""
            pass-arg        = { MYFUNC("a") }
            pass-kwarg1     = { MYFUNC("a", kwarg1: 1) }
            pass-kwarg2     = { MYFUNC("a", kwarg2: "other") }
            pass-kwargs     = { MYFUNC("a", kwarg1: 1, kwarg2: "other") }
            pass-user-arg   = { MYFUNC($arg) }
        """))

    def test_defaults(self):
        val, errs = self.ctx.format('pass-arg', {})
        self.assertEqual(self.args_passed, [("a", None, "default")])
        self.assertEqual(len(errs), 0)

    def test_pass_kwarg1(self):
        val, errs = self.ctx.format('pass-kwarg1', {})
        self.assertEqual(self.args_passed, [("a", 1, "default")])
        self.assertEqual(len(errs), 0)

    def test_pass_kwarg2(self):
        val, errs = self.ctx.format('pass-kwarg2', {})
        self.assertEqual(self.args_passed, [("a", None, "other")])
        self.assertEqual(len(errs), 0)

    def test_pass_kwargs(self):
        val, errs = self.ctx.format('pass-kwargs', {})
        self.assertEqual(self.args_passed, [("a", 1, "other")])
        self.assertEqual(len(errs), 0)

    def test_missing_arg(self):
        val, errs = self.ctx.format('pass-user-arg', {})
        self.assertEqual(self.args_passed,
                         [(FluentNone('arg'), None, "default")])
        self.assertEqual(len(errs), 1)
Example #19
0
class TestSkipIsolating(unittest.TestCase):

    def setUp(self):
        self.ctx = FluentBundle(['en-US'])
        self.ctx.add_messages(dedent_ftl("""
            -brand-short-name = Amaya
            foo = { -brand-short-name }
            with-arg = { $arg }
        """))

    def test_skip_isolating_chars_if_just_one_message_ref(self):
        val, errs = self.ctx.format('foo', {})
        self.assertEqual(val, 'Amaya')
        self.assertEqual(len(errs), 0)

    def test_skip_isolating_chars_if_just_one_placeable_arg(self):
        val, errs = self.ctx.format('with-arg', {'arg': 'Arg'})
        self.assertEqual(val, 'Arg')
        self.assertEqual(len(errs), 0)
class TestSelectExpressionWithStrings(unittest.TestCase):
    def setUp(self):
        self.ctx = FluentBundle(['en-US'], use_isolating=False)

    def test_with_a_matching_selector(self):
        self.ctx.add_messages(
            dedent_ftl("""
            foo = { "a" ->
                [a] A
               *[b] B
             }
        """))
        val, errs = self.ctx.format('foo', {})
        self.assertEqual(val, "A")
        self.assertEqual(len(errs), 0)

    def test_with_a_non_matching_selector(self):
        self.ctx.add_messages(
            dedent_ftl("""
            foo = { "c" ->
                [a] A
               *[b] B
             }
        """))
        val, errs = self.ctx.format('foo', {})
        self.assertEqual(val, "B")
        self.assertEqual(len(errs), 0)

    def test_with_a_missing_selector(self):
        self.ctx.add_messages(
            dedent_ftl("""
            foo = { $none ->
                [a] A
               *[b] B
             }
        """))
        val, errs = self.ctx.format('foo', {})
        self.assertEqual(val, "B")
        self.assertEqual(errs,
                         [FluentReferenceError("Unknown external: none")])

    def test_with_argument_expression(self):
        self.ctx.add_messages(
            dedent_ftl("""
            foo = { $arg ->
                [a] A
               *[b] B
             }
        """))
        val, errs = self.ctx.format('foo', {'arg': 'a'})
        self.assertEqual(val, "A")
class TestSelectExpressionWithTerms(unittest.TestCase):
    def setUp(self):
        self.ctx = FluentBundle(['en-US'], use_isolating=False)
        self.ctx.add_messages(
            dedent_ftl("""
            -my-term = term
                 .attr = termattribute

            ref-term-attr = { -my-term.attr ->
                    [termattribute]   Term Attribute
                   *[other]           Other
            }

            ref-term-attr-other = { -my-term.attr ->
                    [x]      Term Attribute
                   *[other]  Other
            }

            ref-term-attr-missing = { -my-term.missing ->
                    [x]      Term Attribute
                   *[other]  Other
            }
        """))

    def test_ref_term_attribute(self):
        val, errs = self.ctx.format('ref-term-attr')
        self.assertEqual(val, "Term Attribute")
        self.assertEqual(len(errs), 0)

    def test_ref_term_attribute_fallback(self):
        val, errs = self.ctx.format('ref-term-attr-other')
        self.assertEqual(val, "Other")
        self.assertEqual(len(errs), 0)

    def test_ref_term_attribute_missing(self):
        val, errs = self.ctx.format('ref-term-attr-missing')
        self.assertEqual(val, "Other")
        self.assertEqual(len(errs), 1)
        self.assertEqual(
            errs,
            [FluentReferenceError('Unknown attribute: -my-term.missing')])
class TestTermsCalledFromTerms(unittest.TestCase):
    def setUp(self):
        self.ctx = FluentBundle(['en-US'], use_isolating=False)
        self.ctx.add_messages(
            dedent_ftl("""
            -foo = {$a} {$b}
            -bar = {-foo(b: 2)}
            -baz = {-foo}
            ref-bar = {-bar(a: 1)}
            ref-baz = {-baz(a: 1)}
        """))

    def test_term_args_isolated_with_call_syntax(self):
        val, errs = self.ctx.format('ref-bar', {})
        self.assertEqual(val, 'a 2')
        self.assertEqual(errs, [])

    def test_term_args_isolated_without_call_syntax(self):
        val, errs = self.ctx.format('ref-baz', {})
        self.assertEqual(val, 'a b')
        self.assertEqual(errs, [])
class TestParameterizedTermAttributes(unittest.TestCase):
    def setUp(self):
        self.ctx = FluentBundle(['en-US'], use_isolating=False)
        self.ctx.add_messages(
            dedent_ftl("""
            -brand = Cool Thing
                .status = { $version ->
                    [v2]     available
                   *[v1]     deprecated
                }

            attr-with-arg = { -brand } is { -brand.status(version: "v2") ->
                 [available]   available, yay!
                *[deprecated]  deprecated, sorry
            }

            -other = { $arg ->
                        [a]  ABC
                       *[d]  DEF
                     }

            missing-attr-ref = { -other.missing(arg: "a") ->
                 [ABC]  ABC option
                *[DEF]  DEF option
            }
        """))

    def test_with_argument(self):
        val, errs = self.ctx.format('attr-with-arg', {})
        self.assertEqual(val, 'Cool Thing is available, yay!')
        self.assertEqual(errs, [])

    def test_missing_attr(self):
        # We should fall back to the parent, and still pass the args.
        val, errs = self.ctx.format('missing-attr-ref', {})
        self.assertEqual(val, 'ABC option')
        self.assertEqual(
            errs, [FluentReferenceError('Unknown attribute: -other.missing')])
Example #24
0
class TestFluentBundle(unittest.TestCase):
    def setUp(self):
        self.ctx = FluentBundle(['en-US'])

    def test_add_messages(self):
        self.ctx.add_messages(
            dedent_ftl("""
            foo = Foo
            bar = Bar
            -baz = Baz
        """))
        self.assertIn('foo', self.ctx._messages_and_terms)
        self.assertIn('bar', self.ctx._messages_and_terms)
        self.assertIn('-baz', self.ctx._messages_and_terms)

    def test_has_message(self):
        self.ctx.add_messages(dedent_ftl("""
            foo = Foo
        """))

        self.assertTrue(self.ctx.has_message('foo'))
        self.assertFalse(self.ctx.has_message('bar'))

    def test_has_message_for_term(self):
        self.ctx.add_messages(
            dedent_ftl("""
            -foo = Foo
        """))

        self.assertFalse(self.ctx.has_message('-foo'))

    def test_has_message_with_attribute(self):
        self.ctx.add_messages(
            dedent_ftl("""
            foo = Foo
                .attr = Foo Attribute
        """))

        self.assertTrue(self.ctx.has_message('foo'))
        self.assertFalse(self.ctx.has_message('foo.attr'))
        self.assertFalse(self.ctx.has_message('foo.other-attribute'))

    def test_plural_form_english_ints(self):
        ctx = FluentBundle(['en-US'])
        self.assertEqual(ctx._plural_form(0), 'other')
        self.assertEqual(ctx._plural_form(1), 'one')
        self.assertEqual(ctx._plural_form(2), 'other')

    def test_plural_form_english_floats(self):
        ctx = FluentBundle(['en-US'])
        self.assertEqual(ctx._plural_form(0.0), 'other')
        self.assertEqual(ctx._plural_form(1.0), 'one')
        self.assertEqual(ctx._plural_form(2.0), 'other')
        self.assertEqual(ctx._plural_form(0.5), 'other')

    def test_plural_form_french(self):
        # Just spot check one other, to ensure that we
        # are not getting the EN locale by accident or
        ctx = FluentBundle(['fr'])
        self.assertEqual(ctx._plural_form(0), 'one')
        self.assertEqual(ctx._plural_form(1), 'one')
        self.assertEqual(ctx._plural_form(2), 'other')

    def test_format_args(self):
        self.ctx.add_messages('foo = Foo')
        val, errs = self.ctx.format('foo')
        self.assertEqual(val, 'Foo')

        val, errs = self.ctx.format('foo', {})
        self.assertEqual(val, 'Foo')

    def test_format_missing(self):
        self.assertRaises(LookupError, self.ctx.format, 'a-missing-message')

    def test_format_term(self):
        self.ctx.add_messages(
            dedent_ftl("""
            -foo = Foo
        """))
        self.assertRaises(LookupError, self.ctx.format, '-foo')
        self.assertRaises(LookupError, self.ctx.format, 'foo')

    def test_message_and_term_separate(self):
        self.ctx.add_messages(
            dedent_ftl("""
            foo = Refers to { -foo }
            -foo = Foo
        """))
        val, errs = self.ctx.format('foo', {})
        self.assertEqual(val, 'Refers to \u2068Foo\u2069')
        self.assertEqual(errs, [])
Example #25
0

# Create Fluent bundle for composing Fluent objects
bundle = FluentBundle(["en-US"])

# Test String
emailTestString = """
unread-emails = { $unreadEmailsCount -> 
    [one] You have {$unreadEmailsCount} unread email.
   *[other] You have {$unreadEmailsCount} unread emails.	
}"""

print("FLUENT MESSAGE:" + emailTestString + "\n")

# Add String to bundle
bundle.add_messages(emailTestString)

# Add another test string straight to bundle
# bundle.add_messages("""
# shared-photos =
#     {$userName} {$photoCount ->
#         [one] added a new photo
#        *[other] added {$photoCount} new photos
#     } to {$userGender ->
#         [male] his stream
#         [female] her stream
#        *[other] their stream
#     }.""")

# Get compiled fluent message
# translated, errs = bundle.format('shared-photos')
class TestMissing(unittest.TestCase):
    def setUp(self):
        self.ctx = FluentBundle(['en-US'], use_isolating=False)
        self.ctx.add_messages(dedent_ftl("""
            foo = Foo
            bar = Bar
                .attr = Bar Attribute
            baz = { foo } Baz
            qux = { foo } Qux
                .attr = Qux Attribute
            ref-foo = { foo.missing }
            ref-bar = { bar.missing }
            ref-baz = { baz.missing }
            ref-qux = { qux.missing }
            attr-only =
                     .attr  = Attr Only Attribute
            ref-double-missing = { missing.attr }
        """))

    def test_falls_back_for_msg_with_string_value_and_no_attributes(self):
        val, errs = self.ctx.format('ref-foo', {})
        self.assertEqual(val, 'Foo')
        self.assertEqual(errs,
                         [FluentReferenceError(
                             'Unknown attribute: foo.missing')])

    def test_falls_back_for_msg_with_string_value_and_other_attributes(self):
        val, errs = self.ctx.format('ref-bar', {})
        self.assertEqual(val, 'Bar')
        self.assertEqual(errs,
                         [FluentReferenceError(
                             'Unknown attribute: bar.missing')])

    def test_falls_back_for_msg_with_pattern_value_and_no_attributes(self):
        val, errs = self.ctx.format('ref-baz', {})
        self.assertEqual(val, 'Foo Baz')
        self.assertEqual(errs,
                         [FluentReferenceError(
                             'Unknown attribute: baz.missing')])

    def test_falls_back_for_msg_with_pattern_value_and_other_attributes(self):
        val, errs = self.ctx.format('ref-qux', {})
        self.assertEqual(val, 'Foo Qux')
        self.assertEqual(errs,
                         [FluentReferenceError(
                             'Unknown attribute: qux.missing')])

    def test_attr_only_main(self):
        # For reference, Javascript implementation returns null for this case.
        # For Python returning `None` doesn't seem appropriate, since this will
        # only blow up later if you attempt to add this to a string, so we raise
        # a LookupError instead, as per entirely missing messages.
        self.assertRaises(LookupError, self.ctx.format, 'attr-only', {})

    def test_attr_only_attribute(self):
        val, errs = self.ctx.format('attr-only.attr', {})
        self.assertEqual(val, 'Attr Only Attribute')
        self.assertEqual(len(errs), 0)

    def test_missing_message_and_attribute(self):
        val, errs = self.ctx.format('ref-double-missing', {})
        self.assertEqual(val, 'missing.attr')
        self.assertEqual(errs, [FluentReferenceError('Unknown attribute: missing.attr')])
Example #27
0
class TestNumberBuiltin(unittest.TestCase):
    def setUp(self):
        self.ctx = FluentBundle(['en-US'], use_isolating=False)
        self.ctx.add_messages(
            dedent_ftl("""
            implicit-call    = { 123456 }
            implicit-call2   = { $arg }
            defaults         = { NUMBER(123456) }
            percent-style    = { NUMBER(1.234, style: "percent") }
            currency-style   = { NUMBER(123456, style: "currency", currency: "USD") }
            from-arg         = { NUMBER($arg) }
            merge-params     = { NUMBER($arg, useGrouping: 0) }
        """))

    def test_implicit_call(self):
        val, errs = self.ctx.format('implicit-call', {})
        self.assertEqual(val, "123,456")
        self.assertEqual(len(errs), 0)

    def test_implicit_call2_int(self):
        val, errs = self.ctx.format('implicit-call2', {'arg': 123456})
        self.assertEqual(val, "123,456")
        self.assertEqual(len(errs), 0)

    def test_implicit_call2_float(self):
        val, errs = self.ctx.format('implicit-call2', {'arg': 123456.0})
        self.assertEqual(val, "123,456")
        self.assertEqual(len(errs), 0)

    def test_implicit_call2_decimal(self):
        val, errs = self.ctx.format('implicit-call2',
                                    {'arg': Decimal('123456.0')})
        self.assertEqual(val, "123,456")
        self.assertEqual(len(errs), 0)

    def test_defaults(self):
        val, errs = self.ctx.format('defaults', {})
        self.assertEqual(val, "123,456")
        self.assertEqual(len(errs), 0)

    def test_percent_style(self):
        val, errs = self.ctx.format('percent-style', {})
        self.assertEqual(val, "123%")
        self.assertEqual(len(errs), 0)

    def test_currency_style(self):
        val, errs = self.ctx.format('currency-style', {})
        self.assertEqual(val, "$123,456.00")
        self.assertEqual(len(errs), 0)

    def test_from_arg_int(self):
        val, errs = self.ctx.format('from-arg', {'arg': 123456})
        self.assertEqual(val, "123,456")
        self.assertEqual(len(errs), 0)

    def test_from_arg_float(self):
        val, errs = self.ctx.format('from-arg', {'arg': 123456.0})
        self.assertEqual(val, "123,456")
        self.assertEqual(len(errs), 0)

    def test_from_arg_decimal(self):
        val, errs = self.ctx.format('from-arg', {'arg': Decimal('123456.0')})
        self.assertEqual(val, "123,456")
        self.assertEqual(len(errs), 0)

    def test_from_arg_missing(self):
        val, errs = self.ctx.format('from-arg', {})
        self.assertEqual(val, "arg")
        self.assertEqual(len(errs), 1)
        self.assertEqual(errs, [FluentReferenceError('Unknown external: arg')])

    def test_partial_application(self):
        number = fluent_number(123456.78, currency="USD", style="currency")
        val, errs = self.ctx.format('from-arg', {'arg': number})
        self.assertEqual(val, "$123,456.78")
        self.assertEqual(len(errs), 0)

    def test_merge_params(self):
        number = fluent_number(123456.78, currency="USD", style="currency")
        val, errs = self.ctx.format('merge-params', {'arg': number})
        self.assertEqual(val, "$123456.78")
        self.assertEqual(len(errs), 0)
class TestPlaceables(unittest.TestCase):
    def setUp(self):
        self.ctx = FluentBundle(['en-US'], use_isolating=False)
        self.ctx.add_messages(
            dedent_ftl("""
            message = Message
                    .attr = Message Attribute
            -term = Term
                  .attr = Term Attribute
            -term2 = {
               *[variant1] Term Variant 1
                [variant2] Term Variant 2
             }

            uses-message = { message }
            uses-message-attr = { message.attr }
            uses-term = { -term }
            uses-term-variant = { -term2[variant2] }

            bad-message-ref = Text { not-a-message }
            bad-message-attr-ref = Text { message.not-an-attr }
            bad-term-ref = Text { -not-a-term }

            self-referencing-message = Text { self-referencing-message }
            cyclic-msg1 = Text1 { cyclic-msg2 }
            cyclic-msg2 = Text2 { cyclic-msg1 }
            self-cyclic-message = Parent { self-cyclic-message.attr }
                                .attr = Attribute { self-cyclic-message }

            self-attribute-ref-ok = Parent { self-attribute-ref-ok.attr }
                                  .attr = Attribute
            self-parent-ref-ok = Parent
                               .attr =  Attribute { self-parent-ref-ok }
        """))

    def test_placeable_message(self):
        val, errs = self.ctx.format('uses-message', {})
        self.assertEqual(val, 'Message')
        self.assertEqual(len(errs), 0)

    def test_placeable_message_attr(self):
        val, errs = self.ctx.format('uses-message-attr', {})
        self.assertEqual(val, 'Message Attribute')
        self.assertEqual(len(errs), 0)

    def test_placeable_term(self):
        val, errs = self.ctx.format('uses-term', {})
        self.assertEqual(val, 'Term')
        self.assertEqual(len(errs), 0)

    def test_placeable_term_variant(self):
        val, errs = self.ctx.format('uses-term-variant', {})
        self.assertEqual(val, 'Term Variant 2')
        self.assertEqual(len(errs), 0)

    def test_placeable_bad_message(self):
        val, errs = self.ctx.format('bad-message-ref', {})
        self.assertEqual(val, 'Text not-a-message')
        self.assertEqual(len(errs), 1)
        self.assertEqual(
            errs, [FluentReferenceError("Unknown message: not-a-message")])

    def test_placeable_bad_message_attr(self):
        val, errs = self.ctx.format('bad-message-attr-ref', {})
        self.assertEqual(val, 'Text Message')
        self.assertEqual(len(errs), 1)
        self.assertEqual(
            errs,
            [FluentReferenceError("Unknown attribute: message.not-an-attr")])

    def test_placeable_bad_term(self):
        val, errs = self.ctx.format('bad-term-ref', {})
        self.assertEqual(val, 'Text -not-a-term')
        self.assertEqual(len(errs), 1)
        self.assertEqual(errs,
                         [FluentReferenceError("Unknown term: -not-a-term")])

    def test_cycle_detection(self):
        val, errs = self.ctx.format('self-referencing-message', {})
        self.assertEqual(val, 'Text ???')
        self.assertEqual(len(errs), 1)
        self.assertEqual(errs,
                         [FluentCyclicReferenceError("Cyclic reference")])

    def test_mutual_cycle_detection(self):
        val, errs = self.ctx.format('cyclic-msg1', {})
        self.assertEqual(val, 'Text1 Text2 ???')
        self.assertEqual(len(errs), 1)
        self.assertEqual(errs,
                         [FluentCyclicReferenceError("Cyclic reference")])

    def test_allowed_self_reference(self):
        val, errs = self.ctx.format('self-attribute-ref-ok', {})
        self.assertEqual(val, 'Parent Attribute')
        self.assertEqual(len(errs), 0)
        val, errs = self.ctx.format('self-parent-ref-ok.attr', {})
        self.assertEqual(val, 'Attribute Parent')
        self.assertEqual(len(errs), 0)
Example #29
0
def fluent_bundle():
    ctx = FluentBundle(['pl'], use_isolating=False)
    ctx.add_messages(FTL_CONTENT)
    return ctx
class TestParameterizedTerms(unittest.TestCase):
    def setUp(self):
        self.ctx = FluentBundle(['en-US'], use_isolating=False)
        self.ctx.add_messages(
            dedent_ftl("""
            -thing = { $article ->
                  *[definite] the thing
                   [indefinite] a thing
                   [none] thing
            }
            thing-no-arg = { -thing }
            thing-no-arg-alt = { -thing() }
            thing-with-arg = { -thing(article: "indefinite") }
            thing-positional-arg = { -thing("foo") }
            thing-fallback = { -thing(article: "somethingelse") }
            bad-term = { -missing() }
        """))

    def test_argument_omitted(self):
        val, errs = self.ctx.format('thing-no-arg', {})
        self.assertEqual(val, 'the thing')
        self.assertEqual(errs, [])

    def test_argument_omitted_alt(self):
        val, errs = self.ctx.format('thing-no-arg-alt', {})
        self.assertEqual(val, 'the thing')
        self.assertEqual(errs, [])

    def test_with_argument(self):
        val, errs = self.ctx.format('thing-with-arg', {})
        self.assertEqual(val, 'a thing')
        self.assertEqual(errs, [])

    def test_positional_arg(self):
        val, errs = self.ctx.format('thing-positional-arg', {})
        self.assertEqual(val, 'the thing')
        self.assertEqual(errs, [
            FluentFormatError(
                "Ignored positional arguments passed to term '-thing'")
        ])

    def test_fallback(self):
        val, errs = self.ctx.format('thing-fallback', {})
        self.assertEqual(val, 'the thing')
        self.assertEqual(errs, [])

    def test_no_implicit_access_to_external_args(self):
        # The '-thing' term should not get passed article="indefinite"
        val, errs = self.ctx.format('thing-no-arg', {'article': 'indefinite'})
        self.assertEqual(val, 'the thing')
        self.assertEqual(errs, [])

    def test_no_implicit_access_to_external_args_but_term_args_still_passed(
            self):
        val, errs = self.ctx.format('thing-with-arg', {'article': 'none'})
        self.assertEqual(val, 'a thing')
        self.assertEqual(errs, [])

    def test_bad_term(self):
        val, errs = self.ctx.format('bad-term', {})
        self.assertEqual(val, '-missing')
        self.assertEqual(errs,
                         [FluentReferenceError('Unknown term: -missing')])