class IfrsOperatingRevenueAssemblerTest(unittest.TestCase):
    def setUp(self):
        self.assembler = IfrsOperatingRevenueAssembler()
        self.file_utils = FileUtils()

    def tearDown(self):
        self.assembler = None
        self.file_utils = None

    def test_assemble_2330(self):
        # online: http://mops.twse.com.tw/mops/web/ajax_t05st10_ifrs?encodeURIComponent=1&run=Y&step=0&colorchg=&TYPEK=sii%20&co_id=2330&off=1&year=103&month=09&firstin=true
        path = "./stockcat/tests/unit/data/ifrs_operating_revenue/2330/2014/09.html"
        param = {"content": self.file_utils.read_file(path), "stock_symbol": "2330", "date": datetime.date(2014, 9, 30)}
        dao = self.assembler.assemble(param)

        self.assertEqual(dao.get_column_name_list(), [u"項目", datetime.date(2014, 9, 30)])
        self.assertEqual(dao.get_stock_symbol(), param["stock_symbol"])
        self.assertEqual(dao.get_date(), param["date"])

        row_list = dao.get_row_list()
        self.assertEqual(row_list[0], [u"本月", 74846313])
        self.assertEqual(row_list[1], [u"去年同期", 55382473])
        self.assertEqual(row_list[2], [u"增減金額", 19463840])
        self.assertEqual(row_list[3], [u"增減百分比", 35.14])
        self.assertEqual(row_list[4], [u"本年累計", 540285390])
        self.assertEqual(row_list[5], [u"去年累計", 451218350])
        self.assertEqual(row_list[6], [u"增減金額", 89067040])
        self.assertEqual(row_list[7], [u"增減百分比", 19.74])

    def test_assemble_1101(self):
        # online: http://mops.twse.com.tw/mops/web/ajax_t05st10_ifrs?encodeURIComponent=1&run=Y&step=0&colorchg=&TYPEK=sii%20&co_id=1101&off=1&year=103&month=09&firstin=true
        path = "./stockcat/tests/unit/data/ifrs_operating_revenue/1101/2014/09.html"
        param = {"content": self.file_utils.read_file(path), "stock_symbol": "1101", "date": datetime.date(2014, 9, 30)}
        dao = self.assembler.assemble(param)

        self.assertEqual(dao.get_column_name_list(), [u"項目", datetime.date(2014, 9, 30)])
        self.assertEqual(dao.get_stock_symbol(), param["stock_symbol"])
        self.assertEqual(dao.get_date(), param["date"])

        # check negative number
        row_list = dao.get_row_list()
        self.assertEqual(row_list[2], [u"增減金額", -244950])
        self.assertEqual(row_list[3], [u"增減百分比", -2.43])
        self.assertEqual(row_list[7], [u"增減百分比", 7.00])

    def test_assemble_raise_over_query_assemble_error(self):
        path = "./stockcat/tests/unit/data/error/too_much_query_error.html"
        param = {"content": self.file_utils.read_file(path), "stock_symbol": "2330", "date": datetime.date(2010, 9, 30)}
        with self.assertRaises(OverQueryAssembleError) as context:
            self.assembler.assemble(param)
        self.assertEqual(context.exception.param["stock_symbol"], param["stock_symbol"])
        self.assertEqual(context.exception.param["date"], param["date"])

    def test_assemble_raise_no_record_assemble_error(self):
        path = "./stockcat/tests/unit/data/error/no_record_error.html"
        param = {"content": self.file_utils.read_file(path), "stock_symbol": "2330", "date": datetime.date(2010, 9, 30)}
        with self.assertRaises(NoRecordAssembleError) as context:
            self.assembler.assemble(param)
        self.assertEqual(context.exception.param["stock_symbol"], param["stock_symbol"])
        self.assertEqual(context.exception.param["date"], param["date"])
class XbrlCashFlowAssemblerTest(unittest.TestCase):
    def setUp(self):
        self.assembler = XbrlCashFlowAssembler()
        self.file_utils = FileUtils()

    def tearDown(self):
        self.assembler = None
        self.file_utils = None

    def test_assemble_2330_in_2014Q3(self):
        # online: http://mops.twse.com.tw/server-java/t164sb01?step=1&CO_ID=2330&SYEAR=2014&SSEASON=3&REPORT_ID=C
        path = './stockcat/tests/unit/data/xbrl_financial_statement/2330/2014/03.html'
        param = {
            'content' : self.file_utils.read_file(path),
            'stock_symbol' : '2330',
            'date' : datetime.date(2014, 9, 30),
        }
        dao = self.assembler.assemble(param)
        
        column_name_list = dao.get_column_name_list()
        row_list = dao.get_row_list()

        self.assertEqual(column_name_list[0], u'會計項目')
        self.assertEqual(column_name_list[1], (datetime.date(2014, 1, 1), datetime.date(2014, 9, 30)))
        self.assertEqual(column_name_list[2], (datetime.date(2013, 1, 1), datetime.date(2013, 9, 30)))
        self.assertEqual(row_list[0], [u'營業活動之現金流量-間接法'])
