<commit_before>#!/usr/bin/env python3
# Copyright (c) 2019-2020 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.

from test_framework.test_framework import SyscoinTestFramework
from test_framework.util import assert_equal, assert_raises_rpc_error, set_node_times, disconnect_nodes, connect_nodes, bump_node_times
from test_framework.messages import COIN
import time
ZDAG_NOT_FOUND = -1
ZDAG_STATUS_OK = 0
ZDAG_WARNING_RBF = 1
ZDAG_WARNING_NOT_ZDAG_TX = 2
ZDAG_WARNING_SIZE_OVER_POLICY = 3
ZDAG_MAJOR_CONFLICT = 4
MAX_INITIAL_BROADCAST_DELAY = 15 * 60 # 15 minutes in seconds
class AssetZDAGTest(SyscoinTestFramework):
    def set_test_params(self):
        self.setup_clean_chain = True
        self.num_nodes = 4
        self.rpc_timeout = 240
        self.extra_args = [['-assetindex=1'],['-assetindex=1'],['-assetindex=1'],['-assetindex=1']]

    def run_test(self):
        self.nodes[0].generate(200)
        self.sync_blocks()
        self.burn_zdag_doublespend_chain()
        self.basic_zdag_doublespend()
        self.burn_zdag_doublespend()

    def basic_zdag_doublespend(self):
        self.basic_asset()
        self.nodes[0].generate(1)
        newaddress2 = self.nodes[1].getnewaddress()
        newaddress3 = self.nodes[1].getnewaddress()
        newaddress1 = self.nodes[0].getnewaddress()
        self.nodes[2].importprivkey(self.nodes[1].dumpprivkey(newaddress2))
        self.nodes[0].assetsend(self.asset, newaddress1, int(2*COIN))
        # create 2 utxo's so below newaddress1 recipient of 0.5 COIN uses 1 and the newaddress3 recipient on node3 uses the other on dbl spend
        self.nodes[0].sendtoaddress(newaddress2, 1)
        self.nodes[0].sendtoaddress(newaddress2, 1)
        self.nodes[0].generate(1)
        self.sync_blocks()
        out =  self.nodes[0].listunspent(query_options={'assetGuid': self.asset, 'minimumAmountAsset': 0.5})
        assert_equal(len(out), 1)
        out =  self.nodes[2].listunspent()
        assert_equal(len(out), 2)
        # send 2 asset UTXOs to newaddress2 same logic as explained above about dbl spend
        self.nodes[0].assetallocationsend(self.asset, newaddress2, int(0.4*COIN))
        self.nodes[0].assetallocationsend(self.asset, newaddress2, int(1*COIN))
        self.nodes[0].generate(1)
        self.sync_blocks()
        # should have 2 sys utxos and 2 asset utxos
        out =  self.nodes[2].listunspent()
        assert_equal(len(out), 4)
        # this will use 1 sys utxo and 1 asset utxo and send it to change address owned by node2
        self.nodes[1].assetallocationsend(self.asset, newaddress1, int(0.4*COIN))
        self.sync_mempools(timeout=30)
        # node3 should have 2 less utxos because they were sent to change on node2
        out =  self.nodes[2].listunspent(minconf=0)
        assert_equal(len(out), 2)
        tx1 = self.nodes[1].assetallocationsend(self.asset, newaddress1, int(1*COIN))['txid']
        # dbl spend
        tx2 = self.nodes[2].assetallocationsend(self.asset, newaddress1, int(0.9*COIN))['txid']
        # use tx2 to build tx3
        tx3 = self.nodes[2].assetallocationsend(self.asset, newaddress1, int(0.05*COIN))['txid']
        # use tx2 to build tx4
        tx4 = self.nodes[2].assetallocationsend(self.asset, newaddress1, int(0.025*COIN))['txid']
        self.sync_all()
        for i in range(3):
            assert_equal(self.nodes[i].assetallocationverifyzdag(tx1)['status'], ZDAG_MAJOR_CONFLICT)
            # ensure the tx2 made it to mempool, should propogate dbl-spend first time
            assert_equal(self.nodes[i].assetallocationverifyzdag(tx2)['status'], ZDAG_MAJOR_CONFLICT)
            # will conflict because its using tx2 which is in conflict state
            assert_equal(self.nodes[i].assetallocationverifyzdag(tx3)['status'], ZDAG_MAJOR_CONFLICT)
            # will conflict because its using tx3 which uses tx2 which is in conflict state
            assert_equal(self.nodes[i].assetallocationverifyzdag(tx4)['status'], ZDAG_MAJOR_CONFLICT)
        self.nodes[0].generate(1)
        self.sync_blocks()
        tx2inchain = False
        for i in range(3):
            try:
                self.nodes[i].getrawtransaction(tx1)
            except:
                tx2inchain = True
                continue
            assert_equal(self.nodes[i].assetallocationverifyzdag(tx1)['status'], ZDAG_NOT_FOUND)
            assert_equal(self.nodes[i].assetallocationverifyzdag(tx2)['status'], ZDAG_NOT_FOUND)
            assert_equal(self.nodes[i].assetallocationverifyzdag(tx3)['status'], ZDAG_NOT_FOUND)
            assert_equal(self.nodes[i].assetallocationverifyzdag(tx4)['status'], ZDAG_NOT_FOUND)
            assert_raises_rpc_error(-5, 'No such mempool transaction', self.nodes[i].getrawtransaction, tx2)
            assert_raises_rpc_error(-5, 'No such mempool transaction', self.nodes[i].getrawtransaction, tx3)
            assert_raises_rpc_error(-5, 'No such mempool transaction', self.nodes[i].getrawtransaction, tx4)
        out =  self.nodes[0].listunspent(query_options={'assetGuid': self.asset, 'minimumAmountAsset':0,'maximumAmountAsset':0})
        assert_equal(len(out), 1)
        out =  self.nodes[0].listunspent(query_options={'assetGuid': self.asset, 'minimumAmountAsset':0.4,'maximumAmountAsset':0.4})
        assert_equal(len(out), 1)
        out =  self.nodes[0].listunspent(query_options={'assetGuid': self.asset, 'minimumAmountAsset':0.6,'maximumAmountAsset':0.6})
        assert_equal(len(out), 1)
        out =  self.nodes[0].listunspent(query_options={'assetGuid': self.asset, 'minimumAmountAsset':1.0,'maximumAmountAsset':1.0})
        if tx2inchain is True:
            assert_equal(len(out), 0)
            out =  self.nodes[0].listunspent(query_options={'assetGuid': self.asset})
            assert_equal(len(out), 6)
        else:
            assert_equal(len(out), 1)
            out =  self.nodes[0].listunspent(query_options={'assetGuid': self.asset})
            assert_equal(len(out), 4)

    def burn_zdag_doublespend(self):
        self.basic_asset()
        self.nodes[0].generate(1)
        useraddress2 = self.nodes[1].getnewaddress()
        useraddress3 = self.nodes[2].getnewaddress()
        useraddress4 = self.nodes[3].getnewaddress()
        useraddress1 = self.nodes[0].getnewaddress()
        # needed by node4 when dbl-spending
        self.nodes[3].importprivkey(self.nodes[0].dumpprivkey(useraddress1))
        self.nodes[0].sendtoaddress(useraddress1, 1)
        self.nodes[0].sendtoaddress(useraddress1, 1)
        self.nodes[0].sendtoaddress(useraddress2, 1)
        self.nodes[0].sendtoaddress(useraddress3, 1)
        self.nodes[0].sendtoaddress(useraddress4, 1)
        self.nodes[0].assetsendmany(self.asset,[{'address': useraddress1,'amount':int(1.0*COIN)},{'address': useraddress2,'amount':int(0.4*COIN)},{'address': useraddress3,'amount':int(0.5*COIN)}])
        self.nodes[0].generate(1)
        self.sync_blocks()
        # create seperate output for dbl spend
        self.nodes[0].assetsend(self.asset, useraddress1, int(0.5*COIN))
        # try to do multiple asset sends in one block
        assert_raises_rpc_error(-4, 'bad-txns-asset-inputs-missingorspent', self.nodes[0].assetsend, self.asset, useraddress1, int(2*COIN))
        self.nodes[0].generate(1)
        self.sync_blocks()
        self.nodes[0].assetallocationsend(self.asset, useraddress2, int(0.2*COIN))
        self.nodes[1].assetallocationsend(self.asset, useraddress1, int(0.2*COIN))
        self.nodes[0].assetallocationsend(self.asset, useraddress3, int(0.2*COIN))
        self.nodes[2].assetallocationsend(self.asset, useraddress1, int(0.2*COIN))
        self.sync_mempools(timeout=30)
        # put all in useraddress1 so node4 can access in dbl spend, its probably in change address prior to this on node0
        self.nodes[0].assetallocationsend(self.asset, useraddress1, int(1.5*COIN))
        self.sync_mempools(timeout=30)
        txid = self.nodes[0].assetallocationsend(self.asset, useraddress1, int(1.5*COIN))['txid']
        # dbl spend
        txdblspend = self.nodes[3].assetallocationburn(self.asset, int(1.1*COIN), "0x931d387731bbbc988b312206c74f77d004d6b84b")["txid"]
        rawtx = self.nodes[0].getrawtransaction(txid)
        self.nodes[1].sendrawtransaction(rawtx)
        self.nodes[2].sendrawtransaction(rawtx)

        self.nodes[1].assetallocationsend(self.asset, useraddress3, int(0.2*COIN))
        self.nodes[2].assetallocationburn(self.asset, int(0.3*COIN), "0x931d387731bbbc988b312206c74f77d004d6b84b")
        self.sync_mempools(self.nodes[0:3], timeout=30)
        # node1/node2/node3 shouldn't have dbl spend tx because no RBF and not zdag tx
        assert_raises_rpc_error(-5, 'No such mempool transaction', self.nodes[0].getrawtransaction, txdblspend)
        assert_raises_rpc_error(-5, 'No such mempool transaction', self.nodes[1].getrawtransaction, txdblspend)
        assert_raises_rpc_error(-5, 'No such mempool transaction', self.nodes[2].getrawtransaction, txdblspend)
        self.nodes[3].getrawtransaction(txdblspend)
        self.nodes[0].generate(1)
        self.sync_blocks()
        # after block, even node4 should have removed conflicting tx
        assert_raises_rpc_error(-5, 'No such mempool transaction', self.nodes[3].getrawtransaction, txdblspend)
        out =  self.nodes[0].listunspent(query_options={'assetGuid': self.asset, 'minimumAmountAsset':0,'maximumAmountAsset':0})
        assert_equal(len(out), 1)
        out =  self.nodes[0].listunspent(query_options={'assetGuid': self.asset, 'minimumAmountAsset':1.5,'maximumAmountAsset':1.5})
        assert_equal(len(out), 1)
        out =  self.nodes[1].listunspent(query_options={'assetGuid': self.asset, 'minimumAmountAsset':0.2,'maximumAmountAsset':0.2})
        assert_equal(len(out), 1)
        out =  self.nodes[2].listunspent(query_options={'assetGuid': self.asset, 'minimumAmountAsset':0.2,'maximumAmountAsset':0.2})
        assert_equal(len(out), 2)
        out =  self.nodes[3].listunspent(query_options={'assetGuid': self.asset, 'minimumAmountAsset':1.5,'maximumAmountAsset':1.5})
        assert_equal(len(out), 1)

    def burn_zdag_doublespend_chain(self):
        # SYSX guid on regtest is 123456
        self.basic_asset(123456)
        self.nodes[0].generate(1)
        useraddress0 = self.nodes[0].getnewaddress()
        useraddress1 = self.nodes[0].getnewaddress()
        useraddress2 = self.nodes[0].getnewaddress()
        useraddress3 = self.nodes[0].getnewaddress()
        self.nodes[0].syscoinburntoassetallocation(self.asset, int(1*COIN))
        self.nodes[0].syscoinburntoassetallocation(self.asset, int(1*COIN))
        self.nodes[0].assetallocationsend(self.asset, useraddress1, int(0.1*COIN))
        self.nodes[0].assetallocationsend(self.asset, useraddress2, int(0.01*COIN))
        self.nodes[0].assetallocationsend(self.asset, useraddress2, int(0.001*COIN))
        self.nodes[0].assetallocationsend(self.asset, useraddress3, int(0.0001*COIN))
        self.nodes[0].assetallocationsend(self.asset, useraddress2, int(0.00001*COIN))
        self.nodes[0].assetallocationburn(self.asset, int(0.01*COIN), '')
        self.nodes[0].assetallocationburn(self.asset, int(0.01*COIN), '')
        self.nodes[0].assetallocationburn(self.asset, int(0.001*COIN), '')
        self.nodes[0].assetallocationburn(self.asset, int(0.001*COIN), '')
        self.nodes[0].assetallocationburn(self.asset, int(0.0001*COIN), '')
        self.nodes[0].assetallocationburn(self.asset, int(0.0001*COIN), '')
        self.nodes[0].syscoinburntoassetallocation(self.asset, useraddress0, int(1*COIN))
        self.nodes[0].assetupdate(self.asset, '', '', 0, 31, {})
        self.nodes[0].syscoinburntoassetallocation(self.asset, int(1*COIN))
        self.nodes[0].assetupdate(self.asset, '', '', 0, 31, {})
        self.nodes[0].syscoinburntoassetallocation(self.asset, int(1*COIN))
        self.nodes[0].assetupdate(self.asset, '', '', 0, 31, {})
        self.nodes[0].generate(1)

    def basic_asset(self, guid):
        if guid is None:
            self.asset = self.nodes[0].assetnew('1', "TST", "asset description", "0x9f90b5093f35aeac5fbaeb591f9c9de8e2844a46", 8, 1000*COIN, 10000*COIN, 31, {})['asset_guid']
        else:
            self.asset = self.nodes[0].assetnewtest(guid, '1', "TST", "asset description", "0x9f90b5093f35aeac5fbaeb591f9c9de8e2844a46", 8, 1000*COIN, 10000*COIN, 31, {})['asset_guid']

