Example #1
0
    def test_give_partial_information(self):

        r1 = BotlangSystem().eval_bot(
            self.SLOTS_DIGRESS, 'Hola, quiero un cafe mocha grande por favor')
        self.assertEqual(r1.message, '¿Lo quieres con crema?')
        self.assertEqual(r1.data.get('type'), 'mocha')
        self.assertEqual(r1.data.get('size'), 'grande')
        self.assertEqual(r1.next_node, 'node1')

        r2 = BotlangSystem().eval_bot(self.SLOTS_DIGRESS, 'si', r1.next_node,
                                      r1.data)
        self.assertEqual(r2.message, 'Tu pedido es un mocha grande con crema?')
        self.assertEqual(r2.data.get('with-cream'), True)
        self.assertEqual(r2.next_node, 'node3')

        r3 = BotlangSystem().eval_bot(self.SLOTS_DIGRESS, 'no', r2.next_node,
                                      r2.data)
        self.assertEqual(r3.message, 'Bueno, ¿qué café quieres?')
        self.assertEqual(r3.next_node, 'node1')

        r4 = BotlangSystem().eval_bot(self.SLOTS_DIGRESS, 'un latte grande',
                                      r3.next_node, r3.data)
        self.assertEqual(r4.message, '¿Lo quieres con crema?')
        self.assertEqual(r4.next_node, 'node1')

        r5 = BotlangSystem().eval_bot(self.SLOTS_DIGRESS, 'si', r4.next_node,
                                      r4.data)
        self.assertEqual(r5.message, 'Tu pedido es un latte grande con crema?')
        self.assertEqual(r5.next_node, 'node3')
Example #2
0
    def test_before_block(self):

        r = BotlangSystem().eval_bot(self.SLOTS_WITH_BEFORE, 'hola', 'node1')
        self.assertEqual(r.data['meta'], 'b')

        r = BotlangSystem().eval_bot(self.SLOTS_WITH_BEFORE, 'a', 'node1')
        self.assertEqual(r.data['meta'], 'a')
Example #3
0
    def test_in_disgression_check(self):

        r1 = BotlangSystem().eval_bot(self.SLOTS_DIGRESS, 'digress?', 'node1')
        self.assertEqual(r1.message, 'Sí')

        r2 = BotlangSystem().eval_bot(self.SLOTS_DIGRESS, 'digress?', 'node2')
        self.assertEqual(r2.message, 'No')
Example #4
0
    def test_super(self):
        # TODO: still broken in some cases. Test that and then fix.
        code = """{}
        (defclass Wine
            (extends Product)
            (methods
                (init (fun (self id name price)
                    (super self "init" id "wine" name price)
                ))
            )
        )
        (send (new Wine "gato1" "Gato" 2000) "serialize")
        """.format(self.TEST_HIERARCHY_2)

        wine = BotlangSystem.run(code)
        self.assertEqual(len(wine.keys()), 5)
        self.assertEqual(wine['id'], 'gato1')
        self.assertEqual(wine['category'], 'wine')
        self.assertEqual(wine['name'], 'Gato')
        self.assertEqual(wine['price'], 2000)
        self.assertEqual(wine[CLASS_REFERENCE_KEY], 'Wine')

        code = """{}
        (send (new CheapCamembert "id1") "serialize")
        """.format(self.TEST_DEEP_HIERARCHY)

        camembert = BotlangSystem.run(code)
        self.assertEqual(len(camembert.keys()), 5)
        self.assertEqual(camembert['id'], 'id1')
        self.assertEqual(camembert['category'], 'Cheese')
        self.assertEqual(camembert['name'], 'Camembert')
        self.assertEqual(camembert['price'], 2000)
        self.assertEqual(camembert[CLASS_REFERENCE_KEY], 'CheapCamembert')