class LegacyIncomeStatementAssemblerTest(unittest.TestCase):
    def setUp(self):
        self.assembler = LegacyIncomeStatementAssembler()
        self.file_utils = FileUtils()

    def tearDown(self):
        self.assembler = None
        self.file_utils = None

    def test_assemble_2330(self):
        # online: http://mops.twse.com.tw/mops/web/ajax_t05st34?encodeURIComponent=1&step=1&firstin=1&off=1&keyword4=&code1=&TYPEK2=&checkbtn=&queryName=co_id&TYPEK=all&isnew=false&co_id=2330&year=99&season=03
        path = "./stockcat/tests/unit/data/legacy_income_statement/2330/2010/03.html"
        param = {"content": self.file_utils.read_file(path), "stock_symbol": "2330", "date": datetime.date(2010, 9, 30)}
        dao = self.assembler.assemble(param)

        column_name_list = dao.get_column_name_list()
        row_list = dao.get_row_list()

        self.assertEqual(column_name_list, [u"會計科目", datetime.date(2010, 9, 30), datetime.date(2009, 9, 30)])
        self.assertEqual(row_list[0], [u"銷貨收入總額", 318388370, 102.90, 213468240, 104.82])
        self.assertEqual(row_list[1], [u"銷貨退回", 8992668, 2.9, 9820449, 4.82])
        self.assertEqual(row_list[2], [u"銷貨收入淨額", 309395702, 100.00, 203647791, 100.00])
        self.assertEqual(row_list[3], [u"營業收入合計", 309395702, 100.00, 203647791, 100.00])
        self.assertEqual(row_list[4], [u"銷貨成本", 157159327, 50.79, 119013880, 58.44])
        self.assertEqual(row_list[5], [u"營業成本合計", 157159327, 50.79, 119013880, 58.44])

        self.assertEqual(row_list[11], [u"營業淨利(淨損)", 117661857, 38.02, 58320012, 28.63])
        self.assertEqual(row_list[12], [u"營業外收入及利益"])

        self.assertEqual(row_list[-5], [u"合併總損益", 121415006, 39.24, 56605811, 27.79])
        self.assertEqual(row_list[-4], [u"基本每股盈餘"])
        self.assertEqual(row_list[-3], [u"基本每股盈餘", 4.67, 0.00, 2.19, 0.00])
        self.assertEqual(row_list[-2], [u"稀釋每股盈餘"])
        self.assertEqual(row_list[-1], [u"稀釋每股盈餘", 4.66, 0.00, 2.18, 0.00])
class XbrlBalanceSheetAssemblerTest(unittest.TestCase):
    def setUp(self):
        self.assembler = XbrlBalanceSheetAssembler()
        self.file_utils = FileUtils()

    def tearDown(self):
        self.assembler = None
        self.file_utils = None

    def test_assemble_2330_in_2014Q3(self):
        # online: http://mops.twse.com.tw/server-java/t164sb01?step=1&CO_ID=2330&SYEAR=2014&SSEASON=3&REPORT_ID=C
        path = './stockcat/tests/unit/data/xbrl_financial_statement/2330/2014/03.html'
        param = {
            'content' : self.file_utils.read_file(path),
            'stock_symbol' : '2330',
            'date' : datetime.date(2014, 9, 30),
        }
        dao = self.assembler.assemble(param)        
        
        column_name_list = dao.get_column_name_list()
        row_list = dao.get_row_list()

        self.assertEqual(column_name_list[0], u'會計項目')
        self.assertEqual(column_name_list[1], datetime.date(2014, 9, 30))
        self.assertEqual(column_name_list[2], datetime.date(2013, 12, 31))
        self.assertEqual(column_name_list[3], datetime.date(2013, 9, 30))     
        self.assertEqual(row_list[0], [u'資產'])
        self.assertEqual(row_list[1], [u'流動資產'])
        self.assertEqual(row_list[2], [u'現金及約當現金'])
        self.assertEqual(row_list[3], [u'現金及約當現金合計', 225884318, 242695447, 216603697])