if __name__ == '__main__':
    AssetZDAGTest().main()
<commit_msg>fix burn<commit_after>#!/usr/bin/env python3
# Copyright (c) 2019-2020 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.

from test_framework.test_framework import SyscoinTestFramework
from test_framework.util import assert_equal, assert_raises_rpc_error, set_node_times, disconnect_nodes, connect_nodes, bump_node_times
from test_framework.messages import COIN
import time
ZDAG_NOT_FOUND = -1
ZDAG_STATUS_OK = 0
ZDAG_WARNING_RBF = 1
ZDAG_WARNING_NOT_ZDAG_TX = 2
ZDAG_WARNING_SIZE_OVER_POLICY = 3
ZDAG_MAJOR_CONFLICT = 4
MAX_INITIAL_BROADCAST_DELAY = 15 * 60 # 15 minutes in seconds
class AssetZDAGTest(SyscoinTestFramework):
    def set_test_params(self):
        self.setup_clean_chain = True
        self.num_nodes = 4
        self.rpc_timeout = 240
        self.extra_args = [['-assetindex=1'],['-assetindex=1'],['-assetindex=1'],['-assetindex=1']]

    def run_test(self):
        self.nodes[0].generate(200)
        self.sync_blocks()
        self.burn_zdag_doublespend_chain()
        #self.basic_zdag_doublespend()
        #self.burn_zdag_doublespend()

    def basic_zdag_doublespend(self):
        self.basic_asset()
        self.nodes[0].generate(1)
        newaddress2 = self.nodes[1].getnewaddress()
        newaddress3 = self.nodes[1].getnewaddress()
        newaddress1 = self.nodes[0].getnewaddress()
        self.nodes[2].importprivkey(self.nodes[1].dumpprivkey(newaddress2))
        self.nodes[0].assetsend(self.asset, newaddress1, int(2*COIN))
        # create 2 utxo's so below newaddress1 recipient of 0.5 COIN uses 1 and the newaddress3 recipient on node3 uses the other on dbl spend
        self.nodes[0].sendtoaddress(newaddress2, 1)
        self.nodes[0].sendtoaddress(newaddress2, 1)
        self.nodes[0].generate(1)
        self.sync_blocks()
        out =  self.nodes[0].listunspent(query_options={'assetGuid': self.asset, 'minimumAmountAsset': 0.5})
        assert_equal(len(out), 1)
        out =  self.nodes[2].listunspent()
        assert_equal(len(out), 2)
        # send 2 asset UTXOs to newaddress2 same logic as explained above about dbl spend
        self.nodes[0].assetallocationsend(self.asset, newaddress2, int(0.4*COIN))
        self.nodes[0].assetallocationsend(self.asset, newaddress2, int(1*COIN))
        self.nodes[0].generate(1)
        self.sync_blocks()
        # should have 2 sys utxos and 2 asset utxos
        out =  self.nodes[2].listunspent()
        assert_equal(len(out), 4)
        # this will use 1 sys utxo and 1 asset utxo and send it to change address owned by node2
        self.nodes[1].assetallocationsend(self.asset, newaddress1, int(0.4*COIN))
        self.sync_mempools(timeout=30)
        # node3 should have 2 less utxos because they were sent to change on node2
        out =  self.nodes[2].listunspent(minconf=0)
        assert_equal(len(out), 2)
        tx1 = self.nodes[1].assetallocationsend(self.asset, newaddress1, int(1*COIN))['txid']
        # dbl spend
        tx2 = self.nodes[2].assetallocationsend(self.asset, newaddress1, int(0.9*COIN))['txid']
        # use tx2 to build tx3
        tx3 = self.nodes[2].assetallocationsend(self.asset, newaddress1, int(0.05*COIN))['txid']
        # use tx2 to build tx4
        tx4 = self.nodes[2].assetallocationsend(self.asset, newaddress1, int(0.025*COIN))['txid']
        self.sync_all()
        for i in range(3):
            assert_equal(self.nodes[i].assetallocationverifyzdag(tx1)['status'], ZDAG_MAJOR_CONFLICT)
            # ensure the tx2 made it to mempool, should propogate dbl-spend first time
            assert_equal(self.nodes[i].assetallocationverifyzdag(tx2)['status'], ZDAG_MAJOR_CONFLICT)
            # will conflict because its using tx2 which is in conflict state
            assert_equal(self.nodes[i].assetallocationverifyzdag(tx3)['status'], ZDAG_MAJOR_CONFLICT)
            # will conflict because its using tx3 which uses tx2 which is in conflict state
            assert_equal(self.nodes[i].assetallocationverifyzdag(tx4)['status'], ZDAG_MAJOR_CONFLICT)
        self.nodes[0].generate(1)
        self.sync_blocks()
        tx2inchain = False
        for i in range(3):
            try:
                self.nodes[i].getrawtransaction(tx1)
            except:
                tx2inchain = True
                continue
            assert_equal(self.nodes[i].assetallocationverifyzdag(tx1)['status'], ZDAG_NOT_FOUND)
            assert_equal(self.nodes[i].assetallocationverifyzdag(tx2)['status'], ZDAG_NOT_FOUND)
            assert_equal(self.nodes[i].assetallocationverifyzdag(tx3)['status'], ZDAG_NOT_FOUND)
            assert_equal(self.nodes[i].assetallocationverifyzdag(tx4)['status'], ZDAG_NOT_FOUND)
            assert_raises_rpc_error(-5, 'No such mempool transaction', self.nodes[i].getrawtransaction, tx2)
            assert_raises_rpc_error(-5, 'No such mempool transaction', self.nodes[i].getrawtransaction, tx3)
            assert_raises_rpc_error(-5, 'No such mempool transaction', self.nodes[i].getrawtransaction, tx4)
        out =  self.nodes[0].listunspent(query_options={'assetGuid': self.asset, 'minimumAmountAsset':0,'maximumAmountAsset':0})
        assert_equal(len(out), 1)
        out =  self.nodes[0].listunspent(query_options={'assetGuid': self.asset, 'minimumAmountAsset':0.4,'maximumAmountAsset':0.4})
        assert_equal(len(out), 1)
        out =  self.nodes[0].listunspent(query_options={'assetGuid': self.asset, 'minimumAmountAsset':0.6,'maximumAmountAsset':0.6})
        assert_equal(len(out), 1)
        out =  self.nodes[0].listunspent(query_options={'assetGuid': self.asset, 'minimumAmountAsset':1.0,'maximumAmountAsset':1.0})
        if tx2inchain is True:
            assert_equal(len(out), 0)
            out =  self.nodes[0].listunspent(query_options={'assetGuid': self.asset})
            assert_equal(len(out), 6)
        else:
            assert_equal(len(out), 1)
            out =  self.nodes[0].listunspent(query_options={'assetGuid': self.asset})
            assert_equal(len(out), 4)

    def burn_zdag_doublespend(self):
        self.basic_asset()
        self.nodes[0].generate(1)
        useraddress2 = self.nodes[1].getnewaddress()
        useraddress3 = self.nodes[2].getnewaddress()
        useraddress4 = self.nodes[3].getnewaddress()
        useraddress1 = self.nodes[0].getnewaddress()
        # needed by node4 when dbl-spending
        self.nodes[3].importprivkey(self.nodes[0].dumpprivkey(useraddress1))
        self.nodes[0].sendtoaddress(useraddress1, 1)
        self.nodes[0].sendtoaddress(useraddress1, 1)
        self.nodes[0].sendtoaddress(useraddress2, 1)
        self.nodes[0].sendtoaddress(useraddress3, 1)
        self.nodes[0].sendtoaddress(useraddress4, 1)
        self.nodes[0].assetsendmany(self.asset,[{'address': useraddress1,'amount':int(1.0*COIN)},{'address': useraddress2,'amount':int(0.4*COIN)},{'address': useraddress3,'amount':int(0.5*COIN)}])
        self.nodes[0].generate(1)
        self.sync_blocks()
        # create seperate output for dbl spend
        self.nodes[0].assetsend(self.asset, useraddress1, int(0.5*COIN))
        # try to do multiple asset sends in one block
        assert_raises_rpc_error(-4, 'bad-txns-asset-inputs-missingorspent', self.nodes[0].assetsend, self.asset, useraddress1, int(2*COIN))
        self.nodes[0].generate(1)
        self.sync_blocks()
        self.nodes[0].assetallocationsend(self.asset, useraddress2, int(0.2*COIN))
        self.nodes[1].assetallocationsend(self.asset, useraddress1, int(0.2*COIN))
        self.nodes[0].assetallocationsend(self.asset, useraddress3, int(0.2*COIN))
        self.nodes[2].assetallocationsend(self.asset, useraddress1, int(0.2*COIN))
        self.sync_mempools(timeout=30)
        # put all in useraddress1 so node4 can access in dbl spend, its probably in change address prior to this on node0
        self.nodes[0].assetallocationsend(self.asset, useraddress1, int(1.5*COIN))
        self.sync_mempools(timeout=30)
        txid = self.nodes[0].assetallocationsend(self.asset, useraddress1, int(1.5*COIN))['txid']
        # dbl spend
        txdblspend = self.nodes[3].assetallocationburn(self.asset, int(1.1*COIN), "0x931d387731bbbc988b312206c74f77d004d6b84b")["txid"]
        rawtx = self.nodes[0].getrawtransaction(txid)
        self.nodes[1].sendrawtransaction(rawtx)
        self.nodes[2].sendrawtransaction(rawtx)

        self.nodes[1].assetallocationsend(self.asset, useraddress3, int(0.2*COIN))
        self.nodes[2].assetallocationburn(self.asset, int(0.3*COIN), "0x931d387731bbbc988b312206c74f77d004d6b84b")
        self.sync_mempools(self.nodes[0:3], timeout=30)
        # node1/node2/node3 shouldn't have dbl spend tx because no RBF and not zdag tx
        assert_raises_rpc_error(-5, 'No such mempool transaction', self.nodes[0].getrawtransaction, txdblspend)
        assert_raises_rpc_error(-5, 'No such mempool transaction', self.nodes[1].getrawtransaction, txdblspend)
        assert_raises_rpc_error(-5, 'No such mempool transaction', self.nodes[2].getrawtransaction, txdblspend)
        self.nodes[3].getrawtransaction(txdblspend)
        self.nodes[0].generate(1)
        self.sync_blocks()
        # after block, even node4 should have removed conflicting tx
        assert_raises_rpc_error(-5, 'No such mempool transaction', self.nodes[3].getrawtransaction, txdblspend)
        out =  self.nodes[0].listunspent(query_options={'assetGuid': self.asset, 'minimumAmountAsset':0,'maximumAmountAsset':0})
        assert_equal(len(out), 1)
        out =  self.nodes[0].listunspent(query_options={'assetGuid': self.asset, 'minimumAmountAsset':1.5,'maximumAmountAsset':1.5})
        assert_equal(len(out), 1)
        out =  self.nodes[1].listunspent(query_options={'assetGuid': self.asset, 'minimumAmountAsset':0.2,'maximumAmountAsset':0.2})
        assert_equal(len(out), 1)
        out =  self.nodes[2].listunspent(query_options={'assetGuid': self.asset, 'minimumAmountAsset':0.2,'maximumAmountAsset':0.2})
        assert_equal(len(out), 2)
        out =  self.nodes[3].listunspent(query_options={'assetGuid': self.asset, 'minimumAmountAsset':1.5,'maximumAmountAsset':1.5})
        assert_equal(len(out), 1)

    def burn_zdag_doublespend_chain(self):
        # SYSX guid on regtest is 123456
        self.basic_asset(123456)
        self.nodes[0].generate(1)
        useraddress0 = self.nodes[0].getnewaddress()
        useraddress1 = self.nodes[0].getnewaddress()
        useraddress2 = self.nodes[0].getnewaddress()
        useraddress3 = self.nodes[0].getnewaddress()
        self.nodes[0].syscoinburntoassetallocation(self.asset, int(1*COIN))
        self.nodes[0].syscoinburntoassetallocation(self.asset, int(1*COIN))
        self.nodes[0].assetallocationsend(self.asset, useraddress1, int(0.1*COIN))
        self.nodes[0].assetallocationsend(self.asset, useraddress2, int(0.01*COIN))
        self.nodes[0].assetallocationsend(self.asset, useraddress2, int(0.001*COIN))
        self.nodes[0].assetallocationsend(self.asset, useraddress3, int(0.0001*COIN))
        self.nodes[0].assetallocationsend(self.asset, useraddress2, int(0.00001*COIN))
        self.nodes[0].assetallocationburn(self.asset, int(0.01*COIN), '')
        self.nodes[0].assetallocationburn(self.asset, int(0.01*COIN), '')
        self.nodes[0].assetallocationburn(self.asset, int(0.001*COIN), '')
        self.nodes[0].assetallocationburn(self.asset, int(0.001*COIN), '')
        self.nodes[0].assetallocationburn(self.asset, int(0.0001*COIN), '')
        self.nodes[0].assetallocationburn(self.asset, int(0.0001*COIN), '')
        self.nodes[0].syscoinburntoassetallocation(self.asset, int(1*COIN))
        self.nodes[0].assetupdate(self.asset, '', '', 0, 31, {})
        self.nodes[0].syscoinburntoassetallocation(self.asset, int(1*COIN))
        self.nodes[0].assetupdate(self.asset, '', '', 0, 31, {})
        self.nodes[0].syscoinburntoassetallocation(self.asset, int(1*COIN))
        self.nodes[0].assetupdate(self.asset, '', '', 0, 31, {})
        self.nodes[0].generate(1)

    def basic_asset(self, guid):
        if guid is None:
            self.asset = self.nodes[0].assetnew('1', "TST", "asset description", "0x9f90b5093f35aeac5fbaeb591f9c9de8e2844a46", 8, 1000*COIN, 10000*COIN, 31, {})['asset_guid']
        else:
            self.asset = self.nodes[0].assetnewtest(guid, '1', "TST", "asset description", "0x9f90b5093f35aeac5fbaeb591f9c9de8e2844a46", 8, 1000*COIN, 10000*COIN, 31, {})['asset_guid']