Example #5
0
    def test_answer_correctly(self):

        r1 = BotlangSystem().eval_bot(self.SLOTS_DIGRESS, 'hola')
        self.assertEqual(r1.message, '¿De qué tipo quieres tu café?')
        self.assertEqual(r1.next_node, 'node1')

        r2 = BotlangSystem().eval_bot(self.SLOTS_DIGRESS, 'latte',
                                      r1.next_node, r1.data)
        self.assertEqual(r2.message, '¿De qué tamaño quieres tu café?')
        self.assertEqual(r2.data.get('type'), 'latte')
        self.assertEqual(r2.next_node, 'node1')

        r3 = BotlangSystem().eval_bot(self.SLOTS_DIGRESS, 'mediano',
                                      r2.next_node, r2.data)
        self.assertEqual(r3.message, '¿Lo quieres con crema?')
        self.assertEqual(r3.data.get('size'), 'mediano')
        self.assertEqual(r3.next_node, 'node1')

        r4 = BotlangSystem().eval_bot(self.SLOTS_DIGRESS, 'no', r3.next_node,
                                      r3.data)
        self.assertEqual(r4.message,
                         'Tu pedido es un latte mediano sin crema?')
        self.assertEqual(r4.data.get('with-cream'), False)
        self.assertEqual(r4.next_node, 'node3')

        r5 = BotlangSystem().eval_bot(self.SLOTS_DIGRESS, 'si', r4.next_node,
                                      r4.data)
        self.assertEqual(r5.message, 'Confirmado')
        self.assertEqual(r5.data.get('confirm'), True)
        self.assertEqual(r5.next_node, None)
Example #6
0
    def test_extend(self):

        value = BotlangSystem.run('(extend (list 1 2 3) (list 4 5 6))')
        self.assertSequenceEqual(value, [1, 2, 3, 4, 5, 6])

        value = BotlangSystem.run('(extend (list 1 2 3) 4)')
        self.assertSequenceEqual(value, [1, 2, 3, 4])
Example #7
0
    def test_find(self):

        value = BotlangSystem.run('(find (fun (e) (> e 3)) (list 1 2 3 4 5))')
        self.assertEqual(value, 4)

        value = BotlangSystem.run('(find (fun (e) (> e 5)) (list 1 2 3 4 5))')
        self.assertEqual(value, Nil)
Example #8
0
    def load_module(self, path):

        from botlang import BotlangSystem
        module_file = open(path, 'r')
        module_str = module_file.read()
        module_file.close()
        BotlangSystem.run(module_str, module_resolver=self, source_id=path)
Example #9
0
    def test_catch(self):

        complex_botlang = r"""
        [defun fatal-error () (/ 1 0)]
        [defun failure (arg) "Hello"]
        (try-catch fatal-error failure)
        """
        try:
            result = BotlangSystem.run(complex_botlang)
            self.assertEqual(result, 'Hello')
        except Exception:
            self.fail("Try-catch failed")

        complex_botlang = r"""
        [define context (make-dict (list))]
        [defun process () (get (make-dict (list)) 1)]
        [defun failure (arg) (put! context "error" arg) ]
        (try-catch-verbose process failure)
        (get context "error")
        """

        result = BotlangSystem.run(complex_botlang)
        self.assertEqual(result.name, 'system')
        self.assertEqual(result.description,
                         'Collection does not have key/index %s' % '1')

        # Python errors
        complex_botlang = r"""
                [define context (make-dict (list))]
                [defun fatal-error () (/ 1 0)]
                [defun failure (arg) (put! context "error" arg) ]
                (try-catch fatal-error failure)
                (get context "error")
                """
        result = BotlangSystem.run(complex_botlang)
        self.assertEqual(result.name, 'system')
        self.assertEqual(result.description, 'system')

        complex_botlang = r"""
                [define context (make-dict (list))]
                [defun fatal-error () (/ 1 0)]
                [defun failure (arg) (put! context "error" arg) ]
                (try-catch-verbose fatal-error failure)
                (get context "error")
                """
        result = BotlangSystem.run(complex_botlang)
        self.assertEqual(result.name, 'system')
        self.assertRegex(result.description, 'division by zero')

        # Catch returns a value
        code = r"""
        (try-catch
            (function () (/ 1 0))
            (function (e) "Hi")
        )
        """
        self.assertEqual(BotlangSystem.run(code), 'Hi')
