Bringing branch up to date with dev

Merge branch 'development' into ErrorDialog_and_miscfixes

Conflicts:
	eos/saveddata/fit.py
	pyfa.py
This commit is contained in:
blitzman
2017-03-25 22:30:18 -04:00
25 changed files with 673 additions and 147 deletions

View File

@@ -42,6 +42,7 @@ If you wish to help with development or simply need to run pyfa through a Python
* `dateutil` * `dateutil`
* `matplotlib` (for some Linux distributions you may need to install separate wxPython bindings such as `python-matplotlib-wx`) * `matplotlib` (for some Linux distributions you may need to install separate wxPython bindings such as `python-matplotlib-wx`)
* `requests` * `requests`
* `logbook` >= 1.0.0
## Bug Reporting ## Bug Reporting
The preferred method of reporting bugs is through the project's [GitHub Issues interface](https://github.com/pyfa-org/Pyfa/issues). Alternatively, posting a report in the [pyfa thread](http://forums.eveonline.com/default.aspx?g=posts&t=247609) on the official EVE Online forums is acceptable. Guidelines for bug reporting can be found on [this wiki page](https://github.com/DarkFenX/Pyfa/wiki/Bug-Reporting). The preferred method of reporting bugs is through the project's [GitHub Issues interface](https://github.com/pyfa-org/Pyfa/issues). Alternatively, posting a report in the [pyfa thread](http://forums.eveonline.com/default.aspx?g=posts&t=247609) on the official EVE Online forums is acceptable. Guidelines for bug reporting can be found on [this wiki page](https://github.com/DarkFenX/Pyfa/wiki/Bug-Reporting).

0
_development/__init__.py Normal file
View File

143
_development/helpers.py Normal file
View File

@@ -0,0 +1,143 @@
# noinspection PyPackageRequirements
import pytest
import os
import sys
import threading
from sqlalchemy import MetaData, create_engine
from sqlalchemy.orm import sessionmaker
script_dir = os.path.dirname(os.path.abspath(__file__))
# Add root folder to python paths
sys.path.append(os.path.realpath(os.path.join(script_dir, '..', '..')))
sys._called_from_test = True
# noinspection PyUnresolvedReferences,PyUnusedLocal
@pytest.fixture
def DBInMemory_test():
def rollback():
with sd_lock:
saveddata_session.rollback()
print("Creating database in memory")
from os.path import realpath, join, dirname, abspath
debug = False
gamedataCache = True
saveddataCache = True
gamedata_version = ""
gamedata_connectionstring = 'sqlite:///' + realpath(join(dirname(abspath(unicode(__file__))), "..", "eve.db"))
saveddata_connectionstring = 'sqlite:///:memory:'
class ReadOnlyException(Exception):
pass
if callable(gamedata_connectionstring):
gamedata_engine = create_engine("sqlite://", creator=gamedata_connectionstring, echo=debug)
else:
gamedata_engine = create_engine(gamedata_connectionstring, echo=debug)
gamedata_meta = MetaData()
gamedata_meta.bind = gamedata_engine
gamedata_session = sessionmaker(bind=gamedata_engine, autoflush=False, expire_on_commit=False)()
# This should be moved elsewhere, maybe as an actual query. Current, without try-except, it breaks when making a new
# game db because we haven't reached gamedata_meta.create_all()
try:
gamedata_version = gamedata_session.execute(
"SELECT `field_value` FROM `metadata` WHERE `field_name` LIKE 'client_build'"
).fetchone()[0]
except Exception as e:
print("Missing gamedata version.")
gamedata_version = None
if saveddata_connectionstring is not None:
if callable(saveddata_connectionstring):
saveddata_engine = create_engine(creator=saveddata_connectionstring, echo=debug)
else:
saveddata_engine = create_engine(saveddata_connectionstring, echo=debug)
saveddata_meta = MetaData()
saveddata_meta.bind = saveddata_engine
saveddata_session = sessionmaker(bind=saveddata_engine, autoflush=False, expire_on_commit=False)()
else:
saveddata_meta = None
# Lock controlling any changes introduced to session
sd_lock = threading.Lock()
# Import all the definitions for all our database stuff
# noinspection PyPep8
#from eos.db.gamedata import alphaClones, attribute, category, effect, group, icon, item, marketGroup, metaData, metaGroup, queries, traits, unit
# noinspection PyPep8
#from eos.db.saveddata import booster, cargo, character, crest, damagePattern, databaseRepair, drone, fighter, fit, implant, implantSet, loadDefaultDatabaseValues, miscData, module, override, price, queries, skill, targetResists, user
# If using in memory saveddata, you'll want to reflect it so the data structure is good.
if saveddata_connectionstring == "sqlite:///:memory:":
saveddata_meta.create_all()
# Output debug info to help us troubleshoot Travis
print(saveddata_engine)
print(gamedata_engine)
helper = {
#'config': eos.config,
'gamedata_session' : gamedata_session,
'saveddata_session' : saveddata_session,
}
return helper
# noinspection PyUnresolvedReferences,PyUnusedLocal
@pytest.fixture
def DBInMemory():
print("Creating database in memory")
import eos.config
import eos
import eos.db
# Output debug info to help us troubleshoot Travis
print(eos.db.saveddata_engine)
print(eos.db.gamedata_engine)
helper = {
'config': eos.config,
'db' : eos.db,
'gamedata_session' : eos.db.gamedata_session,
'saveddata_session' : eos.db.saveddata_session,
}
return helper
@pytest.fixture
def Gamedata():
print("Building Gamedata")
from eos.gamedata import Item
helper = {
'Item': Item,
}
return helper
@pytest.fixture
def Saveddata():
print("Building Saveddata")
from eos.saveddata.ship import Ship
from eos.saveddata.fit import Fit
from eos.saveddata.character import Character
from eos.saveddata.module import Module, State
from eos.saveddata.citadel import Citadel
helper = {
'Structure': Citadel,
'Ship' : Ship,
'Fit' : Fit,
'Character': Character,
'Module' : Module,
'State' : State,
}
return helper

View File

@@ -0,0 +1,28 @@
import pytest
# noinspection PyPackageRequirements
from _development.helpers import DBInMemory as DB, Gamedata, Saveddata
# noinspection PyShadowingNames
@pytest.fixture
def RifterFit(DB, Gamedata, Saveddata):
print("Creating Rifter")
item = DB['gamedata_session'].query(Gamedata['Item']).filter(Gamedata['Item'].name == "Rifter").first()
ship = Saveddata['Ship'](item)
# setup fit
fit = Saveddata['Fit'](ship, "My Rifter Fit")
return fit
# noinspection PyShadowingNames
@pytest.fixture
def KeepstarFit(DB, Gamedata, Saveddata):
print("Creating Keepstar")
item = DB['gamedata_session'].query(Gamedata['Item']).filter(Gamedata['Item'].name == "Keepstar").first()
ship = Saveddata['Structure'](item)
# setup fit
fit = Saveddata['Fit'](ship, "Keepstar Fit")
return fit

View File

@@ -19,7 +19,7 @@ debug = False
saveInRoot = False saveInRoot = False
# Version data # Version data
version = "1.28.1" version = "1.28.2"
tag = "git" tag = "git"
expansionName = "YC119.3" expansionName = "YC119.3"
expansionVersion = "1.0" expansionVersion = "1.0"

View File

@@ -1,14 +1,25 @@
import sys import sys
from os.path import realpath, join, dirname, abspath from os.path import realpath, join, dirname, abspath
from logbook import Logger
import os
istravis = os.environ.get('TRAVIS') == 'true'
pyfalog = Logger(__name__)
debug = False debug = False
gamedataCache = True gamedataCache = True
saveddataCache = True saveddataCache = True
gamedata_version = "" gamedata_version = ""
gamedata_connectionstring = 'sqlite:///' + unicode(realpath(join(dirname(abspath(__file__)), "..", "eve.db")), gamedata_connectionstring = 'sqlite:///' + unicode(realpath(join(dirname(abspath(__file__)), "..", "eve.db")), sys.getfilesystemencoding())
sys.getfilesystemencoding()) pyfalog.debug("Gamedata connection string: {0}", gamedata_connectionstring)
saveddata_connectionstring = 'sqlite:///' + unicode(
realpath(join(dirname(abspath(__file__)), "..", "saveddata", "saveddata.db")), sys.getfilesystemencoding()) if istravis is True or hasattr(sys, '_called_from_test'):
# Running in Travis. Run saveddata database in memory.
saveddata_connectionstring = 'sqlite:///:memory:'
else:
saveddata_connectionstring = 'sqlite:///' + unicode(realpath(join(dirname(abspath(__file__)), "..", "saveddata", "saveddata.db")), sys.getfilesystemencoding())
pyfalog.debug("Saveddata connection string: {0}", saveddata_connectionstring)
settings = { settings = {
"setting1": True "setting1": True

View File

@@ -173,7 +173,7 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
charges = 0 charges = 0
else: else:
charges = floor(containerCapacity / chargeVolume) charges = floor(containerCapacity / chargeVolume)
return charges return int(charges)
@property @property
def numShots(self): def numShots(self):

View File

@@ -1,27 +0,0 @@
__all__ = [
"openFit",
# "moduleGlobalAmmoPicker",
"moduleAmmoPicker",
"itemStats",
"damagePattern",
"marketJump",
"droneSplit",
"itemRemove",
"droneRemoveStack",
"ammoPattern",
"project",
"factorReload",
"whProjector",
"cargo",
"shipJump",
"changeAffectingSkills",
"tacticalMode",
"targetResists",
"priceClear",
"amount",
"metaSwap",
"implantSets",
"fighterAbilities",
"cargoAmmo",
"droneStack"
]

View File

@@ -1,15 +1,20 @@
from gui.contextMenu import ContextMenu from gui.contextMenu import ContextMenu
import gui.mainFrame import gui.mainFrame
import service
import gui.globalEvents as GE import gui.globalEvents as GE
import wx import wx
from service.settings import ContextMenuSettings
from service.fit import Fit
class CargoAmmo(ContextMenu): class CargoAmmo(ContextMenu):
def __init__(self): def __init__(self):
self.mainFrame = gui.mainFrame.MainFrame.getInstance() self.mainFrame = gui.mainFrame.MainFrame.getInstance()
self.settings = ContextMenuSettings.getInstance()
def display(self, srcContext, selection): def display(self, srcContext, selection):
if not self.settings.get('cargoAmmo'):
return False
if srcContext not in ("marketItemGroup", "marketItemMisc") or self.mainFrame.getActiveFit() is None: if srcContext not in ("marketItemGroup", "marketItemMisc") or self.mainFrame.getActiveFit() is None:
return False return False
@@ -23,7 +28,7 @@ class CargoAmmo(ContextMenu):
return "Add {0} to Cargo (x1000)".format(itmContext) return "Add {0} to Cargo (x1000)".format(itmContext)
def activate(self, fullContext, selection, i): def activate(self, fullContext, selection, i):
sFit = service.Fit.getInstance() sFit = Fit.getInstance()
fitID = self.mainFrame.getActiveFit() fitID = self.mainFrame.getActiveFit()
typeID = int(selection[0].ID) typeID = int(selection[0].ID)

View File

@@ -1,15 +1,20 @@
from gui.contextMenu import ContextMenu from gui.contextMenu import ContextMenu
import gui.mainFrame import gui.mainFrame
import service
import gui.globalEvents as GE import gui.globalEvents as GE
import wx import wx
from service.settings import ContextMenuSettings
from service.fit import Fit
class CargoAmmo(ContextMenu): class DroneStack(ContextMenu):
def __init__(self): def __init__(self):
self.mainFrame = gui.mainFrame.MainFrame.getInstance() self.mainFrame = gui.mainFrame.MainFrame.getInstance()
self.settings = ContextMenuSettings.getInstance()
def display(self, srcContext, selection): def display(self, srcContext, selection):
if not self.settings.get('droneStack'):
return False
if srcContext not in ("marketItemGroup", "marketItemMisc") or self.mainFrame.getActiveFit() is None: if srcContext not in ("marketItemGroup", "marketItemMisc") or self.mainFrame.getActiveFit() is None:
return False return False
@@ -25,7 +30,7 @@ class CargoAmmo(ContextMenu):
return "Add {0} to Drone Bay (x5)".format(itmContext) return "Add {0} to Drone Bay (x5)".format(itmContext)
def activate(self, fullContext, selection, i): def activate(self, fullContext, selection, i):
sFit = service.Fit.getInstance() sFit = Fit.getInstance()
fitID = self.mainFrame.getActiveFit() fitID = self.mainFrame.getActiveFit()
typeID = int(selection[0].ID) typeID = int(selection[0].ID)
@@ -34,4 +39,4 @@ class CargoAmmo(ContextMenu):
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID)) wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
CargoAmmo.register() DroneStack.register()

View File

@@ -268,9 +268,7 @@ class FittingView(d.Display):
We also refresh the fit of the new current page in case We also refresh the fit of the new current page in case
delete fit caused change in stats (projected) delete fit caused change in stats (projected)
""" """
fitID = event.fitID if event.fitID == self.getActiveFit():
if fitID == self.getActiveFit():
self.parent.DeletePage(self.parent.GetPageIndex(self)) self.parent.DeletePage(self.parent.GetPageIndex(self))
try: try:
@@ -279,7 +277,7 @@ class FittingView(d.Display):
sFit.refreshFit(self.getActiveFit()) sFit.refreshFit(self.getActiveFit())
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=self.activeFitID)) wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=self.activeFitID))
except wx._core.PyDeadObjectError: except wx._core.PyDeadObjectError:
pyfalog.warning("Caught dead object") pyfalog.error("Caught dead object")
pass pass
event.Skip() event.Skip()
@@ -485,7 +483,7 @@ class FittingView(d.Display):
self.Show(self.activeFitID is not None and self.activeFitID == event.fitID) self.Show(self.activeFitID is not None and self.activeFitID == event.fitID)
except wx._core.PyDeadObjectError: except wx._core.PyDeadObjectError:
pyfalog.warning("Caught dead object") pyfalog.error("Caught dead object")
finally: finally:
event.Skip() event.Skip()

