Skip to content

Commit

Permalink
add tests for creating, adding to, and drawing from raffles (#4)
Browse files Browse the repository at this point in the history
* add tests for creating, adding to, and drawin from raffles

* move to generic raffle source
  • Loading branch information
austinkline authored Dec 15, 2023
1 parent 0e2ed0a commit 352fb54
Show file tree
Hide file tree
Showing 13 changed files with 370 additions and 45 deletions.
49 changes: 49 additions & 0 deletions contracts/RaffleSources.cdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import "Raffles"

pub contract RaffleSources {
pub resource GenericRaffleSource: Raffles.RaffleSource {
pub let entries: [AnyStruct]
pub let entryType: Type

pub fun getEntryType(): Type {
return self.entryType
}

pub fun getEntryAt(index: Int): AnyStruct {
return self.entries[index]
}

pub fun addEntry(_ v: AnyStruct) {
pre {
v.getType() == self.entryType: "incorrect entry type"
}

self.entries.append(v)
}

pub fun addEntries(_ v: [AnyStruct]) {
pre {
VariableSizedArrayType(self.entryType) == v.getType(): "incorrect array type"
}

self.entries.appendAll(v)
}

pub fun getNumEntries(): Int {
return self.entries.length
}

pub fun getEntries(): [AnyStruct] {
return self.entries
}

init(_ entryType: Type) {
self.entries = []
self.entryType = entryType
}
}

pub fun createRaffleSource(_ type: Type): @GenericRaffleSource {
return <- create GenericRaffleSource(type)
}
}
113 changes: 71 additions & 42 deletions contracts/Raffles.cdc
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ pub contract Raffles {
pub let ManagerStoragePath: StoragePath
pub let ManagerPublicPath: PublicPath

pub event RaffleCreated(address: Address, raffleID: UInt64, sourceType: Type)
pub event RaffleDrawn(address: Address, raffleID: UInt64, sourceType: Type, index: Int, value: String)
pub event RaffleCreated(address: Address?, raffleID: UInt64, sourceType: Type)
pub event RaffleDrawn(address: Address?, raffleID: UInt64, sourceType: Type, index: Int, value: String, valueType: Type)

pub struct Details {
pub let start: UInt64?
Expand All @@ -14,7 +14,7 @@ pub contract Raffles {

init(
_ start: UInt64?,
_ end: UInt64,
_ end: UInt64?,
_ display: MetadataViews.Display

) {
Expand All @@ -24,22 +24,70 @@ pub contract Raffles {
}
}

pub struct DrawingSelection {
pub let index: Int
pub let value: AnyStruct

init(_ index: Int, _ value: AnyStruct) {
self.index = index
self.value = value
}
}

pub resource interface RafflePublic {
pub fun getEntryAt(index: Int): AnyStruct
pub fun getDetails(): Details
pub fun getNumEntries(): Int
pub fun getEntries(): [AnyStruct]
pub fun draw(): DrawingSelection
}

pub resource interface RaffleSource {
pub fun getEntryAt(index: Int): AnyStruct
pub fun addEntry(_ v: AnyStruct)
pub fun addEntries(_ v: [AnyStruct])
pub fun getNumEntries(): Int
pub fun getEntries(): [AnyStruct]
}

pub resource Raffle: RafflePublic, MetadataViews.Resolver {
pub let source: @{RaffleSource}
pub let details: Details

pub fun draw(): Int {
return self.source.draw()
pub fun getDetails(): Details {
return self.details
}

pub fun getNumEntries(): Int {
return self.source.getNumEntries()
}

pub fun getEntries(): [AnyStruct] {
return self.source.getEntries()
}

pub fun draw(): DrawingSelection {
let numEntries = self.source.getNumEntries()
let r = revertibleRandom()
let index = Int(r % UInt64(numEntries))
let value = self.source.getEntryAt(index: index)

Raffles.emitDrawing(self.owner?.address, self.uuid, self.source.getType(), index, value)
return DrawingSelection(index, value)
}

pub fun getEntryAt(index: Int): AnyStruct {
return self.source.getEntryAt(index: index)
}

pub fun addEntry(_ v: AnyStruct) {
self.source.addEntry(v)
}

pub fun addEntries(_ v: [AnyStruct]) {
self.source.addEntries(v)
}

pub fun getViews(): [Type] {
return [
Type<MetadataViews.Display>()
Expand Down Expand Up @@ -68,36 +116,30 @@ pub contract Raffles {
}
}

pub resource interface RaffleSource {
pub fun draw(): Int
pub fun getEntryAt(index: Int): AnyStruct
}

pub resource AddressRaffleSource: RaffleSource {
pub let addresses: [Address]

pub fun draw(): Int {
let r = revertibleRandom()
return Int(r % UInt64(self.addresses.length))
}

pub fun getEntryAt(index: Int): AnyStruct {
return self.addresses[index]
}

init() {
self.addresses = []
}
}

pub resource interface ManagerPublic {
pub fun borrowRafflePublic(id: UInt64): &{RafflePublic}?
}

pub resource Manager: ManagerPublic {
access(self) let raffles: @{UInt64: Raffle}

pub fun createRaffle(source: @{RaffleSource}, details: Details): UInt64 {
let sourceType = source.getType()

let raffle <- create Raffle(source: <- source, details: details)
emit RaffleCreated(address: self.owner!.address, raffleID: raffle.uuid, sourceType: sourceType)

let id = raffle.uuid
destroy self.raffles.insert(key: id, <-raffle)

return id
}

pub fun borrowRafflePublic(id: UInt64): &{RafflePublic}? {
return self.borrowRaffle(id: id)
}

pub fun borrowRaffle(id: UInt64): &Raffle? {
if self.raffles[id] == nil {
return nil
}
Expand All @@ -114,7 +156,7 @@ pub contract Raffles {
}
}

access(contract) fun emitDrawing(address: Address, raffleID: UInt64, sourceType: Type, index: Int, value: AnyStruct) {
access(contract) fun emitDrawing(_ address: Address?, _ raffleID: UInt64, _ sourceType: Type, _ index: Int, _ value: AnyStruct) {
var v = "UNKNOWN"
switch value.getType() {
case Type<Address>():
Expand All @@ -125,26 +167,13 @@ pub contract Raffles {
break
}

emit RaffleDrawn(address: address, raffleID: raffleID, sourceType: sourceType, index: index, value: v)
emit RaffleDrawn(address: address, raffleID: raffleID, sourceType: sourceType, index: index, value: v, valueType: value.getType())
}

pub fun createManager(): @Manager {
return <- create Manager()
}

pub fun createRaffle(source: @{RaffleSource}, details: Details): @Raffle {
return <- create Raffle(source: <- source, details: details)
}

pub fun createRaffleSource(_ type: Type): @{RaffleSource} {
switch type {
case Type<@AddressRaffleSource>():
return <- create AddressRaffleSource()
}

panic("raffle source type ".concat(type.identifier).concat(" is not valid"))
}

init() {
let identifier = "Raffle_".concat(self.account.address.toString())
self.ManagerStoragePath = StoragePath(identifier: identifier)!
Expand Down
6 changes: 6 additions & 0 deletions flow.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@
"testing": "0x0000000000000007"
}
},
"RaffleSources": {
"source": "./contracts/RaffleSources.cdc",
"aliases": {
"testing": "0x0000000000000008"
}
},
"FungibleToken": {
"source": "./node_modules/@flowtyio/flow-contracts/contracts/FungibleToken.cdc",
"aliases": {
Expand Down
11 changes: 11 additions & 0 deletions scripts/get_num_raffle_entries.cdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import "Raffles"

pub fun main(addr: Address, id: UInt64): Int {
let acct = getAuthAccount(addr)
let manager = acct.borrow<&Raffles.Manager{Raffles.ManagerPublic}>(from: Raffles.ManagerStoragePath)
?? panic("raffles manager not found")
let raffle = manager.borrowRafflePublic(id: id)
?? panic("raffle not found")

return raffle.getNumEntries()
}
13 changes: 13 additions & 0 deletions scripts/get_raffle_details.cdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import "Raffles"

pub fun main(addr: Address, id: UInt64): Raffles.Details? {
let acct = getAuthAccount(addr)
let manager = acct.borrow<&Raffles.Manager>(from: Raffles.ManagerStoragePath)
?? panic("raffles manager not found")

if let raffle = manager.borrowRafflePublic(id: id) {
return raffle.getDetails()
}

return nil
}
11 changes: 11 additions & 0 deletions scripts/get_raffle_entries.cdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import "Raffles"

pub fun main(addr: Address, id: UInt64): [AnyStruct] {
let acct = getAuthAccount(addr)
let manager = acct.borrow<&Raffles.Manager{Raffles.ManagerPublic}>(from: Raffles.ManagerStoragePath)
?? panic("raffles manager not found")
let raffle = manager.borrowRafflePublic(id: id)
?? panic("raffle not found")

return raffle.getEntries()
}
7 changes: 7 additions & 0 deletions scripts/get_raffle_source_identifier.cdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import "Raffles"

pub fun main(addr: Address, path: StoragePath): String {
let acct = getAuthAccount(addr)
let source = acct.borrow<&{Raffles.RaffleSource}>(from: path)
return source!.getType().identifier
}
Loading

0 comments on commit 352fb54

Please sign in to comment.