def test_card_type_checkers(self):
        """Check the various utilities for checking card type
           and properties."""
        self.maxDiff = None
        oDob = IAbstractCard(u"L\xe1z\xe1r Dobrescu")
        self.assertTrue(is_vampire(oDob))
        self.assertTrue(is_crypt_card(oDob))
        self.assertFalse(is_trifle(oDob))

        oAbo = IAbstractCard('Abombwe')
        self.assertFalse(is_vampire(oAbo))
        self.assertFalse(is_crypt_card(oAbo))
        self.assertTrue(is_trifle(oAbo))

        oAshur = IAbstractCard('Ashur Tablets')
        self.assertFalse(is_vampire(oAshur))
        self.assertFalse(is_crypt_card(oAshur))
        self.assertFalse(is_trifle(oAshur))

        oEarl = IAbstractCard(u'Earl "Shaka74" Deams')
        self.assertFalse(is_vampire(oEarl))
        self.assertTrue(is_crypt_card(oEarl))
        self.assertFalse(is_trifle(oEarl))

        oOssian = IAbstractCard('Ossian')
        self.assertFalse(is_vampire(oOssian))
        self.assertFalse(is_crypt_card(oOssian))
        self.assertFalse(is_trifle(oOssian))
Пример #2
0
 def _setup_cardlists(self, aSelectedCards):
     """Extract the needed card info from the model"""
     aAllAbsCards = [IAbstractCard(oCard) for oCard in
                     self._get_all_cards()]
     iCryptSize = 0
     iLibrarySize = 0
     self.dSelectedCounts = {}
     self.iSelectedCount = 0
     # Initialise dict 1st, as cards with a count of 0 in the selection
     # are possible.
     for oCard in aSelectedCards:
         self.dSelectedCounts.setdefault(oCard, 0)
     for oCard in aAllAbsCards:
         if is_crypt_card(oCard):
             iCryptSize += 1
         else:
             iLibrarySize += 1
         if oCard in self.dSelectedCounts:
             self.dSelectedCounts[oCard] += 1
             self.iSelectedCount += 1
         # The assumption is that the user is interested in all copies of
         # the selected cards (as it seems the most useful), so we treat
         # the selection of any instance of the card in the list as
         # selecting all of them
     if self.bCrypt:
         self.iTotal = iCryptSize
     else:
         self.iTotal = iLibrarySize
Пример #3
0
    def _update_printing(self, oPrinting, dPrintInfo):
        """Update the specific printing with the required info"""
        # Clear any existing properties (to ensure we reflect
        # updates correctly)
        for oProp in oPrinting.properties:
            oPrinting.removePrintingProperty(oProp)
        # Add properties for the variant
        sDate = dPrintInfo.pop('date')
        sBack = dPrintInfo.pop('back')
        oDateProp = self._oMaker.make_printing_property("Release Date: %s" %
                                                        sDate)
        oBackProp = self._oMaker.make_printing_property("Back Type: %s" %
                                                        sBack)

        # pylint: disable=no-member
        # SQLObject confuses pylint
        oPrinting.addPrintingProperty(oDateProp)
        oPrinting.addPrintingProperty(oBackProp)
        # pylint: enable=no-member

        aCards = dPrintInfo.pop('cards', [])
        # Create Physical cards for the variant cards if needed
        for sCardName in aCards:
            oAbsCard = IAbstractCard(sCardName)
            _oCard = self._oMaker.make_physical_card(oAbsCard, oPrinting)
        # Any other items in the dict get added 'as-is'
        for sKey, sValue in dPrintInfo.items():
            oProp = self._oMaker.make_printing_property("%s: %s" %
                                                        (sKey, sValue))
            oPrinting.addProperty(oProp)
Пример #4
0
    def _group_cards(self, aCards, iNum, aSubSets, bSuperior, bUseCardSet):
        """Group the cards and return only cards with iNum or more
           instances.

           This works because of our database structure and query, which
           ends up returning a match for each discipline in the discipline
           filter that matches."""
        aDistinct = set(aCards)
        dResults = {}
        aDistinct.remove(self.oSelCard)  # Don't match ourselves
        bVampire = is_vampire(self.oSelCard)
        if bUseCardSet:
            aCardSetCards = set([IAbstractCard(x) for x in
                                 self.model.get_card_iterator(
                                     self.model.get_current_filter())])
        else:
            aCardSetCards = None
        for oCard in list(aDistinct):
            if aCards.count(oCard) < iNum:
                aDistinct.remove(oCard)
            elif bUseCardSet and oCard not in aCardSetCards:
                # Remove cards not in the view from the results
                aDistinct.remove(oCard)
        dResults['all'] = aDistinct
        for oCard in aDistinct:
            aFullSet = _make_superset(oCard, bSuperior, bVampire)
            for aSet in aSubSets:
                # We only add the card if it has all elements of the set
                if aSet.issubset(aFullSet):
                    dResults.setdefault(make_key(aSet, bSuperior),
                                        []).append(oCard)
        return dResults
def make_set_3():
    """Copy of the second card set with Abebe dropped"""
    aAddedPhysCards = get_phys_cards()
    oPhysCardSet3 = PhysicalCardSet(name=CARD_SET_NAMES[2])

    oPhysCardSet3.comment = ('A formatted test comment\nA second line\n'
                             'A third line')
    oPhysCardSet3.author = 'A test author'
    oPhysCardSet3.annotations = 'Some Annotations'
    for iLoop in range(5, 10):
        # pylint: disable=no-member
        # SQLObect confused pylint
        oPC = aAddedPhysCards[iLoop]
        if IAbstractCard(oPC).name == 'Abebe (Group 4)':
            continue
        oPhysCardSet3.addPhysicalCard(oPC.id)
    for sName, sExpansion, iCount in SET_2_ONLY_CARDS:
        # pylint: disable=no-member
        # SQLObect confused pylint
        oPC = make_card(sName, sExpansion)
        for _iNum in range(iCount):
            oPhysCardSet3.addPhysicalCard(oPC.id)
    for sName, sExpansion, iCount in SET_3_ONLY_CARDS:
        # pylint: disable=no-member
        # SQLObect confused pylint
        oPC = make_card(sName, sExpansion)
        for _iNum in range(iCount):
            oPhysCardSet3.addPhysicalCard(oPC.id)
    oPhysCardSet3.syncUpdate()
    return oPhysCardSet3
Пример #6
0
    def setUpClass(cls):
        """Setup some useful constants for the test cases"""
        cls.aCards = list(AbstractCard.select())

        cls.oSwallowed = IAbstractCard("Swallowed by the Night")
        cls.oAshur = IAbstractCard("Ashur Tablets")
        cls.oPath = IAbstractCard("The Path of Blood")
        cls.oAire = IAbstractCard("Aire of Elation")
        cls.oAabbt = IAbstractCard("Aabbt Kindred")
        cls.oEarl = IAbstractCard('Earl "Shaka74" Deams')
        cls.oShaEnnu = IAbstractCard("Sha-Ennu")
        cls.oRaven = IAbstractCard("Raven Spy")
        cls.oNewBlood = IAbstractCard("New Blood")
 def make_abstract_card(self, sCard):
     try:
         return IAbstractCard(sCard)
     except SQLObjectNotFound:
         sName = sCard.strip()
         sCanonical = sName.lower()
         return SutekhAbstractCard(canonicalName=sCanonical,
                                   name=sName,
                                   text="")
Пример #8
0
 def _gen_inv(self, oHolder):
     """Process the card set, creating the lines as needed"""
     aUnique = make_unique_names()
     dCards = {'Crypt': {}, 'Library': {}}
     sResult = ""
     for oCard in oHolder.cards:
         sType = type_of_card(IAbstractCard(oCard))
         sName = lackey_name(IAbstractCard(oCard), aUnique)
         dCards[sType].setdefault(sName, 0)
         dCards[sType][sName] += 1
     # Sort the output
     # Need to be in this order
     for sType in ['Library', 'Crypt']:
         for sName, iNum in sorted(dCards[sType].items()):
             sResult += '%d\t%s\n' % (iNum, sName)
         if sType == 'Library':
             sResult += 'Crypt:\n'
     return sResult
Пример #9
0
    def find_twda(self, _oWidget, sMode):
        """Find decks which match the given search"""
        # Only want the distinct cards - numbers are unimportant
        aAbsCards = set(self._get_selected_abs_cards())
        if not aAbsCards:
            do_complaint_error('Need to select some cards for this plugin')
            return
        if len(aAbsCards) > 20:
            do_complaint_error('Too many cards selected (%d). Please select '
                               'no more than 20 cards' % len(aAbsCards))
            return
        aCardFilters = []
        iTotCards = len(aAbsCards)
        for oCard in aAbsCards:
            aCardFilters.append(SpecificCardFilter(oCard))
        # needs to be OR, since we're matching against the card to card set
        # mapping table
        oCardFilter = FilterOrBox(aCardFilters)
        aNames = self._get_twda_names()
        oMapFilter = MultiPhysicalCardSetMapFilter(aNames)
        oFullFilter = FilterAndBox([oCardFilter, oMapFilter])

        # pylint: disable=no-member
        # SQLObject confuses pylint
        dCardSets = {}
        for oMapCard in oFullFilter.select(MapPhysicalCardToPhysicalCardSet):
            oCS = oMapCard.physicalCardSet
            sCardName = IAbstractCard(oMapCard).name
            dCardSets.setdefault(oCS, {})
            dCardSets[oCS].setdefault(sCardName, 0)
            dCardSets[oCS][sCardName] += 1

        if sMode == 'all' and iTotCards > 1:
            # This is a little clunky, but, because of how we construct the
            # filters, we currently have the any match set, so we need to
            # filter this down to those that match all the cards
            for oCS in list(dCardSets):
                if len(dCardSets[oCS]) != iTotCards:
                    # Not all, so drop this one
                    del dCardSets[oCS]

        sCards = '",  "'.join(sorted([x.name for x in aAbsCards]))
        if sMode == 'any':
            sMatchText = 'Matching ANY of "%s"' % sCards
        else:
            sMatchText = 'Matching ALL of "%s"' % sCards

        # Create a dialog showing the results
        if dCardSets:
            oDlg = self._fill_dlg(dCardSets, sMatchText)
        else:
            oDlg = self._empty_dlg(sMatchText)

        oDlg.set_default_size(700, 600)
        oDlg.show_all()
        oDlg.show()