if __name__ == '__main__':
    AssetZDAGTest().main()
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-

from ambry.metadata.schema import Top

from ambry.orm import Config

from test.factories import DatasetFactory
from test.test_base import TestBase

class DatabaseConfigUpdateTest(TestBase):
    """ Tests db update after property tree change. """
    def setUp(self):
        super(DatabaseConfigUpdateTest, self).setUp()
        self.db = self.library().database
        DatasetFactory._meta.sqlalchemy_session = self.db.session
        self.dataset = DatasetFactory()

    def test_create_group_and_config_in_the_db(self):
        """ Setting empty property tree key creates group and config in the db. """
        db = self.db
        dataset = self.dataset

        top = Top()

        # bind tree to the database
        top.link_config(db.session, dataset)

        # change some fields
        top.names.vid = dataset.vid
        top.about.access = 'public'

        # testing
        query = db.session.query(Config)
        top_config = query.filter_by(d_vid=dataset.vid, type='metadata', parent=None).first()

        # top config does not have key or value
        self.assertIsNone(top_config.key, '')
        self.assertEqual(top_config.value, {})

        #
        # names and about groups does not have values
        #
        names_group = query.filter_by(d_vid=dataset.vid, type='metadata', group='names').first()
        self.assertEqual(names_group.key, 'names')
        self.assertEqual(names_group.value, {})
        self.assertEqual(names_group.parent, top_config)

        about_group = query.filter_by(d_vid=dataset.vid, type='metadata', group='about').first()
        self.assertEqual(about_group.key, 'about')
        self.assertEqual(about_group.value, {})
        self.assertEqual(about_group.parent, top_config)

        #
        # Configs have proper parents and values.
        #
        vid_config = query.filter_by(d_vid=dataset.vid, type='metadata', key='vid').first()
        self.assertEqual(vid_config.key, 'vid')
        self.assertEqual(vid_config.value, dataset.vid)
        self.assertEqual(vid_config.parent, names_group)

    def test_change_database_values(self):
        """ Changing existing property tree key value changes config instance. """
        db = self.db
        dataset = self.dataset

        top = Top()

        # bind tree to the database
        top.link_config(db.session, dataset)

        # change some fields
        top.names.vid = dataset.vid

        # testing
        query = db.session.query(Config)
        vid_config = query.filter_by(d_vid=dataset.vid, type='metadata', key='vid').first()
        self.assertEqual(vid_config.value, dataset.vid)

        top.names.vid = 'vid-1'
        vid_config = query.filter_by(type='metadata', key='vid').first()
        self.assertEqual(vid_config.value, 'vid-1')