Example #10
0
    def test_uri_escape(self):

        test_segment = "Pascual Baburizza 595"
        unescaped = BotlangSystem.run('"%s"' % test_segment)
        escaped = BotlangSystem.run('(uri-escape "%s")' % test_segment)
        expected = quote(test_segment)

        self.assertNotEqual(unescaped, expected)
        self.assertEqual(escaped, expected)
Example #11
0
    def test_macro_arguments_error(self):

        code = '{}(times-ten 4)'.format(self.macro_arguments_error_code())
        with self.assertRaises(BotLangSyntaxError) as cm:
            BotlangSystem.run(code)
        self.assertTrue('Line 5' in cm.exception.args[0])
        self.assertTrue(
            'Expansion of macro def-fun failed' in cm.exception.args[0])
        self.assertTrue('expected 3 arguments, got 4' in cm.exception.args[0])
Example #12
0
 def test_matches(self):
     self.assertTrue(
         BotlangSystem.run(
             '(match? ".*pedro.*" "hola pedro, como estas?")'))
     self.assertFalse(
         BotlangSystem.run(
             '(match? ".*pedro.*" "hola julito, como estas?")'))
     self.assertEqual(
         'juan',
         BotlangSystem.run(r'(match "hola\s(\w+).*" "hola juan!!" 1)'))
Example #13
0
    def test_recursive_digression(self):

        r1 = BotlangSystem().eval_bot(self.SLOTS_DIGRESS, 'mocha', 'node1')
        self.assertEqual(r1.message, '¿De qué tamaño quieres tu café?')
        self.assertEqual(r1.next_node, 'node1')

        r2 = BotlangSystem().eval_bot(self.SLOTS_DIGRESS, 'coffee',
                                      r1.next_node, r1.data)
        self.assertEqual(r2.message, '¿De qué tipo quieres tu café?')
        self.assertEqual(r2.next_node, 'node1')
Example #14
0
    def test_dont_show_macro_source(self):

        code = """
        (defun f1 (x) (* 2 x))
        (defun f2 (x) (+ (f1 x) 4))
        (f2 nil)
        """
        with self.assertRaises(BotlangErrorException) as cm:
            BotlangSystem.run(code)
        stack_trace = cm.exception.print_stack_trace()
        self.assertFalse('(function args body)' in stack_trace)
Example #15
0
    def test_exception_values(self):

        self.assertFalse(BotlangSystem().eval('(exception? #t)'))
        self.assertFalse(BotlangSystem().eval('(exception? nil)'))
        self.assertTrue(BotlangSystem().eval(
            '(exception? (try-catch (fun () (get (make-dict) 1)) (fun (e) e)))'
        ))
        self.assertFalse(BotlangSystem().eval(
            '(exception? (try-catch (fun () (get (list 1) 0)) (fun (e) e)))'))
        self.assertTrue(BotlangSystem().eval(
            '(exception? (try-catch (fun () (get (list 1) 1)) (fun (e) e)))'))
Example #16
0
    def test_dont_show_macro_source(self):

        code = """
        (defun f1 (x) (* 2 x))
        (defun f2 (x) (+ (f1 x) 4))
        (f2 nil)
        """
        with self.assertRaises(BotlangErrorException) as cm:
            BotlangSystem.run(code)
        stack_trace = cm.exception.print_stack_trace()
        self.assertFalse('(function args body)' in stack_trace)
Example #17
0
    def test_key_exists(self):

        value = BotlangSystem.run("""
        (define a (make-dict (list (cons "a" "b"))))
        (exists? a "a")
        """)
        self.assertTrue(value)

        value = BotlangSystem.run("""
        (define d (make-dict (list (cons "a" "b"))))
        (exists? d "b")
        """)
        self.assertFalse(value)