Пример #10
0
 def add_row(oTBody, iCount, sName):
     """Add a row to the display table"""
     oCard = IAbstractCard(sName)
     oTR = SubElement(oTBody, "tr")
     oTD = SubElement(oTR, "td")
     _add_span(oTD, '%dx' % iCount, 'tablevalue')
     oTD = SubElement(oTR, "td")
     oSpan = SubElement(oTD, "span")
     oSpan.attrib["class"] = "tablevalue"
     self._gen_link(oCard, oSpan, sName, False)
Пример #11
0
 def _get_cards(self, oCardIter):
     """Create the dictionary of cards given the list of cards"""
     dDict = {}
     for oCard in oCardIter:
         oPhysCard = IPhysicalCard(oCard)
         oAbsCard = IAbstractCard(oCard)
         sSet = self._get_ardb_exp_name(oPhysCard)
         dDict.setdefault((oAbsCard, sSet), 0)
         dDict[(oAbsCard, sSet)] += 1
     return dDict
Пример #12
0
    def test_find_vamps(self):
        """Test functions for finding base/adv vampires."""
        oAlanBase = IAbstractCard('Alan Sovereign (Group 3)')
        oNewBlood = IAbstractCard('New Blood')
        oAlanAdv = IAbstractCard('Alan Sovereign (Group 3) (Advanced)')

        self.assertEqual(find_base_vampire(oAlanAdv), oAlanBase)

        self.assertEqual(find_adv_vampire(oAlanBase), oAlanAdv)
        self.assertEqual(find_adv_vampire(oNewBlood), None)

        # These aren't real vampires, but allows us to test the
        # storyline logic
        oAlanAdv = FakeCard('Alan Sovereign (EC 2013) (Advanced)')
        self.assertEqual(find_base_vampire(oAlanAdv), oAlanBase)
        oAlanAdv = FakeCard('Alan Sovereign (Red Sign) (Advanced)')
        self.assertEqual(find_base_vampire(oAlanAdv), oAlanBase)
        oAlanAdv = FakeCard('Alan Sovereign (Ascension of Caine) (Advanced)')
        self.assertEqual(find_base_vampire(oAlanAdv), oAlanBase)
Пример #13
0
def find_adv_vampire(oVampire):
    """Find the corresponding advanced vampire

       Returns None if the vampre cannout be found."""
    sAdvName = oVampire.name + ' (Advanced)'
    # Note that base Brunhilde links to the non-storyline advanced version
    try:
        return IAbstractCard(sAdvName)
    except SQLObjectNotFound:
        return None
Пример #14
0
 def _make_base_map(self):
     """Find all the vampires with advanced versions."""
     aAllAdvanced = list(SutekhAbstractCard.selectBy(level='advanced'))
     for oAbsCard in aAllAdvanced:
         sBaseName = oAbsCard.name.replace(' (Advanced)', '')
         try:
             oBaseCard = IAbstractCard(sBaseName)
             self._aBaseVamps.add(oBaseCard)
         except SQLObjectNotFound:
             # we skip the special cases here
             continue
    def test_adapters(self):
        """Extra sanity checks on the adapaters."""
        self.maxDiff = None
        for oAdapter in (IAbstractCard, IPhysicalCard,
                         IExpansion, IRarity, IRarityPair,
                         ICardType, IArtist, IKeyword):
            self.assertRaises(NotImplementedError, oAdapter, 1)
            self.assertRaises(NotImplementedError, oAdapter, None)

        # Various pass through tests
        self.assertEqual(IAbstractCard("Ossian"),
                         IAbstractCard(IAbstractCard("Ossian")))
        oExp = IExpansion("KMW")
        self.assertEqual(oExp, IExpansion(oExp))

        oPrinting = IPrinting((oExp, None))
        self.assertEqual(oPrinting, IPrinting(oPrinting))

        oPhysCard = IPhysicalCard((IAbstractCard("Ossian"), oPrinting))
        self.assertEqual(oPhysCard, IPhysicalCard(oPhysCard))
        self.assertEqual(oPhysCard.abstractCard, IAbstractCard("Ossian"))
        self.assertEqual(oPhysCard.abstractCard, IAbstractCard(oPhysCard))

        self.assertEqual(IArtist("Lawrence Snelly"),
                         IArtist(IArtist("Lawrence Snelly")))
        self.assertEqual(IKeyword('not for legal play'),
                         IKeyword(IKeyword('not for legal play')))
        self.assertEqual(IRarity("Common"), IRarity(IRarity("Common")))
        self.assertEqual(IRarityPair(("EK", "Common")),
                         IRarityPair(IRarityPair(("EK", "Common"))))
        self.assertEqual(ICardType("Vampire"), ICardType(ICardType("Vampire")))
Пример #16
0
    def begin_print(self, oPrintOp, _oContext):
        """Set up printing context.

           This includes determining pagination and the number of pages.
           """
        self._aMissing = set()
        oPrintOp.set_unit(Gtk.Units.POINTS)
        oPrintOp.set_n_pages(1)
        oIter = self.model.get_card_iterator(self.model.get_current_filter())
        aCards = sorted([IPhysicalCard(x) for x in oIter],
                        key=lambda y: IAbstractCard(y).name)

        # We lookup all the images here, so we can cancel before printing
        # if we're missing images.
        for oTheCard in aCards:
            oCard = oTheCard
            if self._ePrintExpansion == PrintExpOption.PRINT_LATEST:
                # We build a fake card with the correct expansion
                sLatestPrinting = get_printing_info(oTheCard.abstractCard)[0]
                oExp = IPrinting(sLatestPrinting)
                oCard = IPhysicalCard((oTheCard.abstractCard, oExp))

            sFilename = self._oImageFrame.lookup_filename(oCard)[0]
            if not check_file(sFilename):
                bOk = False
                for sExpName in get_printing_info(oTheCard.abstractCard):
                    oPrinting = IPrinting(sExpName)
                    oCard = IPhysicalCard((oTheCard.abstractCard, oPrinting))
                    sFilename = self._oImageFrame.lookup_filename(oCard)[0]
                    if check_file(sFilename):
                        bOk = True
                        self._aFiles.append(sFilename)
                        break
                if not bOk:
                    self._aMissing.add(oTheCard.abstractCard.name)
                    # Move onto the next card
                    continue
            else:
                self._aFiles.append(sFilename)
        if self._aMissing:
            # Abort the print operation
            oPrintOp.cancel()
            return

        # We put 9 images on a page
        iNumCards = len(aCards)
        iNumPages = iNumCards // 9
        # Add extra page if needed for the excess cards
        if iNumPages * 9 < iNumCards:
            iNumPages += 1
        oPrintOp.set_n_pages(iNumPages)
Пример #17
0
 def _get_ardb_exp_name(self, oPhysCard):
     """Extract the correct ARDB name for the expansion"""
     if oPhysCard.printing:
         oExpansion = oPhysCard.printing.expansion
     else:
         oAbsCard = IAbstractCard(oPhysCard)
         # ARDB doesn't have a concept of 'No expansion', so we
         # need to fake it. We use the first legitimate expansion
         # We sort the list to ensure stable results across databases, etc.
         aExp = sorted([oP.expansion for oP in oAbsCard.rarity],
                       key=lambda x: x.shortname)
         oExpansion = aExp[0]
     sSet = escape_ardb_expansion_name(oExpansion)
     return sSet
Пример #18
0
    def _find_card(self, sTitle):
        """Find the abstract card this rules applies to."""
        sTitle = self._oMasterOut.sub('', sTitle)
        sTitle = self._oCommaThe.sub('', sTitle)

        try:
            return IAbstractCard(sTitle)
        except SQLObjectNotFound:
            pass

        try:
            return IAbstractCard(self._dOddTitles[sTitle])
        except KeyError:
            pass
        except SQLObjectNotFound:
            pass

        try:
            return IAbstractCard(('The ' + sTitle))
        except SQLObjectNotFound:
            pass

        return None
Пример #19
0
    def activate(self, _oWidget):
        """Create the actual dialog, and populate it"""
        oFilter = self.model.get_current_filter()
        aCards = [
            IAbstractCard(oCard)
            for oCard in self.model.get_card_iterator(oFilter)
        ]

        oDialog = RandomPromoDialog(self.parent, aCards)
        oDialog.set_size_request(450, 600)
        oDialog.show_all()

        oDialog.run()
        oDialog.destroy()
Пример #20
0
    def _verify_database(self):
        """Check that the database is correctly populated"""
        try:
            _oCard = IAbstractCard('Ossian')
        except SQLObjectNotFound:
            # Log error so verbose picks it up
            logging.warning('Ossian not found in the database')
            # Inform the user
            iResponse = do_complaint(
                'Database is missing cards. Try import the cardlist now?',
                Gtk.MessageType.ERROR, Gtk.ButtonsType.YES_NO, False)
            if iResponse == Gtk.ResponseType.YES:
                self.do_refresh_card_list()

        # Create object cache
        self.__oSutekhObjectCache = SutekhObjectCache()
