diff --git a/.github/workflows/python-app.yml b/.github/workflows/python-app.yml index 3348e0b..0c11503 100644 --- a/.github/workflows/python-app.yml +++ b/.github/workflows/python-app.yml @@ -32,5 +32,4 @@ jobs: pip install pytest==8.2.1 pip install -e . - name: Test with pytest - run: | - python run_all_tests.py && pytest + run: pytest diff --git a/isthisstockgood/Active/MSNMoney.py b/isthisstockgood/Active/MSNMoney.py index fbfc9ed..26482c8 100644 --- a/isthisstockgood/Active/MSNMoney.py +++ b/isthisstockgood/Active/MSNMoney.py @@ -1,6 +1,8 @@ import json import isthisstockgood.RuleOneInvestingCalculations as RuleOne + + class MSNMoney: # This key appears to be fixed? So we can use it for now /shrug _API_KEY = '0QfOX3Vn51YCzitbLaRkTTBadtWpgTN8NZLW0C1SEM' @@ -78,7 +80,7 @@ def parse_annual_report_data(self, content): most_recent_statement = annual_statements[max(annual_statements.keys())] if not most_recent_statement: return - self.total_debt = str(float(most_recent_statement.get('longTermDebt', 0))) + self.total_debt = float(most_recent_statement.get('longTermDebt', 0)) self.shares_outstanding = float(most_recent_statement.get('sharesOutstanding', 0)) key_metrics = data.get('analysis', {}).get('keyMetrics', {}) @@ -92,7 +94,7 @@ def parse_ratios_data(self, content): return False self.name = json_content.get('displayName', '') - self.industy = json_content.get('industry', '') + self.industry = json_content.get('industry', '') # PE Ratios self._parse_pe_ratios(yearly_data) diff --git a/isthisstockgood/CompanyInfo.py b/isthisstockgood/CompanyInfo.py new file mode 100644 index 0000000..38be852 --- /dev/null +++ b/isthisstockgood/CompanyInfo.py @@ -0,0 +1,28 @@ +from dataclasses import dataclass + + +@dataclass +class CompanyInfo: + ticker_symbol: str + name: str + description: str + industry: str + current_price: float + average_volume: float + market_cap: float + shares_outstanding: int + pe_high: float + pe_low: float + roic: float + roic_averages: [float] + equity: float + equity_growth_rates: [float] + free_cash_flow: float + free_cash_flow_growth_rates: [float] + revenue: float + revenue_growth_rates: [float] + eps: float + eps_growth_rates: [float] + debt_equity_ratio: float + last_year_net_income: float + total_debt: float diff --git a/run_all_tests.py b/run_all_tests.py deleted file mode 100644 index 27c5eed..0000000 --- a/run_all_tests.py +++ /dev/null @@ -1,18 +0,0 @@ -#!/usr/bin/env python - -"""Gathers all tests in the /tests/ subdirectory and runs them.""" -import os -import unittest - - -def main(): - # Execute all tests. - test_loader = unittest.TestLoader() - tests_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'tests') - test_suite = test_loader.discover(tests_dir, '*.py') - test_runner = unittest.TextTestRunner() - test_runner.run(test_suite) - - -if __name__ == '__main__': - main() diff --git a/tests/__init__.py b/tests/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/tests/test_DataSources.py b/tests/test_DataSources.py new file mode 100644 index 0000000..e07e190 --- /dev/null +++ b/tests/test_DataSources.py @@ -0,0 +1,70 @@ +from isthisstockgood.CompanyInfo import CompanyInfo +from isthisstockgood.DataFetcher import DataFetcher + + +def test_msn_money(): + test_ticker = 'MSFT' + test_name = 'Microsoft Corp' + + data = get_msn_money_data(test_ticker) + + assert data.ticker_symbol == test_ticker + assert data.name == test_name + assert data.description != '' + assert data.industry != '' + assert data.current_price > 0.0 + assert data.average_volume > 0 + assert data.market_cap > 0.0 + assert data.shares_outstanding > 0 + assert data.pe_high > 0.0 + assert data.pe_low > 0.0 + assert data.roic != [] + assert data.roic_averages != [] + assert data.equity != [] + assert data.equity_growth_rates != [] + assert data.free_cash_flow != [] + assert data.free_cash_flow_growth_rates != [] + assert data.revenue != [] + assert data.revenue_growth_rates != [] + assert data.eps != [] + assert data.eps_growth_rates != [] + assert data.debt_equity_ratio > 0.0 + assert data.last_year_net_income > 0.0 + assert data.total_debt >= 0.0 + +def test_yahoo(): + test_ticker = 'MSFT' + test_name = 'Microsoft Corp' + + data = get_yahoo_data(test_ticker) + + assert data.ticker_symbol == test_ticker + assert float(data.five_year_growth_rate) > 0.0 + +def get_msn_money_data(ticker): + data_fetcher = DataFetcher() + data_fetcher.ticker_symbol = ticker + + # Make all network request asynchronously to build their portion of + # the json results. + data_fetcher.fetch_msn_money_data() + + # Wait for each RPC result before proceeding. + for rpc in data_fetcher.rpcs: + rpc.result() + + return CompanyInfo(**vars(data_fetcher.msn_money)) + +def get_yahoo_data(ticker): + data_fetcher = DataFetcher() + data_fetcher.ticker_symbol = ticker + + # Make all network request asynchronously to build their portion of + # the json results. + data_fetcher.fetch_yahoo_finance_analysis() + + # Wait for each RPC result before proceeding. + for rpc in data_fetcher.rpcs: + rpc.result() + + return data_fetcher.yahoo_finance_analysis diff --git a/tests/MSNMoney.py b/tests/test_MSNMoney.py similarity index 93% rename from tests/MSNMoney.py rename to tests/test_MSNMoney.py index d784b35..402dade 100644 --- a/tests/MSNMoney.py +++ b/tests/test_MSNMoney.py @@ -1,13 +1,8 @@ """Tests for the MSNMoney.py functions.""" -import os -import sys import unittest -app_path = os.path.join(os.path.dirname(__file__), "..", 'isthisstockgood') -sys.path.append(app_path) - from isthisstockgood.Active.MSNMoney import MSNMoney class MSNMoneyTest(unittest.TestCase): diff --git a/tests/RuleOneInvestingCalculationsTest.py b/tests/test_RuleOneInvestingCalculations.py similarity index 95% rename from tests/RuleOneInvestingCalculationsTest.py rename to tests/test_RuleOneInvestingCalculations.py index 8b74bae..8fe9d22 100644 --- a/tests/RuleOneInvestingCalculationsTest.py +++ b/tests/test_RuleOneInvestingCalculations.py @@ -1,14 +1,9 @@ """Tests for the app/RuleOneInvestingCalculations.py functions.""" -import os -import sys import unittest -app_path = os.path.join(os.path.dirname(__file__), "..", 'isthisstockgood') -sys.path.append(app_path) - -import RuleOneInvestingCalculations as RuleOne +import isthisstockgood.RuleOneInvestingCalculations as RuleOne class RuleOneInvestingCalculationsTest(unittest.TestCase):