#!/usr/bin/env python
# -*- coding: utf-8 -*-

#
# Related to AboutOpenClasses in the Ruby Koans
#

from runner.koan import *

class AboutMonkeyPatching(Koan):
    class Dog:
        def bark(self):
            return "WOOF"

    def test_as_defined_dogs_do_bark(self):
        fido = self.Dog()
        self.assertEqual(__, fido.bark())

    # ------------------------------------------------------------------

    # Add a new method to an existing class.
    def test_after_patching_dogs_can_both_wag_and_bark(self):
        def wag(self): return "HAPPY"
        self.Dog.wag = wag

        fido = self.Dog()
        self.assertEqual(__, fido.wag())
        self.assertEqual(__, fido.bark())

    # ------------------------------------------------------------------

    def test_most_built_in_classes_cannot_be_monkey_patched(self):
        try:
            int.is_even = lambda self: (self % 2) == 0
        except Exception as ex:
            err_msg = ex.args[0]

        self.assertRegex(err_msg, __)

    # ------------------------------------------------------------------

    class MyInt(int): pass

    def test_subclasses_of_built_in_classes_can_be_be_monkey_patched(self):
        self.MyInt.is_even = lambda self: (self % 2) == 0

        self.assertEqual(__, self.MyInt(1).is_even())
        self.assertEqual(__, self.MyInt(2).is_even())

@@ -306,34 +306,38 @@
 elf.assertEqual(
-__
+%22WOOF%22
 , fido.bark())%0A%0A
@@ -630,26 +630,31 @@
 assertEqual(
-__
+%22HAPPY%22
 , fido.wag()
@@ -680,18 +680,22 @@
 rtEqual(
-__
+%22WOOF%22
 , fido.b
@@ -1011,18 +1011,71 @@
 rr_msg, 
-__
+%22can't set attributes of built-in/extension type 'int'%22
 )%0A%0A    #
@@ -1323,34 +1323,37 @@
 elf.assertEqual(
-__
+False
 , self.MyInt(1).
@@ -1392,10 +1392,12 @@
 ual(
-__
+True
 , se

Complete 'About Monkey Patching' koans