class StockSymbolAssemblerTest(unittest.TestCase):
    def setUp(self):
        self.assembler = StockSymbolAssembler()
        self.file_utils = FileUtils()

    def tearDown(self):
        self.assembler = None
        self.file_utils = None
    
    def test_assemble_stock_exchange_market(self):
        # online: http://isin.twse.com.tw/isin/C_public.jsp?strMode=2 
        path = './stockcat/tests/unit/data/stock_symbol/stock_exchange_market.html'
        param = { 'content' : self.file_utils.read_file(path) }
        dao = self.assembler.assemble(param)

        actual = dao.get_column_name_list()
        expected = [u'有價證券代號', u'名稱', u'國際證券辨識號碼(ISIN Code)', u'上市日', u'市場別', u'產業別', u'CFICode', u'備註']
        self.assertEqual(actual, expected)

        row_list = dao.get_row_list()
        self.assertEqual(row_list[0], [u'1101', u'台泥', u'TW0001101004', datetime.date(1962, 2, 9), u'上市', u'水泥工業', u'ESVUFR', u''])
        for row in row_list:
            self.assertEqual(len(row), 8)

        self.assertEqual(dao.get_release_date(), datetime.date(2015, 8, 7))

    def test_assemble_otc_market(self):
        # online: http://isin.twse.com.tw/isin/C_public.jsp?strMode=4
        path = './stockcat/tests/unit/data/stock_symbol/otc_market.html'
        param = { 'content' : self.file_utils.read_file(path) }
        dao = self.assembler.assemble(param)

        actual = dao.get_column_name_list()
        expected = [u'有價證券代號', u'名稱', u'國際證券辨識號碼(ISIN Code)', u'上市日', u'市場別', u'產業別', u'CFICode', u'備註']
        self.assertEqual(actual, expected)

        row_list = dao.get_row_list()
        self.assertEqual(row_list[0], [u'5364', u'力麗店', u'TW0005364004', datetime.date(2013, 8, 26), u'上櫃', u'其他業', u'ESVUFR', u''])
        for row in row_list:
            self.assertEqual(len(row), 8)

        self.assertEqual(dao.get_release_date(), datetime.date(2015, 8, 7))
class StockCapitalIncreaseHistoryAssemblerTest(unittest.TestCase):
    def setUp(self):
        self.assembler = DividendPolicyAssembler()
        self.file_utils = FileUtils()

    def tearDown(self):
        self.assembler = None
        self.file_utils = None
    
    def test_assemble_2498(self):
        # online: http://jdata.yuanta.com.tw/z/zc/zcc/zcc_2498.djhtm
        path = './stockcat/tests/unit/data/dividend_policy/2498.html'
        param = {
            'content' : self.file_utils.read_file(path),
            'stock_symbol' : '2498'
        }
        dao = self.assembler.assemble(param)

        self.assertEqual(dao.get_stock_symbol(), param['stock_symbol'])

        actual = dao.get_column_name_list()
        expected = [u'年度', u'現金股利', u'盈餘配股', u'公積配股', u'股票股利', u'合計', u'員工配股率%']
        self.assertEqual(actual, expected)

        row_list = dao.get_row_list()
        self.assertEqual(row_list[0], [datetime.date(2014, 12, 31), 0.38, 0, 0, 0, 0.38, 0.0000])
        self.assertEqual(row_list[4], [datetime.date(2010, 12, 31), 37, 0.5000000092, 0, 0.5000000092, 37.5000000092, 0.0050])
        for row in row_list:
            self.assertEqual(len(row), 7)

    def test_assemble_raise_no_record_assemble_error(self):
        # online: http://jdata.yuanta.com.tw/z/zc/zcc/zcc_3009.djhtm
        path = './stockcat/tests/unit/data/error/dividend_policy_not_found_error.html'
        param = {
            'content' : self.file_utils.read_file(path),
            'stock_symbol' : '3009'
        }
        with self.assertRaises(NoRecordAssembleError) as context:
            self.assembler.assemble(param)
        self.assertEqual(context.exception.param['stock_symbol'], param['stock_symbol'])   