Пример #21
0
def find_base_vampire(oVampire):
    """Find the corresponding base vampire.

       Returns None if the vampire cannot be found."""
    sBaseName = oVampire.name.replace(' (Advanced)', '')
    # Special cases
    if '(EC 2013)' in sBaseName:
        sBaseName = sBaseName.replace(' (EC 2013)', '')
    if '(Red Sign)' in sBaseName:
        sBaseName = sBaseName.replace(' (Red Sign)', '')
    if '(Ascension of Caine)' in sBaseName:
        sBaseName = sBaseName.replace(' (Ascension of Caine)', '')
    try:
        return IAbstractCard(sBaseName)
    except SQLObjectNotFound:
        return None
Пример #22
0
    def _add_library_text(self, oCardText, aSortedLibCards):
        """Add the text of the library cards to the tree."""
        def gen_requirements(oCard):
            """Extract the requirements from the card"""
            oList = Element("ul")
            # Clan requirements
            aClan = [x.name for x in oCard.clan]
            if aClan:
                oListItem = SubElement(oList, "li")
                _add_span(oListItem, 'Requires:', 'label')
                _add_span(oListItem, "/".join(aClan), 'requirement')
            # Cost
            if oCard.costtype is not None:
                oListItem = SubElement(oList, "li")
                _add_span(oListItem, 'Cost:', 'label')
                _add_span(oListItem, "%d %s" % (oCard.cost,
                                                oCard.costtype), 'cost')
            # Disciplines
            sDisciplines = self._gen_disciplines(oCard)
            if sDisciplines != "":
                oListItem = SubElement(oList, "li")
                _add_span(oListItem, 'Disciplines:', 'label')
                _add_span(oListItem, sDisciplines, 'disciplines')
            return oList

        for sType, aList in aSortedLibCards:
            oTypeHead = SubElement(oCardText, "h4")
            oTypeHead.attrib["class"] = "libraryttype"
            oTypeHead.text = sType
            for sName in sorted([x[1] for x in aList[1:]]):
                oCard = IAbstractCard(sName)
                oCardHead = SubElement(oCardText, "h5")
                oCardHead.attrib["class"] = "cardname"
                oCardHead.text = sName
                oReqList = gen_requirements(oCard)
                # pylint: disable=len-as-condition
                # ElementTree is special, and and using bool to check
                # for children is officially deprecated.
                if len(oReqList):
                    # not empty, so add
                    oCardText.append(oReqList)
                # Text
                _add_text(oCardText, oCard)
 def _gen_inv(self, oHolder):
     """Process the card set, creating the lines as needed"""
     dCards = {}
     aSeen = set()
     sResult = ""
     for oCard in AbstractCard.select():
         dCards[oCard] = 0
     for oCard in oHolder.cards:
         oAbsCard = IAbstractCard(oCard)
         dCards[oAbsCard] += 1
     # We sort to ensure we process multi-group cards in the right order
     for oCard in sorted(dCards, key=lambda x: x.name):
         iNum = dCards[oCard]
         sName = norm_name(oCard)
         # FIXME: It's not clear if ELDB is still being developed enough
         # to support the multi-group vampires, but we try this anyway
         if sName in aSeen and is_crypt_card(oCard):
             sName = f'{sName} (Group {oCard.group})'
         aSeen.add(sName)
         sResult += '"%s",%d,0,"","%s"\n' % (sName, iNum,
                                             type_of_card(oCard))
     return sResult
Пример #24
0
    def tabulate(self, aCards):
        """Create a table from the list of (or iterator over) cards.

           Returns the table which is a nested list where each element is a row
           and each row consists of column values.
           The rows are in the same order as the cards in aCards.
           The columns are in the same order as in the aColNames list passed to
           __init__.
           """
        aColFuncs = [self._dPropFuncs[x] for x in self._aColNames]

        aTable = []

        for oCard in aCards:
            oCard = IAbstractCard(oCard)
            aRow = []

            for fProp in aColFuncs:
                aRow.append(fProp(oCard))

            aTable.append(aRow)

        return aTable