class BuildPropertyTreeFromDatabaseTest(TestBase):

    def setUp(self):
        super(self.__class__, self).setUp()
        self.db = self.library().database
        DatasetFactory._meta.sqlalchemy_session = self.db.session
        self.dataset = DatasetFactory()

    # helpers
    def _create_db_tree(self):
        """ Creates tree in the database.

            .names.vid = dataset.vid
        """
        db = self.db
        dataset = self.dataset
        top_config = Config(d_vid=dataset.vid, parent=None, type='metadata', sequence_id=1)
        db.session.add(top_config)
        db.session.commit()
        names_config = Config(
            d_vid=dataset.vid, key='names', group='names',
            parent=top_config, type='metadata', sequence_id=2)
        db.session.add(names_config)
        db.session.commit()

        vid_value_config = Config(
            d_vid=dataset.vid, key='vid', value=dataset.vid,
            parent=names_config, type='metadata', sequence_id=3)
        db.session.add(vid_value_config)
        db.session.commit()

    # tests
    def test_build_tree_from_database(self):
        """ Populates property tree with values from database. """

        # create appropriate tree in the database
        self._create_db_tree()

        # build from db
        top = Top()
        top.build_from_db(self.dataset)
        self.assertEqual(top.names.vid, self.dataset.vid)

    def test_change_tree_build_from_database(self):

        # create appropriate tree in the database
        self._create_db_tree()

        # build from db
        top = Top()
        top.build_from_db(self.dataset)

        # change and test
        assert top.is_bound()
        vid_value_config = self.db.session.query(Config).filter_by(key='vid', type='metadata').one()
        self.assertNotEqual(vid_value_config.value, 'vid-2')
        top.names.vid = 'vid-2'
        vid_value_config = self.db.session.query(Config).filter_by(key='vid', type='metadata').one()
        self.assertEqual(vid_value_config.value, 'vid-2')
<commit_msg>Property tree tests use proto library. #187.<commit_after># -*- coding: utf-8 -*-

from ambry.metadata.schema import Top

from ambry.orm import Config

from test.factories import DatasetFactory
from test.proto import TestBase