class StockCapitalIncreaseHistoryAssemblerTest(unittest.TestCase):
    def setUp(self):
        self.assembler = CapitalIncreaseHistoryAssembler()
        self.file_utils = FileUtils()

    def tearDown(self):
        self.assembler = None
        self.file_utils = None
    
    def test_assemble_2498(self):
        # online: http://jdata.yuanta.com.tw/z/zc/zcb/zcb_2498.djhtm
        path = './stockcat/tests/unit/data/capital_increase_history/2498.html'
        param = {
            'content' : self.file_utils.read_file(path),
            'stock_symbol' : '2498'
        }
        dao = self.assembler.assemble(param)

        self.assertEqual(dao.get_stock_symbol(), param['stock_symbol'])

        actual = dao.get_column_name_list()
        expected = [u'年度', u'現金增資', u'比重', u'盈餘轉增資', u'比重', u'公積及其他', u'比重']
        self.assertEqual(actual, expected)

        row_list = dao.get_row_list()
        self.assertEqual(row_list[0], [datetime.date(2015, 12, 31), 14.464519, 0.1747, 67.724067, 0.8180, 0.598634, 0.0072])
        for row in row_list:
            self.assertEqual(len(row), 7)

    def test_assemble_raise_no_record_assemble_error(self):
        # online: http://jdata.yuanta.com.tw/z/zc/zcb/zcb_3009.djhtm
        path = './stockcat/tests/unit/data/error/capital_increase_history_not_found_error.html'
        param = {
            'content' : self.file_utils.read_file(path),
            'stock_symbol' : '3009'
        }
        with self.assertRaises(NoRecordAssembleError) as context:
            self.assembler.assemble(param)
        self.assertEqual(context.exception.param['stock_symbol'], param['stock_symbol'])   
class LegacyBalanceSheetAssemblerTest(unittest.TestCase):
    def setUp(self):
        self.assembler = LegacyBalanceSheetAssembler()
        self.file_utils = FileUtils()

    def tearDown(self):
        self.assembler = None
        self.file_utils = None

    def test_assemble_2330(self):
        # online: http://mops.twse.com.tw/mops/web/ajax_t05st33?encodeURIComponent=1&step=1&firstin=1&off=1&keyword4=&code1=&TYPEK2=&checkbtn=&queryName=co_id&TYPEK=all&isnew=false&co_id=2330&year=99&season=03
        param = {
            'content' : self.file_utils.read_file('./stockcat/tests/unit/data/legacy_balance_sheet/2330/2010/03.html'),
            'stock_symbol' : '2330',
            'date' : datetime.date(2010, 9, 30), 
        }
        dao = self.assembler.assemble(param)
        
        column_name_list = dao.get_column_name_list()
        row_list = dao.get_row_list()
        
        self.assertEqual(column_name_list, [u'會計科目', datetime.date(2010, 9, 30), datetime.date(2009, 9, 30)])
        self.assertEqual(row_list[0], [u'資產'])
        self.assertEqual(row_list[1], [u'流動資產'])
        self.assertEqual(row_list[2], [u'現金及約當現金', 132268758, 156935077])
        self.assertEqual(row_list[6], [u'應收帳款淨額', 47370155, 35879778])
        self.assertEqual(row_list[10], [u'存 貨', 26663415, 19176052])
        self.assertEqual(row_list[12], [u'流動資產', 246637178, 244240939])
        self.assertEqual(row_list[13], [u'基金及投資'])
        self.assertEqual(row_list[19], [u'基金及投資', 39784245, 38553304])
        self.assertEqual(row_list[30], [u'固定資產淨額', 349179208, 236816024])
        self.assertEqual(row_list[40], [u'資產總計', 667552049, 541897118])
        self.assertEqual(row_list[41], [u'負債及股東權益'])
        self.assertEqual(row_list[42], [u'負債'])
        self.assertEqual(row_list[43], [u'流動負債'])
        self.assertEqual(row_list[53], [u'流動負債', 109235939, 55008722])
        self.assertEqual(row_list[54], [u'長期負債'])
        self.assertEqual(row_list[58], [u'長期負債', 12397877, 14967865])
        self.assertEqual(row_list[65], [u'負債總計', 126647972, 75270447])
        self.assertEqual(row_list[66], [u'股東權益'])
        self.assertEqual(row_list[67], [u'股本'])
        self.assertEqual(row_list[68], [u'普通股股本', 259073440, 259006623])
        self.assertEqual(row_list[69], [u'資本公積'])
        self.assertEqual(row_list[70], [u'資本公積合計', 55634070, 55439919])
        self.assertEqual(row_list[71], [u'保留盈餘'])
        self.assertEqual(row_list[75], [u'保留盈餘合計', 225059122, 149216633])
        self.assertEqual(row_list[81], [u'股東權益總計', 540904077, 466626671])
示例#9
0
class FileSpiderStorage():
    def __init__(self):
        self.file_utils = FileUtils()
        self.base_path = './stockcat/data/'

    def set(self, key, url):
        filepath = self.__build_filepath(key)
        self.file_utils.copy_url_to_file(url, filepath)

    def contains(self, key):
        filepath = self.__build_filepath(key)
        return self.file_utils.is_file(filepath)
        
    def get(self, key):
        filepath = self.__build_filepath(key)
        return self.file_utils.read_file(filepath)

    def __build_filepath(self, key):
        relative_path = '''{key}.html'''.format(key=key)
        return self.file_utils.join_paths(self.base_path, relative_path)
