[
{"name": "a dollar receivable revalued down is a loss", "args": [[{"account": "1210", "balance": {"minor": 1000000, "currency": "USD"}, "bookedValue": {"minor": 780000, "currency": "GBP"}}], [{"base": "USD", "quote": "GBP", "rate": {"numerator": 75, "denominator": 100}}], "GBP"], "expect": {"lines": [{"account": "1210", "balance": {"minor": 1000000, "currency": "USD"}, "bookedValue": {"minor": 780000, "currency": "GBP"}, "revaluedValue": {"minor": 750000, "currency": "GBP"}, "gainLoss": {"minor": -30000, "currency": "GBP"}}], "netGainLoss": {"minor": -30000, "currency": "GBP"}}},
{"name": "the same dollars owed to a supplier are a gain", "args": [[{"account": "2110", "balance": {"minor": -1000000, "currency": "USD"}, "bookedValue": {"minor": -780000, "currency": "GBP"}}], [{"base": "USD", "quote": "GBP", "rate": {"numerator": 75, "denominator": 100}}], "GBP"], "expect": {"lines": [{"account": "2110", "balance": {"minor": -1000000, "currency": "USD"}, "bookedValue": {"minor": -780000, "currency": "GBP"}, "revaluedValue": {"minor": -750000, "currency": "GBP"}, "gainLoss": {"minor": 30000, "currency": "GBP"}}], "netGainLoss": {"minor": 30000, "currency": "GBP"}}},
{"name": "a receivable and a payable in the same currency net to nothing", "args": [[{"account": "1210", "balance": {"minor": 1000000, "currency": "USD"}, "bookedValue": {"minor": 780000, "currency": "GBP"}}, {"account": "2110", "balance": {"minor": -1000000, "currency": "USD"}, "bookedValue": {"minor": -780000, "currency": "GBP"}}], [{"base": "USD", "quote": "GBP", "rate": {"numerator": 75, "denominator": 100}}], "GBP"], "expect": {"lines": [{"account": "1210", "balance": {"minor": 1000000, "currency": "USD"}, "bookedValue": {"minor": 780000, "currency": "GBP"}, "revaluedValue": {"minor": 750000, "currency": "GBP"}, "gainLoss": {"minor": -30000, "currency": "GBP"}}, {"account": "2110", "balance": {"minor": -1000000, "currency": "USD"}, "bookedValue": {"minor": -780000, "currency": "GBP"}, "revaluedValue": {"minor": -750000, "currency": "GBP"}, "gainLoss": {"minor": 30000, "currency": "GBP"}}], "netGainLoss": {"minor": 0, "currency": "GBP"}}},
{"name": "a euro bank balance at a four-decimal rate, rounded half-up once", "args": [[{"account": "1250", "balance": {"minor": 123456, "currency": "EUR"}, "bookedValue": {"minor": 105000, "currency": "GBP"}}], [{"base": "EUR", "quote": "GBP", "rate": {"numerator": 8567, "denominator": 10000}}], "GBP"], "expect": {"lines": [{"account": "1250", "balance": {"minor": 123456, "currency": "EUR"}, "bookedValue": {"minor": 105000, "currency": "GBP"}, "revaluedValue": {"minor": 105765, "currency": "GBP"}, "gainLoss": {"minor": 765, "currency": "GBP"}}], "netGainLoss": {"minor": 765, "currency": "GBP"}}},
{"name": "yen have no minor unit: 1,000,000 yen at 0.0052", "args": [[{"account": "1260", "balance": {"minor": 1000000, "currency": "JPY"}, "bookedValue": {"minor": 530000, "currency": "GBP"}}], [{"base": "JPY", "quote": "GBP", "rate": {"numerator": 52, "denominator": 10000}}], "GBP"], "expect": {"lines": [{"account": "1260", "balance": {"minor": 1000000, "currency": "JPY"}, "bookedValue": {"minor": 530000, "currency": "GBP"}, "revaluedValue": {"minor": 520000, "currency": "GBP"}, "gainLoss": {"minor": -10000, "currency": "GBP"}}], "netGainLoss": {"minor": -10000, "currency": "GBP"}}},
{"name": "half a penny rounds away from zero on an asset", "args": [[{"account": "1210", "balance": {"minor": 1, "currency": "USD"}, "bookedValue": {"minor": 0, "currency": "GBP"}}], [{"base": "USD", "quote": "GBP", "rate": {"numerator": 1, "denominator": 2}}], "GBP"], "expect": {"lines": [{"account": "1210", "balance": {"minor": 1, "currency": "USD"}, "bookedValue": {"minor": 0, "currency": "GBP"}, "revaluedValue": {"minor": 1, "currency": "GBP"}, "gainLoss": {"minor": 1, "currency": "GBP"}}], "netGainLoss": {"minor": 1, "currency": "GBP"}}},
{"name": "and on a liability, symmetrically", "args": [[{"account": "2110", "balance": {"minor": -1, "currency": "USD"}, "bookedValue": {"minor": 0, "currency": "GBP"}}], [{"base": "USD", "quote": "GBP", "rate": {"numerator": 1, "denominator": 2}}], "GBP"], "expect": {"lines": [{"account": "2110", "balance": {"minor": -1, "currency": "USD"}, "bookedValue": {"minor": 0, "currency": "GBP"}, "revaluedValue": {"minor": -1, "currency": "GBP"}, "gainLoss": {"minor": -1, "currency": "GBP"}}], "netGainLoss": {"minor": -1, "currency": "GBP"}}},
{"name": "several currencies, rates listed in any order, unused rates ignored", "args": [[{"account": "1250", "balance": {"minor": 10000, "currency": "EUR"}, "bookedValue": {"minor": 8500, "currency": "GBP"}}, {"account": "1210", "balance": {"minor": 10000, "currency": "USD"}, "bookedValue": {"minor": 7500, "currency": "GBP"}}], [{"base": "CHF", "quote": "GBP", "rate": {"numerator": 9, "denominator": 10}}, {"base": "USD", "quote": "GBP", "rate": {"numerator": 75, "denominator": 100}}, {"base": "EUR", "quote": "GBP", "rate": {"numerator": 86, "denominator": 100}}], "GBP"], "expect": {"lines": [{"account": "1250", "balance": {"minor": 10000, "currency": "EUR"}, "bookedValue": {"minor": 8500, "currency": "GBP"}, "revaluedValue": {"minor": 8600, "currency": "GBP"}, "gainLoss": {"minor": 100, "currency": "GBP"}}, {"account": "1210", "balance": {"minor": 10000, "currency": "USD"}, "bookedValue": {"minor": 7500, "currency": "GBP"}, "revaluedValue": {"minor": 7500, "currency": "GBP"}, "gainLoss": {"minor": 0, "currency": "GBP"}}], "netGainLoss": {"minor": 100, "currency": "GBP"}}},
{"name": "no balances: a zero net in the functional currency", "args": [[], [{"base": "USD", "quote": "GBP", "rate": {"numerator": 75, "denominator": 100}}], "GBP"], "expect": {"lines": [], "netGainLoss": {"minor": 0, "currency": "GBP"}}},
{"name": "a currency with no closing rate is refused", "args": [[{"account": "1250", "balance": {"minor": 100, "currency": "EUR"}, "bookedValue": {"minor": 85, "currency": "GBP"}}], [{"base": "USD", "quote": "GBP", "rate": {"numerator": 75, "denominator": 100}}], "GBP"], "expectError": "no period-end rate from EUR to GBP"},
{"name": "a rate into another currency does not count", "args": [[{"account": "1250", "balance": {"minor": 100, "currency": "EUR"}, "bookedValue": {"minor": 85, "currency": "GBP"}}], [{"base": "EUR", "quote": "USD", "rate": {"numerator": 11, "denominator": 10}}], "GBP"], "expectError": "no period-end rate from EUR to GBP"},
{"name": "two closing rates for one currency are refused", "args": [[{"account": "1210", "balance": {"minor": 100, "currency": "USD"}, "bookedValue": {"minor": 75, "currency": "GBP"}}], [{"base": "USD", "quote": "GBP", "rate": {"numerator": 75, "denominator": 100}}, {"base": "USD", "quote": "GBP", "rate": {"numerator": 76, "denominator": 100}}], "GBP"], "expectError": "more than one period-end rate from USD to GBP"},
{"name": "a balance already in the functional currency is refused", "args": [[{"account": "1200", "balance": {"minor": 100, "currency": "GBP"}, "bookedValue": {"minor": 100, "currency": "GBP"}}], [{"base": "USD", "quote": "GBP", "rate": {"numerator": 75, "denominator": 100}}], "GBP"], "expectError": "account 1200 is already in GBP"},
{"name": "a booked value in the foreign currency is refused", "args": [[{"account": "1210", "balance": {"minor": 100, "currency": "USD"}, "bookedValue": {"minor": 100, "currency": "USD"}}], [{"base": "USD", "quote": "GBP", "rate": {"numerator": 75, "denominator": 100}}], "GBP"], "expectError": "booked value of account 1210 must be in GBP"}
]