View File

@@ -181,7 +181,7 @@ class ContextMenu(object):
# noinspection PyUnresolvedReferences # noinspection PyUnresolvedReferences
from gui.builtinContextMenus import ( # noqa: E402,F401 from gui.builtinContextMenus import ( # noqa: E402,F401
openFit, openFit,
# moduleGlobalAmmoPicker, moduleGlobalAmmoPicker,
moduleAmmoPicker, moduleAmmoPicker,
itemStats, itemStats,
damagePattern, damagePattern,
@@ -200,6 +200,8 @@ from gui.builtinContextMenus import ( # noqa: E402,F401
targetResists, targetResists,
priceClear, priceClear,
amount, amount,
cargoAmmo,
droneStack,
metaSwap, metaSwap,
implantSets, implantSets,
fighterAbilities, fighterAbilities,

View File

@@ -29,13 +29,14 @@ import gui.mainFrame
import gui.globalEvents as GE import gui.globalEvents as GE
from gui.graph import Graph from gui.graph import Graph
from gui.bitmapLoader import BitmapLoader from gui.bitmapLoader import BitmapLoader
import traceback
pyfalog = Logger(__name__) pyfalog = Logger(__name__)
try: try:
import matplotlib as mpl import matplotlib as mpl
mpl_version = int(mpl.__version__[0]) mpl_version = int(mpl.__version__[0]) or -1
if mpl_version >= 2: if mpl_version >= 2:
mpl.use('wxagg') mpl.use('wxagg')
mplImported = True mplImported = True
@@ -48,43 +49,33 @@ try:
graphFrame_enabled = True graphFrame_enabled = True
mplImported = True mplImported = True
except ImportError: except ImportError as e:
pyfalog.warning("Matplotlib failed to import. Likely missing or incompatible version.")
mpl_version = -1
Patch = mpl = Canvas = Figure = None
graphFrame_enabled = False
mplImported = False
except Exception:
# We can get exceptions deep within matplotlib. Catch those. See GH #1046
tb = traceback.format_exc()
pyfalog.critical("Exception when importing Matplotlib. Continuing without importing.")
pyfalog.critical(tb)
mpl_version = -1
Patch = mpl = Canvas = Figure = None Patch = mpl = Canvas = Figure = None
graphFrame_enabled = False graphFrame_enabled = False
mplImported = False mplImported = False
pyfalog = Logger(__name__)
class GraphFrame(wx.Frame): class GraphFrame(wx.Frame):
def __init__(self, parent, style=wx.DEFAULT_FRAME_STYLE | wx.NO_FULL_REPAINT_ON_RESIZE | wx.FRAME_FLOAT_ON_PARENT): def __init__(self, parent, style=wx.DEFAULT_FRAME_STYLE | wx.NO_FULL_REPAINT_ON_RESIZE | wx.FRAME_FLOAT_ON_PARENT):
global graphFrame_enabled global graphFrame_enabled
global mplImported global mplImported
global mpl_version
self.Patch = None
self.mpl_version = -1
try:
import matplotlib as mpl
self.mpl_version = int(mpl.__version__[0])
if self.mpl_version >= 2:
mpl.use('wxagg')
mplImported = True
else:
mplImported = False
from matplotlib.patches import Patch
self.Patch = Patch
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as Canvas
from matplotlib.figure import Figure
graphFrame_enabled = True
except ImportError:
Patch = mpl = Canvas = Figure = None
graphFrame_enabled = False
self.legendFix = False self.legendFix = False
if not graphFrame_enabled: if not graphFrame_enabled:
pyfalog.info("Problems importing matplotlib; continuing without graphs") pyfalog.warning("Matplotlib is not enabled. Skipping initialization.")
return return
try: try:
@@ -236,6 +227,8 @@ class GraphFrame(wx.Frame):
self.draw() self.draw()
def draw(self, event=None): def draw(self, event=None):
global mpl_version
values = self.getValues() values = self.getValues()
view = self.getView() view = self.getView()
self.subplot.clear() self.subplot.clear()
@@ -260,7 +253,7 @@ class GraphFrame(wx.Frame):
self.canvas.draw() self.canvas.draw()
return return
if self.mpl_version < 2: if mpl_version < 2:
if self.legendFix and len(legend) > 0: if self.legendFix and len(legend) > 0:
leg = self.subplot.legend(tuple(legend), "upper right", shadow=False) leg = self.subplot.legend(tuple(legend), "upper right", shadow=False)
for t in leg.get_texts(): for t in leg.get_texts():
@@ -276,7 +269,7 @@ class GraphFrame(wx.Frame):
for l in leg.get_lines(): for l in leg.get_lines():
l.set_linewidth(1) l.set_linewidth(1)
elif self.mpl_version >= 2: elif mpl_version >= 2:
legend2 = [] legend2 = []
legend_colors = { legend_colors = {
0: "blue", 0: "blue",

View File

@@ -1746,6 +1746,7 @@ class FitItem(SFItem.SFBrowserItem):
self.deleteFit() self.deleteFit()
def deleteFit(self, event=None): def deleteFit(self, event=None):
pyfalog.debug("Deleting ship fit.")
if self.deleted: if self.deleted:
return return
else: else:

View File

@@ -1,4 +1,4 @@
logbook logbook>=1.0.0
matplotlib matplotlib
PyYAML PyYAML
python-dateutil python-dateutil

View File

@@ -79,12 +79,14 @@ class Fit(object):
@staticmethod @staticmethod
def getAllFits(): def getAllFits():
pyfalog.debug("Fetching all fits")
fits = eos.db.getFitList() fits = eos.db.getFitList()
return fits return fits
@staticmethod @staticmethod
def getFitsWithShip(shipID): def getFitsWithShip(shipID):
""" Lists fits of shipID, used with shipBrowser """ """ Lists fits of shipID, used with shipBrowser """
pyfalog.debug("Fetching all fits for ship ID: {0}", shipID)
fits = eos.db.getFitsWithShip(shipID) fits = eos.db.getFitsWithShip(shipID)
names = [] names = []
for fit in fits: for fit in fits:
@@ -95,6 +97,7 @@ class Fit(object):
@staticmethod @staticmethod
def getBoosterFits(): def getBoosterFits():
""" Lists fits flagged as booster """ """ Lists fits flagged as booster """
pyfalog.debug("Fetching all fits flagged as a booster.")
fits = eos.db.getBoosterFits() fits = eos.db.getBoosterFits()
names = [] names = []
for fit in fits: for fit in fits:
@@ -104,10 +107,12 @@ class Fit(object):
@staticmethod @staticmethod
def countAllFits(): def countAllFits():
pyfalog.debug("Getting count of all fits.")
return eos.db.countAllFits() return eos.db.countAllFits()
@staticmethod @staticmethod
def countFitsWithShip(stuff): def countFitsWithShip(stuff):
pyfalog.debug("Getting count of all fits for: {0}", stuff)
count = eos.db.countFitsWithShip(stuff) count = eos.db.countFitsWithShip(stuff)
return count return count
@@ -117,6 +122,7 @@ class Fit(object):
return fit.modules[pos] return fit.modules[pos]
def newFit(self, shipID, name=None): def newFit(self, shipID, name=None):
pyfalog.debug("Creating new fit for ID: {0}", shipID)
try: try:
ship = es_Ship(eos.db.getItem(shipID)) ship = es_Ship(eos.db.getItem(shipID))
except ValueError: except ValueError:
@@ -133,18 +139,21 @@ class Fit(object):
@staticmethod @staticmethod
def toggleBoostFit(fitID): def toggleBoostFit(fitID):
pyfalog.debug("Toggling as booster for fit ID: {0}", fitID)
fit = eos.db.getFit(fitID) fit = eos.db.getFit(fitID)
fit.booster = not fit.booster fit.booster = not fit.booster
eos.db.commit() eos.db.commit()
@staticmethod @staticmethod
def renameFit(fitID, newName): def renameFit(fitID, newName):
pyfalog.debug("Renaming fit ({0}) to: {1}", fitID, newName)
fit = eos.db.getFit(fitID) fit = eos.db.getFit(fitID)
fit.name = newName fit.name = newName
eos.db.commit() eos.db.commit()
@staticmethod @staticmethod
def deleteFit(fitID): def deleteFit(fitID):
pyfalog.debug("Deleting fit for fit ID: {0}", fitID)
fit = eos.db.getFit(fitID) fit = eos.db.getFit(fitID)
eos.db.remove(fit) eos.db.remove(fit)
@@ -157,6 +166,7 @@ class Fit(object):
@staticmethod @staticmethod
def copyFit(fitID): def copyFit(fitID):
pyfalog.debug("Creating copy of fit ID: {0}", fitID)
fit = eos.db.getFit(fitID) fit = eos.db.getFit(fitID)
newFit = copy.deepcopy(fit) newFit = copy.deepcopy(fit)
eos.db.save(newFit) eos.db.save(newFit)
@@ -164,6 +174,7 @@ class Fit(object):
@staticmethod @staticmethod
def clearFit(fitID): def clearFit(fitID):
pyfalog.debug("Clearing fit for fit ID: {0}", fitID)
if fitID is None: if fitID is None:
return None return None
@@ -172,6 +183,7 @@ class Fit(object):
return fit return fit
def toggleFactorReload(self, fitID): def toggleFactorReload(self, fitID):
pyfalog.debug("Toggling factor reload for fit ID: {0}", fitID)
if fitID is None: if fitID is None:
return None return None
@@ -181,6 +193,7 @@ class Fit(object):
self.recalc(fit) self.recalc(fit)
def switchFit(self, fitID): def switchFit(self, fitID):
pyfalog.debug("Switching fit to fit ID: {0}", fitID)
if fitID is None: if fitID is None:
return None return None
@@ -204,6 +217,7 @@ class Fit(object):
Projected is a recursion flag that is set to reduce recursions into projected fits Projected is a recursion flag that is set to reduce recursions into projected fits
Basic is a flag to simply return the fit without any other processing Basic is a flag to simply return the fit without any other processing
""" """
pyfalog.debug("Getting fit for fit ID: {0}", fitID)
if fitID is None: if fitID is None:
return None return None
fit = eos.db.getFit(fitID) fit = eos.db.getFit(fitID)
@@ -229,6 +243,7 @@ class Fit(object):
@staticmethod @staticmethod
def searchFits(name): def searchFits(name):
pyfalog.debug("Searching for fit: {0}", name)
results = eos.db.searchFits(name) results = eos.db.searchFits(name)
fits = [] fits = []
for fit in results: for fit in results:
@@ -238,6 +253,7 @@ class Fit(object):
return fits return fits
def addImplant(self, fitID, itemID, recalc=True): def addImplant(self, fitID, itemID, recalc=True):
pyfalog.debug("Adding implant to fit ({0}) for item ID: {1}", fitID, itemID)
if fitID is None: if fitID is None:
return False return False
@@ -255,6 +271,7 @@ class Fit(object):
return True return True
def removeImplant(self, fitID, position): def removeImplant(self, fitID, position):
pyfalog.debug("Removing implant from position ({0}) for fit ID: {1}", position, fitID)
if fitID is None: if fitID is None:
return False return False
@@ -265,6 +282,7 @@ class Fit(object):
return True return True
def addBooster(self, fitID, itemID): def addBooster(self, fitID, itemID):
pyfalog.debug("Adding booster ({0}) to fit ID: {1}", itemID, fitID)
if fitID is None: if fitID is None:
return False return False
@@ -281,6 +299,7 @@ class Fit(object):
return True return True
def removeBooster(self, fitID, position): def removeBooster(self, fitID, position):
pyfalog.debug("Removing booster from position ({0}) for fit ID: {1}", position, fitID)
if fitID is None: if fitID is None:
return False return False
@@ -291,6 +310,7 @@ class Fit(object):
return True return True
def project(self, fitID, thing): def project(self, fitID, thing):
pyfalog.debug("Projecting fit ({0}) onto: {1}", fitID, thing)
if fitID is None: if fitID is None:
return return
@@ -340,6 +360,7 @@ class Fit(object):
return True return True
def addCommandFit(self, fitID, thing): def addCommandFit(self, fitID, thing):
pyfalog.debug("Projecting command fit ({0}) onto: {1}", fitID, thing)
if fitID is None: if fitID is None:
return return
@@ -359,6 +380,7 @@ class Fit(object):
return True return True
def toggleProjected(self, fitID, thing, click): def toggleProjected(self, fitID, thing, click):
pyfalog.debug("Toggling projected on fit ({0}) for: {1}", fitID, thing)
fit = eos.db.getFit(fitID) fit = eos.db.getFit(fitID)
if isinstance(thing, es_Drone): if isinstance(thing, es_Drone):
if thing.amountActive == 0 and thing.canBeApplied(fit): if thing.amountActive == 0 and thing.canBeApplied(fit):
@@ -380,6 +402,7 @@ class Fit(object):
self.recalc(fit) self.recalc(fit)
def toggleCommandFit(self, fitID, thing): def toggleCommandFit(self, fitID, thing):
pyfalog.debug("Toggle command fit ({0}) for: {1}", fitID, thing)
fit = eos.db.getFit(fitID) fit = eos.db.getFit(fitID)
commandInfo = thing.getCommandInfo(fitID) commandInfo = thing.getCommandInfo(fitID)
if commandInfo: if commandInfo:
@@ -390,6 +413,7 @@ class Fit(object):
def changeAmount(self, fitID, projected_fit, amount): def changeAmount(self, fitID, projected_fit, amount):
"""Change amount of projected fits""" """Change amount of projected fits"""
pyfalog.debug("Changing fit ({0}) for projected fit ({1}) to new amount: {2}", fitID, projected_fit.getProjectionInfo(fitID), amount)
fit = eos.db.getFit(fitID) fit = eos.db.getFit(fitID)
amount = min(20, max(1, amount)) # 1 <= a <= 20 amount = min(20, max(1, amount)) # 1 <= a <= 20
projectionInfo = projected_fit.getProjectionInfo(fitID) projectionInfo = projected_fit.getProjectionInfo(fitID)
@@ -400,6 +424,7 @@ class Fit(object):
self.recalc(fit) self.recalc(fit)
def changeActiveFighters(self, fitID, fighter, amount): def changeActiveFighters(self, fitID, fighter, amount):
pyfalog.debug("Changing active fighters ({0}) for fit ({1}) to amount: {2}", fighter.itemID, amount)
fit = eos.db.getFit(fitID) fit = eos.db.getFit(fitID)
fighter.amountActive = amount fighter.amountActive = amount
@@ -407,6 +432,7 @@ class Fit(object):
self.recalc(fit) self.recalc(fit)
def removeProjected(self, fitID, thing): def removeProjected(self, fitID, thing):
pyfalog.debug("Removing projection on fit ({0}) from: {1}", fitID, thing)
fit = eos.db.getFit(fitID) fit = eos.db.getFit(fitID)
if isinstance(thing, es_Drone): if isinstance(thing, es_Drone):
fit.projectedDrones.remove(thing) fit.projectedDrones.remove(thing)
@@ -422,6 +448,7 @@ class Fit(object):
self.recalc(fit) self.recalc(fit)
def removeCommand(self, fitID, thing): def removeCommand(self, fitID, thing):
pyfalog.debug("Removing command projection from fit ({0}) for: {1}", fitID, thing)
fit = eos.db.getFit(fitID) fit = eos.db.getFit(fitID)
del fit.__commandFits[thing.ID] del fit.__commandFits[thing.ID]
@@ -429,6 +456,7 @@ class Fit(object):
self.recalc(fit) self.recalc(fit)
def appendModule(self, fitID, itemID): def appendModule(self, fitID, itemID):
pyfalog.debug("Appending module for fit ({0}) using item: {1}", fitID, itemID)
fit = eos.db.getFit(fitID) fit = eos.db.getFit(fitID)
item = eos.db.getItem(itemID, eager=("attributes", "group.category")) item = eos.db.getItem(itemID, eager=("attributes", "group.category"))
try: try:
@@ -460,6 +488,7 @@ class Fit(object):
return None return None
def removeModule(self, fitID, position): def removeModule(self, fitID, position):
pyfalog.debug("Removing module from position ({0}) for fit ID: {1}", position, fitID)
fit = eos.db.getFit(fitID) fit = eos.db.getFit(fitID)
if fit.modules[position].isEmpty: if fit.modules[position].isEmpty:
return None return None
@@ -473,6 +502,7 @@ class Fit(object):
return numSlots != len(fit.modules) return numSlots != len(fit.modules)
def changeModule(self, fitID, position, newItemID): def changeModule(self, fitID, position, newItemID):
pyfalog.debug("Changing position of module from position ({0}) for fit ID: {1}", position, fitID)
fit = eos.db.getFit(fitID) fit = eos.db.getFit(fitID)
# Dummy it out in case the next bit fails # Dummy it out in case the next bit fails
@@ -511,6 +541,7 @@ class Fit(object):
sanity checks as opposed to the GUI View. This is different than how the sanity checks as opposed to the GUI View. This is different than how the
normal .swapModules() does things, which is mostly a blind swap. normal .swapModules() does things, which is mostly a blind swap.
""" """
pyfalog.debug("Moving cargo item to module for fit ID: {1}", fitID)
fit = eos.db.getFit(fitID) fit = eos.db.getFit(fitID)
module = fit.modules[moduleIdx] module = fit.modules[moduleIdx]
@@ -558,6 +589,7 @@ class Fit(object):
@staticmethod @staticmethod
def swapModules(fitID, src, dst): def swapModules(fitID, src, dst):
pyfalog.debug("Swapping modules from source ({0}) to destination ({1}) for fit ID: {1}", src, dst, fitID)
fit = eos.db.getFit(fitID) fit = eos.db.getFit(fitID)
# Gather modules # Gather modules
srcMod = fit.modules[src] srcMod = fit.modules[src]
@@ -577,6 +609,7 @@ class Fit(object):
This will overwrite dst! Checking for empty module must be This will overwrite dst! Checking for empty module must be
done at a higher level done at a higher level
""" """
pyfalog.debug("Cloning modules from source ({0}) to destination ({1}) for fit ID: {1}", src, dst, fitID)
fit = eos.db.getFit(fitID) fit = eos.db.getFit(fitID)
# Gather modules # Gather modules
srcMod = fit.modules[src] srcMod = fit.modules[src]
@@ -597,6 +630,7 @@ class Fit(object):
Adds cargo via typeID of item. If replace = True, we replace amount with Adds cargo via typeID of item. If replace = True, we replace amount with
given parameter, otherwise we increment given parameter, otherwise we increment
""" """
pyfalog.debug("Adding cargo ({0}) fit ID: {1}", itemID, fitID)
if fitID is None: if fitID is None:
return False return False
@@ -629,6 +663,7 @@ class Fit(object):
return True return True
def removeCargo(self, fitID, position): def removeCargo(self, fitID, position):
pyfalog.debug("Removing cargo from position ({0}) fit ID: {1}", position, fitID)
if fitID is None: if fitID is None:
return False return False
@@ -639,6 +674,7 @@ class Fit(object):
return True return True
def addFighter(self, fitID, itemID): def addFighter(self, fitID, itemID):
pyfalog.debug("Adding fighters ({0}) to fit ID: {1}", itemID, fitID)
if fitID is None: if fitID is None:
return False return False
@@ -685,6 +721,7 @@ class Fit(object):
return False return False
def removeFighter(self, fitID, i): def removeFighter(self, fitID, i):
pyfalog.debug("Removing fighters from fit ID: {0}", fitID)
fit = eos.db.getFit(fitID) fit = eos.db.getFit(fitID)
f = fit.fighters[i] f = fit.fighters[i]
fit.fighters.remove(f) fit.fighters.remove(f)
@@ -694,6 +731,7 @@ class Fit(object):
return True return True
def addDrone(self, fitID, itemID, numDronesToAdd=1): def addDrone(self, fitID, itemID, numDronesToAdd=1):
pyfalog.debug("Adding {0} drones ({1}) to fit ID: {2}", numDronesToAdd, itemID, fitID)
if fitID is None: if fitID is None:
return False return False
@@ -720,6 +758,7 @@ class Fit(object):
return False return False
def mergeDrones(self, fitID, d1, d2, projected=False): def mergeDrones(self, fitID, d1, d2, projected=False):
pyfalog.debug("Merging drones on fit ID: {0}", fitID)
if fitID is None: if fitID is None:
return False return False
@@ -746,6 +785,7 @@ class Fit(object):
@staticmethod @staticmethod
def splitDrones(fit, d, amount, l): def splitDrones(fit, d, amount, l):
pyfalog.debug("Splitting drones for fit ID: {0}", fit)
total = d.amount total = d.amount
active = d.amountActive > 0 active = d.amountActive > 0
d.amount = amount d.amount = amount
@@ -758,6 +798,7 @@ class Fit(object):
eos.db.commit() eos.db.commit()
def splitProjectedDroneStack(self, fitID, d, amount): def splitProjectedDroneStack(self, fitID, d, amount):
pyfalog.debug("Splitting projected drone stack for fit ID: {0}", fitID)
if fitID is None: if fitID is None:
return False return False
@@ -765,6 +806,7 @@ class Fit(object):
self.splitDrones(fit, d, amount, fit.projectedDrones) self.splitDrones(fit, d, amount, fit.projectedDrones)
def splitDroneStack(self, fitID, d, amount): def splitDroneStack(self, fitID, d, amount):
pyfalog.debug("Splitting drone stack for fit ID: {0}", fitID)
if fitID is None: if fitID is None:
return False return False
@@ -772,6 +814,7 @@ class Fit(object):
self.splitDrones(fit, d, amount, fit.drones) self.splitDrones(fit, d, amount, fit.drones)
def removeDrone(self, fitID, i, numDronesToRemove=1): def removeDrone(self, fitID, i, numDronesToRemove=1):
pyfalog.debug("Removing {0} drones for fit ID: {1}", numDronesToRemove, fitID)
fit = eos.db.getFit(fitID) fit = eos.db.getFit(fitID)
d = fit.drones[i] d = fit.drones[i]
d.amount -= numDronesToRemove d.amount -= numDronesToRemove
@@ -786,6 +829,7 @@ class Fit(object):
return True return True
def toggleDrone(self, fitID, i): def toggleDrone(self, fitID, i):
pyfalog.debug("Toggling drones for fit ID: {0}", fitID)
fit = eos.db.getFit(fitID) fit = eos.db.getFit(fitID)
d = fit.drones[i] d = fit.drones[i]
if d.amount == d.amountActive: if d.amount == d.amountActive:
@@ -798,6 +842,7 @@ class Fit(object):
return True return True
def toggleFighter(self, fitID, i): def toggleFighter(self, fitID, i):
pyfalog.debug("Toggling fighters for fit ID: {0}", fitID)
fit = eos.db.getFit(fitID) fit = eos.db.getFit(fitID)
f = fit.fighters[i] f = fit.fighters[i]
f.active = not f.active f.active = not f.active
@@ -807,6 +852,7 @@ class Fit(object):
return True return True
def toggleImplant(self, fitID, i): def toggleImplant(self, fitID, i):
pyfalog.debug("Toggling implant for fit ID: {0}", fitID)
fit = eos.db.getFit(fitID) fit = eos.db.getFit(fitID)
implant = fit.implants[i] implant = fit.implants[i]
implant.active = not implant.active implant.active = not implant.active
@@ -816,6 +862,7 @@ class Fit(object):
return True return True
def toggleImplantSource(self, fitID, source): def toggleImplantSource(self, fitID, source):
pyfalog.debug("Toggling implant source for fit ID: {0}", fitID)
fit = eos.db.getFit(fitID) fit = eos.db.getFit(fitID)
fit.implantSource = source fit.implantSource = source
@@ -824,6 +871,7 @@ class Fit(object):
return True return True
def toggleBooster(self, fitID, i): def toggleBooster(self, fitID, i):
pyfalog.debug("Toggling booster for fit ID: {0}", fitID)
fit = eos.db.getFit(fitID) fit = eos.db.getFit(fitID)
booster = fit.boosters[i] booster = fit.boosters[i]
booster.active = not booster.active booster.active = not booster.active
@@ -833,12 +881,14 @@ class Fit(object):
return True return True
def toggleFighterAbility(self, fitID, ability): def toggleFighterAbility(self, fitID, ability):
pyfalog.debug("Toggling fighter ability for fit ID: {0}", fitID)
fit = eos.db.getFit(fitID) fit = eos.db.getFit(fitID)
ability.active = not ability.active ability.active = not ability.active
eos.db.commit() eos.db.commit()
self.recalc(fit) self.recalc(fit)
def changeChar(self, fitID, charID): def changeChar(self, fitID, charID):
pyfalog.debug("Changing character ({0}) for fit ID: {1}", charID, fitID)
if fitID is None or charID is None: if fitID is None or charID is None:
if charID is not None: if charID is not None:
self.character = Character.getInstance().all5() self.character = Character.getInstance().all5()
@@ -854,6 +904,7 @@ class Fit(object):
return eos.db.getItem(itemID).category.name == "Charge" return eos.db.getItem(itemID).category.name == "Charge"
def setAmmo(self, fitID, ammoID, modules): def setAmmo(self, fitID, ammoID, modules):
pyfalog.debug("Set ammo for fit ID: {0}", fitID)
if fitID is None: if fitID is None:
return return
@@ -868,6 +919,7 @@ class Fit(object):
@staticmethod @staticmethod
def getTargetResists(fitID): def getTargetResists(fitID):
pyfalog.debug("Get target resists for fit ID: {0}", fitID)
if fitID is None: if fitID is None:
return return
@@ -875,6 +927,7 @@ class Fit(object):
return fit.targetResists return fit.targetResists
def setTargetResists(self, fitID, pattern): def setTargetResists(self, fitID, pattern):
pyfalog.debug("Set target resist for fit ID: {0}", fitID)
if fitID is None: if fitID is None:
return return
@@ -886,6 +939,7 @@ class Fit(object):
@staticmethod @staticmethod
def getDamagePattern(fitID): def getDamagePattern(fitID):
pyfalog.debug("Get damage pattern for fit ID: {0}", fitID)
if fitID is None: if fitID is None:
return return
@@ -893,6 +947,7 @@ class Fit(object):
return fit.damagePattern return fit.damagePattern
def setDamagePattern(self, fitID, pattern): def setDamagePattern(self, fitID, pattern):
pyfalog.debug("Set damage pattern for fit ID: {0}", fitID)
if fitID is None: if fitID is None:
return return
@@ -903,6 +958,7 @@ class Fit(object):
self.recalc(fit) self.recalc(fit)
def setMode(self, fitID, mode): def setMode(self, fitID, mode):
pyfalog.debug("Set mode for fit ID: {0}", fitID)
if fitID is None: if fitID is None:
return return
@@ -913,6 +969,7 @@ class Fit(object):
self.recalc(fit) self.recalc(fit)
def setAsPattern(self, fitID, ammo): def setAsPattern(self, fitID, ammo):
pyfalog.debug("Set as pattern for fit ID: {0}", fitID)
if fitID is None: if fitID is None:
return return
@@ -930,6 +987,7 @@ class Fit(object):
self.recalc(fit) self.recalc(fit)
def checkStates(self, fit, base): def checkStates(self, fit, base):
pyfalog.debug("Check states for fit ID: {0}", fit)
changed = False changed = False
for mod in fit.modules: for mod in fit.modules:
if mod != base: if mod != base:
@@ -954,6 +1012,7 @@ class Fit(object):
self.recalc(fit) self.recalc(fit)
def toggleModulesState(self, fitID, base, modules, click): def toggleModulesState(self, fitID, base, modules, click):
pyfalog.debug("Toggle module state for fit ID: {0}", fitID)
changed = False changed = False
proposedState = self.__getProposedState(base, click) proposedState = self.__getProposedState(base, click)
@@ -993,6 +1052,7 @@ class Fit(object):
State.ONLINE: State.OFFLINE} State.ONLINE: State.OFFLINE}
def __getProposedState(self, mod, click, proposedState=None): def __getProposedState(self, mod, click, proposedState=None):
pyfalog.debug("Get proposed state for module.")
if mod.slot == Slot.SUBSYSTEM or mod.isEmpty: if mod.slot == Slot.SUBSYSTEM or mod.isEmpty:
return State.ONLINE return State.ONLINE
@@ -1020,6 +1080,7 @@ class Fit(object):
return currState return currState
def refreshFit(self, fitID): def refreshFit(self, fitID):
pyfalog.debug("Refresh fit for fit ID: {0}", fitID)
if fitID is None: if fitID is None:
return None return None

View File

@@ -29,7 +29,8 @@ pyfalog = Logger(__name__)
class SettingsProvider(object): class SettingsProvider(object):
BASE_PATH = os.path.join(config.savePath, 'settings') if config.savePath:
BASE_PATH = os.path.join(config.savePath, 'settings')
settings = {} settings = {}
_instance = None _instance = None
@@ -41,13 +42,15 @@ class SettingsProvider(object):
return cls._instance return cls._instance
def __init__(self): def __init__(self):
if not os.path.exists(self.BASE_PATH): if hasattr(self, 'BASE_PATH'):
os.mkdir(self.BASE_PATH) if not os.path.exists(self.BASE_PATH):
os.mkdir(self.BASE_PATH)
def getSettings(self, area, defaults=None): def getSettings(self, area, defaults=None):
s = self.settings.get(area) s = self.settings.get(area)
if s is None:
if s is None and hasattr(self, 'BASE_PATH'):
p = os.path.join(self.BASE_PATH, area) p = os.path.join(self.BASE_PATH, area)
if not os.path.exists(p): if not os.path.exists(p):
@@ -71,6 +74,8 @@ class SettingsProvider(object):
info[item] = defaults[item] info[item] = defaults[item]
self.settings[area] = s = Settings(p, info) self.settings[area] = s = Settings(p, info)
else:
s = None
return s return s
@@ -408,14 +413,17 @@ class ContextMenuSettings(object):
"ammoPattern" : 1, "ammoPattern" : 1,
"amount" : 1, "amount" : 1,
"cargo" : 1, "cargo" : 1,
"cargoAmmo" : 1,
"changeAffectingSkills" : 1, "changeAffectingSkills" : 1,
"damagePattern" : 1, "damagePattern" : 1,
"droneRemoveStack" : 1, "droneRemoveStack" : 1,
"droneSplit" : 1, "droneSplit" : 1,
"droneStack" : 1,
"factorReload" : 1, "factorReload" : 1,
"fighterAbilities" : 1, "fighterAbilities" : 1,
"implantSet" : 1, "implantSets" : 1,
"itemStats" : 1, "itemStats" : 1,
"itemRemove" : 1,
"marketJump" : 1, "marketJump" : 1,
"metaSwap" : 1, "metaSwap" : 1,
"moduleAmmoPicker" : 1, "moduleAmmoPicker" : 1,

View File

@@ -1,9 +0,0 @@
from gui.aboutData import versionString, licenses, developers, credits, description
def test_aboutData():
assert versionString.__len__() > 0
assert licenses.__len__() > 0
assert developers.__len__() > 0
assert credits.__len__() > 0
assert description.__len__() > 0

View File

@@ -0,0 +1,17 @@
# Add root folder to python paths
# This must be done on every test in order to pass in Travis
import os
import sys
script_dir = os.path.dirname(os.path.abspath(__file__))
sys.path.append(os.path.realpath(os.path.join(script_dir, '..', '..', '..')))
# noinspection PyPackageRequirements
from _development.helpers import DBInMemory as DB, Gamedata, Saveddata
from _development.helpers_fits import RifterFit, KeepstarFit
def test_race(DB, RifterFit, KeepstarFit):
"""
Test race code
"""
assert RifterFit.ship.item.race == 'minmatar'
assert KeepstarFit.ship.item.race == 'upwell'

View File

@@ -0,0 +1,50 @@
# Add root folder to python paths
# This must be done on every test in order to pass in Travis
import math
import os
import sys
script_dir = os.path.dirname(os.path.abspath(__file__))
script_dir = os.path.realpath(os.path.join(script_dir, '..', '..', '..'))
print script_dir
sys.path.append(script_dir)
# noinspection PyPackageRequirements
from _development.helpers import DBInMemory as DB, Gamedata, Saveddata
from _development.helpers_fits import RifterFit
def test_multiply_stacking_penalties(DB, Saveddata, RifterFit):
"""
Tests the stacking penalties under multiply
"""
char0 = Saveddata['Character'].getAll0()
RifterFit.character = char0
starting_em_resist = RifterFit.ship.getModifiedItemAttr("shieldEmDamageResonance")
mod = Saveddata['Module'](DB['db'].getItem("EM Ward Amplifier II"))
item_modifer = mod.item.getAttribute("emDamageResistanceBonus")
RifterFit.calculateModifiedAttributes()
for _ in range(10):
if _ == 0:
# First run we have no modules, se don't try and calculate them.
calculated_resist = RifterFit.ship.getModifiedItemAttr("shieldEmDamageResonance")
else:
# Calculate what our next resist should be
# Denominator: [math.exp((i / 2.67) ** 2.0) for i in xrange(8)]
current_effectiveness = 1 / math.exp(((_ - 1) / 2.67) ** 2.0)
new_item_modifier = 1 + ((item_modifer * current_effectiveness) / 100)
calculated_resist = (em_resist * new_item_modifier)
# Add another resist module to our fit.
RifterFit.modules.append(mod)
# Modify our fit so that Eos generates new numbers for us.
RifterFit.clear()
RifterFit.calculateModifiedAttributes()
em_resist = RifterFit.ship.getModifiedItemAttr("shieldEmDamageResonance")
assert em_resist == calculated_resist
# print(str(em_resist) + "==" + str(calculated_resist))

View File

@@ -0,0 +1,19 @@
# Add root folder to python paths
# This must be done on every test in order to pass in Travis
import os
import sys
script_dir = os.path.dirname(os.path.abspath(__file__))
sys.path.append(os.path.realpath(os.path.join(script_dir, '..', '..', '..')))
from gui.aboutData import versionString, licenses, developers, credits, description
def test_aboutData():
"""
Simple test to validate all about data exists
"""
assert versionString.__len__() > 0
assert licenses.__len__() > 0
assert developers.__len__() > 0
assert credits.__len__() > 0
assert description.__len__() > 0

View File

@@ -1,9 +1,16 @@
# Add root folder to python paths
# This must be done on every test in order to pass in Travis
import os
import sys
script_dir = os.path.dirname(os.path.abspath(__file__))
sys.path.append(os.path.realpath(os.path.join(script_dir, '..', '..', '..')))
from service.attribute import Attribute from service.attribute import Attribute
def test_attribute(): def test_attribute():
""" """
We don't really have much to test here, to throw a generic attribute at it and validate we get the expected results We don't really have much to test here, so throw a generic attribute at it and validate we get the expected results
:return: :return:
""" """

View File

@@ -0,0 +1,36 @@
# Add root folder to python paths
# This must be done on every test in order to pass in Travis
import os
import sys
script_dir = os.path.dirname(os.path.abspath(__file__))
sys.path.append(os.path.realpath(os.path.join(script_dir, '..', '..', '..')))
# noinspection PyPackageRequirements
from _development.helpers import DBInMemory as DB, Gamedata, Saveddata
# noinspection PyPackageRequirements
from _development.helpers_fits import RifterFit, KeepstarFit
from service.fit import Fit
# Fake import wx
from types import ModuleType
wx = ModuleType("fake_module")
sys.modules[wx.__name__] = wx
def test_getAllFits(DB, RifterFit, KeepstarFit):
assert len(Fit.getAllFits()) == 0
DB['db'].save(RifterFit)
assert len(Fit.getAllFits()) == 1
DB['db'].save(KeepstarFit)
assert len(Fit.getAllFits()) == 2
# Cleanup after ourselves
DB['db'].remove(RifterFit)
DB['db'].remove(KeepstarFit)
def test_getFitsWithShip_RifterFit(DB, RifterFit):
DB['db'].save(RifterFit)
assert Fit.getFitsWithShip(587)[0][1] == 'My Rifter Fit'
DB['db'].remove(RifterFit)

View File

@@ -1,58 +0,0 @@
"""import tests."""
import os
import sys
# import importlib
# noinspection PyPackageRequirements
# import pytest
script_dir = os.path.dirname(os.path.abspath(__file__))
# Add root to python paths, this allows us to import submodules
sys.path.append(os.path.realpath(os.path.join(script_dir, '..')))
# noinspection PyPep8
import service
# noinspection PyPep8
import gui
# noinspection PyPep8
import eos
# noinspection PyPep8
import utils
def test_packages():
assert service
assert gui
assert eos
assert utils
def service_modules():
for root, folders, files in os.walk("service"):
for file_ in files:
if file_.endswith(".py") and not file_.startswith("_"):
mod_name = "{}.{}".format(
root.replace("/", "."),
file_.split(".py")[0],
)
yield mod_name
def eos_modules():
for root, folders, files in os.walk("eos"):
for file_ in files:
if file_.endswith(".py") and not file_.startswith("_"):
mod_name = "{}.{}".format(
root.replace("/", "."),
file_.split(".py")[0],
)
yield mod_name
# TODO: Disable walk through Eos paths until eos.types is killed. eos.types causes the import to break
'''
@pytest.mark.parametrize("mod_name", eos_modules())
def test_eos_imports(mod_name):
assert importlib.import_module(mod_name)
'''

View File

@@ -0,0 +1,235 @@
# Add root folder to python paths
# This must be done on every test in order to pass in Travis
import os
import sys
script_dir = os.path.dirname(os.path.abspath(__file__))
sys.path.append(os.path.realpath(os.path.join(script_dir, '..', '..')))
# noinspection PyPackageRequirements
from _development.helpers import DBInMemory as DB, Gamedata, Saveddata
from _development.helpers_fits import RifterFit
# noinspection PyShadowingNames
def test_rifter_empty_char0(DB, Saveddata, RifterFit):
"""
We test an empty ship because if we use this as a base for testing our V skills,
and CCP ever fucks with the base states, all our derived stats will be wrong.
"""
char0 = Saveddata['Character'].getAll0()
RifterFit.character = char0
RifterFit.calculateModifiedAttributes()
assert RifterFit.ship.getModifiedItemAttr("agility") == 3.2
assert RifterFit.ship.getModifiedItemAttr("armorEmDamageResonance") == 0.4
assert RifterFit.ship.getModifiedItemAttr("armorExplosiveDamageResonance") == 0.9
assert RifterFit.ship.getModifiedItemAttr("armorHP") == 450.0
assert RifterFit.ship.getModifiedItemAttr("armorKineticDamageResonance") == 0.75
assert RifterFit.ship.getModifiedItemAttr("armorThermalDamageResonance") == 0.65
assert RifterFit.ship.getModifiedItemAttr("armorUniformity") == 0.75
assert RifterFit.ship.getModifiedItemAttr("baseWarpSpeed") == 1.0
assert RifterFit.ship.getModifiedItemAttr("capacitorCapacity") == 250.0
assert RifterFit.ship.getModifiedItemAttr("capacity") == 140.0
assert RifterFit.ship.getModifiedItemAttr("cpuLoad") == 0.0
assert RifterFit.ship.getModifiedItemAttr("cpuOutput") == 130.0
assert RifterFit.ship.getModifiedItemAttr("damage") == 0.0
assert RifterFit.ship.getModifiedItemAttr("droneBandwidth") == 0.0
assert RifterFit.ship.getModifiedItemAttr("droneCapacity") == 0.0
assert RifterFit.ship.getModifiedItemAttr("emDamageResonance") == 0.67
assert RifterFit.ship.getModifiedItemAttr("explosiveDamageResonance") == 0.67
assert RifterFit.ship.getModifiedItemAttr("fwLpKill") == 25.0
assert RifterFit.ship.getModifiedItemAttr("gfxBoosterID") == 397.0
assert RifterFit.ship.getModifiedItemAttr("heatAttenuationHi") == 0.63
assert RifterFit.ship.getModifiedItemAttr("heatAttenuationLow") == 0.5
assert RifterFit.ship.getModifiedItemAttr("heatAttenuationMed") == 0.5
assert RifterFit.ship.getModifiedItemAttr("heatCapacityHi") == 100.0
assert RifterFit.ship.getModifiedItemAttr("heatCapacityLow") == 100.0
assert RifterFit.ship.getModifiedItemAttr("heatCapacityMed") == 100.0
assert RifterFit.ship.getModifiedItemAttr("heatDissipationRateHi") == 0.01
assert RifterFit.ship.getModifiedItemAttr("heatDissipationRateLow") == 0.01
assert RifterFit.ship.getModifiedItemAttr("heatDissipationRateMed") == 0.01
assert RifterFit.ship.getModifiedItemAttr("heatGenerationMultiplier") == 1.0
assert RifterFit.ship.getModifiedItemAttr("hiSlots") == 4.0
assert RifterFit.ship.getModifiedItemAttr("hp") == 350.0
assert RifterFit.ship.getModifiedItemAttr("hullEmDamageResonance") == 1.0
assert RifterFit.ship.getModifiedItemAttr("hullExplosiveDamageResonance") == 1.0
assert RifterFit.ship.getModifiedItemAttr("hullKineticDamageResonance") == 1.0
assert RifterFit.ship.getModifiedItemAttr("hullThermalDamageResonance") == 1.0
assert RifterFit.ship.getModifiedItemAttr("kineticDamageResonance") == 0.67
assert RifterFit.ship.getModifiedItemAttr("launcherSlotsLeft") == 2.0
assert RifterFit.ship.getModifiedItemAttr("lowSlots") == 3.0
assert RifterFit.ship.getModifiedItemAttr("mainColor") == 16777215.0
assert RifterFit.ship.getModifiedItemAttr("mass") == 1067000.0
assert RifterFit.ship.getModifiedItemAttr("maxDirectionalVelocity") == 3000.0
assert RifterFit.ship.getModifiedItemAttr("maxLockedTargets") == 4.0
assert RifterFit.ship.getModifiedItemAttr("maxPassengers") == 2.0
assert RifterFit.ship.getModifiedItemAttr("maxTargetRange") == 22500.0
assert RifterFit.ship.getModifiedItemAttr("maxVelocity") == 365.0
assert RifterFit.ship.getModifiedItemAttr("medSlots") == 3.0
assert RifterFit.ship.getModifiedItemAttr("metaLevel") == 0.0
assert RifterFit.ship.getModifiedItemAttr("minTargetVelDmgMultiplier") == 0.05
assert RifterFit.ship.getModifiedItemAttr("powerLoad") == 0.0
assert RifterFit.ship.getModifiedItemAttr("powerOutput") == 41.0
assert RifterFit.ship.getModifiedItemAttr("powerToSpeed") == 1.0
assert RifterFit.ship.getModifiedItemAttr("propulsionGraphicID") == 397.0
assert RifterFit.ship.getModifiedItemAttr("radius") == 31.0
assert RifterFit.ship.getModifiedItemAttr("rechargeRate") == 125000.0
assert RifterFit.ship.getModifiedItemAttr("requiredSkill1") == 3329.0
assert RifterFit.ship.getModifiedItemAttr("requiredSkill1Level") == 1.0
assert RifterFit.ship.getModifiedItemAttr("rigSize") == 1.0
assert RifterFit.ship.getModifiedItemAttr("rigSlots") == 3.0
assert RifterFit.ship.getModifiedItemAttr("scanGravimetricStrength") == 0.0
assert RifterFit.ship.getModifiedItemAttr("scanLadarStrength") == 8.0
assert RifterFit.ship.getModifiedItemAttr("scanMagnetometricStrength") == 0.0
assert RifterFit.ship.getModifiedItemAttr("scanRadarStrength") == 0.0
assert RifterFit.ship.getModifiedItemAttr("scanResolution") == 660.0
assert RifterFit.ship.getModifiedItemAttr("scanSpeed") == 1500.0
assert RifterFit.ship.getModifiedItemAttr("shieldCapacity") == 450.0
assert RifterFit.ship.getModifiedItemAttr("shieldEmDamageResonance") == 1.0
assert RifterFit.ship.getModifiedItemAttr("shieldExplosiveDamageResonance") == 0.5
assert RifterFit.ship.getModifiedItemAttr("shieldKineticDamageResonance") == 0.6
assert RifterFit.ship.getModifiedItemAttr("shieldRechargeRate") == 625000.0
assert RifterFit.ship.getModifiedItemAttr("shieldThermalDamageResonance") == 0.8
assert RifterFit.ship.getModifiedItemAttr("shieldUniformity") == 0.75
assert RifterFit.ship.getModifiedItemAttr("shipBonusMF") == 5.0
assert RifterFit.ship.getModifiedItemAttr("shipBonusMF2") == 10.0
assert RifterFit.ship.getModifiedItemAttr("shipScanResistance") == 0.0
assert RifterFit.ship.getModifiedItemAttr("signatureRadius") == 35.0
assert RifterFit.ship.getModifiedItemAttr("structureUniformity") == 1.0
assert RifterFit.ship.getModifiedItemAttr("techLevel") == 1.0
assert RifterFit.ship.getModifiedItemAttr("thermalDamageResonance") == 0.67
assert RifterFit.ship.getModifiedItemAttr("turretSlotsLeft") == 3.0
assert RifterFit.ship.getModifiedItemAttr("typeColorScheme") == 11342.0
assert RifterFit.ship.getModifiedItemAttr("uniformity") == 1.0
assert RifterFit.ship.getModifiedItemAttr("upgradeCapacity") == 400.0
assert RifterFit.ship.getModifiedItemAttr("upgradeSlotsLeft") == 3.0
assert RifterFit.ship.getModifiedItemAttr("volume") == 27289.0
assert RifterFit.ship.getModifiedItemAttr("warpCapacitorNeed") == 2.24e-06
assert RifterFit.ship.getModifiedItemAttr("warpFactor") == 0.0
assert RifterFit.ship.getModifiedItemAttr("warpSpeedMultiplier") == 5.0
# noinspection PyShadowingNames
def test_rifter_empty_char5(DB, Saveddata, RifterFit):
"""
Test char skills applying to a ship
"""
char5 = Saveddata['Character'].getAll5()
RifterFit.character = char5
RifterFit.calculateModifiedAttributes()
assert RifterFit.ship.getModifiedItemAttr("agility") == 2.16
assert RifterFit.ship.getModifiedItemAttr("armorEmDamageResonance") == 0.4
assert RifterFit.ship.getModifiedItemAttr("armorExplosiveDamageResonance") == 0.9
assert RifterFit.ship.getModifiedItemAttr("armorHP") == 562.5
assert RifterFit.ship.getModifiedItemAttr("armorKineticDamageResonance") == 0.75
assert RifterFit.ship.getModifiedItemAttr("armorThermalDamageResonance") == 0.65
assert RifterFit.ship.getModifiedItemAttr("armorUniformity") == 0.75
assert RifterFit.ship.getModifiedItemAttr("baseWarpSpeed") == 1.0
assert RifterFit.ship.getModifiedItemAttr("capacitorCapacity") == 312.5
assert RifterFit.ship.getModifiedItemAttr("capacity") == 140.0
assert RifterFit.ship.getModifiedItemAttr("cpuLoad") == 0.0
assert RifterFit.ship.getModifiedItemAttr("cpuOutput") == 162.5
assert RifterFit.ship.getModifiedItemAttr("damage") == 0.0
assert RifterFit.ship.getModifiedItemAttr("droneBandwidth") == 0.0
assert RifterFit.ship.getModifiedItemAttr("droneCapacity") == 0.0
assert RifterFit.ship.getModifiedItemAttr("emDamageResonance") == 0.67
assert RifterFit.ship.getModifiedItemAttr("explosiveDamageResonance") == 0.67
assert RifterFit.ship.getModifiedItemAttr("fwLpKill") == 25.0
assert RifterFit.ship.getModifiedItemAttr("gfxBoosterID") == 397.0
assert RifterFit.ship.getModifiedItemAttr("heatAttenuationHi") == 0.63
assert RifterFit.ship.getModifiedItemAttr("heatAttenuationLow") == 0.5
assert RifterFit.ship.getModifiedItemAttr("heatAttenuationMed") == 0.5
assert RifterFit.ship.getModifiedItemAttr("heatCapacityHi") == 100.0
assert RifterFit.ship.getModifiedItemAttr("heatCapacityLow") == 100.0
assert RifterFit.ship.getModifiedItemAttr("heatCapacityMed") == 100.0
assert RifterFit.ship.getModifiedItemAttr("heatDissipationRateHi") == 0.01
assert RifterFit.ship.getModifiedItemAttr("heatDissipationRateLow") == 0.01
assert RifterFit.ship.getModifiedItemAttr("heatDissipationRateMed") == 0.01
assert RifterFit.ship.getModifiedItemAttr("heatGenerationMultiplier") == 1.0
assert RifterFit.ship.getModifiedItemAttr("hiSlots") == 4.0
assert RifterFit.ship.getModifiedItemAttr("hp") == 437.5
assert RifterFit.ship.getModifiedItemAttr("hullEmDamageResonance") == 1.0
assert RifterFit.ship.getModifiedItemAttr("hullExplosiveDamageResonance") == 1.0
assert RifterFit.ship.getModifiedItemAttr("hullKineticDamageResonance") == 1.0
assert RifterFit.ship.getModifiedItemAttr("hullThermalDamageResonance") == 1.0
assert RifterFit.ship.getModifiedItemAttr("kineticDamageResonance") == 0.67
assert RifterFit.ship.getModifiedItemAttr("launcherSlotsLeft") == 2.0
assert RifterFit.ship.getModifiedItemAttr("lowSlots") == 3.0
assert RifterFit.ship.getModifiedItemAttr("mainColor") == 16777215.0
assert RifterFit.ship.getModifiedItemAttr("mass") == 1067000.0
assert RifterFit.ship.getModifiedItemAttr("maxDirectionalVelocity") == 3000.0
assert RifterFit.ship.getModifiedItemAttr("maxLockedTargets") == 4.0
assert RifterFit.ship.getModifiedItemAttr("maxPassengers") == 2.0
assert RifterFit.ship.getModifiedItemAttr("maxTargetRange") == 28125.0
assert RifterFit.ship.getModifiedItemAttr("maxVelocity") == 456.25
assert RifterFit.ship.getModifiedItemAttr("medSlots") == 3.0
assert RifterFit.ship.getModifiedItemAttr("metaLevel") == 0.0
assert RifterFit.ship.getModifiedItemAttr("minTargetVelDmgMultiplier") == 0.05
assert RifterFit.ship.getModifiedItemAttr("powerLoad") == 0.0
assert RifterFit.ship.getModifiedItemAttr("powerOutput") == 51.25
assert RifterFit.ship.getModifiedItemAttr("powerToSpeed") == 1.0
assert RifterFit.ship.getModifiedItemAttr("propulsionGraphicID") == 397.0
assert RifterFit.ship.getModifiedItemAttr("radius") == 31.0
assert RifterFit.ship.getModifiedItemAttr("rechargeRate") == 93750.0
assert RifterFit.ship.getModifiedItemAttr("requiredSkill1") == 3329.0
assert RifterFit.ship.getModifiedItemAttr("requiredSkill1Level") == 1.0
assert RifterFit.ship.getModifiedItemAttr("rigSize") == 1.0
assert RifterFit.ship.getModifiedItemAttr("rigSlots") == 3.0
assert RifterFit.ship.getModifiedItemAttr("scanGravimetricStrength") == 0.0
assert RifterFit.ship.getModifiedItemAttr("scanLadarStrength") == 9.6
assert RifterFit.ship.getModifiedItemAttr("scanMagnetometricStrength") == 0.0
assert RifterFit.ship.getModifiedItemAttr("scanRadarStrength") == 0.0
assert RifterFit.ship.getModifiedItemAttr("scanResolution") == 825.0
assert RifterFit.ship.getModifiedItemAttr("scanSpeed") == 1500.0
assert RifterFit.ship.getModifiedItemAttr("shieldCapacity") == 562.5
assert RifterFit.ship.getModifiedItemAttr("shieldEmDamageResonance") == 1.0
assert RifterFit.ship.getModifiedItemAttr("shieldExplosiveDamageResonance") == 0.5
assert RifterFit.ship.getModifiedItemAttr("shieldKineticDamageResonance") == 0.6
assert RifterFit.ship.getModifiedItemAttr("shieldRechargeRate") == 468750.0
assert RifterFit.ship.getModifiedItemAttr("shieldThermalDamageResonance") == 0.8
assert RifterFit.ship.getModifiedItemAttr("shieldUniformity") == 1
assert RifterFit.ship.getModifiedItemAttr("shipBonusMF") == 5.0
assert RifterFit.ship.getModifiedItemAttr("shipBonusMF2") == 10.0
assert RifterFit.ship.getModifiedItemAttr("shipScanResistance") == 0.0
assert RifterFit.ship.getModifiedItemAttr("signatureRadius") == 35.0
assert RifterFit.ship.getModifiedItemAttr("structureUniformity") == 1.0
assert RifterFit.ship.getModifiedItemAttr("techLevel") == 1.0
assert RifterFit.ship.getModifiedItemAttr("thermalDamageResonance") == 0.67
assert RifterFit.ship.getModifiedItemAttr("turretSlotsLeft") == 3.0
assert RifterFit.ship.getModifiedItemAttr("typeColorScheme") == 11342.0
assert RifterFit.ship.getModifiedItemAttr("uniformity") == 1.0
assert RifterFit.ship.getModifiedItemAttr("upgradeCapacity") == 400.0
assert RifterFit.ship.getModifiedItemAttr("upgradeSlotsLeft") == 3.0
assert RifterFit.ship.getModifiedItemAttr("volume") == 27289.0
assert RifterFit.ship.getModifiedItemAttr("warpCapacitorNeed") == 1.12e-06
assert RifterFit.ship.getModifiedItemAttr("warpFactor") == 0.0
assert RifterFit.ship.getModifiedItemAttr("warpSpeedMultiplier") == 5.0
# noinspection PyShadowingNames
def test_rifter_coprocessor(DB, Saveddata, RifterFit):
char5 = Saveddata['Character'].getAll5()
char0 = Saveddata['Character'].getAll0()
RifterFit.character = char0
mod = Saveddata['Module'](DB['db'].getItem("Co-Processor II"))
mod.state = Saveddata['State'].OFFLINE
RifterFit.modules.append(mod)
assert RifterFit.ship.getModifiedItemAttr("cpuOutput") == 130
RifterFit.calculateModifiedAttributes()
assert RifterFit.ship.getModifiedItemAttr("cpuOutput") == 130
mod.state = Saveddata['State'].ONLINE
RifterFit.clear()
RifterFit.calculateModifiedAttributes()
assert RifterFit.ship.getModifiedItemAttr("cpuOutput") == 143
RifterFit.character = char5
RifterFit.clear()
RifterFit.calculateModifiedAttributes()
assert RifterFit.ship.getModifiedItemAttr("cpuOutput") == 178.75