class OperatingRevenueSummaryAssemblerTest(unittest.TestCase):
    def setUp(self):
        self.assembler = OperatingRevenueSummaryAssembler()
        self.file_utils = FileUtils()

    def tearDown(self):
        self.assembler = None
        self.file_utils = None
    
    def test_assemble_stock_exchange_market_in_2010(self):
        # online: http://mops.twse.com.tw/nas/t21/sii/t21sc03_99_9.html
        path = './stockcat/tests/unit/data/operating_revenue_summary/stock_exchange_market/2010/9.html'
        param = {
            'content' : self.file_utils.read_file(path),
            'date' : datetime.date(2010, 9, 30)
        }
        dao = self.assembler.assemble(param)

        actual = dao.get_column_name_list()
        expected = [u'公司代號', u'公司名稱', u'當月營收', u'上月營收', u'去年當月營收', u'上月比較增減(%)', u'去年同月增減(%)', u'當月累計營收', u'去年累計營收', u'前期比較增減(%)']
        self.assertEqual(actual, expected)

        row_list = dao.get_row_list()
        self.assertEqual(row_list[0], [u'1101', u'台泥', 1804805, 1861703, 1823433, -3.05, -1.02, 16344206, 15719543, 3.97])
        for row in row_list:
            self.assertEqual(len(row), 10)

        self.assertEqual(dao.get_stmt_date(), param['date'])
        self.assertEqual(dao.get_release_date(), datetime.date(2013, 5, 7))

    def test_assemble_stock_exchange_market_in_2012(self):
        # online: http://mops.twse.com.tw/nas/t21/sii/t21sc03_101_1.html
        path = './stockcat/tests/unit/data/operating_revenue_summary/stock_exchange_market/2012/1.html'
        param = {
            'content' : self.file_utils.read_file(path),
            'date' : datetime.date(2012, 1, 31)   
        }
        dao = self.assembler.assemble(param)

        actual = dao.get_column_name_list()
        expected = [u'公司代號', u'公司名稱', u'當月營收', u'上月營收', u'去年當月營收', u'上月比較增減(%)', u'去年同月增減(%)', u'當月累計營收', u'去年累計營收', u'前期比較增減(%)']
        self.assertEqual(actual, expected)

        row_list = dao.get_row_list()
        self.assertEqual(row_list[0], [u'1101', u'台泥', 1752202, 2072570, 2337946, -15.45, -25.05, 1752202, 2337946, -25.05])
        self.assertEqual(row_list[7], [u'1201', u'味全公司', 1115106, 1127058, 1110017, -1.06, 0.45, 1115106, 1110017, 0.45])
        self.assertEqual(row_list[-1], [u'912398', u'友佳國際', 420469, 576524, 742870, -27.06, -43.39, 420469, 742870, -43.39])
        for row in row_list:
            self.assertEqual(len(row), 10)

        self.assertEqual(dao.get_stmt_date(), param['date'])
        self.assertEqual(dao.get_release_date(), datetime.date(2015, 6, 25))

    def test_assemble_stock_exchange_market_in_Feb_2013(self):
        # online: http://mops.twse.com.tw/nas/t21/sii/t21sc03_102_2.html
        path = './stockcat/tests/unit/data/operating_revenue_summary/stock_exchange_market/2013/2.html'
        param = {
            'content' : self.file_utils.read_file(path),
            'date' : datetime.date(2013, 2, 28)
        }
        dao = self.assembler.assemble(param)

        actual = dao.get_column_name_list()
        expected = [u'公司代號', u'公司名稱', u'當月營收', u'上月營收', u'去年當月營收', u'上月比較增減(%)', u'去年同月增減(%)', u'當月累計營收', u'去年累計營收', u'前期比較增減(%)']
        self.assertEqual(actual, expected)

        row_list = dao.get_row_list()
        self.assertEqual(row_list[0], [u'1101', u'台泥', 5540346, 9134465, 7983023, -39.34, -30.59, 14674811, 15108059, -2.86])
        self.assertEqual(row_list[-1], [u'912398', u'友佳國際', 245279, 547037, 701056, -55.16, -65.01, 792316, 1121522, -29.35])
        for row in row_list:
            self.assertEqual(len(row), 10)

        self.assertEqual(dao.get_stmt_date(), param['date'])
        self.assertEqual(dao.get_release_date(), datetime.date(2015, 6, 25))

    def test_assemble_stock_exchange_market_in_2014(self):
        # online: http://mops.twse.com.tw/nas/t21/sii/t21sc03_103_1.html
        path = './stockcat/tests/unit/data/operating_revenue_summary/stock_exchange_market/2014/1.html'
        param = {
            'content' : self.file_utils.read_file(path),
            'date' : datetime.date(2014, 1, 31)
        }
        dao = self.assembler.assemble(param)

        actual = dao.get_column_name_list()
        expected = [u'公司代號', u'公司名稱', u'當月營收', u'上月營收', u'去年當月營收', u'上月比較增減(%)', u'去年同月增減(%)', u'當月累計營收', u'去年累計營收', u'前期比較增減(%)']
        self.assertEqual(actual, expected)

        row_list = dao.get_row_list()
        self.assertEqual(row_list[0], [u'1101', u'台泥', 9801691, 11416657, 9134465, -14.14, 7.30, 9801691, 9134465, 7.30])
        for row in row_list:
            self.assertEqual(len(row), 10)

        self.assertEqual(dao.get_stmt_date(), param['date'])
        self.assertEqual(dao.get_release_date(), datetime.date(2015, 2, 1))

    def test_assemble_stock_exchange_market_in_2015(self):
        # online: http://mops.twse.com.tw/nas/t21/sii/t21sc03_104_1.html
        path = './stockcat/tests/unit/data/operating_revenue_summary/stock_exchange_market/2015/1.html'
        param = {
            'content' : self.file_utils.read_file(path),
            'date' : datetime.date(2015, 1, 31)
        }
        dao = self.assembler.assemble(param)

        actual = dao.get_column_name_list()
        expected = [u'公司代號', u'公司名稱', u'當月營收', u'上月營收', u'去年當月營收', u'上月比較增減(%)', u'去年同月增減(%)', u'當月累計營收', u'去年累計營收', u'前期比較增減(%)']
        self.assertEqual(actual, expected)

        row_list = dao.get_row_list()
        self.assertEqual(row_list[0], [u'1101', u'台泥', 8921719, 9913147, 9801691, -10.00, -8.97, 8921719, 9801691, -8.97])
        for row in row_list:
            self.assertEqual(len(row), 10)

        self.assertEqual(dao.get_stmt_date(), param['date'])
        self.assertEqual(dao.get_release_date(), datetime.date(2015, 8, 16))

    def test_assemble_otc_market_in_2010(self):
        # online: http://mops.twse.com.tw/nas/t21/otc/t21sc03_99_9.html
        path = './stockcat/tests/unit/data/operating_revenue_summary/otc_market/2010/9.html'
        param = {
            'content' : self.file_utils.read_file(path),
            'date' : datetime.date(2010, 9, 30)
        }
        dao = self.assembler.assemble(param)

        actual = dao.get_column_name_list()
        expected = [u'公司代號', u'公司名稱', u'當月營收', u'上月營收', u'去年當月營收', u'上月比較增減(%)', u'去年同月增減(%)', u'當月累計營收', u'去年累計營收', u'前期比較增減(%)']
        self.assertEqual(actual, expected)

        row_list = dao.get_row_list()
        self.assertEqual(row_list[0], [u'4205', u'恆義公司', 92492, 112118, 92552, -17.50, -0.06, 871040, 840174, 3.67])
        for row in row_list:
            self.assertEqual(len(row), 10)

        self.assertEqual(dao.get_stmt_date(), param['date'])
        self.assertEqual(dao.get_release_date(), datetime.date(2013, 5, 7))

    def test_assemble_otc_market_in_2014(self):
        # online: http://mops.twse.com.tw/nas/t21/otc/t21sc03_103_9.html
        path = './stockcat/tests/unit/data/operating_revenue_summary/otc_market/2014/9.html'
        param = {
            'content' : self.file_utils.read_file(path),
            'date' : datetime.date(2014, 9, 30)
        }
        dao = self.assembler.assemble(param)

        actual = dao.get_column_name_list()
        expected = [u'公司代號', u'公司名稱', u'當月營收', u'上月營收', u'去年當月營收', u'上月比較增減(%)', u'去年同月增減(%)', u'當月累計營收', u'去年累計營收', u'前期比較增減(%)']
        self.assertEqual(actual, expected)

        row_list = dao.get_row_list()
        self.assertEqual(row_list[0], [u'1256', u'F-鮮活', 193070, 208084, 181554, -7.21, 6.34, 1660110, 1368966, 21.26])
        for row in row_list:
            self.assertEqual(len(row), 10)

        self.assertEqual(dao.get_stmt_date(), param['date'])
        self.assertEqual(dao.get_release_date(), datetime.date(2015, 8, 16))

    def test_assemble_otc_market_in_2015(self):
        # online: http://mops.twse.com.tw/nas/t21/otc/t21sc03_104_1.html
        path = './stockcat/tests/unit/data/operating_revenue_summary/otc_market/2015/1.html'
        param = {
            'content' : self.file_utils.read_file(path),
            'date' : datetime.date(2015, 1, 31)
        }
        dao = self.assembler.assemble(param)

        actual = dao.get_column_name_list()
        expected = [u'公司代號', u'公司名稱', u'當月營收', u'上月營收', u'去年當月營收', u'上月比較增減(%)', u'去年同月增減(%)', u'當月累計營收', u'去年累計營收', u'前期比較增減(%)']
        self.assertEqual(actual, expected)

        row_list = dao.get_row_list()
        self.assertEqual(row_list[0], [u'1256', u'F-鮮活', 209686, 148468, 154455, 41.23, 35.75, 209686, 154455, 35.75])
        for row in row_list:
            self.assertEqual(len(row), 10)

        self.assertEqual(dao.get_stmt_date(), param['date'])
        self.assertEqual(dao.get_release_date(), datetime.date(2015, 8, 16))

    def test_assemble_raise_no_record_assemble_error(self):
        # online: http://mops.twse.com.tw/nas/t21/sii/t21sc03_105_1.html
        path = './stockcat/tests/unit/data/error/url_not_found_error.html'
        param = {
            'content' : self.file_utils.read_file(path),
            'date' : datetime.date(2016, 1, 31)
        }
        with self.assertRaises(NoRecordAssembleError) as context:
            self.assembler.assemble(param)
        self.assertEqual(context.exception.param['date'], param['date'])   