Example #18
0
    def test_string_operations(self):
        lower = BotlangSystem.run('(lowercase "AbCdEfgH")')
        self.assertEqual(lower, "abcdefgh")

        upper = BotlangSystem.run('(uppercase "AbCdEfgH")')
        self.assertEqual(upper, "ABCDEFGH")

        capitalized = BotlangSystem.run('(capitalize "aleluya hmno")')
        self.assertEqual(capitalized, "Aleluya hmno")

        split = BotlangSystem.run('(split "perro,gato,zapallo" ",")')
        self.assertEqual(split, ['perro', 'gato', 'zapallo'])

        join = BotlangSystem.run(
            '(join ", " (list "pollos" "pavos" "iguana"))')
        self.assertEqual(join, 'pollos, pavos, iguana')

        plain = BotlangSystem.run('(plain "ÉnTérO BellákO")')
        self.assertEqual(plain, 'entero bellako')

        replaced = BotlangSystem.run('(replace "muajaja" "j" "h")')
        self.assertEqual(replaced, 'muahaha')

        trimmed = BotlangSystem.run('(trim "   hola, soy julito  ")')
        self.assertEqual(trimmed, 'hola, soy julito')
Example #19
0
    def test_to_json(self):

        json_list = BotlangSystem.run('(to-json (list 1 2 3))')
        self.assertEqual(json_list, "[1, 2, 3]")

        json_dict = BotlangSystem.run(
            '(to-json (make-dict (list (cons "a" 2))))')
        self.assertEqual(json_dict, '{"a": 2}')

        python_dict = {'a': None, 'b': 'hola', 'c': 12, 'd': True, 'e': False}
        runtime = BotlangSystem()
        runtime.environment.update({'python-dict': python_dict})
        json_dict = runtime.eval('(to-json python-dict)')
        self.assertEqual(json_dict, json.dumps(python_dict, sort_keys=True))
Example #20
0
    def test_http_post_json_no_headers(self, mock_post):

        payload = '(make-dict (list (cons "key" "value")))'
        BotlangSystem.run('(http-post "http://some.url" %s)' % payload)
        post_call_args = mock_post.call_args[0]
        url = post_call_args[0]

        post_call_kwargs = mock_post.call_args[1]
        headers = post_call_kwargs['headers']
        json = post_call_kwargs['json']

        self.assertEqual(url, 'http://some.url')
        self.assertIsNone(headers)
        self.assertDictEqual(json, {'key': 'value'})
Example #21
0
    def test_http_delete(self, mock_delete):

        headers = '(make-dict (list (cons "a-header" "its-value")))'
        BotlangSystem.run(
            '(http-delete "http://some.url" %s)' % headers
        )
        call_args = mock_delete.call_args[0]
        url = call_args[0]

        call_kwargs = mock_delete.call_args[1]
        headers = call_kwargs['headers']

        self.assertIsNone(call_kwargs.get('json'))
        self.assertEqual(url, 'http://some.url')
        self.assertDictEqual(headers, {'a-header': 'its-value'})
Example #22
0
    def test_optional_slot(self):

        r1 = BotlangSystem().eval_bot(self.SLOTS_DIGRESS,
                                      'descuento 123 para mocha chico',
                                      'node1')
        self.assertEqual(r1.data.get('discount'), '123')
        self.assertEqual(r1.message, '¿Lo quieres con crema?')

        r2 = BotlangSystem().eval_bot(self.SLOTS_DIGRESS, 'si', r1.next_node,
                                      r1.data)
        self.assertEqual(r2.message, 'Tu pedido es un mocha chico con crema?')

        r3 = BotlangSystem().eval_bot(self.SLOTS_DIGRESS, 'si', r2.next_node,
                                      r2.data)
        self.assertEqual(r3.message, 'Confirmado. Te saldrá gratis :)')