class DatabaseConfigUpdateTest(TestBase):
    """ Tests db update after property tree change. """
    def setUp(self):
        super(DatabaseConfigUpdateTest, self).setUp()
        self.db = self.library().database
        DatasetFactory._meta.sqlalchemy_session = self.db.session
        self.dataset = DatasetFactory()

    def test_create_group_and_config_in_the_db(self):
        """ Setting empty property tree key creates group and config in the db. """
        db = self.db
        dataset = self.dataset

        top = Top()

        # bind tree to the database
        top.link_config(db.session, dataset)

        # change some fields
        top.names.vid = dataset.vid
        top.about.access = 'public'

        # testing
        query = db.session.query(Config)
        top_config = query.filter_by(d_vid=dataset.vid, type='metadata', parent=None).first()

        # top config does not have key or value
        self.assertIsNone(top_config.key, '')
        self.assertEqual(top_config.value, {})

        #
        # names and about groups does not have values
        #
        names_group = query.filter_by(d_vid=dataset.vid, type='metadata', group='names').first()
        self.assertEqual(names_group.key, 'names')
        self.assertEqual(names_group.value, {})
        self.assertEqual(names_group.parent, top_config)

        about_group = query.filter_by(d_vid=dataset.vid, type='metadata', group='about').first()
        self.assertEqual(about_group.key, 'about')
        self.assertEqual(about_group.value, {})
        self.assertEqual(about_group.parent, top_config)

        #
        # Configs have proper parents and values.
        #
        vid_config = query.filter_by(d_vid=dataset.vid, type='metadata', key='vid').first()
        self.assertEqual(vid_config.key, 'vid')
        self.assertEqual(vid_config.value, dataset.vid)
        self.assertEqual(vid_config.parent, names_group)

    def test_change_database_values(self):
        """ Changing existing property tree key value changes config instance. """
        db = self.db
        dataset = self.dataset

        top = Top()

        # bind tree to the database
        top.link_config(db.session, dataset)

        # change some fields
        top.names.vid = dataset.vid

        # testing
        query = db.session.query(Config)
        vid_config = query.filter_by(d_vid=dataset.vid, type='metadata', key='vid').first()
        self.assertEqual(vid_config.value, dataset.vid)

        top.names.vid = 'vid-1'
        vid_config = query.filter_by(type='metadata', key='vid').first()
        self.assertEqual(vid_config.value, 'vid-1')

class BuildPropertyTreeFromDatabaseTest(TestBase):

    def setUp(self):
        super(self.__class__, self).setUp()
        self.db = self.library().database
        DatasetFactory._meta.sqlalchemy_session = self.db.session
        self.dataset = DatasetFactory()

    # helpers
    def _create_db_tree(self):
        """ Creates tree in the database.

            .names.vid = dataset.vid
        """
        db = self.db
        dataset = self.dataset
        top_config = Config(d_vid=dataset.vid, parent=None, type='metadata', sequence_id=1)
        db.session.add(top_config)
        db.session.commit()
        names_config = Config(
            d_vid=dataset.vid, key='names', group='names',
            parent=top_config, type='metadata', sequence_id=2)
        db.session.add(names_config)
        db.session.commit()

        vid_value_config = Config(
            d_vid=dataset.vid, key='vid', value=dataset.vid,
            parent=names_config, type='metadata', sequence_id=3)
        db.session.add(vid_value_config)
        db.session.commit()

    # tests
    def test_build_tree_from_database(self):
        """ Populates property tree with values from database. """

        # create appropriate tree in the database
        self._create_db_tree()

        # build from db
        top = Top()
        top.build_from_db(self.dataset)
        self.assertEqual(top.names.vid, self.dataset.vid)

    def test_change_tree_build_from_database(self):

        # create appropriate tree in the database
        self._create_db_tree()

        # build from db
        top = Top()
        top.build_from_db(self.dataset)

        # change and test
        assert top.is_bound()
        vid_value_config = self.db.session.query(Config).filter_by(key='vid', type='metadata').one()
        self.assertNotEqual(vid_value_config.value, 'vid-2')
        top.names.vid = 'vid-2'
        vid_value_config = self.db.session.query(Config).filter_by(key='vid', type='metadata').one()
        self.assertEqual(vid_value_config.value, 'vid-2')
<|endoftext|>


<commit_before>import pymbolic.primitives as p
from finiteelementbase import FiniteElementBase, Recipe
from utils import doc_inherit, IndexSum
import FIAT
import indices

class Lagrange(FiniteElementBase):
    def __init__(self, cell, degree):
        super(Lagrange, self).__init__()

        self._cell = cell
        self._degree = degree

        self._fiat_element = FIAT.Lagrange(cell, degree)

    @property
    def entity_dofs(self):
        '''Return the map of topological entities to degrees of
        freedom for the finite element.

        Note that entity numbering needs to take into account the tensor case.
        '''

        return self._fiat_element.entity_dofs()

    @property
    def entity_closure_dofs(self):
        '''Return the map of topological entities to degrees of
        freedom on the closure of those entities for the finite element.'''

        return self._fiat_element.entity_dofs()

    @property
    def facet_support_dofs(self):
        '''Return the map of facet id to the degrees of freedom for which the
        corresponding basis functions take non-zero values.'''

        return self._fiat_element.entity_support_dofs()

    @doc_inherit
    def basis_evaluation(self, points, kernel_data, derivative=None):

        # updates the requisite static data, which in this case
        # is just the matrix.
        static_key = (id(self), id(points), id(derivative))

        static_data = kernel_data.static
        fiat_element = self._fiat_element

        if static_key in static_data:
            phi = static_data[static_key][0]
        else:
            phi = p.Variable('phi_e' + str(self._id))
            # FIXME: for derivative != None, we've got to reengineer this.
            data = fiat_element.tabulate(0, points.points)[
                tuple([0]*points.points.shape[1])]
            static_data[static_key] = (phi, lambda: data)

        # Note for derivative you get a spatial index in here too.
        i = indices.BasisFunctionIndex(fiat_element.space_dimension())
        q = indices.PointIndex(points.points.shape[0])

        ind = [i, q]

        instructions = [phi[i, q]]

        params = []

        return Recipe(ind, instructions, params)

    @doc_inherit
    def field_evaluation(self, field_var, points,
                         kernel_data, derivative=None):

        # updates the requisite static data, which in this case
        # is just the matrix.
        static_key = (id(self), id(points), id(derivative))

        static_data = kernel_data.static
        fiat_element = self._fiat_element

        if static_key in static_data:
            phi = static_data[static_key][0]
        else:
            phi = p.Variable('phi_e' + str(self._id))
            # FIXME: for derivative != None, we've got to reengineer this.
            data = fiat_element.tabulate(0, points.points)[
                tuple([0]*points.points.shape[1])]
            static_data[static_key] = (phi, lambda: data)

        # Note for derivative you get a spatial index in here too.
        i = indices.BasisFunctionIndex(fiat_element.space_dimension())
        q = indices.PointIndex(points.points.shape[0])

        ind = [q]

        instructions = [IndexSum(i, field_var[i] * phi[i, q])]

        params = [field_var]

        return Recipe(ind, instructions, params)
<commit_msg>Lagrange element with derivatives<commit_after>import pymbolic.primitives as p
from finiteelementbase import FiniteElementBase, Recipe
from utils import doc_inherit, IndexSum
import FIAT
import indices
from derivatives import div, grad, curl
import numpy as np

