Git Product home page Git Product logo

ent-factory's Introduction

Ent Factory

Golang CI Maintainability Go Report Card

A Model Instance Factory Code Generation Tool For Ent Go. 中文文档

Function

Simplify the process of creating mock model objects for ent schemas.

  • Auto reading the struct of ent model schemas to create factory functions.
    • Support build-in type and imported type field.
    • PS: it will generate the imported type fields in default.
  • Auto fake data for each field as default.
  • Allow self define the value of any field independently by using function optional pattern.
  • The ID field of table cannot be edited by default, so the with function and setter will not generated for the ID field.

Todo

  • Unit Test Coverage
  • Version Compatibility Test
  • Read Foreign Key, Support Post Create Related Instance
  • Improve Code Maintainability From B to A
  • A CI config for self generating in CI/CD
  • Code Lint Fix From C to B
  • Provide Setter For No ReadOnly Imported Fields
  • Better Format
    • Add A Blank Space Between With Functions. Fixed by adding doc for each function.
    • Import Sort by fmt rules. (Fix by exec.Command)
  • Add documents for each function
  • Generate imported fields have a switch to control
  • Auto Format Code
  • Support Time Optional Function
  • Support Json Field Optional Function
  • Add Code Lint
  • CI Add Auto Lint
  • Option param to control overwrite exist factory or not

Struct

-- cmd
    -- root.go
    -- generate.go  // main logic
-- constants
    -- constants.go
    -- errors.go
-- factories        // the test generate code in here
-- gen              // ent generate code in here
-- service          // simulate app and ent client for test
-- spec             // ent tables definition dir
-- main.go
-- README.md
-- Makefile

Requirement

  • Golang 1.18~1.19
  • Ent 0.10.0 - 0.11.4
  • Faker 2.0

How to install

Install

go install golang.org/x/tools/cmd/goimports@latest
go install github.com/zaihui/ent-factory@latest

Setup

Flags

  • schemaPath
    • path of your entschema, normally is "gen/entschema"
    • required
  • outputPath
    • path of your factories
    • the endpoint must be "factories"
    • required
  • projectPath
    • the relative path of this project
    • eg. github.com/zaihui/ent-factory
    • required
  • overwrite
    • whether overwrite these exist files
    • the default value is false
  • factoriesPath
    • the relative path of these factories located in this project
    • eg. factories, means projectPath/factories
    • the default value is factories
  • appPath
    • the relative path of app client
    • eg. service/app means github.com/zaihui/ent-factory/service/app
    • the default value is service/app
  • entClientName
    • the name of ent client, means appPath.entClientName
    • the default value is EntClient
  • genImportFields
    • the bool value to set whether generate those imported fields of the models
    • the default value is true

Makefile Command

CAUTION!: This Command will NOT regenerate every factory based on the current struct of table in default.

If you want to Regenerate, please use the overwrite flag. Or delete what you want to regenerate then use this command.

all_factory:
  go run ent-factory generate --schemaPath {your ent schema path} --outputPath {path of your factories} ----projectPath {your project module path}

Sample

all_factory:
  go run ent-factory generate --schemaPath gen/entschema --outputPath  /Users/lvxinyan/zaihui/ent-factory/factories --projectPath github.com/zaihui/ent-factory
## for one factory
ent-factory generate --schemaFile gen/entschema/{one ent model file}.go --outputPath  /Users/lvxinyan/zaihui/ent-factory/factories --projectPath github.com/zaihui/ent-factory

Sample

The sample of a factory

package booktableorderfactory

import (
	"github.com/bxcodec/faker"
	"github/zaihui/ent-factory/factories"
	"github/zaihui/ent-factory/gen/entschema"
	"github/zaihui/ent-factory/service/app"
)

type BookTableOrderFieldSetter func(*entschema.BookTableOrder)


func SetUID(uIDGen string) BookTableOrderFieldSetter {
	return func(bookTableOrderGen *entschema.BookTableOrder) {
		bookTableOrderGen.UID = uIDGen
	}
}