Example #23
0
    def test_class_instance(self):

        code = "{} (new Car)".format(self.TEST_CLASS)
        car_instance = BotlangSystem.run(code)
        self.assertTrue(isinstance(car_instance, dict))
        self.assertEqual(car_instance['wheels'], 4)

        code = """{}
        (define my-car (new Car))
        (@! my-car "speed" 2)
        (cons Car my-car)
        """.format(self.TEST_CLASS)
        car_class, car_instance = BotlangSystem.run(code)
        self.assertEqual(car_class[INSTANCE_ATTRS_KEY]['speed'], 0)
        self.assertEqual(car_instance['speed'], 2)
        self.assertEqual(car_instance[CLASS_REFERENCE_KEY], car_class)
    def test_validate_rut(self):

        dsl = BotlangSystem.bot_instance()

        self.assertTrue(
            dsl.eval('(require "bot-helpers") (validate-rut "16926695-6")')
        )
        self.assertTrue(
            dsl.eval('(require "bot-helpers") (validate-rut "16.926.695-6 ")')
        )
        self.assertTrue(
            dsl.eval('(require "bot-helpers") (validate-rut " 30.686.957-4")')
        )
        self.assertTrue(
            dsl.eval('(require "bot-helpers") (validate-rut "7015383-1")')
        )
        self.assertFalse(
            dsl.eval('(require "bot-helpers") (validate-rut "16926695-5")')
        )
        self.assertFalse(
            dsl.eval('(require "bot-helpers") (validate-rut "16.926.696-6")')
        )
        self.assertFalse(
            dsl.eval('(require "bot-helpers") (validate-rut "30.685.957-4")')
        )
        self.assertFalse(
            dsl.eval('(require "bot-helpers") (validate-rut "7015383-0")')
        )
        self.assertFalse(
            dsl.eval('(require "bot-helpers") (validate-rut "70153830")')
        )
Example #25
0
    def test_class_side(self):

        code = """
        (defclass Singleton
            [attributes (data 10)]
            [class-attributes instance]
            [class-methods
                (get-instance (fun (cls)
                    (define instance (@ cls "instance"))
                    (if (nil? instance)
                        (begin
                            (define new-instance (new cls))
                            (@! cls "instance" new-instance)
                            new-instance
                        )
                        instance
                    )
                ))
            ]
        )
        (list
            (send Singleton "get-instance")
            (send Singleton "get-instance")
            (send Singleton "get-instance")
        )
        """
        i1, i2, i3 = BotlangSystem.run(code)
        self.assertTrue(i1 is i2)
        self.assertTrue(i2 is i3)
Example #26
0
    def test_primitives_exception(self):

        try:
            BotlangSystem().eval('(+ (list 1) #f)')
            self.fail('Should not reach this')
        except BotlangErrorException as e:
            self.assertEqual(len(e.stack), 1)
Example #27
0
    def test_method_invocation(self):

        code = """{}
        (define my-car (new Car))
        (send my-car "accelerate" 2)
        (@ my-car "speed") 
        """.format(self.TEST_CLASS)
        self.assertEqual(BotlangSystem.run(code), 2)
Example #28
0
    def test_from_json(self):

        python_list = BotlangSystem.run('(from-json "[1, 2, 3]")')
        self.assertEqual(python_list, [1, 2, 3])

        json_dict = json.dumps({
            'a': None,
            'b': 'hola',
            'c': 12,
            'd': True,
            'e': False
        })
        runtime = BotlangSystem()
        runtime.environment.update({'json-dict': json_dict})
        python_dict = runtime.eval('(from-json json-dict)')

        self.assertDictEqual(json.loads(json_dict), python_dict)