Пример #25
0
def main_with_args(aTheArgs):
    """
    Main function: Loop through the options and process the database
    accordingly.
    """
    # Turn off some pylint refactoring warnings
    # pylint: disable=too-many-statements, too-many-branches
    # pylint: disable=too-many-return-statements, too-many-locals
    oOptParser, (oOpts, aArgs) = parse_options(aTheArgs)
    sPrefsDir = prefs_dir(SutekhInfo.NAME)

    oLogHandler = StreamHandler(sys.stdout)

    if len(aArgs) != 1:
        oOptParser.print_help()
        return 1

    if oOpts.db is None:
        ensure_dir_exists(sPrefsDir)
        oOpts.db = sqlite_uri(os.path.join(sPrefsDir, "sutekh.db"))

    bDoCardListChecks = False

    oConn = connectionForURI(oOpts.db)
    sqlhub.processConnection = oConn

    if oOpts.sql_debug:
        oConn.debug = True

    if not oConn.tableExists('abstract_card'):
        if not oOpts.refresh_tables:
            print("Database has not been created.")
            return 1
    else:
        try:
            _oCard = IAbstractCard('Ossian')
        except SQLObjectNotFound:
            if not oOpts.fetch and oOpts.ww_file is None:
                print("Database is missing cards - please import the cardlist")
                return 1

    # Only log critical messages by default
    setup_logging(oOpts.verbose)

    if oOpts.reload:
        if not oOpts.refresh_tables:
            print("reload should be called with --refresh-tables")
            return 1
        sTempdir = gen_temp_dir()
        (fTemp, sReloadZipName) = \
            tempfile.mkstemp('.zip', 'sutekh', sTempdir)
        os.close(fTemp)
        oZipFile = ZipFileWrapper(sReloadZipName)
        oZipFile.do_dump_all_to_zip(oLogHandler)
        # We dump the databases here
        # We will reload them later

    if oOpts.refresh_ruling_tables:
        if not refresh_tables([Ruling], sqlhub.processConnection):
            print("refresh failed")
            return 1

    if oOpts.refresh_tables:
        if not refresh_tables(TABLE_LIST, sqlhub.processConnection):
            print("refresh failed")
            return 1

    if oOpts.refresh_physical_card_tables:
        if not refresh_tables(PHYSICAL_LIST, sqlhub.processConnection):
            print("refresh failed")
            return 1

    if oOpts.lookup_file is not None:
        read_lookup_data(EncodedFile(oOpts.lookup_file), oLogHandler)

    if oOpts.ww_file is not None:
        read_white_wolf_list(EncodedFile(oOpts.ww_file), oLogHandler)
        bDoCardListChecks = True

    if oOpts.extra_file is not None:
        read_white_wolf_list(EncodedFile(oOpts.extra_file), oLogHandler)
        bDoCardListChecks = True

    if oOpts.exp_data_file is not None:
        read_exp_info_file(EncodedFile(oOpts.exp_data_file), oLogHandler)

    if oOpts.ruling_file is not None:
        read_rulings(EncodedFile(oOpts.ruling_file), oLogHandler)

    if oOpts.fetch:
        read_lookup_data(EncodedFile(LOOKUP_DATA_URL, True), oLogHandler)
        read_white_wolf_list(EncodedFile(WW_CARDLIST_URL, True), oLogHandler)
        read_rulings(EncodedFile(WW_RULINGS_URL, True), oLogHandler)
        read_white_wolf_list(EncodedFile(EXTRA_CARD_URL, True), oLogHandler)
        read_exp_info_file(EncodedFile(EXP_DATA_URL, True), oLogHandler)
        bDoCardListChecks = True

    if bDoCardListChecks:
        # Run the consistency checks on the database
        for oAbsCard in AbstractCard.select():
            aMessages = do_card_checks(oAbsCard)
            if aMessages:
                print('\n'.join(aMessages))

    if oOpts.upgrade_db:
        oDBUpgrade = DBUpgradeManager()
        oDBUpgrade.attempt_database_upgrade(oLogHandler)

    if oOpts.save_all_css and oOpts.save_cs is not None:
        print("Can't use --save-cs and --save-all-cs Simulatenously")
        return 1

    # initialise the caches, so adapters, etc work for reading / writing
    # card sets
    make_adapter_caches()

    if oOpts.read_physical_cards_from is not None:
        oFile = PhysicalCardXmlFile(oOpts.read_physical_cards_from)
        oFile.read()

    if oOpts.save_all_css:
        write_all_pcs()

    if oOpts.dump_zip_name is not None:
        oZipFile = ZipFileWrapper(oOpts.dump_zip_name)
        oZipFile.do_dump_all_to_zip(oLogHandler)

    if oOpts.restore_zip_name is not None:
        oZipFile = ZipFileWrapper(oOpts.restore_zip_name)
        oZipFile.do_restore_from_zip(oLogHandler=oLogHandler)

    if oOpts.save_cs is not None:
        oFile = PhysicalCardSetXmlFile(oOpts.cs_filename)
        oFile.write(oOpts.save_cs)

    if oOpts.print_cs is not None:
        try:
            oCS = IPhysicalCardSet(oOpts.print_cs)
            fPrint = StringIO()
            oPrinter = WriteArdbText()
            oPrinter.write(fPrint, CardSetWrapper(oCS))
            print(fPrint.getvalue())
        except SQLObjectNotFound:
            print('Unable to load card set', oOpts.print_cs)
            return 1

    if oOpts.list_cs:
        if not print_card_list(oOpts.limit_list):
            return 1
    elif oOpts.limit_list is not None:
        print("Can't use limit-list-to without list-cs")
        return 1

    if oOpts.filter_string is not None:
        dResults = run_filter(oOpts.filter_string, oOpts.filter_cs)
        print_card_filter_list(dResults, print_card_details,
                               oOpts.filter_detailed)

    if oOpts.print_card is not None:
        if not do_print_card(oOpts.print_card, print_card_details):
            return 1

    if oOpts.read_cs is not None:
        oFile = PhysicalCardSetXmlFile(oOpts.read_cs)
        oFile.read()

    if oOpts.read_acs is not None:
        oFile = AbstractCardSetXmlFile(oOpts.read_acs)
        oFile.read()

    if oOpts.reload:
        oZipFile = ZipFileWrapper(sReloadZipName)
        oZipFile.do_restore_from_zip(oLogHandler=oLogHandler)
        os.remove(sReloadZipName)
        os.rmdir(sTempdir)

    if oOpts.upgrade_db and oOpts.refresh_tables:
        print("Can't use --upgrade-db and --refresh-tables simulatenously")
        return 1

    return 0
    def test_basic(self):
        """Basic WW list parser tests"""
        # pylint: disable=too-many-statements, too-many-locals
        # Want a long, sequential test case to minimise repeated setups
        self.maxDiff = None

        # Check that we've added the 'last updated' date entry
        oToday = datetime.date.today()
        self.assertEqual(get_metadata_date(CARDLIST_UPDATE_DATE), oToday)

        aCards = sorted(list(AbstractCard.select()), key=lambda oC: oC.name)

        # Check card names
        self.assertEqual(len(aCards), len(self.aExpectedCards))
        self.assertEqual([oC.name for oC in aCards], self.aExpectedCards)

        # Check Magnum
        # pylint: disable=invalid-name
        # o44 is OK here
        o44 = IAbstractCard(".44 Magnum")
        self.assertEqual(o44.canonicalName, u".44 magnum")
        self.assertEqual(o44.name, u".44 Magnum")
        self.assertTrue(o44.text.startswith(u"Weapon, gun.\n2R"))
        self.assertTrue(o44.text.endswith(u"each combat."))
        self.assertEqual(o44.group, None)
        self.assertEqual(o44.capacity, None)
        self.assertEqual(o44.cost, 2)
        self.assertEqual(o44.life, None)
        self.assertEqual(o44.costtype, 'pool')
        self.assertEqual(o44.level, None)

        # pylint: enable=invalid-name
        oCommon = IRarity('Common')
        oJyhad = IExpansion('Jyhad')
        oVTES = IExpansion('VTES')
        oAnthology = IExpansion('Anthology')

        self.assertTrue(oCommon in [oP.rarity for oP in o44.rarity])
        self.assertTrue(oJyhad in [oP.expansion for oP in o44.rarity])
        self.assertTrue(oVTES in [oP.expansion for oP in o44.rarity])
        self.assertTrue(oAnthology not in [oP.expansion for oP in o44.rarity])

        self.assertTrue(IRarityPair(('VTES', 'Common')) in o44.rarity)

        self.assertTrue(IKeyword('gun') in o44.keywords)
        self.assertTrue(IKeyword('weapon') in o44.keywords)

        # Find some discipline pairs
        oFortInf = IDisciplinePair((u"Fortitude", u"inferior"))
        oFortSup = IDisciplinePair((u"Fortitude", u"superior"))
        oQuiSup = IDisciplinePair((u"Quietus", u"superior"))
        oCelInf = IDisciplinePair((u"Celerity", u"inferior"))
        oAusInf = IDisciplinePair((u"Auspex", u"inferior"))
        oAusSup = IDisciplinePair((u"Auspex", u"superior"))
        oPreSup = IDisciplinePair((u"Presence", u"superior"))
        oObfSup = IDisciplinePair((u"Obfuscate", u"superior"))
        oAboInf = IDisciplinePair((u"Abombwe", u"inferior"))
        oAboSup = IDisciplinePair((u"Abombwe", u"superior"))
        oValSup = IDisciplinePair((u'Valeren', u"superior"))

        # Check Dobrescu
        oDob = IAbstractCard(u"L\xe1z\xe1r Dobrescu")
        self.assertEqual(oDob.canonicalName, u"l\xe1z\xe1r dobrescu (group 2)")
        self.assertEqual(oDob.name, u"L\xe1z\xe1r Dobrescu (Group 2)")
        self.assertTrue(oDob.text.startswith(
            u"Independent: L\xe1z\xe1r may move"))
        self.assertTrue(oDob.text.endswith(u"as a (D) action."))
        self.assertEqual(oDob.group, 2)
        self.assertEqual(oDob.capacity, 3)
        self.assertEqual(oDob.cost, None)
        self.assertEqual(oDob.life, None)
        self.assertEqual(oDob.costtype, None)
        self.assertEqual(oDob.level, None)

        self.assertTrue(IClan('Ravnos') in oDob.clan)
        self.assertEqual(len(oDob.discipline), 1)
        self.assertTrue(oFortInf in oDob.discipline)
        self.assertEqual(len(oDob.cardtype), 1)
        self.assertTrue(ICardType('Vampire') in oDob.cardtype)
        self.assertTrue(ISect('Independent') in oDob.sect)
        self.assertEqual(len(oDob.artists), 1)
        self.assertTrue(IArtist('Rebecca Guay') in oDob.artists)

        self.assertEqual(len(oDob.rulings), 1)
        oRuling = oDob.rulings[0]
        self.assertTrue(oRuling.text.startswith("Cannot use his special"))
        self.assertTrue(oRuling.text.endswith("uncontrolled region."))
        self.assertEqual(oRuling.code, "[LSJ 19990215]")

        # Check Ashur Tablets
        oAshur = IAbstractCard('Ashur Tablets')
        self.assertTrue(oAnthology in [oP.expansion for oP in oAshur.rarity])
        self.assertTrue(IRarityPair(('Anthology', 'Fixed'))
                        in oAshur.rarity)

        # Check Abstract and Physical expansions match
        for oAbs in AbstractCard.select():
            aExps = [oPair.expansion for oPair in oAbs.rarity]
            for oExp in aExps:
                try:
                    oPrint = IPrinting((oExp, None))
                    _oPair = IPhysicalCard((oAbs, oPrint))
                except SQLObjectNotFound:  # pragma: no cover
                    # We don't except to hit this during testing.
                    self.fail(f"Missing physical card {oAbs.name}"
                              f" from expansion {oExp.name}")

        # Check Yvette
        oYvette = IAbstractCard(u"Yvette, The Hopeless")
        self.assertEqual(oYvette.canonicalName, u"yvette, the hopeless (group 3)")
        self.assertEqual(oYvette.name, u"Yvette, The Hopeless (Group 3)")
        self.assertTrue(oYvette.text.startswith("Camarilla."))
        self.assertEqual(oYvette.group, 3)
        self.assertEqual(oYvette.capacity, 3)
        self.assertEqual(oYvette.cost, None)
        self.assertEqual(oYvette.life, None)
        self.assertEqual(oYvette.costtype, None)
        self.assertEqual(oYvette.level, None)

        self.assertTrue(IClan('Toreador') in oYvette.clan)
        self.assertEqual(len(oYvette.clan), 1)
        self.assertEqual(len(oYvette.discipline), 2)
        self.assertTrue(oFortInf not in oYvette.discipline)
        self.assertTrue(oCelInf in oYvette.discipline)
        self.assertTrue(oAusInf in oYvette.discipline)
        self.assertEqual(len(oYvette.cardtype), 1)
        self.assertTrue(ICardType('Vampire') in oYvette.cardtype)
        self.assertTrue(ISect('Camarilla') in oYvette.sect)
        self.assertEqual(len(oYvette.artists), 1)
        self.assertTrue(IArtist('Leif Jones') in oYvette.artists)

        # Check Sha-Ennu

        oShaEnnu = IAbstractCard(u"Sha-Ennu")
        self.assertEqual(oShaEnnu.canonicalName, u"sha-ennu (group 4)")
        self.assertEqual(oShaEnnu.name, u"Sha-Ennu (Group 4)")
        self.assertTrue(oShaEnnu.text.startswith("Sabbat regent:"))
        self.assertTrue(oShaEnnu.text.endswith("+2 bleed."))
        self.assertEqual(oShaEnnu.group, 4)
        self.assertEqual(oShaEnnu.capacity, 11)
        self.assertEqual(oShaEnnu.cost, None)
        self.assertEqual(oShaEnnu.life, None)
        self.assertEqual(oShaEnnu.costtype, None)
        self.assertEqual(oShaEnnu.level, None)

        self.assertTrue(IClan('Tzimisce') in oShaEnnu.clan)
        self.assertEqual(len(oShaEnnu.clan), 1)
        self.assertEqual(len(oShaEnnu.discipline), 6)
        self.assertTrue(oAusSup in oShaEnnu.discipline)
        self.assertTrue(oAusInf not in oShaEnnu.discipline)
        self.assertEqual(len(oShaEnnu.cardtype), 1)
        self.assertTrue(ICardType('Vampire') in oShaEnnu.cardtype)
        self.assertTrue(ISect('Sabbat') in oShaEnnu.sect)
        self.assertTrue(ITitle('Regent') in oShaEnnu.title)
        self.assertTrue(IRarityPair(('Third', 'Vampire')) in oShaEnnu.rarity)
        self.assertFalse(IRarityPair(('VTES', 'Common')) in oShaEnnu.rarity)
        self.assertFalse(IRarityPair(('VTES', 'Vampire')) in oShaEnnu.rarity)
        self.assertEqual(len(oShaEnnu.artists), 1)
        self.assertTrue(IArtist('Richard Thomas') in oShaEnnu.artists)

        self.assertTrue(IKeyword('0 stealth') in oShaEnnu.keywords)
        self.assertTrue(IKeyword('0 intercept') in oShaEnnu.keywords)
        self.assertTrue(IKeyword('1 strength') in oShaEnnu.keywords)
        self.assertTrue(IKeyword('3 bleed') in oShaEnnu.keywords)

        oShaEnnu2 = IAbstractCard(u"Sha-Ennu (Group 4)")
        self.assertEqual(oShaEnnu2.id, oShaEnnu.id)

        # Check Kabede

        oKabede = IAbstractCard(u"Kabede Maru")
        self.assertEqual(oKabede.canonicalName, u"kabede maru (group 5)")
        self.assertEqual(oKabede.name, u"Kabede Maru (Group 5)")
        self.assertTrue(oKabede.text.startswith("Laibon magaji:"))
        self.assertTrue(oKabede.text.endswith("affect Kabede.)"))
        self.assertEqual(oKabede.group, 5)
        self.assertEqual(oKabede.capacity, 9)
        self.assertEqual(oKabede.cost, None)
        self.assertEqual(oKabede.life, None)
        self.assertEqual(oKabede.costtype, None)
        self.assertEqual(oKabede.level, None)

        self.assertTrue(IClan('Banu Haqim') in oKabede.clan)
        self.assertEqual(len(oKabede.clan), 1)
        self.assertEqual(len(oKabede.discipline), 6)
        self.assertTrue(oAusSup in oKabede.discipline)
        self.assertTrue(oQuiSup in oKabede.discipline)
        self.assertTrue(oAboInf in oKabede.discipline)
        self.assertTrue(oAboSup not in oKabede.discipline)
        self.assertEqual(len(oKabede.cardtype), 1)
        self.assertTrue(ICardType('Vampire') in oKabede.cardtype)
        self.assertTrue(ISect('Laibon') in oKabede.sect)
        self.assertTrue(ITitle('Magaji') in oKabede.title)
        self.assertTrue(IRarityPair(('LotN', 'Uncommon')) in oKabede.rarity)
        self.assertEqual(len(oKabede.artists), 1)
        self.assertTrue(IArtist('Ken Meyer, Jr.') in oKabede.artists)

        self.assertTrue(IKeyword('0 stealth') in oKabede.keywords)
        self.assertTrue(IKeyword('0 intercept') in oKabede.keywords)
        self.assertTrue(IKeyword('1 strength') in oKabede.keywords)
        self.assertTrue(IKeyword('1 bleed') in oKabede.keywords)

        # Check Predator's Communion
        oPredComm = IAbstractCard(u"Predator's Communion")
        self.assertEqual(oPredComm.canonicalName, u"predator's communion")
        self.assertEqual(oPredComm.name, u"Predator's Communion")
        self.assertTrue(oPredComm.text.startswith("[abo] [REFLEX]"))
        self.assertTrue(oPredComm.text.endswith("unlocks."))
        self.assertEqual(oPredComm.group, None)
        self.assertEqual(oPredComm.capacity, None)
        self.assertEqual(oPredComm.cost, None)
        self.assertEqual(oPredComm.life, None)
        self.assertEqual(oPredComm.costtype, None)
        self.assertEqual(oPredComm.level, None)

        self.assertEqual(len(oPredComm.discipline), 1)
        self.assertTrue(oAboSup in oPredComm.discipline)
        self.assertEqual(len(oPredComm.cardtype), 2)
        self.assertTrue(ICardType('Reaction') in oPredComm.cardtype)
        self.assertTrue(ICardType('Reflex') in oPredComm.cardtype)
        self.assertTrue(IRarityPair(('LoB', 'Common')) in oPredComm.rarity)
        self.assertEqual(len(oPredComm.artists), 1)
        self.assertTrue(IArtist('David Day') in oPredComm.artists)

        # Check Earl
        oEarl = IAbstractCard(u'Earl "Shaka74" Deams')
        self.assertEqual(oEarl.canonicalName, u'earl "shaka74" deams (group 4)')
        self.assertEqual(oEarl.name, u'Earl "Shaka74" Deams (Group 4)')
        self.assertTrue(oEarl.text.startswith("Earl gets +1 stealth"))
        self.assertTrue(oEarl.text.endswith("[1 CONVICTION]."))
        self.assertEqual(oEarl.group, 4)
        self.assertEqual(oEarl.capacity, None)
        self.assertEqual(oEarl.cost, None)
        self.assertEqual(oEarl.life, 6)
        self.assertEqual(oEarl.costtype, None)
        self.assertEqual(oEarl.level, None)

        self.assertTrue(ICreed('Visionary') in oEarl.creed)
        self.assertEqual(len(oEarl.creed), 1)
        self.assertEqual(len(oEarl.virtue), 3)
        self.assertTrue(IVirtue('Martyrdom') in oEarl.virtue)
        self.assertTrue(IVirtue('Judgment') in oEarl.virtue)
        self.assertTrue(IVirtue('Vision') in oEarl.virtue)
        self.assertEqual(len(oEarl.cardtype), 1)
        self.assertTrue(ICardType('Imbued') in oEarl.cardtype)
        self.assertTrue(IRarityPair(('NoR', 'Uncommon')) in oEarl.rarity)
        self.assertEqual(len(oEarl.artists), 1)
        self.assertTrue(IArtist('David Day') in oEarl.artists)

        # Check Aire
        oAire = IAbstractCard("Aire of Elation")
        self.assertEqual(oAire.canonicalName, u"aire of elation")
        self.assertEqual(oAire.name, u"Aire of Elation")
        self.assertTrue(oAire.text.startswith("You cannot play another"))
        self.assertTrue(oAire.text.endswith("is Toreador."))
        self.assertEqual(oAire.group, None)
        self.assertEqual(oAire.capacity, None)
        self.assertEqual(oAire.cost, 1)
        self.assertEqual(oAire.life, None)
        self.assertEqual(oAire.costtype, 'blood')
        self.assertEqual(oAire.level, None)

        self.assertEqual(len(oAire.discipline), 1)
        self.assertTrue(oPreSup in oAire.discipline)
        self.assertEqual(len(oAire.cardtype), 1)
        self.assertTrue(ICardType("Action Modifier") in oAire.cardtype)

        self.assertTrue(IRarityPair(('DS', 'Common')) in oAire.rarity)
        self.assertTrue(IRarityPair(('FN', 'Precon')) in oAire.rarity)
        self.assertTrue(IRarityPair(('CE', 'Common')) in oAire.rarity)
        self.assertTrue(IRarityPair(('CE', 'Precon')) in oAire.rarity)
        self.assertTrue(IRarityPair(('Anarchs', 'Precon')) in oAire.rarity)
        self.assertTrue(IRarityPair(('KMW', 'Precon')) in oAire.rarity)

        self.assertEqual(len(oAire.artists), 1)
        self.assertTrue(IArtist('Greg Simanson') in oAire.artists)

        # Abjure
        oAbjure = IAbstractCard("Abjure")
        self.assertEqual(oAbjure.canonicalName, u"abjure")
        self.assertEqual(oAbjure.name, u"Abjure")
        self.assertTrue(oAbjure.text.startswith("[COMBAT] Lock this"))
        self.assertTrue(oAbjure.text.endswith("or ash heap."))
        self.assertEqual(oAbjure.group, None)
        self.assertEqual(oAbjure.capacity, None)
        self.assertEqual(oAbjure.cost, None)
        self.assertEqual(oAbjure.life, None)
        self.assertEqual(oAbjure.costtype, None)
        self.assertEqual(oAbjure.level, None)

        self.assertEqual(len(oAbjure.virtue), 1)
        self.assertTrue(IVirtue('Redemption') in oAbjure.virtue)
        self.assertEqual(len(oAbjure.cardtype), 1)
        self.assertTrue(ICardType('Power') in oAbjure.cardtype)
        self.assertEqual(len(oAbjure.artists), 1)
        self.assertTrue(IArtist('Brian LeBlanc') in oAbjure.artists)

        # Abombwe Master Card
        oAbo = IAbstractCard('Abombwe')

        self.assertEqual(oAbo.canonicalName, 'abombwe')
        self.assertEqual(oAbo.name, 'Abombwe')
        self.assertTrue(oAbo.text.startswith("Master: Discipline. Trifle"))
        self.assertTrue(oAbo.text.endswith("superior Abombwe."))
        self.assertEqual(oAbo.group, None)
        self.assertEqual(oAbo.capacity, 1)
        self.assertEqual(oAbo.cost, None)
        self.assertEqual(oAbo.life, None)
        self.assertEqual(oAbo.costtype, None)
        self.assertEqual(oAbo.level, None)


        self.assertEqual(len(oAbo.discipline), 0)
        self.assertEqual(len(oAbo.cardtype), 1)
        self.assertTrue(ICardType('Master') in oAbo.cardtype)
        self.assertEqual(len(oAbo.rulings), 0)
        self.assertEqual(len(oAbo.artists), 1)
        self.assertTrue(IArtist('Ken Meyer, Jr.') in oAbo.artists)

        self.assertTrue(IKeyword('trifle') in oAbo.keywords)
        self.assertTrue(IKeyword('discipline') in oAbo.keywords)

        # Ablative Skin Card
        oAblat = IAbstractCard('Ablative Skin')

        self.assertEqual(oAblat.canonicalName, 'ablative skin')
        self.assertEqual(oAblat.name, 'Ablative Skin')
        self.assertTrue(oAblat.text.startswith("+1 stealth action"))
        self.assertTrue(oAblat.text.endswith("damage in combat in this way."))
        self.assertEqual(oAblat.group, None)
        self.assertEqual(oAblat.cost, None)
        self.assertEqual(oAblat.life, None)
        self.assertEqual(oAblat.costtype, None)
        self.assertEqual(oAblat.level, None)

        self.assertEqual(len(oAblat.discipline), 1)
        self.assertTrue(oFortSup in oAblat.discipline)
        self.assertEqual(len(oAblat.cardtype), 1)
        self.assertTrue(ICardType('Action') in oAblat.cardtype)
        self.assertEqual(len(oAblat.rulings), 1)
        oRuling = oAblat.rulings[0]
        self.assertTrue(oRuling.text.startswith("Cannot be used to prevent"))
        self.assertTrue(oRuling.text.endswith("Blood Fury)."))
        self.assertEqual(oRuling.code, "[LSJ 19990216]")
        self.assertEqual(len(oAblat.artists), 1)
        self.assertTrue(IArtist('Richard Thomas') in oAblat.artists)

        # Check Independent titles
        oAmbrig = IAbstractCard(u"Ambrogino Giovanni")
        self.assertTrue(ITitle('Independent with 1 vote') in oAmbrig.title)
        oAmisa = IAbstractCard(u"Amisa")
        self.assertTrue(ITitle('Independent with 2 votes') in oAmisa.title)

        # Check Kemintiri
        oKemintiri = IAbstractCard(u"Kemintiri (Advanced)")
        self.assertEqual(oKemintiri.canonicalName, u"kemintiri (group 2) (advanced)")
        self.assertEqual(oKemintiri.name, u"Kemintiri (Group 2) (Advanced)")
        self.assertTrue(oKemintiri.text.startswith("Advanced, Independent."))
        self.assertEqual(oKemintiri.group, 2)
        self.assertEqual(oKemintiri.capacity, 10)
        self.assertEqual(oKemintiri.cost, None)
        self.assertEqual(oKemintiri.life, None)
        self.assertEqual(oKemintiri.costtype, None)
        self.assertEqual(oKemintiri.level, 'advanced')
        self.assertTrue(IKeyword('advanced') in oKemintiri.keywords)

        self.assertTrue(IClan('Ministry') in oKemintiri.clan)
        self.assertEqual(len(oKemintiri.clan), 1)
        self.assertEqual(len(oKemintiri.discipline), 6)
        self.assertTrue(oAusInf in oKemintiri.discipline)
        self.assertTrue(oObfSup in oKemintiri.discipline)
        self.assertTrue(oPreSup in oKemintiri.discipline)
        self.assertEqual(len(oKemintiri.cardtype), 1)
        self.assertTrue(ICardType('Vampire') in oKemintiri.cardtype)
        self.assertTrue(ISect('Independent') in oKemintiri.sect)
        self.assertEqual(len(oKemintiri.artists), 1)
        self.assertTrue(IArtist('Lawrence Snelly') in oKemintiri.artists)

        # Make sure we're not picking up the Merged title
        self.assertEqual(len(oKemintiri.title), 0)
        self.assertTrue(IRarityPair(('KMW', 'Uncommon')) in oKemintiri.rarity)

        # Check lookups
        for sLookup in ["Kemintiri (Adv)", "Kemintiri (ADV)",
                        "Kemintiri (Group 2) (Adv)",
                        "Kemintiri (Group 2) (ADV)",
                        "Kemintiri (Advanced) (Group 2)",
                        "Kemintiri (Adv) (Group 2)",
                        "Kemintiri (ADV) (Group 2)"]:
            oKem2 = IAbstractCard(sLookup)
            self.assertEqual(oKem2.id, oKemintiri.id)

        # Check ANY group handling
        oNewBlood = IAbstractCard('New Blood')
        self.assertEqual(oNewBlood.group, -1)
        self.assertEqual(oNewBlood.capacity, 2)
        self.assertEqual(oNewBlood.life, None)
        self.assertEqual(oNewBlood.cost, None)

        self.assertTrue(IClan('Blood Brother') in oNewBlood.clan)
        self.assertEqual(len(oNewBlood.clan), 1)
        self.assertEqual(len(oNewBlood.discipline), 1)
        self.assertTrue('belongs to the chosen circle.' in oNewBlood.text)

        # Check The Path
        oPath1 = IAbstractCard('The Path of Blood')

        self.assertTrue(IClan('Banu Haqim') in oPath1.clan)
        self.assertEqual(oPath1.cost, 1)
        self.assertEqual(oPath1.costtype, 'pool')
        self.assertTrue(ICardType('Master') in oPath1.cardtype)

        self.assertTrue(IKeyword('unique') in oPath1.keywords)

        # Check alternative lookup
        oPath2 = IAbstractCard('Path of Blood, The')
        self.assertEqual(oPath1.id, oPath2.id)

        # Check The Slaughterhouse
        oSlaughter = IAbstractCard('The Slaughterhouse')
        self.assertEqual(oSlaughter.canonicalName, u"the slaughterhouse")
        self.assertEqual(len(oSlaughter.keywords), 2)
        self.assertTrue(IKeyword('burn option') in oSlaughter.keywords)
        self.assertTrue(IKeyword('location') in oSlaughter.keywords)

        # Check keywords for The Ankara Citadel, Turkey
        oCitadel = IAbstractCard('The Ankara Citadel, Turkey')
        self.assertEqual(oCitadel.cost, 2)
        self.assertTrue(IClan('Tremere') in oCitadel.clan)
        self.assertEqual(oCitadel.costtype, 'blood')
        self.assertTrue(IKeyword('location') in oCitadel.keywords)
        self.assertTrue(IKeyword('unique') in oCitadel.keywords)

        # Check life & keywords for Ossian
        oOssian = IAbstractCard('Ossian')
        self.assertEqual(oOssian.life, 4)
        self.assertEqual(oOssian.cost, 3)
        self.assertEqual(oOssian.costtype, 'pool')
        self.assertTrue(IKeyword('werewolf') in oOssian.keywords)
        self.assertTrue(IKeyword('red list') in oOssian.keywords)
        self.assertTrue(IKeyword('unique') in oOssian.keywords)
        self.assertTrue(IKeyword('0 bleed') in oOssian.keywords)
        self.assertTrue(IKeyword('2 strength') in oOssian.keywords)

        # Check life & keywords for Raven Spy
        oRaven = IAbstractCard('Raven Spy')
        self.assertTrue(IKeyword('animal') in oRaven.keywords)
        self.assertTrue(IKeyword('1 strength') not in oRaven.keywords)
        self.assertEqual(oRaven.life, 1)
        self.assertEqual(oRaven.cost, 1)
        self.assertEqual(oRaven.costtype, 'blood')

        # Check slave keywords for Fidus and Sheela Na Gig
        oFidus = IAbstractCard(u"Fidus, The Shrunken Beast")
        self.assertTrue(IKeyword('tremere slave') in oFidus.keywords)

        oSheela = IAbstractCard(u"Sheela Na Gig")
        self.assertTrue(IKeyword('tremere antitribu slave')
                        in oSheela.keywords)

        # Check for Anarch sect status
        oAlab = IAbstractCard(u"Alabástrom")
        self.assertTrue(ISect('Anarch') in oAlab.sect)

        # Check special cases
        oRetainer = IAbstractCard('Ghoul Retainer')
        self.assertTrue(IKeyword('1 strength') in oRetainer.keywords)
        oHighTop = IAbstractCard('High Top')
        self.assertTrue(IKeyword('1 intercept') in oHighTop.keywords)
        oGypsies = IAbstractCard('Gypsies')
        self.assertTrue(IKeyword('1 stealth') in oGypsies.keywords)
        # Check brace normalisation
        self.assertTrue('{strength' in oGypsies.text)
        self.assertTrue('{mortal' in oGypsies.text)
        self.assertTrue('-{' not in oGypsies.text)
        # check brace filtering
        self.assertTrue('{' not in oGypsies.search_text)
        oRebekka = IAbstractCard('Rebekka, Chantry Elder of Munich')
        self.assertTrue(IKeyword('1 stealth') in oRebekka.keywords)
        oProtracted = IAbstractCard('Protracted Investment')
        self.assertTrue(IKeyword('investment') in oProtracted.keywords)
        oBravo = IAbstractCard('Bravo')
        self.assertTrue(IKeyword('archetype') in oBravo.keywords)
        oDramatic = IAbstractCard('Dramatic Upheaval')
        self.assertTrue(IKeyword('not for legal play') in oDramatic.keywords)
        oMotivated = IAbstractCard('Motivated by Gehenna')
        self.assertTrue(IKeyword('not for legal play') in oMotivated.keywords)
        oAaron = IAbstractCard("Aaron's Feeding Razor")
        self.assertTrue(IKeyword('unique') in oAaron.keywords)

        # Test adding extra expansions works

        oAnarchRailroad = IAbstractCard("Anarch Railroad")
        self.assertEqual(oAnarchRailroad.canonicalName, u"anarch railroad")
        self.assertEqual(oAnarchRailroad.cost, 2)
        self.assertEqual(oAnarchRailroad.costtype, 'pool')
        self.assertTrue(oAnarchRailroad.text.startswith(u"Master: unique"))
        oAnarchs = IExpansion('Anarchs')
        oAA = IExpansion('Anarchs and Alastors Storyline')

        self.assertTrue(oAnarchs in [oP.expansion for oP in
                                     oAnarchRailroad.rarity])
        self.assertTrue(oAA in [oP.expansion for oP in oAnarchRailroad.rarity])

        oAnarchRevolt = IAbstractCard("Anarch Revolt")
        self.assertEqual(oAnarchRevolt.canonicalName, u"anarch revolt")
        self.assertEqual(oAnarchRevolt.cost, None)
        self.assertTrue(oAnarchRevolt.text.startswith(u"Master."))

        self.assertTrue(oAnarchs in [oP.expansion for oP in
                                     oAnarchRevolt.rarity])
        self.assertTrue(oAA in [oP.expansion for oP in oAnarchRevolt.rarity])
        self.assertTrue(oJyhad in [oP.expansion for oP in
                                   oAnarchRevolt.rarity])

        oHtH = IAbstractCard("Hide the Heart")
        self.assertEqual(oHtH.canonicalName, u"hide the heart")
        self.assertEqual(len(oHtH.discipline), 2)
        self.assertTrue(oAusSup in oHtH.discipline)
        self.assertTrue(oValSup in oHtH.discipline)
        self.assertEqual(len(oHtH.cardtype), 1)
        self.assertTrue(ICardType("Reaction") in oHtH.cardtype)
        self.assertTrue(oHtH.text.startswith('[aus] Reduce'))

        self.assertTrue(IRarityPair(('HttB', 'Common')) in oHtH.rarity)
        self.assertTrue(IRarityPair(('Black Chantry', 'Fixed')) in oHtH.rarity)
        self.assertTrue(IRarityPair(('HttB', 'Precon')) in oHtH.rarity)

        oSmite = IAbstractCard("Smite")
        self.assertEqual(oSmite.canonicalName, u"smite")
        self.assertEqual(oSmite.cost, 3)
        self.assertEqual(oSmite.costtype, "conviction")
        self.assertTrue(oSmite.text.startswith('{Strike:}'))

        # Check for Black Chantry Expansion data
        oBaronD = IAbstractCard('Baron Dieudonne')
        oKoT = IExpansion('Keepers of Tradition')
        oBC = IExpansion('Black Chantry')
        # Check we handle the conversion of our old name for the Black Chantry
        # cards correctly
        oBCold = IExpansion('Black Chantry Reprint')
        self.assertEqual(oBC, oBCold)
        self.assertTrue(oKoT in [oP.expansion for oP in oBaronD.rarity])
        self.assertTrue(oBC in [oP.expansion for oP in oBaronD.rarity])
        # Check that we also pick up the BC expansion for Hide the Heart
        self.assertTrue(oBC in [oP.expansion for oP in oHtH.rarity])
        self.assertFalse(oKoT in [oP.expansion for oP in oHtH.rarity])

        # Check we get the rarity for Aye correct
        oAye = IAbstractCard("Aye")
        self.assertEqual(oAye.canonicalName, u"aye")
        oLoB = IExpansion('Legacy of Blood')
        oEK = IExpansion('EK')
        # Check some expansion properties while we're here
        self.assertEqual(oLoB.name, 'Legacy of Blood')
        self.assertEqual(oLoB.shortname, 'LoB')
        self.assertEqual(oEK.name, 'Ebony Kingdom')
        self.assertEqual(oEK.shortname, 'EK')
        self.assertTrue(oLoB in [oP.expansion for oP in oAye.rarity])
        self.assertTrue(oEK in [oP.expansion for oP in oAye.rarity])
        self.assertTrue(oCommon in [oP.rarity for oP in oAye.rarity])
        # Check that we only got 1 rarity for Aye
        self.assertEqual(set([oCommon]),
                         set([oP.rarity for oP in oAye.rarity]))

        self.assertTrue(IRarityPair(('LoB', 'Common')) in oAye.rarity)
        self.assertTrue(IRarityPair(('EK', 'Common')) in oAye.rarity)

        # Check that Anarchs Unbound cards have both PDF and kickstart versions

        oCrow = IAbstractCard("Crow")
        oPDFDM = IExpansion("Anarchs Unbound")
        self.assertTrue(oPDFDM.shortname, "AU")
        oKickstarterDM = IExpansion("Anarchs Unbound (Kickstarter Edition)")
        self.assertTrue(oPDFDM in [oP.expansion for oP in oCrow.rarity])
        self.assertTrue(oKickstarterDM in [oP.expansion for oP in oCrow.rarity])

        # ditto Danse Macabre

        oClaudia = IAbstractCard("Claudia")
        oPDFDM = IExpansion("Danse Macabre")
        self.assertTrue(oPDFDM.shortname, "DM")
        oKickstarterDM = IExpansion("Danse Macabre (Kickstarter Edition)")
        self.assertTrue(oPDFDM in [oP.expansion for oP in oClaudia.rarity])
        self.assertTrue(oKickstarterDM in [oP.expansion for oP in oClaudia.rarity])

        # Check The Unaligned pdf

        oCountJ = IAbstractCard("Count Jocalo")
        oPDFDM = IExpansion("The Unaligned")
        self.assertTrue(oPDFDM.shortname, "TU")
        oKickstarterDM = IExpansion("The Unaligned (Kickstarter Edition)")
        self.assertTrue(oPDFDM in [oP.expansion for oP in oCountJ.rarity])
        self.assertTrue(oKickstarterDM in [oP.expansion for oP in oCountJ.rarity])

        # Check the kickstarter on reprinted promos don't have PDF versions

        oRise = IAbstractCard("Rise of the Fallen")

        # Must have kickstarter version
        self.assertTrue(oKickstarterDM in [oP.expansion for oP in oRise.rarity])
        # But not PDF
        self.assertFalse(oPDFDM in [oP.expansion for oP in oRise.rarity])

        # Check that we create the correct lookup for Victoria Ash (to group 2)
        oVicAsh2 = IAbstractCard("Victoria Ash (Group 2)")
        oVicAsh7 = IAbstractCard("Victoria Ash (Group 7)")
        oVicAsh = IAbstractCard("Victoria Ash")
        self.assertNotEqual(oVicAsh2.id, oVicAsh7.id)
        self.assertEqual(oVicAsh2.id, oVicAsh.id)

        # Check that we have the Pentex lookups correct
        # The list checks that we have handled the rename correctly
        oPentex1 = IAbstractCard('Pentex Subversion')
        oPentex2 = IAbstractCard('Pentex(TM) Subversion')
        oPentex3 = IAbstractCard('Pentex™ Subversion')

        self.assertEqual(oPentex1.id, oPentex2.id)
        self.assertEqual(oPentex1.id, oPentex3.id)
 def test_basic(self):
     """Set of simple tests of the Card List Model"""
     # pylint: disable=too-many-statements, too-many-locals
     # Want a long, sequential test case to minimise
     # repeated setups, so it has lots of lines + variables
     oModel = CardListModel(self.oConfig)
     # We test with illegal cards shown
     oModel.hideillegal = False
     oListener = LocalTestListener(oModel, True)
     self.assertFalse(oListener.bLoadCalled)
     oModel.load()
     self.assertTrue(oListener.bLoadCalled)
     aExpectedCards = set(AbstractCard.select())
     self.assertEqual(aExpectedCards, set(oListener.aCards))
     self.assertEqual(
         oModel.get_card_iterator(None).count(),
         PhysicalCard.select().count())
     # The model as an entry for every AbstractCard and entries
     # below that for every PhysicalCard
     # Set grouping to None for these tests
     oModel.groupby = NullGrouping
     oModel.load()
     self.assertEqual(count_all_cards(oModel),
                      AbstractCard.select().count())
     self.assertEqual(count_second_level(oModel),
                      PhysicalCard.select().count())
     # Check without expansions
     oModel.bExpansions = False
     oModel.load()
     self.assertEqual(count_all_cards(oModel),
                      AbstractCard.select().count())
     self.assertEqual(count_second_level(oModel), 0)
     oModel.bExpansions = True
     oModel.groupby = CryptLibraryGrouping
     oModel.load()
     self.assertEqual(count_all_cards(oModel),
                      AbstractCard.select().count())
     self.assertEqual(count_second_level(oModel),
                      PhysicalCard.select().count())
     self.assertEqual(count_top_level(oModel), 2)
     # Test filtering
     # Test filter which selects nothing works
     oModel.selectfilter = BaseFilters.CardNameFilter('ZZZZZZZ')
     oModel.applyfilter = True
     oModel.load()
     self.assertEqual(count_top_level(oModel), 1)
     self.assertEqual(count_all_cards(oModel), 0)
     oModel.applyfilter = False
     oModel.load()
     self.assertEqual(count_all_cards(oModel),
                      AbstractCard.select().count())
     self.assertEqual(count_second_level(oModel),
                      PhysicalCard.select().count())
     self.assertEqual(count_top_level(oModel), 2)
     # Test card type
     oModel.selectfilter = BaseFilters.CardTypeFilter('Vampire')
     oModel.applyfilter = True
     oModel.load()
     self.assertEqual(count_top_level(oModel), 1)
     self.assertEqual(count_second_level(oModel),
                      oModel.get_card_iterator(oModel.selectfilter).count())
     oModel.groupby = CardTypeGrouping
     oModel.load()
     self.assertEqual(count_top_level(oModel), 1)
     self.assertEqual(count_second_level(oModel),
                      oModel.get_card_iterator(oModel.selectfilter).count())
     # Test path queries
     # The remain tests require a sorted model
     oModel.enable_sorting()
     oPath = '0:0:0'  # First expansion for the first card
     self.assertEqual(oModel.get_exp_name_from_path(oPath),
                      oModel.sUnknownExpansion)
     self.assertEqual(oModel.get_card_name_from_path(oPath),
                      u'Aabbt Kindred (Group 2)')
     tAll = oModel.get_all_from_path(oPath)
     self.assertEqual(tAll[0], u'Aabbt Kindred (Group 2)')
     self.assertEqual(tAll[1], oModel.sUnknownExpansion)
     self.assertEqual(tAll[2], 0)
     self.assertEqual(tAll[3], 2)
     oIter = oModel.get_iter(oPath)
     self.assertEqual(oModel.get_child_entries_from_iter(oIter), [])
     oPath = '0:0'  # First card
     self.assertEqual(oModel.get_exp_name_from_path(oPath), None)
     self.assertEqual(oModel.get_inc_dec_flags_from_path(oPath),
                      (False, False))
     oIter = oModel.get_iter(oPath)
     tAll = oModel.get_all_from_path(oPath)
     self.assertEqual(tAll[0], u'Aabbt Kindred (Group 2)')
     self.assertEqual(tAll[1], None)
     self.assertEqual(tAll[2], 0)
     self.assertEqual(tAll[3], 1)
     oAbbt = IAbstractCard(u'Aabbt Kindred (Group 2)')
     oFirst = IPhysicalCard((oAbbt, None))
     oSecond = IPhysicalCard((oAbbt, IExpansion('Final Nights')))
     self.assertEqual(oModel.get_child_entries_from_iter(oIter),
                      [(oFirst, 0), (oSecond, 0)])
     # Test that the different variants show correctly
     oPath = '0:28:0'  # Harold's position
     self.assertEqual(oModel.get_card_name_from_path(oPath),
                      u"Harold Zettler, Pentex Director (Group 4)")
     self.assertEqual(oModel.get_exp_name_from_path(oPath),
                      oModel.sUnknownExpansion)
     oPath = '0:28:1'
     self.assertEqual(oModel.get_card_name_from_path(oPath),
                      u"Harold Zettler, Pentex Director (Group 4)")
     self.assertEqual(oModel.get_exp_name_from_path(oPath), "Third Edition")
     oPath = '0:28:2'
     self.assertEqual(oModel.get_card_name_from_path(oPath),
                      u"Harold Zettler, Pentex Director (Group 4)")
     self.assertEqual(oModel.get_exp_name_from_path(oPath),
                      "Third Edition (Sketch)")
     oListener.bLoadCalled = False
     # Test MessageBus clear does the right thing
     MessageBus.clear(oModel)
     oModel.load()
     self.assertFalse(oListener.bLoadCalled)