func SetUserUID(userUIDGen string) BookTableOrderFieldSetter {
	return func(bookTableOrderGen *entschema.BookTableOrder) {
		bookTableOrderGen.UserUID = userUIDGen
	}
}
func SetOrderNo(orderNoGen string) BookTableOrderFieldSetter {
	return func(bookTableOrderGen *entschema.BookTableOrder) {
		bookTableOrderGen.OrderNo = orderNoGen
	}
}
func SetType(typeGen string) BookTableOrderFieldSetter {
	return func(bookTableOrderGen *entschema.BookTableOrder) {
		bookTableOrderGen.Type = typeGen
	}
}

func New(s factories.TestSuite, opts ...BookTableOrderFieldSetter) *entschema.BookTableOrder {
	data := entschema.BookTableOrder{}
	s.NoError(faker.FakeData(&data))
	for _, opt := range opts {
		opt(&data)
	}
	return app.EntClient.BookTableOrder.Create().
		SetUID(data.UID).
		SetUserUID(data.UserUID).
		SetOrderNo(data.OrderNo).
		SetType(data.Type).
		SaveX(s.Context())
}

How to use this factory

package main
import (
	your_location_of_factories/booktableorderfactory
)
// s is an instance of test suite
order := booktableorderfactory.new(s) 
// if you want to customize the value of a field, eg. UID
order2: = booktableorderfactory.new(s, booktableorderfactory.SetUID("your uid"))

Special Thank

Special Thanks splunk. The part of codegen about function optional pattern is based on this project from splunk.

I edit some logic of it to implement my reqirements, so I haven't imported it as a package to use it.

How to contribute

Process

  1. Fork this repo
  2. Clone your repo to local
  3. Create a branch based on master
  4. Add your code
  5. You can use the make self_test to test your code. It will build this package, then generate code for the table in spec/schema.
  6. Use make fmt format your code, and use make lint to check the code styles.
  7. Follow the base rule to create a pull request, happy coding!

Base Rule

  1. PR only can have one commit, and it needs to rebase the master branch
  2. It must have UTs, if it is possible.
  3. Commit Message must fit the format.
EF-{Number}(label): title
label:
- feat, for feature
- fix, for bug fix
- ut, for ut
- doc, for document
- refactor, for refactor code

Happy Coding, Happy Sharing!

ent-factory's People

Contributors

lxy1992 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

ent-factory's Issues

Imported Fields Not generated

Problem

  • Imported fields can generate Setter function for optional value set. However, when it comes to the ent Create() part, the imported fields will not be setted.

Why Not

Why is function haven't been done?

  • First, some imported fields cannot be set value, like update default fields, it will set automatically.
  • Second, even we can set these default fields, such as created_at, the mock data, will be wrong.
  • Three, now this tool generates factory code by reading the ent generated structs of models, which not contains such detail information, like have a default value, or default update field.

Why Need

Why we need this function?

  • Sometimes, we may want to set some imported fields, like json fields, even some time field.

Discussion

So, please provide some ideas to address this problem. You are welcomed.

generate fail by not exist go file

When no.go file with the same name is found in a folder under schemaPath, the whole program simply ends. No, I don't think this is reasonable. Although the console prints the error (file_name.go not exist). I thought I'd skip this faulty factories build section and prompt the user at the console that the Factories build is not there
(当schemaPath下文件夹未找到与文件夹同名的.go文件时,整个程序直接结束掉不,我认为这是不合理的。虽然控制台输出了该错误(file_name.go not exist)。我认为应该跳过这部分错误的factories生成部分,并在控制台提示用户该部分未生成)

want to support optional fields

such as :

field.Int("print_times").Nillable().Optional().Comment("打印次数")

now generate code:

SetPrintTimes(data.PrintTimes)

maybe the code could be SetNillablePrintTimes(data.PrintTimes)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.