Example #29
0
    def test_split_n(self):

        list1, list2 = BotlangSystem.run('(split-n (list 1 2 3 4 5 6) 2)')
        self.assertSequenceEqual(list1, [1, 2])
        self.assertSequenceEqual(list2, [3, 4, 5, 6])

        list1, list2 = BotlangSystem.run('(split-n (list 1 2 3 4 5 6) 10)')
        self.assertSequenceEqual(list1, [1, 2, 3, 4, 5, 6])
        self.assertSequenceEqual(list2, [])

        list1, list2 = BotlangSystem.run('(split-n (list 1 2 3 4 5 6) 0)')
        self.assertSequenceEqual(list1, [])
        self.assertSequenceEqual(list2, [1, 2, 3, 4, 5, 6])

        list1, list2 = BotlangSystem.run('(split-n (list) 5)')
        self.assertSequenceEqual(list1, [])
        self.assertSequenceEqual(list2, [])
    def test_format_link(self):
        code = """
        (require "bot-helpers")

        (bot-node (data)
            (node-result
                data
                (format-link-with-image
                    data
                    "Título"
                    "http://test.botlang.cl"
                    "http://test.botlang.cl/image.png"
                )
                end-node
            )
        )
        """
        plain = BotlangSystem.bot_instance().eval_bot(code, input_msg='hi')
        self.assertTrue('Título:' in plain.message)
        self.assertTrue('http://test.botlang.cl' in plain.message)
        self.assertFalse('http://test.botlang.cl/image.png' in plain.message)

        fb = BotlangSystem.bot_instance().eval_bot(
            code,
            input_msg='hi',
            data={'social_network': 'facebook'}
        )
        self.assertDictEqual(
            fb.message,
            {
                'attachment': {
                    'type': 'template',
                    'payload': {
                        'template_type': 'generic',
                        'elements': [
                            {
                                'title': 'Título',
                                'item_url': 'http://test.botlang.cl',
                                'image_url': 'http://test.botlang.cl/image.png'
                            }
                        ]
                    }
                }
            }
        )
Example #31
0
    def test_answer_incorrectly_no_digress(self):

        r1 = BotlangSystem().eval_bot(
            self.SLOTS_NO_DIGRESS,
            'Hola, quiero un cafe americano chico por favor')
        self.assertEqual(r1.message, '¿Lo quieres con crema?')
        self.assertEqual(r1.next_node, 'node1')

        r2 = BotlangSystem().eval_bot(self.SLOTS_NO_DIGRESS, 'qwerty',
                                      r1.next_node, r1.data)
        self.assertEqual(r2.message, '¿Lo quieres con crema?')
        self.assertEqual(r2.next_node, 'node1')

        r3 = BotlangSystem().eval_bot(self.SLOTS_NO_DIGRESS, 'no',
                                      r2.next_node, r2.data)
        self.assertEqual(r3.message,
                         'Tu pedido es un americano chico sin crema?')
        self.assertEqual(r3.next_node, 'node3')
Example #32
0
    def test_http_post_form(self, mock_post):

        payload = '(make-dict (list (cons "key" "value")))'
        headers = '(make-dict (list (cons "a-header" "its-value")))'
        BotlangSystem.run(
            '(http-post-form "http://some.url" %s %s)' % (payload, headers)
        )
        post_call_args = mock_post.call_args[0]
        url = post_call_args[0]

        post_call_kwargs = mock_post.call_args[1]
        headers = post_call_kwargs['headers']
        data = post_call_kwargs['data']

        self.assertIsNone(post_call_kwargs.get('json'))
        self.assertEqual(url, 'http://some.url')
        self.assertDictEqual(headers, {'a-header': 'its-value'})
        self.assertDictEqual(data, {'key': 'value'})
Example #33
0
    def apply(self, *values):

        if len(self.params) != len(values):
            raise InvalidArgumentsException(len(self.params), len(values))

        from botlang import BotlangSystem
        new_bindings = {self.params[i]: v for i, v in enumerate(values)}
        return BotlangSystem.interpret([self.body], self.evaluator,
                                       self.env.new_environment(new_bindings))
Example #34
0
    def test_defun_macro(self):

        code = """
        (define-syntax-rule (def-fun name args body)
            (define name (function args body))
        )
        (def-fun squared (x) (* x x))
        (squared 4)
        """
        result = BotlangSystem.run(code)
        self.assertEqual(result, 16)
    def test_separate_list(self):

        code = """
        (require "facebook-formatter")

        (separate-list
            (list 1 2 3 4 5 6 7 8)
            3
        )
        """
        result = BotlangSystem.bot_instance().eval(code)
        self.assertEqual([[1, 2, 3], [4, 5, 6], [7, 8]], result)