class Lagrange(FiniteElementBase):
    def __init__(self, cell, degree):
        super(Lagrange, self).__init__()

        self._cell = cell
        self._degree = degree

        self._fiat_element = FIAT.Lagrange(cell, degree)

    @property
    def entity_dofs(self):
        '''Return the map of topological entities to degrees of
        freedom for the finite element.

        Note that entity numbering needs to take into account the tensor case.
        '''

        return self._fiat_element.entity_dofs()

    @property
    def entity_closure_dofs(self):
        '''Return the map of topological entities to degrees of
        freedom on the closure of those entities for the finite element.'''

        return self._fiat_element.entity_dofs()

    @property
    def facet_support_dofs(self):
        '''Return the map of facet id to the degrees of freedom for which the
        corresponding basis functions take non-zero values.'''

        return self._fiat_element.entity_support_dofs()

    def _tabulate(self, points, derivative):

        if derivative is None:
            return fiat_element.tabulate(0, points.points)[
                tuple([0]*points.points.shape[1])]
        elif derivative is grad:
            tab = fiat_element.tabulate(1, points.points)

            indices = np.eye(points.points.shape[1], dtype=int)

            return np.array([tab[tuple(i)] for i in indices])

        else:
            raise ValueError(
                "Lagrange elements do not have a %s operation") % derivative

    @doc_inherit
    def basis_evaluation(self, points, kernel_data, derivative=None):

        # updates the requisite static data, which in this case
        # is just the matrix.
        static_key = (id(self), id(points), id(derivative))

        static_data = kernel_data.static
        fiat_element = self._fiat_element

        if static_key in static_data:
            phi = static_data[static_key][0]
        else:
            phi = p.Variable('phi_e' if derivative is None else "dphi_e"
                             + str(self._id))
            # FIXME: for derivative != None, we've got to reengineer this.
            data = self._tabulate(points, derivative)
            static_data[static_key] = (phi, lambda: data)

        # Note for derivative you get a spatial index in here too.
        i = indices.BasisFunctionIndex(fiat_element.space_dimension())
        q = indices.PointIndex(points.points.shape[0])

        ind = [i, q]

        if derivative is grad:
            alpha = indices.DimensionIndex(points.points.shape[1])
            ind = [alpha] + ind

        instructions = [phi[ind]]

        params = []

        return Recipe(ind, instructions, params)

    @doc_inherit
    def field_evaluation(self, field_var, points,
                         kernel_data, derivative=None):

        # updates the requisite static data, which in this case
        # is just the matrix.
        static_key = (id(self), id(points), id(derivative))

        static_data = kernel_data.static
        fiat_element = self._fiat_element

        if static_key in static_data:
            phi = static_data[static_key][0]
        else:
            phi = p.Variable('phi_e' if derivative is None else "dphi_e"
                             + str(self._id))
            # FIXME: for derivative != None, we've got to reengineer this.
            data = self._tabulate(points, derivative)
            static_data[static_key] = (phi, lambda: data)

        # Note for derivative you get a spatial index in here too.
        i = indices.BasisFunctionIndex(fiat_element.space_dimension())
        q = indices.PointIndex(points.points.shape[0])

        ind = [q]
        data_ind = [i, q]

        if derivative is grad:
            alpha = indices.DimensionIndex(points.points.shape[1])
            ind = [alpha] + ind
            data_ind = [alpha] + data_ind

        instructions = [IndexSum(i, field_var[i] * phi[data_ind])]

        params = [field_var]

        return Recipe(ind, instructions, params)
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
"""A YAML loader that loads mappings into ordered dictionaries.
(http://stackoverflow.com/questions/5121931/in-python-how-can-you-load-yaml-mappings-as-ordereddicts)
"""

import yaml
import sys
if float('%d.%d' % sys.version_info[:2]) < 2.7:
    from ordereddict import OrderedDict
else:
    from collections import OrderedDict

class Loader(yaml.Loader):
    def __init__(self, *args, **kwargs):
        yaml.Loader.__init__(self, *args, **kwargs)
        self.add_constructor(
            'tag:yaml.org,2002:map', type(self).construct_yaml_map)
        self.add_constructor(
            'tag:yaml.org,2002:omap', type(self).construct_yaml_map)

    def construct_yaml_map(self, node):
        data = OrderedDict()
        yield data
        value = self.construct_mapping(node)
        data.update(value)

    def construct_mapping(self, node, deep=False):
        if isinstance(node, yaml.MappingNode):
            self.flatten_mapping(node)
        else:
            msg = 'expected a mapping node, but found %s' % node.id
            raise yaml.constructor.ConstructError(None,
                                                  None,
                                                  msg,
                                                  node.start_mark)

        mapping = OrderedDict()
        for key_node, value_node in node.value:
            key = self.construct_object(key_node, deep=deep)
            try:
                hash(key)
            except TypeError as err:
                raise yaml.constructor.ConstructError(
                    'while constructing a mapping', node.start_mark,
                    'found unacceptable key (%s)' % err, key_node.start_mark)
            value = self.construct_object(value_node, deep=deep)
            mapping[key] = value
        return mapping

def represent_ordereddict(self, data):
    return self.represent_mapping('tag:yaml.org,2002:map', data.items())

class Dumper(yaml.Dumper):
    def __init__(self, *args, **kwargs):
        yaml.Dumper.__init__(self, *args, **kwargs)
        self.add_representer(OrderedDict, type(self).represent_ordereddict)

    represent_ordereddict = represent_ordereddict

class SafeDumper(yaml.Dumper):
    def __init__(self, *args, **kwargs):
        yaml.SafeDumper.__init__(self, *args, **kwargs)
        self.add_representer(OrderedDict, type(self).represent_ordereddict)

    represent_ordereddict = represent_ordereddict
<commit_msg>Correct inheritance from the wrong object for the SafeDumper object.<commit_after># -*- coding: utf-8 -*-
"""A YAML loader that loads mappings into ordered dictionaries.
(http://stackoverflow.com/questions/5121931/in-python-how-can-you-load-yaml-mappings-as-ordereddicts)
"""

import yaml
import sys
if float('%d.%d' % sys.version_info[:2]) < 2.7:
    from ordereddict import OrderedDict
else:
    from collections import OrderedDict

class Loader(yaml.Loader):
    def __init__(self, *args, **kwargs):
        yaml.Loader.__init__(self, *args, **kwargs)
        self.add_constructor(
            'tag:yaml.org,2002:map', type(self).construct_yaml_map)
        self.add_constructor(
            'tag:yaml.org,2002:omap', type(self).construct_yaml_map)

    def construct_yaml_map(self, node):
        data = OrderedDict()
        yield data
        value = self.construct_mapping(node)
        data.update(value)

    def construct_mapping(self, node, deep=False):
        if isinstance(node, yaml.MappingNode):
            self.flatten_mapping(node)
        else:
            msg = 'expected a mapping node, but found %s' % node.id
            raise yaml.constructor.ConstructError(None,
                                                  None,
                                                  msg,
                                                  node.start_mark)

        mapping = OrderedDict()
        for key_node, value_node in node.value:
            key = self.construct_object(key_node, deep=deep)
            try:
                hash(key)
            except TypeError as err:
                raise yaml.constructor.ConstructError(
                    'while constructing a mapping', node.start_mark,
                    'found unacceptable key (%s)' % err, key_node.start_mark)
            value = self.construct_object(value_node, deep=deep)
            mapping[key] = value
        return mapping

def represent_ordereddict(self, data):
    return self.represent_mapping('tag:yaml.org,2002:map', data.items())

class Dumper(yaml.Dumper):
    def __init__(self, *args, **kwargs):
        yaml.Dumper.__init__(self, *args, **kwargs)
        self.add_representer(OrderedDict, type(self).represent_ordereddict)

    represent_ordereddict = represent_ordereddict

class SafeDumper(yaml.SafeDumper):
    def __init__(self, *args, **kwargs):
        yaml.SafeDumper.__init__(self, *args, **kwargs)
        self.add_representer(OrderedDict, type(self).represent_ordereddict)

    represent_ordereddict = represent_ordereddict
<|endoftext|>


<commit_before># Copyright 2015 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Entry points for YAPF.

The main APIs that YAPF exposes to drive the reformatting.

  FormatFile(): reformat a file.
  FormatCode(): reformat a string of code.

These APIs have some common arguments:

  style_config: (string) Either a style name or a path to a file that contains
    formatting style settings. If None is specified, use the default style
    as set in style.DEFAULT_STYLE_FACTORY
  lines: (list of tuples of integers) A list of tuples of lines, [start, end],
    that we want to format. The lines are 1-based indexed. It can be used by
    third-party code (e.g., IDEs) when reformatting a snippet of code rather
    than a whole file.
  print_diff: (bool) Instead of returning the reformatted source, return a
    diff that turns the formatted source into reformatter source.