Пример #28
0
    def test_basic(self):
        """Basic card set holder tests."""
        # pylint: disable=too-many-statements, too-many-locals
        # Want a long, sequential test case to minimise repeated setup
        # Everything is in the database, so should be no problems
        dSet1 = {
            '.44 Magnum': [3, None],
            'AK-47': [2, 'LotN'],
            'Abebe': [3, 'LoB'],
            'Abombwe': [3, 'LoB'],
            'Abbot': [1, 'Third Edition'],
        }
        oCSH = CardSetHolder()
        aExpectedPrintings = []

        for sCardName, aInfo in dSet1.items():
            iCnt, sExpName = aInfo
            oCSH.add(iCnt, sCardName, sExpName, None)
            if sExpName:
                oExp = IExpansion(sExpName)
                oThisPrint = IPrinting((oExp, None))
            else:
                oThisPrint = None
            aExpectedPrintings.extend([oThisPrint] * iCnt)

        aExpectedPrintings.sort(key=lambda x: x.id if x else -1)
        self.assertRaises(RuntimeError, oCSH.create_pcs)
        oCSH.name = 'Test Set 1'
        oCSH.create_pcs()
        oCS = IPhysicalCardSet('Test Set 1')
        self.assertEqual(len(oCS.cards), 12)
        oPCSFilter = BaseFilters.PhysicalCardSetFilter('Test Set 1')
        oAbbotFilter = BaseFilters.FilterAndBox(
            [oPCSFilter, BaseFilters.SpecificCardFilter('Abbot')])
        aCSCards = [
            IAbstractCard(x).name for x in oAbbotFilter.select(
                MapPhysicalCardToPhysicalCardSet).distinct()
        ]
        self.assertEqual(aCSCards, [u'Abbot'])
        oVampireFilter = BaseFilters.FilterAndBox(
            [oPCSFilter, BaseFilters.CardTypeFilter('Vampire')])
        aCSCards = [
            IAbstractCard(x).name for x in oVampireFilter.select(
                MapPhysicalCardToPhysicalCardSet).distinct()
        ]
        self.assertEqual(
            aCSCards,
            [u'Abebe (Group 4)', u'Abebe (Group 4)', u'Abebe (Group 4)'])
        aPrintings = [oCard.printing for oCard in oCS.cards]
        aPrintings.sort(key=lambda x: x.id if x else -1)
        self.assertEqual(aPrintings, aExpectedPrintings)

        oCSH.name = 'Test Set 2'
        oCSH.parent = 'Test Set 1'
        self.assertRaises(RuntimeError, oCSH.remove, 1, 'Abbot', None, None)
        self.assertRaises(RuntimeError, oCSH.remove, 2, 'Abbot',
                          'Third Edition', None)
        oCSH.remove(1, 'Abbot', 'Third Edition', None)
        oCSH.remove(1, 'Abombwe', 'LoB', None)
        oCSH.create_pcs()

        oCS2 = IPhysicalCardSet('Test Set 2')
        self.assertEqual(oCS2.parent, oCS)
        self.assertEqual(len(oCS2.cards), 10)

        oPCSFilter = BaseFilters.PhysicalCardSetFilter('Test Set 2')
        oAbbotFilter = BaseFilters.FilterAndBox(
            [oPCSFilter, BaseFilters.SpecificCardFilter('Abbot')])
        aCSCards = [
            IAbstractCard(x).name for x in oAbbotFilter.select(
                MapPhysicalCardToPhysicalCardSet).distinct()
        ]
        self.assertEqual(aCSCards, [])
        oVampireFilter = BaseFilters.FilterAndBox(
            [oPCSFilter, BaseFilters.CardTypeFilter('Vampire')])
        aCSCards = [
            IAbstractCard(x).name for x in oVampireFilter.select(
                MapPhysicalCardToPhysicalCardSet).distinct()
        ]
        self.assertEqual(
            aCSCards,
            [u'Abebe (Group 4)', u'Abebe (Group 4)', u'Abebe (Group 4)'])

        # Misspelt cards - the default lookup should exclude these
        dSet2 = {
            '.44 Magnum': [3, None],
            'Abede': [3, 'LoB'],
        }
        oCSH = CardSetHolder()
        for sCardName, aInfo in dSet2.items():
            iCnt, sExpName = aInfo
            oCSH.add(iCnt, sCardName, sExpName, None)

        oCSH.name = 'Test Set 3'

        oCSH.create_pcs()

        oCS = IPhysicalCardSet('Test Set 3')
        self.assertEqual(len(oCS.cards), 3)
        oPCSFilter = BaseFilters.PhysicalCardSetFilter('Test Set 3')
        oGunFilter = BaseFilters.FilterAndBox(
            [oPCSFilter,
             BaseFilters.SpecificCardFilter('.44 Magnum')])
        aCSCards = [
            IAbstractCard(x).name for x in oGunFilter.select(
                MapPhysicalCardToPhysicalCardSet).distinct()
        ]
        self.assertEqual(aCSCards,
                         [u'.44 Magnum', u'.44 Magnum', '.44 Magnum'])
        oVampireFilter = BaseFilters.FilterAndBox(
            [oPCSFilter, BaseFilters.CardTypeFilter('Vampire')])
        aCSCards = [
            IAbstractCard(x).name for x in oVampireFilter.select(
                MapPhysicalCardToPhysicalCardSet).distinct()
        ]
        self.assertEqual(aCSCards, [])

        # Misspelt expansions - all cards should be added, but some with
        # None for the expansion
        dSet3 = {
            'AK-47': [2, 'Lords of the Knight'],
            'Abebe': [3, 'Legacy of Bllod'],
        }

        oCSH = CardSetHolder()
        for sCardName, aInfo in dSet3.items():
            iCnt, sExpName = aInfo
            oCSH.add(iCnt, sCardName, sExpName, None)

        aExpectedPrintings = [None] * 5

        # Also check parent warnings
        oCSH.parent = 'Test Set 5'
        oCSH.name = 'Test Set 4'
        self.assertEqual(oCSH.get_parent_pcs(), None)
        self.assertNotEqual(len(oCSH.get_warnings()), 0)
        oCSH.clear_warnings()
        self.assertEqual(len(oCSH.get_warnings()), 0)
        oCSH.create_pcs()
        self.assertNotEqual(len(oCSH.get_warnings()), 0)

        oCS = IPhysicalCardSet('Test Set 4')
        self.assertEqual(len(oCS.cards), 5)
        oPCSFilter = BaseFilters.PhysicalCardSetFilter('Test Set 4')
        oGunFilter = BaseFilters.FilterAndBox(
            [oPCSFilter, BaseFilters.SpecificCardFilter('AK-47')])
        aCSCards = [
            IAbstractCard(x).name for x in oGunFilter.select(
                MapPhysicalCardToPhysicalCardSet).distinct()
        ]
        self.assertEqual(aCSCards, [u'AK-47', u'AK-47'])
        oVampireFilter = BaseFilters.FilterAndBox(
            [oPCSFilter, BaseFilters.CardTypeFilter('Vampire')])
        aCSCards = [
            IAbstractCard(x).name for x in oVampireFilter.select(
                MapPhysicalCardToPhysicalCardSet).distinct()
        ]
        self.assertEqual(
            aCSCards,
            [u'Abebe (Group 4)', u'Abebe (Group 4)', u'Abebe (Group 4)'])

        aPrintings = [oCard.printing for oCard in oCS.cards]
        aPrintings.sort(key=lambda x: x.id if x else -1)
        self.assertEqual(aPrintings, aExpectedPrintings)