class LegacyOperatingRevenueAssemblerTest(unittest.TestCase):
    def setUp(self):
        self.assembler = LegacyOperatingRevenueAssembler()
        self.file_utils = FileUtils()

    def tearDown(self):
        self.assembler = None
        self.file_utils = None
    
    def test_assemble_2330(self):
        # online: http://mops.twse.com.tw/mops/web/ajax_t05st10?encodeURIComponent=1&run=Y&step=0&colorchg=&TYPEK=sii%20&co_id=2330&off=1&year=99&month=09&firstin=true
        path = './stockcat/tests/unit/data/legacy_operating_revenue/2330/2010/09.html'
        param = {
            'content' : self.file_utils.read_file(path),
            'stock_symbol' : '2330',
            'date' : datetime.date(2010, 9, 30)
        }
        dao = self.assembler.assemble(param)

        self.assertEqual(dao.get_column_name_list(), [u'項目', datetime.date(2010, 9, 30)])
        self.assertEqual(dao.get_stock_symbol(), param['stock_symbol'])
        self.assertEqual(dao.get_date(), param['date'])

        row_list = dao.get_row_list()
        self.assertEqual(row_list[0], [u'本月', 37637898])
        self.assertEqual(row_list[1], [u'去年同期', 28936225])
        self.assertEqual(row_list[2], [u'增減金額', 8701673])
        self.assertEqual(row_list[3], [u'增減百分比', 30.07])
        self.assertEqual(row_list[4], [u'本年累計', 309395679])
        self.assertEqual(row_list[5], [u'去年累計', 203647791])
        self.assertEqual(row_list[6], [u'增減金額', 105747888])
        self.assertEqual(row_list[7], [u'增減百分比', 51.93])
    
    def test_assemble_raise_private_record_assemble_error(self):
        # online: http://mops.twse.com.tw/mops/web/ajax_t05st10?encodeURIComponent=1&run=Y&step=0&colorchg=&TYPEK=sii%20&co_id=1101&off=1&year=99&month=09&firstin=true
        path = './stockcat/tests/unit/data/legacy_operating_revenue/1101/2010/09.html'
        param = {
            'content' : self.file_utils.read_file(path),
            'stock_symbol' : '1101',
            'date' : datetime.date(2010, 9, 30)
        }
        with self.assertRaises(PrivateRecordAssembleError) as context:
            self.assembler.assemble(param)
        self.assertEqual(context.exception.param['stock_symbol'], param['stock_symbol'])
        self.assertEqual(context.exception.param['date'], param['date'])

    def test_assemble_raise_over_query_assemble_error(self):
        path = './stockcat/tests/unit/data/error/too_much_query_error.html'
        param = {
            'content' : self.file_utils.read_file(path),
            'stock_symbol' : '2330',
            'date' : datetime.date(2010, 9, 30)
        }
        with self.assertRaises(OverQueryAssembleError) as context:
            self.assembler.assemble(param)
        self.assertEqual(context.exception.param['stock_symbol'], param['stock_symbol'])
        self.assertEqual(context.exception.param['date'], param['date'])

    def test_assemble_raise_no_record_assemble_error(self):
        path = './stockcat/tests/unit/data/error/no_record_error.html'
        param = {
            'content' : self.file_utils.read_file(path),
            'stock_symbol' : '2330',
            'date' : datetime.date(2010, 9, 30)
        }
        with self.assertRaises(NoRecordAssembleError) as context:
            self.assembler.assemble(param)
        self.assertEqual(context.exception.param['stock_symbol'], param['stock_symbol'])
        self.assertEqual(context.exception.param['date'], param['date'])
