Code Monkey home page Code Monkey logo

factlin's Introduction

Download CircleCI codecov

factlin

factlin is Kotlin test fixture generator from existing database schema.

This gradle plugin generate fixture factory class and insert helper method (currentlly support only Ninja-Squad/DbSetup)

example

From this database schema

CREATE TABLE users (
  id SERIAL PRIMARY KEY,
  name VARCHAR(256) NOT NULL,
  job VARCHAR(256) NOT NULL DEFAULT 'engineer',
  status VARCHAR(256) NOT NULL DEFAULT 'ACTIVE',
  age INTEGER NOT NULL,
  score NUMERIC NOT NULL,
  is_admin BOOLEAN NOT NULL,
  birth_day DATE NOT NULL,
  nick_name VARCHAR(256),
  created_timestamp TIMESTAMP WITHOUT TIME ZONE NOT NULL,
  updated_timestamp TIMESTAMP WITHOUT TIME ZONE
);

COMMENT ON TABLE users IS 'user table';
COMMENT ON COLUMN users.id IS 'primary key';
COMMENT ON COLUMN users.name IS 'user name';
COMMENT ON COLUMN users.job IS 'job name';
COMMENT ON COLUMN users.status IS 'activate status';
COMMENT ON COLUMN users.age IS 'user age';
COMMENT ON COLUMN users.score IS 'game score';
COMMENT ON COLUMN users.is_admin IS 'user is admin user or not';
COMMENT ON COLUMN users.birth_day IS 'user birth day';
COMMENT ON COLUMN users.nick_name IS 'nick name';

Generated Kotlin code is like this

data class UsersFixture (
    val id: Int = 0, // primary key
    val name: String = "", // user name
    val job: String = "", // job name
    val status: String = "", // activate status
    val age: Int = 0, // user age
    val score: BigDecimal = 0.toBigDecimal(), // game score
    val is_admin: Boolean = false, // user is admin user or not
    val birth_day: LocalDate = LocalDate.now(), // user birth day
    val nick_name: String? = null, // nick name
    val created_timestamp: LocalDateTime = LocalDateTime.now(), 
    val updated_timestamp: LocalDateTime? = null 
)

fun DbSetupBuilder.insertUsersFixture(f: UsersFixture) {
    insertInto("users") {
        mappedValues(
                "id" to f.id,
                "name" to f.name,
                "job" to f.job,
                "status" to f.status,
                "age" to f.age,
                "score" to f.score,
                "is_admin" to f.is_admin,
                "birth_day" to f.birth_day,
                "nick_name" to f.nick_name,
                "created_timestamp" to f.created_timestamp,
                "updated_timestamp" to f.updated_timestamp
        )
    }
}

Use in your test (with Ninja-Squad/DbSetup)

dbSetup(dest) {
    deleteAllFrom(listOf("users")) 
    
    // using generated codes. this codes insert datas to your database
    insertUsersFixture(UsersFixture(id = 1, name = "user1"))
    insertUsersFixture(UsersFixture(id = 2, name = "user2", is_admin = true))
}.launch()


...your db test

benefit

  • type and null safe db test fixture generation (no more excel and insert into...)
  • help to generate similar test fixtures from another fixture (generated fixture class is Kotlin data class)

supported databases

  • PostgreSQL
  • MariaDB

how to use

create tables in your db

CREATE TABLE ...

build.gradle

buildscript {
    repositories {
        jcenter() // factlin is published at jcenter
    }
    dependencies {
        classpath 'com.maeharin:factlin:0.1.1'
        classpath "org.postgresql:postgresql:42.1.4"
    }
}

apply plugin: 'kotlin'

// factlin config
apply plugin: 'factlin'
factlin {
    dbUrl = "jdbc:postgresql://{DB_HOST}/{DB_NAME}"
    dbUser = "{DB_USER}"
    dbPassword = "{DB_PASS}"
    dbDialect = "postgres"
}

repositories {
    mavenCentral()
}
dependencies {
    compile "org.postgresql:postgresql:42.1.4"
    testCompile 'com.ninja-squad:DbSetup-kotlin:2.1.0' // generated code depends on dbsetup
}

generate codes

./gradlew factlin

use generated codes for your db connection test (ex: JUnit)

class SampleTest {
    val dest = DriverManagerDestination("jdbc:postgresql://{DB_HOST}/{DB_NAME}", "DB_USER", "DB_PASS")

    init {
        Class.forName("org.postgresql.Driver")
    }

    @Test
    fun testInsertUser() {
        dbSetup(dest) {
            deleteAllFrom(listOf("users"))
            insertUsersFixture(UsersFixture())
        }.launch()
        
        val stmt = dest.connection.createStatement()
        val rs = stmt.executeQuery("select * from users")
        
        assertTrue(rs.next())
        assertEquals("", rs.getString("name"))
    }
}

run test

./gradlew test

done!

customize

you can customize default behavior at build.gradle like this:

apply plugin: 'factlin'
factlin {
    dbUrl = "jdbc:postgresql://{DB_HOST}/{DB_NAME}"
    
    dbUser = "{DB_USER}"
    
    dbPassword = "{DB_PASS}"
    
    // postgres or mariadb
    dbDialect = "postgres"
    
    // output directory of generaged code
    // defult: src/test/kotlin/com/maeharin/factlin/fixtures
    fixtureOutputDir = "src/test/kotlin/com/example/myapp/fixtures"
    
    // package name of generated code
    // default: com.maeharin.factlin.fixtures
    fixturePackageName = "com.example.myapp.fixtures"
    
    // custom template(FreeMarker) path
    // default: nothing (use factlin default template file)
    // https://github.com/maeharin/factlin/blob/master/src/main/resources/factlin/class.ftl
    fixtureTemplatePath = "src/test/resources/factlin/class_template.ftl"
    
    // exclude table names
    // default: nothing
    excludeTables = ["payment_p2007_01", "payment_p2007_02", "payment_p2007_03", "payment_p2007_04", "payment_p2007_05", "payment_p2007_06"]
    
    // include table names
    // default: all tables
    includeTables = ["users", "film"]
    
    // true if delete output directory before code generation 
    // * recommended to be true for ease of maintenance
    // default: false
    cleanOutputDir = true
    
    // override specific default value
    // format: [tableName, columnName, defaultValue]
    // default: nothing
    customDefaultValues = [
        ["users", "job", "\"engineer\""],
        ["users", "status", "\"ACTIVE\""],
    ]
    
    // override database column type to kotlin type mapping
    // format: [databaseColumnType, KotlinType]
    // see default mapper: https://github.com/maeharin/factlin/blob/master/src/main/kotlin/com/maeharin/factlin/core/kclassbuilder/KClassBuilder.kt#L59
    customTypeMapper = [
        "year": "SHORT", // treat custom type [year] as SHORT
    ]
    
    // name of target database schema
    // this is not working for no schema support database(ex: mariadb, mysql...)
    // default: null (include all schemas)
    schema = "public"

    // if true, use camel-case for fixture class property  name.
    useCamelCase = false
}

sample project

how to develop

unit test

./gradlew test

integration test

docker-compose up
./init-db.sh
./integration-test.sh

publish

// .env is secret
source .env
./gradlew clean build bintrayUpload --info

factlin's People

Contributors

maeharin avatar suusan2go avatar

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.