"""

import difflib
import io
import logging
import re

from yapf.yapflib import blank_line_calculator
from yapf.yapflib import comment_splicer
from yapf.yapflib import line_joiner
from yapf.yapflib import pytree_unwrapper
from yapf.yapflib import pytree_utils
from yapf.yapflib import reformatter
from yapf.yapflib import split_penalty
from yapf.yapflib import style
from yapf.yapflib import subtype_assigner

def FormatFile(filename, style_config=None, lines=None, print_diff=False):
  """Format a single Python file and return the formatted code.

  Arguments:
    filename: (unicode) The file to reformat.
    style_config, lines, print_diff: see comment at the top of this module.

  Returns:
    The reformatted code or None if the file doesn't exist.
  """
  original_source = ReadFile(filename, logging.warning)
  if original_source is None:
    return None

  return FormatCode(original_source, style_config=style_config,
                    filename=filename, lines=lines, print_diff=print_diff)

def FormatCode(unformatted_source, filename='<unknown>', style_config=None,
               lines=None, print_diff=False):
  """Format a string of Python code.

  This provides an alternative entry point to YAPF.

  Arguments:
    unformatted_source: (unicode) The code to format.
    filename: (unicode) The name of the file being reformatted.
    style_config, lines, print_diff: see comment at the top of this module.

  Returns:
    The code reformatted to conform to the desired formatting style.
  """
  style.SetGlobalStyle(style.CreateStyleFromConfig(style_config))
  tree = pytree_utils.ParseCodeToTree(unformatted_source)

  # Run passes on the tree, modifying it in place.
  comment_splicer.SpliceComments(tree)
  subtype_assigner.AssignSubtypes(tree)
  split_penalty.ComputeSplitPenalties(tree)
  blank_line_calculator.CalculateBlankLines(tree)

  uwlines = pytree_unwrapper.UnwrapPyTree(tree)
  if not uwlines:
    return ''
  for uwl in uwlines:
    uwl.CalculateFormattingInformation()

  line_joiner.CanMergeMultipleLines(uwlines)

  if lines is not None:
    reformatted_source = _FormatLineSnippets(unformatted_source, uwlines, lines)
  else:
    lines = _LinesToSkip(uwlines)
    if lines:
      reformatted_source = _FormatLineSnippets(unformatted_source, uwlines,
                                               lines)
    else:
      reformatted_source = reformatter.Reformat(uwlines)

  if unformatted_source == reformatted_source:
    return '' if print_diff else reformatted_source

  code_diff = _GetUnifiedDiff(unformatted_source, reformatted_source,
                              filename=filename)

  if print_diff:
    return code_diff

  return reformatted_source

def ReadFile(filename, logger=None):
  """Read the contents of the file.

  An optional logger can be specified to emit messages to your favorite logging
  stream. If specified, then no exception is raised.

  Arguments:
    filename: (unicode) The name of the file.
    logger: (function) A function or lambda that takes a string and emits it.

  Returns:
    The contents of filename.

  Raises:
    IOError: raised during an error if a logger is not specified.
  """
  try:
    with io.open(filename, mode='r', newline='') as fd:
      source = fd.read()
    return source
  except IOError as err:
    if logger:
      logger(err)
    else:
      raise

DISABLE_PATTERN = r'^#+ +yapf: *disable$'
ENABLE_PATTERN = r'^#+ +yapf: *enable$'

def _LinesToSkip(uwlines):
  """Skip sections of code that we shouldn't reformat."""
  start = 1
  lines = []
  for uwline in uwlines:
    if uwline.is_comment:
      if re.search(DISABLE_PATTERN, uwline.first.value.strip(), re.IGNORECASE):
        lines.append((start, uwline.lineno))
      elif re.search(ENABLE_PATTERN, uwline.first.value.strip(), re.IGNORECASE):
        start = uwline.lineno
    elif re.search(DISABLE_PATTERN, uwline.last.value.strip(), re.IGNORECASE):
      # Disable only one line.
      if uwline.lineno != start:
        lines.append((start, uwline.lineno - 1))
      start = uwline.last.lineno + 1

  if start != 1 and start <= uwlines[-1].last.lineno + 1:
    lines.append((start, uwlines[-1].last.lineno))
  return lines

def _FormatLineSnippets(unformatted_source, uwlines, lines):
  """Format a string of Python code.

  This provides an alternative entry point to YAPF.

  Arguments:
    unformatted_source: (unicode) The code to format.
    uwlines: (list of UnwrappedLine) The unwrapped lines.
    lines: (list of tuples of integers) A list of lines that we want to format.
      The lines are 1-indexed.

  Returns:
    The code reformatted to conform to the desired formatting style.
  """
  # First we reformat only those lines that we want to reformat.
  index = 0
  reformatted_sources = dict()
  for start, end in sorted(lines):
    snippet = []
    while index < len(uwlines):
      if start <= uwlines[index].lineno or start < uwlines[index].last.lineno:
        while index < len(uwlines):
          if end < uwlines[index].lineno:
            break
          snippet.append(uwlines[index])
          index += 1
        break
      index += 1
    reformatted_sources[(start, end)] = reformatter.Reformat(snippet).rstrip()

  # Next we reconstruct the finalized lines inserting the reformatted lines at
  # the appropriate places.
  prev_end = 0
  finalized_lines = []
  unformatted_lines = unformatted_source.splitlines()
  for key in sorted(reformatted_sources):
    start, end = key
    finalized_lines.extend(unformatted_lines[prev_end:start - 1])
    finalized_lines.append(reformatted_sources[key])
    prev_end = end

  # If there are any remaining lines, place them at the end.
  if prev_end < len(unformatted_lines):
    finalized_lines.extend(unformatted_lines[prev_end:])

  # Construct the reformatted sources.
  return '\n'.join(finalized_lines).rstrip() + '\n'

def _GetUnifiedDiff(before, after, filename='code'):
  """Get a unified diff of the changes.

  Arguments:
    before: (unicode) The original source code.
    after: (unicode) The reformatted source code.
    filename: (unicode) The code's filename.

  Returns:
    The unified diff text.
  """
  before = before.splitlines()
  after = after.splitlines()
  return '\n'.join(difflib.unified_diff(before, after, filename, filename,
                                        '(original)', '(reformatted)',
                                        lineterm='')) + '\n'
<commit_msg>Make sure we re-add blank lines.<commit_after># Copyright 2015 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Entry points for YAPF.

The main APIs that YAPF exposes to drive the reformatting.

  FormatFile(): reformat a file.
  FormatCode(): reformat a string of code.

These APIs have some common arguments:

  style_config: (string) Either a style name or a path to a file that contains
    formatting style settings. If None is specified, use the default style
    as set in style.DEFAULT_STYLE_FACTORY
  lines: (list of tuples of integers) A list of tuples of lines, [start, end],
    that we want to format. The lines are 1-based indexed. It can be used by
    third-party code (e.g., IDEs) when reformatting a snippet of code rather
    than a whole file.
  print_diff: (bool) Instead of returning the reformatted source, return a
    diff that turns the formatted source into reformatter source.