Пример #29
0
 def get_card(self, oPath):
     """Return the AbstractCard for the given path"""
     oIter = self.get_iter(oPath)
     sName = self.get_value(oIter, 0)
     return IAbstractCard(sName)
Пример #30
0
    def test_basic(self):
        """Test behaviour"""
        oCard = IAbstractCard("Pier 13, Port of Baltimore")
        self.assertEqual(oCard, IAbstractCard("Pier 13"))

        oCard = IAbstractCard("Anastasz di Zagreb")
        self.assertEqual(oCard, IAbstractCard("Anastaszdi Zagreb"))

        oCard = IAbstractCard("The Path of Blood")
        # Article shifting
        self.assertEqual(oCard, IAbstractCard("Path of Blood, The"))

        # Odd cases
        self.assertEqual(oCard, IAbstractCard("THE PATH OF bLOOD"))
        self.assertEqual(oCard, IAbstractCard("the paTH oF bLOOD"))

        # Check that the AKA parsing works as expected
        oCard = IAbstractCard(u"L\xe1z\xe1r Dobrescu")
        self.assertEqual(oCard, IAbstractCard("Lazar Dobrescu"))

        # check (Adv) automatic lookups
        oCard = IAbstractCard(u"Kemintiri (Advanced)")
        self.assertEqual(oCard, IAbstractCard("Kemintiri (Adv)"))

        oCard = IAbstractCard(u"Alan Sovereign (Advanced)")
        self.assertEqual(oCard, IAbstractCard("Alan Sovereign (Adv)"))