text: import copy
  
  from django import forms
  from django.test import TestCase
  
  from widgy.models.links import (
      link_registry, get_link_field_from_model, LinkFormMixin, LinkFormField,
      get_composite_key, convert_linkable_to_choice, LinkRegistry, LinkField
  )
  
  from modeltests.core_tests.models import (
      LinkableThing, ThingWithLink, AnotherLinkableThing, LinkableThing3,
      Bucket, VersionPageThrough, ChildThingWithLink
  )
  
  
  class TestLinkField(TestCase):
      def test_inheritance(self):
          # the only field local to ChildThingWithLink is its pk. The link
          # field is inherited, so it shouldn't be in local_fields.
          self.assertFalse(any(
              i.name == 'linkable_content_type' for i in ChildThingWithLink._meta.local_fields
          ))
  
      def test_copy(self):
          # a LinkField has a reference to a LinkRegistry. Copying the LinkField
          # shouldn't copy the registry. Copying the field happens with model
          # inheritance.
          registry = LinkRegistry()
          f1 = LinkField(link_registry=registry)
          f2 = copy.deepcopy(f1)
          self.assertIs(f1._link_registry, f2._link_registry)
  
  
  class TestLinkRelations(TestCase):
      def test_get_all_linkable_classes(self):
          self.assertIn(LinkableThing, link_registry)
          self.assertIn(AnotherLinkableThing, link_registry)
  
      def test_get_all_linker_classes(self):
          self.assertIn(ThingWithLink, link_registry.get_all_linker_classes())
          self.assertNotIn(Bucket, link_registry.get_all_linker_classes())
          self.assertNotIn(VersionPageThrough, link_registry.get_all_linker_classes())
  
      def test_get_all_links_for_obj(self):
          linkable = LinkableThing.objects.create()
  
          self.assertEqual(len(list(link_registry.get_links(linkable))), 0)
  
          thing = ThingWithLink.objects.create(
              link=linkable,
          )
  
          self.assertEqual(list(link_registry.get_links(linkable)), [thing])
  
          linkable2 = AnotherLinkableThing.objects.create()
  
          thing2 = ThingWithLink.objects.create(
              link=linkable2,
          )
  
          self.assertEqual(list(link_registry.get_links(linkable2)), [thing2])
  
      def test_get_all_possible_linkables(self):
          l1 = LinkableThing.objects.create()
          l2 = LinkableThing.objects.create()
          l3 = AnotherLinkableThing.objects.create()
  
          choices = get_link_field_from_model(ThingWithLink, 'link').get_choices()
  
          keyfn = get_composite_key
          self.assertEqual(sorted(list(choices), key=keyfn), sorted([l3, l1, l2], key=keyfn))
  
  
  class LinkForm(LinkFormMixin, forms.ModelForm):
      link = LinkFormField()
  
      class Meta:
          model = ThingWithLink
          fields = ('link',)
  
  
  class TestLinkForm(TestCase):
      def test_save_and_create(self):
          page = LinkableThing.objects.create()
          form = LinkForm()
          choice = get_composite_key(page)
          form = LinkForm({
              'link': choice,
          })
          self.assertTrue(form.is_valid())
          instance = form.save(commit=False)
          self.assertEqual(instance.link, page)
  
          form2 = LinkForm({
              'link': choice,
          })
          # save without validating.
          form2.save(commit=False)
  
      def test_choices(self):
          page1 = LinkableThing.objects.create(name='Z')
          page2 = LinkableThing.objects.create(name='a')
          page3 = AnotherLinkableThing.objects.create()
          page4 = LinkableThing3.objects.create()
          form = LinkForm()
  
          self.assertEqual(form.fields['link'].choices, [
              ('Another linkable things', [
                  convert_linkable_to_choice(page3),
              ]),
              ('Linkable things', [
                  convert_linkable_to_choice(page2),
                  convert_linkable_to_choice(page1),
              ]),
              ('ZZZZZ should be last', [
                  convert_linkable_to_choice(page4),
              ]),
          ])
  