"""

import difflib
import io
import logging
import re

from yapf.yapflib import blank_line_calculator
from yapf.yapflib import comment_splicer
from yapf.yapflib import line_joiner
from yapf.yapflib import pytree_unwrapper
from yapf.yapflib import pytree_utils
from yapf.yapflib import reformatter
from yapf.yapflib import split_penalty
from yapf.yapflib import style
from yapf.yapflib import subtype_assigner

def FormatFile(filename, style_config=None, lines=None, print_diff=False):
  """Format a single Python file and return the formatted code.

  Arguments:
    filename: (unicode) The file to reformat.
    style_config, lines, print_diff: see comment at the top of this module.

  Returns:
    The reformatted code or None if the file doesn't exist.
  """
  original_source = ReadFile(filename, logging.warning)
  if original_source is None:
    return None

  return FormatCode(original_source, style_config=style_config,
                    filename=filename, lines=lines, print_diff=print_diff)

def FormatCode(unformatted_source, filename='<unknown>', style_config=None,
               lines=None, print_diff=False):
  """Format a string of Python code.

  This provides an alternative entry point to YAPF.

  Arguments:
    unformatted_source: (unicode) The code to format.
    filename: (unicode) The name of the file being reformatted.
    style_config, lines, print_diff: see comment at the top of this module.

  Returns:
    The code reformatted to conform to the desired formatting style.
  """
  style.SetGlobalStyle(style.CreateStyleFromConfig(style_config))
  tree = pytree_utils.ParseCodeToTree(unformatted_source)

  # Run passes on the tree, modifying it in place.
  comment_splicer.SpliceComments(tree)
  subtype_assigner.AssignSubtypes(tree)
  split_penalty.ComputeSplitPenalties(tree)
  blank_line_calculator.CalculateBlankLines(tree)

  uwlines = pytree_unwrapper.UnwrapPyTree(tree)
  if not uwlines:
    return ''
  for uwl in uwlines:
    uwl.CalculateFormattingInformation()

  line_joiner.CanMergeMultipleLines(uwlines)

  if lines is not None:
    reformatted_source = _FormatLineSnippets(unformatted_source, uwlines, lines)
  else:
    lines = _LinesToFormat(uwlines)
    if lines:
      reformatted_source = _FormatLineSnippets(unformatted_source, uwlines,
                                               lines)
    else:
      reformatted_source = reformatter.Reformat(uwlines)

  if unformatted_source == reformatted_source:
    return '' if print_diff else reformatted_source

  code_diff = _GetUnifiedDiff(unformatted_source, reformatted_source,
                              filename=filename)

  if print_diff:
    return code_diff

  return reformatted_source

def ReadFile(filename, logger=None):
  """Read the contents of the file.

  An optional logger can be specified to emit messages to your favorite logging
  stream. If specified, then no exception is raised.

  Arguments:
    filename: (unicode) The name of the file.
    logger: (function) A function or lambda that takes a string and emits it.

  Returns:
    The contents of filename.

  Raises:
    IOError: raised during an error if a logger is not specified.
  """
  try:
    with io.open(filename, mode='r', newline='') as fd:
      source = fd.read()
    return source
  except IOError as err:
    if logger:
      logger(err)
    else:
      raise

DISABLE_PATTERN = r'^#+ +yapf: *disable$'
ENABLE_PATTERN = r'^#+ +yapf: *enable$'

def _LinesToFormat(uwlines):
  """Skip sections of code that we shouldn't reformat."""
  start = 1
  lines = []
  for uwline in uwlines:
    if uwline.is_comment:
      if re.search(DISABLE_PATTERN, uwline.first.value.strip(), re.IGNORECASE):
        lines.append((start, uwline.lineno))
      elif re.search(ENABLE_PATTERN, uwline.first.value.strip(), re.IGNORECASE):
        start = uwline.lineno
    elif re.search(DISABLE_PATTERN, uwline.last.value.strip(), re.IGNORECASE):
      # Disable only one line.
      if uwline.lineno != start:
        lines.append((start, uwline.lineno - 1))
      start = uwline.last.lineno + 1

  if start != 1 and start <= uwlines[-1].last.lineno + 1:
    lines.append((start, uwlines[-1].last.lineno))
  return lines

def _FormatLineSnippets(unformatted_source, uwlines, lines):
  """Format a string of Python code.

  This provides an alternative entry point to YAPF.

  Arguments:
    unformatted_source: (unicode) The code to format.
    uwlines: (list of UnwrappedLine) The unwrapped lines.
    lines: (list of tuples of integers) A list of lines that we want to format.
      The lines are 1-indexed.

  Returns:
    The code reformatted to conform to the desired formatting style.
  """
  # First we reformat only those lines that we want to reformat.
  index = 0
  reformatted_sources = dict()
  for start, end in sorted(lines):
    snippet = []
    while index < len(uwlines):
      if start <= uwlines[index].lineno or start < uwlines[index].last.lineno:
        while index < len(uwlines):
          if end < uwlines[index].lineno:
            break
          snippet.append(uwlines[index])
          index += 1
        break
      index += 1
    # Make sure to re-add preceding blank lines to the code snippet.
    blank_lines = ''
    if snippet:
      blank_lines = '\n' * (snippet[0].lineno - start)
      if snippet[0].is_comment:
        if snippet[0].first.value.count('\n') == len(blank_lines):
          blank_lines = ''
    reformatted_sources[(start, end)] = (
        blank_lines + reformatter.Reformat(snippet).rstrip())

  # Next we reconstruct the finalized lines inserting the reformatted lines at
  # the appropriate places.
  prev_end = 0
  finalized_lines = []
  unformatted_lines = unformatted_source.splitlines()
  for key in sorted(reformatted_sources):
    start, end = key
    finalized_lines.extend(unformatted_lines[prev_end:start - 1])
    finalized_lines.append(reformatted_sources[key])
    prev_end = end

  # If there are any remaining lines, place them at the end.
  if prev_end < len(unformatted_lines):
    finalized_lines.extend(unformatted_lines[prev_end:])

  # Construct the reformatted sources.
  return '\n'.join(finalized_lines).rstrip() + '\n'

def _GetUnifiedDiff(before, after, filename='code'):
  """Get a unified diff of the changes.

  Arguments:
    before: (unicode) The original source code.
    after: (unicode) The reformatted source code.
    filename: (unicode) The code's filename.

  Returns:
    The unified diff text.
  """
  before = before.splitlines()
  after = after.splitlines()
  return '\n'.join(difflib.unified_diff(before, after, filename, filename,
                                        '(original)', '(reformatted)',
                                        lineterm='')) + '\n'
<|endoftext|>


<commit_before>"""
Test that formatter categories can work for multiple languages
"""
import lldb
from lldbsuite.test.lldbtest import *
from lldbsuite.test.decorators import *
import lldbsuite.test.lldbutil as lldbutil
import os

class TestMultilangFormatterCategories(TestBase):

    mydir = TestBase.compute_mydir(__file__)

    def setUp(self):
        TestBase.setUp(self)

    @swiftTest
    @add_test_categories(["swiftpr"])
    def test_multilang_formatter_categories(self):
        """Test that formatter categories can work for multiple languages"""
        self.build()
        target, process, thread, a_breakpoint = \
            lldbutil.run_to_source_breakpoint(
                self, 'break here', lldb.SBFileSpec('main.swift'))
        frame = thread.frames[0]
        self.assertTrue(frame, "Frame 0 is valid.")

        dic = frame.FindVariable("dic")
        lldbutil.check_variable(
            self,
            dic,
            use_dynamic=False,
            summary="2 key/value pairs",
            num_children=2)

        child0 = dic.GetChildAtIndex(0)
        lldbutil.check_variable(
            self,
            child0,
            use_dynamic=False,
            num_children=2,
            typename="__lldb_autogen_nspair")

        id1 = child0.GetChildAtIndex(1)
        lldbutil.check_variable(self, id1, use_dynamic=False, typename="id")

        id1child0 = dic.GetChildAtIndex(1).GetChildAtIndex(0)
        lldbutil.check_variable(
            self,
            id1child0,
            use_dynamic=True,
            typename="NSURL *",
            summary='"http://www.google.com"')

if __name__ == '__main__':
    import atexit
    lldb.SBDebugger.Initialize()
    atexit.register(lambda: lldb.SBDebugger.Terminate())
    unittest2.main()
<commit_msg>Revert enabling this Darwin-specific test on Linux<commit_after>"""
Test that formatter categories can work for multiple languages
"""
import lldb
from lldbsuite.test.lldbtest import *
from lldbsuite.test.decorators import *
import lldbsuite.test.lldbutil as lldbutil
import os

class TestMultilangFormatterCategories(TestBase):

    mydir = TestBase.compute_mydir(__file__)

    def setUp(self):
        TestBase.setUp(self)

    @swiftTest
    @skipUnlessDarwin
    @add_test_categories(["swiftpr"])
    def test_multilang_formatter_categories(self):
        """Test that formatter categories can work for multiple languages"""
        self.build()
        target, process, thread, a_breakpoint = \
            lldbutil.run_to_source_breakpoint(
                self, 'break here', lldb.SBFileSpec('main.swift'))
        frame = thread.frames[0]
        self.assertTrue(frame, "Frame 0 is valid.")

        dic = frame.FindVariable("dic")
        lldbutil.check_variable(
            self,
            dic,
            use_dynamic=False,
            summary="2 key/value pairs",
            num_children=2)

        child0 = dic.GetChildAtIndex(0)
        lldbutil.check_variable(
            self,
            child0,
            use_dynamic=False,
            num_children=2,
            typename="__lldb_autogen_nspair")

        id1 = child0.GetChildAtIndex(1)
        lldbutil.check_variable(self, id1, use_dynamic=False, typename="id")

        id1child0 = dic.GetChildAtIndex(1).GetChildAtIndex(0)
        lldbutil.check_variable(
            self,
            id1child0,
            use_dynamic=True,
            typename="NSURL *",
            summary='"http://www.google.com"')

if __name__ == '__main__':
    import atexit
    lldb.SBDebugger.Initialize()
    atexit.register(lambda: lldb.SBDebugger.Terminate())
    unittest2.main()
<|endoftext|>