mirror of
https://github.com/corda/corda.git
synced 2025-02-01 08:48:09 +00:00
contracts, core: Expose top-level DSL values/functions to Java by wrapping them in an object
core: Add overloads for convenient Java interop contracts, core: Uniform Java interop for tests, use camelCase
This commit is contained in:
parent
28e85923a3
commit
040e51ec12
@ -48,25 +48,42 @@ fun generateState() = DummyContract.State(Random().nextInt())
|
||||
// contract `fails requirement` "some substring of the error message"
|
||||
// }
|
||||
|
||||
infix fun Cash.State.`owned by`(owner: PublicKey) = copy(owner = owner)
|
||||
infix fun Cash.State.`issued by`(party: Party) = copy(amount = Amount<Issued<Currency>>(amount.quantity, issuanceDef.copy(issuer = deposit.copy(party = party))))
|
||||
infix fun Cash.State.`issued by`(deposit: PartyAndReference) = copy(amount = Amount<Issued<Currency>>(amount.quantity, issuanceDef.copy(issuer = deposit)))
|
||||
infix fun Cash.State.`with notary`(notary: Party) = TransactionState(this, notary)
|
||||
// For Java compatibility please define helper methods here and then define the infix notation
|
||||
object Java {
|
||||
@JvmStatic fun ownedBy(state: Cash.State, owner: PublicKey) = state.copy(owner = owner)
|
||||
@JvmStatic fun issuedBy(state: Cash.State, party: Party) = state.copy(amount = Amount<Issued<Currency>>(state.amount.quantity, state.issuanceDef.copy(issuer = state.deposit.copy(party = party))))
|
||||
@JvmStatic fun issuedBy(state: Cash.State, deposit: PartyAndReference) = state.copy(amount = Amount<Issued<Currency>>(state.amount.quantity, state.issuanceDef.copy(issuer = deposit)))
|
||||
@JvmStatic fun withNotary(state: Cash.State, notary: Party) = TransactionState(state, notary)
|
||||
@JvmStatic fun withDeposit(state: Cash.State, deposit: PartyAndReference) = state.copy(amount = state.amount.copy(token = state.amount.token.copy(issuer = deposit)))
|
||||
|
||||
infix fun CommercialPaper.State.`owned by`(owner: PublicKey) = this.copy(owner = owner)
|
||||
infix fun CommercialPaper.State.`with notary`(notary: Party) = TransactionState(this, notary)
|
||||
infix fun ICommercialPaperState.`owned by`(new_owner: PublicKey) = this.withOwner(new_owner)
|
||||
@JvmStatic fun ownedBy(state: CommercialPaper.State, owner: PublicKey) = state.copy(owner = owner)
|
||||
@JvmStatic fun withNotary(state: CommercialPaper.State, notary: Party) = TransactionState(state, notary)
|
||||
@JvmStatic fun ownedBy(state: ICommercialPaperState, new_owner: PublicKey) = state.withOwner(new_owner)
|
||||
|
||||
infix fun Cash.State.`with deposit`(deposit: PartyAndReference): Cash.State =
|
||||
copy(amount = amount.copy(token = amount.token.copy(issuer = deposit)))
|
||||
@JvmStatic fun withNotary(state: ContractState, notary: Party) = TransactionState(state, notary)
|
||||
|
||||
@JvmStatic fun CASH(amount: Amount<Currency>) = Cash.State(
|
||||
Amount<Issued<Currency>>(amount.quantity, Issued<Currency>(DUMMY_CASH_ISSUER, amount.token)),
|
||||
NullPublicKey)
|
||||
@JvmStatic fun STATE(amount: Amount<Issued<Currency>>) = Cash.State(amount, NullPublicKey)
|
||||
}
|
||||
|
||||
|
||||
infix fun Cash.State.`owned by`(owner: PublicKey) = Java.ownedBy(this, owner)
|
||||
infix fun Cash.State.`issued by`(party: Party) = Java.issuedBy(this, party)
|
||||
infix fun Cash.State.`issued by`(deposit: PartyAndReference) = Java.issuedBy(this, deposit)
|
||||
infix fun Cash.State.`with notary`(notary: Party) = Java.withNotary(this, notary)
|
||||
infix fun Cash.State.`with deposit`(deposit: PartyAndReference): Cash.State = Java.withDeposit(this, deposit)
|
||||
|
||||
infix fun CommercialPaper.State.`owned by`(owner: PublicKey) = Java.ownedBy(this, owner)
|
||||
infix fun CommercialPaper.State.`with notary`(notary: Party) = Java.withNotary(this, notary)
|
||||
infix fun ICommercialPaperState.`owned by`(new_owner: PublicKey) = Java.ownedBy(this, new_owner)
|
||||
|
||||
infix fun ContractState.`with notary`(notary: Party) = Java.withNotary(this, notary)
|
||||
|
||||
val DUMMY_CASH_ISSUER_KEY = generateKeyPair()
|
||||
val DUMMY_CASH_ISSUER = Party("Snake Oil Issuer", DUMMY_CASH_ISSUER_KEY.public).ref(1)
|
||||
/** Allows you to write 100.DOLLARS.CASH */
|
||||
val Amount<Currency>.CASH: Cash.State get() = Cash.State(
|
||||
Amount<Issued<Currency>>(this.quantity, Issued<Currency>(DUMMY_CASH_ISSUER, this.token)),
|
||||
NullPublicKey)
|
||||
val Amount<Currency>.CASH: Cash.State get() = Java.CASH(this)
|
||||
val Amount<Issued<Currency>>.STATE: Cash.State get() = Java.STATE(this)
|
||||
|
||||
val Amount<Issued<Currency>>.STATE: Cash.State get() = Cash.State(this, NullPublicKey)
|
||||
|
||||
infix fun ContractState.`with notary`(notary: Party) = TransactionState(this, notary)
|
||||
|
@ -0,0 +1,58 @@
|
||||
package com.r3corda.contracts.cash;
|
||||
|
||||
import com.r3corda.core.contracts.PartyAndReference;
|
||||
import com.r3corda.core.serialization.OpaqueBytes;
|
||||
import org.junit.Test;
|
||||
|
||||
import static com.r3corda.core.testing.Java.*;
|
||||
import static com.r3corda.core.contracts.Java.*;
|
||||
import static com.r3corda.contracts.testing.Java.*;
|
||||
|
||||
/**
|
||||
* This is an incomplete Java replica of CashTests.kt to show how to use the Java test DSL
|
||||
*/
|
||||
public class CashTestsJava {
|
||||
|
||||
private OpaqueBytes defaultRef = new OpaqueBytes(new byte[]{1});;
|
||||
private PartyAndReference defaultIssuer = MEGA_CORP.ref(defaultRef);
|
||||
private Cash.State inState = new Cash.State(issuedBy(DOLLARS(1000), defaultIssuer), DUMMY_PUBKEY_1);
|
||||
private Cash.State outState = new Cash.State(inState.getAmount(), DUMMY_PUBKEY_2);;
|
||||
|
||||
@Test
|
||||
public void trivial() {
|
||||
|
||||
transaction(tx -> {
|
||||
tx.input(inState);
|
||||
tx.failsRequirement("the amounts balance");
|
||||
|
||||
tx.tweak(tw -> {
|
||||
tw.output(new Cash.State(issuedBy(DOLLARS(2000), defaultIssuer), DUMMY_PUBKEY_2));
|
||||
return tw.failsRequirement("the amounts balance");
|
||||
});
|
||||
|
||||
tx.tweak(tw -> {
|
||||
tw.output(outState);
|
||||
// No command arguments
|
||||
return tw.failsRequirement("required com.r3corda.contracts.cash.FungibleAsset.Commands.Move command");
|
||||
});
|
||||
tx.tweak(tw -> {
|
||||
tw.output(outState);
|
||||
tw.arg(DUMMY_PUBKEY_2, new Cash.Commands.Move());
|
||||
return tw.failsRequirement("the owning keys are the same as the signing keys");
|
||||
});
|
||||
tx.tweak(tw -> {
|
||||
tw.output(outState);
|
||||
tw.output(issuedBy(outState, MINI_CORP));
|
||||
tw.arg(DUMMY_PUBKEY_1, new Cash.Commands.Move());
|
||||
return tw.failsRequirement("at least one asset input");
|
||||
});
|
||||
|
||||
// Simple reallocation works.
|
||||
return tx.tweak(tw -> {
|
||||
tw.output(outState);
|
||||
tw.arg(DUMMY_PUBKEY_1, new Cash.Commands.Move());
|
||||
return tw.accepts();
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
@ -1,56 +0,0 @@
|
||||
package com.r3corda.contracts.cash;
|
||||
|
||||
import com.r3corda.core.contracts.PartyAndReference;
|
||||
import com.r3corda.core.serialization.OpaqueBytes;
|
||||
import com.r3corda.core.testing.TransactionTestBase;
|
||||
import org.junit.Test;
|
||||
|
||||
import static com.r3corda.core.testing.Dummies.*;
|
||||
import static com.r3corda.contracts.testing.Methods.*;
|
||||
import static com.r3corda.core.contracts.Currencies.*;
|
||||
import static com.r3corda.core.contracts.Methods.*;
|
||||
|
||||
public class CashTestsJava extends TransactionTestBase {
|
||||
|
||||
private OpaqueBytes defaultRef = new OpaqueBytes(new byte[]{1});;
|
||||
private PartyAndReference defaultIssuer = MEGA_CORP.ref(defaultRef);
|
||||
private Cash.State inState = new Cash.State(issued_by(DOLLARS(2000), defaultIssuer), DUMMY_PUBKEY_1);
|
||||
private Cash.State outState = inState.copy(inState.getAmount(), DUMMY_PUBKEY_2);;
|
||||
|
||||
@Test
|
||||
public void trivial() {
|
||||
transaction(begin
|
||||
.input(inState)
|
||||
.fails_requirement("the amounts balance")
|
||||
|
||||
.tweak(begin
|
||||
.output(outState.copy(issued_by(DOLLARS(2000), defaultIssuer), DUMMY_PUBKEY_2))
|
||||
.fails_requirement("the amounts balance")
|
||||
)
|
||||
|
||||
.tweak(begin
|
||||
.output(outState)
|
||||
.fails_requirement("required com.r3corda.contracts.cash.FungibleAsset.Commands.Move command")
|
||||
)
|
||||
|
||||
.tweak(begin
|
||||
.output(outState)
|
||||
.arg(DUMMY_PUBKEY_2, new Cash.Commands.Move())
|
||||
.fails_requirement("the owning keys are the same as the signing keys")
|
||||
)
|
||||
|
||||
.tweak(begin
|
||||
.output(outState)
|
||||
.output(issued_by(outState, MINI_CORP))
|
||||
.arg(DUMMY_PUBKEY_1, new Cash.Commands.Move())
|
||||
.fails_requirement("at least one asset input")
|
||||
)
|
||||
|
||||
.tweak(begin
|
||||
.output(outState)
|
||||
.arg(DUMMY_PUBKEY_1, new Cash.Commands.Move())
|
||||
.accepts()
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
@ -19,18 +19,32 @@ import java.util.*
|
||||
|
||||
fun currency(code: String) = Currency.getInstance(code)
|
||||
|
||||
val USD = currency("USD")
|
||||
val GBP = currency("GBP")
|
||||
val CHF = currency("CHF")
|
||||
// Java interop
|
||||
object Java {
|
||||
@JvmField val USD = currency("USD")
|
||||
@JvmField val GBP = currency("GBP")
|
||||
@JvmField val CHF = currency("CHF")
|
||||
|
||||
val Int.DOLLARS: Amount<Currency> get() = Amount(this.toLong() * 100, USD)
|
||||
val Int.POUNDS: Amount<Currency> get() = Amount(this.toLong() * 100, GBP)
|
||||
val Int.SWISS_FRANCS: Amount<Currency> get() = Amount(this.toLong() * 100, CHF)
|
||||
@JvmStatic fun DOLLARS(amount: Int) = Amount(amount.toLong() * 100, USD)
|
||||
@JvmStatic fun DOLLARS(amount: Double) = Amount((amount * 100).toLong(), USD)
|
||||
@JvmStatic fun POUNDS(amount: Int) = Amount(amount.toLong() * 100, GBP)
|
||||
@JvmStatic fun SWISS_FRANCS(amount: Int) = Amount(amount.toLong() * 100, CHF)
|
||||
|
||||
val Double.DOLLARS: Amount<Currency> get() = Amount((this * 100).toLong(), USD)
|
||||
@JvmStatic fun issuedBy(currency: Currency, deposit: PartyAndReference) = Issued<Currency>(deposit, currency)
|
||||
@JvmStatic fun issuedBy(amount: Amount<Currency>, deposit: PartyAndReference) = Amount(amount.quantity, issuedBy(amount.token, deposit))
|
||||
}
|
||||
|
||||
infix fun Currency.`issued by`(deposit: PartyAndReference) : Issued<Currency> = Issued<Currency>(deposit, this)
|
||||
infix fun <T> Amount<T>.`issued by`(deposit: PartyAndReference) : Amount<Issued<T>> = Amount(quantity, Issued<T>(deposit, this.token))
|
||||
val USD = Java.USD
|
||||
val GBP = Java.GBP
|
||||
val CHF = Java.CHF
|
||||
|
||||
val Int.DOLLARS: Amount<Currency> get() = Java.DOLLARS(this)
|
||||
val Double.DOLLARS: Amount<Currency> get() = Java.DOLLARS(this)
|
||||
val Int.POUNDS: Amount<Currency> get() = Java.POUNDS(this)
|
||||
val Int.SWISS_FRANCS: Amount<Currency> get() = Java.SWISS_FRANCS(this)
|
||||
|
||||
infix fun Currency.`issued by`(deposit: PartyAndReference) = Java.issuedBy(this, deposit)
|
||||
infix fun Amount<Currency>.`issued by`(deposit: PartyAndReference) = Java.issuedBy(this, deposit)
|
||||
|
||||
//// Requirements /////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -43,8 +43,8 @@ object TestUtils {
|
||||
* JAVA INTEROP. Please keep the following points in mind when extending the Kotlin DSL
|
||||
*
|
||||
* - Annotate functions with Kotlin defaults with @JvmOverloads. This produces the relevant overloads for Java.
|
||||
* - Void closures in arguments are inconvenient in Java, use overloading to define non-closure variants as well
|
||||
* - Top-level vals should be defined in the [Java] object and annotated with @JvmField first and should be referred
|
||||
* - Void closures in arguments are inconvenient in Java, use overloading to define non-closure variants as well.
|
||||
* - Top-level vals should be defined in a [Java] object and annotated with @JvmField first and should be referred
|
||||
* to from the global val. This allows static importing of [Java] in Java tests, which mimicks top-level vals.
|
||||
* - Same goes for top-level funs. Define them in [Java] with annotation @JvmStatic and define a global alias later.
|
||||
* - Infix functions work as regular ones from Java, but symbols with spaces in them don't! Define a camelCase variant
|
||||
@ -52,39 +52,73 @@ object TestUtils {
|
||||
* - varargs are exposed as array types in Java. Define overloads for common cases.
|
||||
* - The Int.DOLLARS syntax doesn't work from Java. To remedy add a @JvmStatic DOLLARS(Int) function to [Java]
|
||||
*/
|
||||
object Java {
|
||||
// A dummy time at which we will be pretending test transactions are created.
|
||||
@JvmField val TEST_TX_TIME = Instant.parse("2015-04-17T12:00:00.00Z")
|
||||
|
||||
// A few dummy values for testing.
|
||||
val MEGA_CORP_KEY = TestUtils.keypair
|
||||
val MEGA_CORP_PUBKEY = MEGA_CORP_KEY.public
|
||||
@JvmField val MEGA_CORP_KEY = TestUtils.keypair
|
||||
@JvmField val MEGA_CORP_PUBKEY = MEGA_CORP_KEY.public
|
||||
|
||||
val MINI_CORP_KEY = TestUtils.keypair2
|
||||
val MINI_CORP_PUBKEY = MINI_CORP_KEY.public
|
||||
@JvmField val MINI_CORP_KEY = TestUtils.keypair2
|
||||
@JvmField val MINI_CORP_PUBKEY = MINI_CORP_KEY.public
|
||||
|
||||
val ORACLE_KEY = TestUtils.keypair3
|
||||
val ORACLE_PUBKEY = ORACLE_KEY.public
|
||||
@JvmField val ORACLE_KEY = TestUtils.keypair3
|
||||
@JvmField val ORACLE_PUBKEY = ORACLE_KEY.public
|
||||
|
||||
val DUMMY_PUBKEY_1 = DummyPublicKey("x1")
|
||||
val DUMMY_PUBKEY_2 = DummyPublicKey("x2")
|
||||
@JvmField val DUMMY_PUBKEY_1 = DummyPublicKey("x1")
|
||||
@JvmField val DUMMY_PUBKEY_2 = DummyPublicKey("x2")
|
||||
|
||||
val ALICE_KEY = generateKeyPair()
|
||||
val ALICE_PUBKEY = ALICE_KEY.public
|
||||
val ALICE = Party("Alice", ALICE_PUBKEY)
|
||||
@JvmField val ALICE_KEY = generateKeyPair()
|
||||
@JvmField val ALICE_PUBKEY = ALICE_KEY.public
|
||||
@JvmField val ALICE = Party("Alice", ALICE_PUBKEY)
|
||||
|
||||
val BOB_KEY = generateKeyPair()
|
||||
val BOB_PUBKEY = BOB_KEY.public
|
||||
val BOB = Party("Bob", BOB_PUBKEY)
|
||||
@JvmField val BOB_KEY = generateKeyPair()
|
||||
@JvmField val BOB_PUBKEY = BOB_KEY.public
|
||||
@JvmField val BOB = Party("Bob", BOB_PUBKEY)
|
||||
|
||||
val MEGA_CORP = Party("MegaCorp", MEGA_CORP_PUBKEY)
|
||||
val MINI_CORP = Party("MiniCorp", MINI_CORP_PUBKEY)
|
||||
@JvmField val MEGA_CORP = Party("MegaCorp", MEGA_CORP_PUBKEY)
|
||||
@JvmField val MINI_CORP = Party("MiniCorp", MINI_CORP_PUBKEY)
|
||||
|
||||
val DUMMY_NOTARY_KEY = generateKeyPair()
|
||||
val DUMMY_NOTARY = Party("Notary Service", DUMMY_NOTARY_KEY.public)
|
||||
@JvmField val DUMMY_NOTARY_KEY = generateKeyPair()
|
||||
@JvmField val DUMMY_NOTARY = Party("Notary Service", DUMMY_NOTARY_KEY.public)
|
||||
|
||||
val ALL_TEST_KEYS = listOf(MEGA_CORP_KEY, MINI_CORP_KEY, ALICE_KEY, BOB_KEY, DUMMY_NOTARY_KEY)
|
||||
@JvmField val ALL_TEST_KEYS = listOf(MEGA_CORP_KEY, MINI_CORP_KEY, ALICE_KEY, BOB_KEY, DUMMY_NOTARY_KEY)
|
||||
|
||||
val MOCK_IDENTITY_SERVICE = MockIdentityService(listOf(MEGA_CORP, MINI_CORP, DUMMY_NOTARY))
|
||||
@JvmField val MOCK_IDENTITY_SERVICE = MockIdentityService(listOf(MEGA_CORP, MINI_CORP, DUMMY_NOTARY))
|
||||
|
||||
fun generateStateRef() = StateRef(SecureHash.randomSHA256(), 0)
|
||||
@JvmStatic fun generateStateRef() = StateRef(SecureHash.randomSHA256(), 0)
|
||||
|
||||
@JvmStatic fun transaction(body: TransactionForTest.() -> LastLineShouldTestForAcceptOrFailure): LastLineShouldTestForAcceptOrFailure {
|
||||
return body(TransactionForTest())
|
||||
}
|
||||
}
|
||||
|
||||
val TEST_TX_TIME = Java.TEST_TX_TIME
|
||||
val MEGA_CORP_KEY = Java.MEGA_CORP_KEY
|
||||
val MEGA_CORP_PUBKEY = Java.MEGA_CORP_PUBKEY
|
||||
val MINI_CORP_KEY = Java.MINI_CORP_KEY
|
||||
val MINI_CORP_PUBKEY = Java.MINI_CORP_PUBKEY
|
||||
val ORACLE_KEY = Java.ORACLE_KEY
|
||||
val ORACLE_PUBKEY = Java.ORACLE_PUBKEY
|
||||
val DUMMY_PUBKEY_1 = Java.DUMMY_PUBKEY_1
|
||||
val DUMMY_PUBKEY_2 = Java.DUMMY_PUBKEY_2
|
||||
val ALICE_KEY = Java.ALICE_KEY
|
||||
val ALICE_PUBKEY = Java.ALICE_PUBKEY
|
||||
val ALICE = Java.ALICE
|
||||
val BOB_KEY = Java.BOB_KEY
|
||||
val BOB_PUBKEY = Java.BOB_PUBKEY
|
||||
val BOB = Java.BOB
|
||||
val MEGA_CORP = Java.MEGA_CORP
|
||||
val MINI_CORP = Java.MINI_CORP
|
||||
val DUMMY_NOTARY_KEY = Java.DUMMY_NOTARY_KEY
|
||||
val DUMMY_NOTARY = Java.DUMMY_NOTARY
|
||||
val ALL_TEST_KEYS = Java.ALL_TEST_KEYS
|
||||
val MOCK_IDENTITY_SERVICE = Java.MOCK_IDENTITY_SERVICE
|
||||
|
||||
fun generateStateRef() = Java.generateStateRef()
|
||||
|
||||
fun transaction(body: TransactionForTest.() -> LastLineShouldTestForAcceptOrFailure) = Java.transaction(body)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
@ -120,7 +154,10 @@ abstract class AbstractTransactionForTest {
|
||||
protected val signers = LinkedHashSet<PublicKey>()
|
||||
protected val type = TransactionType.General()
|
||||
|
||||
@JvmOverloads
|
||||
open fun output(label: String? = null, s: () -> ContractState) = LabeledOutput(label, TransactionState(s(), DUMMY_NOTARY)).apply { outStates.add(this) }
|
||||
@JvmOverloads
|
||||
open fun output(label: String? = null, s: ContractState) = output(label) { s }
|
||||
|
||||
protected fun commandsToAuthenticatedObjects(): List<AuthenticatedObject<CommandData>> {
|
||||
return commands.map { AuthenticatedObject(it.signers, it.signers.mapNotNull { MOCK_IDENTITY_SERVICE.partyFromKey(it) }, it.value) }
|
||||
@ -130,10 +167,11 @@ abstract class AbstractTransactionForTest {
|
||||
attachments.add(attachmentID)
|
||||
}
|
||||
|
||||
fun arg(vararg key: PublicKey, c: () -> CommandData) {
|
||||
val keys = listOf(*key)
|
||||
addCommand(Command(c(), keys))
|
||||
fun arg(vararg keys: PublicKey, c: () -> CommandData) {
|
||||
val keysList = listOf(*keys)
|
||||
addCommand(Command(c(), keysList))
|
||||
}
|
||||
fun arg(key: PublicKey, c: CommandData) = arg(key) { c }
|
||||
|
||||
fun timestamp(time: Instant) {
|
||||
val data = TimestampCommand(time, 30.seconds)
|
||||
@ -165,12 +203,15 @@ sealed class LastLineShouldTestForAcceptOrFailure {
|
||||
}
|
||||
|
||||
// Corresponds to the args to Contract.verify
|
||||
// Note on defaults: try to avoid Kotlin defaults as they don't work from Java. Instead define overloads
|
||||
open class TransactionForTest : AbstractTransactionForTest() {
|
||||
private val inStates = arrayListOf<TransactionState<ContractState>>()
|
||||
|
||||
fun input(s: () -> ContractState) {
|
||||
signers.add(DUMMY_NOTARY.owningKey)
|
||||
inStates.add(TransactionState(s(), DUMMY_NOTARY))
|
||||
}
|
||||
fun input(s: ContractState) = input { s }
|
||||
|
||||
protected fun runCommandsAndVerify(time: Instant) {
|
||||
val cmds = commandsToAuthenticatedObjects()
|
||||
@ -178,10 +219,13 @@ open class TransactionForTest : AbstractTransactionForTest() {
|
||||
tx.verify()
|
||||
}
|
||||
|
||||
@JvmOverloads
|
||||
fun accepts(time: Instant = TEST_TX_TIME): LastLineShouldTestForAcceptOrFailure {
|
||||
runCommandsAndVerify(time)
|
||||
return LastLineShouldTestForAcceptOrFailure.Token
|
||||
}
|
||||
|
||||
@JvmOverloads
|
||||
fun rejects(withMessage: String? = null, time: Instant = TEST_TX_TIME): LastLineShouldTestForAcceptOrFailure {
|
||||
val r = try {
|
||||
runCommandsAndVerify(time)
|
||||
@ -202,8 +246,7 @@ open class TransactionForTest : AbstractTransactionForTest() {
|
||||
* Used to confirm that the test, when (implicitly) run against the .verify() method, fails with the text of the message
|
||||
*/
|
||||
infix fun `fails requirement`(msg: String): LastLineShouldTestForAcceptOrFailure = rejects(msg)
|
||||
|
||||
fun fails_requirement(msg: String) = this.`fails requirement`(msg)
|
||||
fun failsRequirement(msg: String) = this.`fails requirement`(msg)
|
||||
|
||||
// Use this to create transactions where the output of this transaction is automatically used as an input of
|
||||
// the next.
|
||||
@ -251,10 +294,6 @@ open class TransactionForTest : AbstractTransactionForTest() {
|
||||
}
|
||||
}
|
||||
|
||||
fun transaction(body: TransactionForTest.() -> LastLineShouldTestForAcceptOrFailure): LastLineShouldTestForAcceptOrFailure {
|
||||
return body(TransactionForTest())
|
||||
}
|
||||
|
||||
class TransactionGroupDSL<T : ContractState>(private val stateType: Class<T>) {
|
||||
open inner class WireTransactionDSL : AbstractTransactionForTest() {
|
||||
private val inStates = ArrayList<StateRef>()
|
||||
@ -335,6 +374,7 @@ class TransactionGroupDSL<T : ContractState>(private val stateType: Class<T>) {
|
||||
val txns = ArrayList<WireTransaction>()
|
||||
private val txnToLabelMap = HashMap<SecureHash, String>()
|
||||
|
||||
@JvmOverloads
|
||||
fun transaction(label: String? = null, body: WireTransactionDSL.() -> Unit): WireTransaction {
|
||||
val forTest = InternalWireTransactionDSL()
|
||||
forTest.body()
|
||||
|
@ -1,24 +0,0 @@
|
||||
package com.r3corda.contracts.testing
|
||||
|
||||
import com.r3corda.contracts.Obligation
|
||||
import com.r3corda.contracts.cash.Cash
|
||||
import com.r3corda.core.contracts.Amount
|
||||
import com.r3corda.core.contracts.Issued
|
||||
import com.r3corda.core.crypto.NullPublicKey
|
||||
import com.r3corda.core.crypto.Party
|
||||
import com.r3corda.core.testing.MINI_CORP
|
||||
import com.r3corda.core.utilities.nonEmptySetOf
|
||||
import java.security.PublicKey
|
||||
import java.time.Instant
|
||||
import java.util.*
|
||||
|
||||
infix fun <T> Obligation.State<T>.`at`(dueBefore: Instant) = copy(template = template.copy(dueBefore = dueBefore))
|
||||
infix fun <T> Obligation.State<T>.`between`(parties: Pair<Party, PublicKey>) = copy(issuer = parties.first, owner = parties.second)
|
||||
infix fun <T> Obligation.State<T>.`owned by`(owner: PublicKey) = copy(owner = owner)
|
||||
infix fun <T> Obligation.State<T>.`issued by`(party: Party) = copy(issuer = party)
|
||||
|
||||
// Allows you to write 100.DOLLARS.OBLIGATION
|
||||
val Issued<Currency>.OBLIGATION_DEF: Obligation.StateTemplate<Currency> get() = Obligation.StateTemplate(nonEmptySetOf(Cash().legalContractReference),
|
||||
nonEmptySetOf(this), Instant.parse("2020-01-01T17:00:00Z"))
|
||||
val Amount<Issued<Currency>>.OBLIGATION: Obligation.State<Currency> get() = Obligation.State(Obligation.Lifecycle.NORMAL, MINI_CORP,
|
||||
this.token.OBLIGATION_DEF, this.quantity, NullPublicKey)
|
@ -0,0 +1,33 @@
|
||||
package com.r3corda.contracts.testing
|
||||
|
||||
import com.r3corda.contracts.Obligation
|
||||
import com.r3corda.contracts.cash.Cash
|
||||
import com.r3corda.core.contracts.Amount
|
||||
import com.r3corda.core.contracts.Issued
|
||||
import com.r3corda.core.crypto.NullPublicKey
|
||||
import com.r3corda.core.crypto.Party
|
||||
import com.r3corda.core.testing.MINI_CORP
|
||||
import com.r3corda.core.utilities.nonEmptySetOf
|
||||
import java.security.PublicKey
|
||||
import java.time.Instant
|
||||
import java.util.*
|
||||
|
||||
object JavaExperimental {
|
||||
@JvmStatic fun <T> at(state: Obligation.State<T>, dueBefore: Instant) = state.copy(template = state.template.copy(dueBefore = dueBefore))
|
||||
@JvmStatic fun <T> between(state: Obligation.State<T>, parties: Pair<Party, PublicKey>) = state.copy(issuer = parties.first, owner = parties.second)
|
||||
@JvmStatic fun <T> ownedBy(state: Obligation.State<T>, owner: PublicKey) = state.copy(owner = owner)
|
||||
@JvmStatic fun <T> issuedBy(state: Obligation.State<T>, party: Party) = state.copy(issuer = party)
|
||||
|
||||
@JvmStatic fun OBLIGATION_DEF(issued: Issued<Currency>)
|
||||
= Obligation.StateTemplate(nonEmptySetOf(Cash().legalContractReference), nonEmptySetOf(issued), Instant.parse("2020-01-01T17:00:00Z"))
|
||||
@JvmStatic fun OBLIGATION(amount: Amount<Issued<Currency>>) = Obligation.State(Obligation.Lifecycle.NORMAL, MINI_CORP,
|
||||
OBLIGATION_DEF(amount.token), amount.quantity, NullPublicKey)
|
||||
}
|
||||
infix fun <T> Obligation.State<T>.`at`(dueBefore: Instant) = JavaExperimental.at(this, dueBefore)
|
||||
infix fun <T> Obligation.State<T>.`between`(parties: Pair<Party, PublicKey>) = JavaExperimental.between(this, parties)
|
||||
infix fun <T> Obligation.State<T>.`owned by`(owner: PublicKey) = JavaExperimental.ownedBy(this, owner)
|
||||
infix fun <T> Obligation.State<T>.`issued by`(party: Party) = JavaExperimental.issuedBy(this, party)
|
||||
|
||||
// Allows you to write 100.DOLLARS.OBLIGATION
|
||||
val Issued<Currency>.OBLIGATION_DEF: Obligation.StateTemplate<Currency> get() = JavaExperimental.OBLIGATION_DEF(this)
|
||||
val Amount<Issued<Currency>>.OBLIGATION: Obligation.State<Currency> get() = JavaExperimental.OBLIGATION(this)
|
Loading…
x
Reference in New Issue
Block a user