class LegacyCashFlowAssemblerTest(unittest.TestCase):
    def setUp(self):
        self.assembler = LegacyCashFlowAssembler()
        self.file_utils = FileUtils()

    def tearDown(self):
        self.assembler = None
        self.file_utils = None

    def test_assemble_2330_in_2010Q3(self):
        # online: http://mops.twse.com.tw/mops/web/ajax_t05st39?encodeURIComponent=1&step=1&firstin=1&off=1&keyword4=&code1=&TYPEK2=&checkbtn=&queryName=co_id&TYPEK=all&isnew=false&co_id=2330&year=99&season=03
        path = './stockcat/tests/unit/data/legacy_cash_flow/2330/2010/03.html'
        param = {
            'content' : self.file_utils.read_file(path),
            'stock_symbol' : '2330',
            'date' : datetime.date(2010, 9, 30),
        }
        dao = self.assembler.assemble(param)
        
        column_name_list = dao.get_column_name_list()
        row_list = dao.get_row_list()
        
        self.assertEqual(column_name_list, [u'會計科目', datetime.date(2010, 9, 30), datetime.date(2009, 9, 30)])
        self.assertEqual(row_list[0], [u'營業活動之現金流量:'])
        self.assertEqual(row_list[1], [u'歸屬予母公司股東之淨利', 120884560, 56551787])
        self.assertEqual(row_list[2], [u'歸屬予少數股權之淨利', 530446, 54024])
        self.assertEqual(row_list[34], [u'營業活動之淨現金流入', 158911867, 97967044])
        self.assertEqual(row_list[48], [u'投資活動之淨現金流出', -155529046, -49366789])
        self.assertEqual(row_list[60], [u'融資活動之淨現金流出', -41335338, -85193851])

    def test_assemble_2330_in_2011Q1(self):
        # online: http://mops.twse.com.tw/mops/web/ajax_t05st39?encodeURIComponent=1&step=1&firstin=1&off=1&keyword4=&code1=&TYPEK2=&checkbtn=&queryName=co_id&TYPEK=all&isnew=false&co_id=2330&year=100&season=01
        path = './stockcat/tests/unit/data/legacy_cash_flow/2330/2011/01.html'
        param = {
            'content' : self.file_utils.read_file(path),
            'stock_symbol' : '2330',
            'date' : datetime.date(2011, 3, 31),
        }
        dao = self.assembler.assemble(param)
        
        column_name_list = dao.get_column_name_list()
        row_list = dao.get_row_list()

        self.assertEqual(column_name_list, [u'會計科目', datetime.date(2011, 3, 31), datetime.date(2010, 3, 31)])
        self.assertEqual(row_list[0], [u'營業活動之現金流量-間接法'])
        self.assertEqual(row_list[1], [u'合併總(損)益', 36427092, 33825315])

    def test_assemble_2330_in_2011Q2(self):
        # online: http://mops.twse.com.tw/mops/web/ajax_t05st39?encodeURIComponent=1&step=1&firstin=1&off=1&keyword4=&code1=&TYPEK2=&checkbtn=&queryName=co_id&TYPEK=all&isnew=false&co_id=2330&year=100&season=02
        path = './stockcat/tests/unit/data/legacy_cash_flow/2330/2011/02.html'
        param = {
            'content' : self.file_utils.read_file(path),
            'stock_symbol' : '2330',
            'date' : datetime.date(2011, 6, 30),
        }
        dao = self.assembler.assemble(param)
        
        column_name_list = dao.get_column_name_list()
        row_list = dao.get_row_list()

        self.assertEqual(column_name_list, [u'會計科目', datetime.date(2011, 6, 30), datetime.date(2010, 6, 30)])
        self.assertEqual(row_list[0], [u'營業活動之現金流量-間接法'])
        self.assertEqual(row_list[1], [u'合併總(損)益', 72455291, 74291550])
        self.assertEqual(row_list[29], [u'營業活動之淨現金流入(流出)', 119541434, 94959938])
        self.assertEqual(row_list[44], [u'投資活動之淨現金流入(流出)', -116023709, -110497580])
        self.assertEqual(row_list[52], [u'融資活動之淨現金流入(流出)', 1876424, 16772654])