Skip to content

Commit

Permalink
Merge pull request #1451 from onflow/chasefleming/gen-contract-test
Browse files Browse the repository at this point in the history
 Generate contract test file along with contract boilerplate
  • Loading branch information
chasefleming authored Mar 13, 2024
2 parents bb0f71b + 1b16948 commit f611b10
Show file tree
Hide file tree
Showing 2 changed files with 129 additions and 16 deletions.
79 changes: 67 additions & 12 deletions internal/super/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ import (
"path/filepath"
"strings"

flowsdk "github.com/onflow/flow-go-sdk"

"github.com/onflow/flowkit/config"

"github.com/onflow/flowkit"
Expand All @@ -36,6 +38,7 @@ import (

type generateFlagsDef struct {
Directory string `default:"" flag:"dir" info:"Directory to generate files in"`
SkipTests bool `default:"false" flag:"skip-tests" info:"Skip generating test files"`
}

var generateFlags = generateFlagsDef{}
Expand Down Expand Up @@ -116,6 +119,17 @@ func generateScript(
return generateNew(args, "script", logger, state)
}

func addCDCExtension(name string) string {
if strings.HasSuffix(name, ".cdc") {
return name
}
return fmt.Sprintf("%s.cdc", name)
}

func stripCDCExtension(name string) string {
return strings.TrimSuffix(name, filepath.Ext(name))
}

func generateNew(
args []string,
templateType string,
Expand All @@ -126,17 +140,11 @@ func generateNew(
return nil, fmt.Errorf("invalid number of arguments")
}

name := args[0]
var filename string

// Don't add .cdc extension if it's already there
if strings.HasSuffix(name, ".cdc") {
filename = name
} else {
filename = fmt.Sprintf("%s.cdc", name)
}
name := stripCDCExtension(args[0])
filename := addCDCExtension(name)

var fileToWrite string
var testFileToWrite string
var basePath string

if generateFlags.Directory != "" {
Expand All @@ -156,11 +164,23 @@ func generateNew(

switch templateType {
case "contract":
fileToWrite = fmt.Sprintf(`
access(all)
fileToWrite = fmt.Sprintf(`access(all)
contract %s {
init() {}
}`, name)
testFileToWrite = fmt.Sprintf(`import Test
access(all) let account = Test.createAccount()
access(all) fun testContract() {
let err = Test.deployContract(
name: "%s",
path: "../contracts/%s.cdc",
arguments: [],
)
Test.expect(err, Test.beNil())
}`, name, name)
case "script":
fileToWrite = `access(all)
fun main() {
Expand Down Expand Up @@ -188,15 +208,50 @@ fun main() {
return nil, fmt.Errorf("error creating directories: %w", err)
}

// Write files
err = state.ReaderWriter().WriteFile(filenameWithBasePath, []byte(fileToWrite), 0644)
if err != nil {
return nil, fmt.Errorf("error writing file: %w", err)
}

logger.Info(fmt.Sprintf("Generated new %s: %s at %s", templateType, name, filenameWithBasePath))

if generateFlags.SkipTests != true && templateType == "contract" {
testsBasePath := "cadence/tests"
testFilenameWithBasePath := filepath.Join(testsBasePath, addCDCExtension(fmt.Sprintf("%s_test", name)))

if _, err := state.ReaderWriter().ReadFile(testFilenameWithBasePath); err == nil {
return nil, fmt.Errorf("file already exists: %s", testFilenameWithBasePath)
}

if err := state.ReaderWriter().MkdirAll(testsBasePath, 0755); err != nil {
return nil, fmt.Errorf("error creating test directory: %w", err)
}

err = state.ReaderWriter().WriteFile(testFilenameWithBasePath, []byte(testFileToWrite), 0644)
if err != nil {
return nil, fmt.Errorf("error writing test file: %w", err)
}

logger.Info(fmt.Sprintf("Generated new test file: %s at %s", name, testFilenameWithBasePath))
}

if templateType == "contract" {
state.Contracts().AddOrUpdate(config.Contract{Name: name, Location: filenameWithBasePath})
var aliases config.Aliases

if generateFlags.SkipTests != true {
aliases = config.Aliases{{
Network: config.TestingNetwork.Name,
Address: flowsdk.HexToAddress("0x0000000000000007"),
}}
}

contract := config.Contract{
Name: name,
Location: filenameWithBasePath,
Aliases: aliases,
}
state.Contracts().AddOrUpdate(contract)
err = state.SaveDefault()
if err != nil {
return nil, fmt.Errorf("error saving to flow.json: %w", err)
Expand Down
66 changes: 62 additions & 4 deletions internal/super/generate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,20 +40,79 @@ func TestGenerateNewContract(t *testing.T) {
assert.NoError(t, err, "Failed to read generated file")
assert.NotNil(t, fileContent)

testContent, err := state.ReaderWriter().ReadFile("cadence/tests/TestContract_test.cdc")
assert.NoError(t, err, "Failed to read generated file")
assert.NotNil(t, testContent)

// Check content is correct
expectedContent := `
access(all)
expectedContent := `access(all)
contract TestContract {
init() {}
}`

expectedTestContent := `import Test
access(all) let account = Test.createAccount()
access(all) fun testContract() {
let err = Test.deployContract(
name: "TestContract",
path: "../contracts/TestContract.cdc",
arguments: [],
)
Test.expect(err, Test.beNil())
}`

assert.Equal(t, expectedContent, string(fileContent))
assert.Equal(t, expectedTestContent, string(testContent))

// Test file already exists scenario
_, err = generateNew([]string{"TestContract"}, "contract", logger, state)
assert.Error(t, err)
assert.Equal(t, "file already exists: cadence/contracts/TestContract.cdc", err.Error())
}

func TestGenerateNewContractSkipTests(t *testing.T) {
logger := output.NewStdoutLogger(output.NoneLog)
_, state, _ := util.TestMocks(t)

generateFlags.SkipTests = true

t.Cleanup(func() {
generateFlags.SkipTests = false
})

// Test contract generation
_, err := generateNew([]string{"TestContract"}, "contract", logger, state)
assert.NoError(t, err, "Failed to generate contract")

fileContent, err := state.ReaderWriter().ReadFile("cadence/contracts/TestContract.cdc")
assert.NoError(t, err, "Failed to read generated file")
assert.NotNil(t, fileContent)

testContent, err := state.ReaderWriter().ReadFile("cadence/tests/TestContract_test.cdc")
assert.Error(t, err, "Failed to read generated file")
assert.Nil(t, testContent)
}

func TestGenerateNewContractWithCDCExtension(t *testing.T) {
logger := output.NewStdoutLogger(output.NoneLog)
_, state, _ := util.TestMocks(t)

// Test contract generation
_, err := generateNew([]string{"Tester.cdc"}, "contract", logger, state)
assert.NoError(t, err, "Failed to generate contract")

fileContent, err := state.ReaderWriter().ReadFile("cadence/contracts/Tester.cdc")
assert.NoError(t, err, "Failed to read generated file")
assert.NotNil(t, fileContent)

testContent, err := state.ReaderWriter().ReadFile("cadence/tests/Tester_test.cdc")
assert.NoError(t, err, "Failed to read generated file")
assert.NotNil(t, testContent)
}

func TestGenerateNewContractFileAlreadyExists(t *testing.T) {
logger := output.NewStdoutLogger(output.NoneLog)
_, state, _ := util.TestMocks(t)
Expand Down Expand Up @@ -137,8 +196,7 @@ func TestGenerateNewWithDirFlag(t *testing.T) {
assert.NoError(t, err, "Failed to read generated file")
assert.NotNil(t, content)

expectedContent := `
access(all)
expectedContent := `access(all)
contract TestContract {
init() {}
}`
Expand Down

0 comments on commit f611b10

Please sign in to comment.