Example #36
0
    def test_syntax_rule(self):

        code = """
        (define-syntax-rule (my-and x y)
            (if x
                (if y #t #f)
                #f
            )
        )
        (my-and (> 5 3) (< -1 8))
        """
        result = BotlangSystem.run(code)
        self.assertTrue(result)
Example #37
0
    def test_syntax_rule_hygiene(self):

        code = """
        (define-syntax-rule (my-and x y)
            (if x
                (if y #t #f)
                #f
            )
        )
        (define y #t)
        (my-and y #f) ;; Yields #t if expansion is not hygienic
        """
        result = BotlangSystem.run(code)
        self.assertFalse(result)
Example #38
0
    def apply(self, *values):

        if len(self.params) != len(values):
            raise InvalidArgumentsException(len(self.params), len(values))

        from botlang import BotlangSystem
        new_bindings = {
            self.params[i]: v for i, v in enumerate(values)
        }
        return BotlangSystem.interpret(
            [self.body],
            self.evaluator,
            self.env.new_environment(new_bindings)
        )
    def test_format_simple_list(self):

        code = """
        (require "bot-helpers")
        (format-simple-list
            (make-dict (list))
            "Hola"
            (list
                (cons "Juanito" "Lechuga")
                (cons "Edulio" "Caluga")
            )
        )
        """
        result = BotlangSystem.bot_instance().eval_bot(code, input_msg='')
        self.assertEqual(
            result,
            'Hola\n\nJuanito. Lechuga\n\nEdulio. Caluga'
        )
    def test_format_list(self):

        code = """
        (require "plain-formatter")
        (format-plain-simple-list
            "VITAL APOQUINDO ESQ. / VIA LACTEA"
            (list
                (cons "501: Menos de 5 min" "A 197 metros. Patente BJFD-87")
                (cons "C03: Menos de 5 min" "A 401 metros. Patente CJRT-77")
                (cons "518: Menos de 5 min" "A 406 metros. Patente BJFR-37")
                (cons "427: Menos de 5 min" "A 982 metros. Patente CJRS-49")
            )
        )
        """
        result = BotlangSystem.bot_instance().eval_bot(code, '')
        self.assertEqual(
            result,
            'VITAL APOQUINDO ESQ. / VIA LACTEA'
            '\n\n501: Menos de 5 min. A 197 metros. Patente BJFD-87\n\nC03: '
            'Menos de 5 min. A 401 metros. Patente CJRT-77\n\n518: Menos de 5 '
            'min. A 406 metros. Patente BJFR-37\n\n427: Menos de 5 min. A 982 '
            'metros. Patente CJRS-49'
        )
    def test_global_storage(self):

        db = DummyStore()
        runtime = BotlangSystem.bot_instance().setup_global_storage(db)
        results = runtime.eval("""
        (globaldb-put "test1" 444)
        (globaldb-put "test2" "miau")
        [define got1 (globaldb-get-or-else "test3" (function () ":3"))]
        [define got2 (globaldb-get-or-else "test3" (function () "3:"))]
        (globaldb-remove "test2")
        (make-dict
            (list
                (list "test1" (globaldb-get "test1"))
                (list "test2" (globaldb-get "test2"))
                (list "got1" got1)
                (list "got2" got2)
            )
        )
        """)
        self.assertEqual(results['test1'], 444)
        self.assertEqual(results['test2'], None)
        self.assertEqual(results['got1'], ':3')
        self.assertEqual(results['got2'], ':3')
    def test_cache(self):

        cache = DummyStore()
        runtime = BotlangSystem.bot_instance().setup_cache_extension(cache)
        results = runtime.eval("""
        (cache-put "test1" 444)
        (cache-put "test2" "miau")
        [define got1 (cache-get-or-else "test3" (function () ":3"))]
        [define got2 (cache-get-or-else "test3" (function () "3:"))]
        (cache-remove "test2")
        (make-dict
            (list
                (list "test1" (cache-get "test1"))
                (list "test2" (cache-get "test2"))
                (list "got1" got1)
                (list "got2" got2)
            )
        )
        """)
        self.assertEqual(results['test1'], 444)
        self.assertEqual(results['test2'], None)
        self.assertEqual(results['got1'], ':3')
        self.assertEqual(results['got2'], ':3')
    def test_format_list(self):

        code = """
        (require "facebook-formatter")
        (format-facebook-simple-list
            "VITAL APOQUINDO ESQ. / VIA LACTEA"
            (list
                (cons "501: Menos de 5 min" "A 197 metros. Patente BJFD-87")
                (cons "C03: Menos de 5 min" "A 401 metros. Patente CJRT-77")
                (cons "518: Menos de 5 min" "A 406 metros. Patente BJFR-37")
                (cons "427: Menos de 5 min" "A 982 metros. Patente CJRS-49")
                (cons "427: Menos de 5 min" "A 982 metros. Patente CJRS-49")
            )
        )
        """
        result = BotlangSystem.bot_instance().eval_bot(code, '')
        self.assertEqual(len(result), 3)
        self.assertEqual(result[0], 'VITAL APOQUINDO ESQ. / VIA LACTEA')
        self.assertDictEqual(
            result[1],
            {
                'attachment': {
                    'type': 'template',
                    'payload': {
                        'template_type': 'list',
                        'top_element_style': 'compact',
                        'elements': [
                            {
                                'title': '501: Menos de 5 min',
                                'subtitle': 'A 197 metros. Patente BJFD-87'
                            },
                            {
                                'title': 'C03: Menos de 5 min',
                                'subtitle': 'A 401 metros. Patente CJRT-77'
                            },
                            {
                                'title': '518: Menos de 5 min',
                                'subtitle': 'A 406 metros. Patente BJFR-37'
                            }
                        ]
                    }
                }
            }
        )
        self.assertDictEqual(
            result[2],
            {
                'attachment': {
                    'type': 'template',
                    'payload': {
                        'template_type': 'list',
                        'top_element_style': 'compact',
                        'elements': [
                            {
                                'title': '427: Menos de 5 min',
                                'subtitle': 'A 982 metros. Patente CJRS-49'
                            },
                            {
                                'title': '427: Menos de 5 min',
                                'subtitle': 'A 982 metros. Patente CJRS-49'
                            }
                        ]
                    }
                }
            }
        )
    def test_format_options(self):

        code = """
        (require "facebook-formatter")

        (bot-node (data)
            (node-result
                data
                (format-facebook-options
                    "Opciones"
                    (list
                        (cons 1 "option 1")
                        (cons 2 "option 2")
                        (cons 3 "option 3")
                        (cons 4 "option 4")
                        (cons 5 "option 5")
                    )
                )
                end-node
            )
        )
        """
        fb = BotlangSystem.bot_instance().eval_bot(
            code,
            input_msg='hi',
            data={'social_network': 'facebook'}
        )
        self.assertEqual(len(fb.message), 2)
        self.assertDictEqual(
            fb.message[0],
            {
                'attachment': {
                    'type': 'template',
                    'payload': {
                        'template_type': 'button',
                        'text': 'Opciones',
                        'buttons': [
                            {
                                'type': 'postback',
                                'title': 'option 1',
                                'payload': 1
                            },
                            {
                                'type': 'postback',
                                'title': 'option 2',
                                'payload': 2
                            },
                            {
                                'type': 'postback',
                                'title': 'option 3',
                                'payload': 3
                            }
                        ]
                    }
                }
            }
        )
        self.assertDictEqual(
            fb.message[1],
            {
                'attachment': {
                    'type': 'template',
                    'payload': {
                        'template_type': 'button',
                        'text': u'\u2063',
                        'buttons': [
                            {
                                'type': 'postback',
                                'title': 'option 4',
                                'payload': 4
                            },
                            {
                                'type': 'postback',
                                'title': 'option 5',
                                'payload': 5
                            }
                        ]
                    }
                }
            }
        )