Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Jennifer support #766

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions spec/amber/cli/commands/generator_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,21 @@ module Amber::CLI
end
end
end

describe "sam" do
MainCommand.run %w(generate sam)

it "generates sam file" do
File.exists?("./sam.cr").should be_true
end

it "generates proper content" do
file_content = File.read("./sam.cr")
file_content.should contain("Sam.help")
file_content.should contain(%(require "sam"))
file_content.should contain(%(require "./config/*"))
end
end
cleanup
end
end
9 changes: 9 additions & 0 deletions spec/amber/cli/commands/init_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,15 @@ module Amber::CLI
end
end
end

context "--sam" do
cleanup
scaffold_app(TESTING_APP, "--sam")

it "generates sam file" do
File.exists?("./sam.cr").should be_true
end
end
end

context "Database settings" do
Expand Down
12 changes: 5 additions & 7 deletions spec/amber/cli/templates/app_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,17 @@ require "../../../spec_helper"

module Amber::CLI
describe App do
pg_app = App.new("sample-app")
mysql_app = App.new("sample-app", "mysql")
sqlite_app = App.new("sample-app", "sqlite")
pg_app = App.new("sample-app", "pg", "slang", "jennifer", false)
mysql_app = App.new("sample-app", "mysql", "slang", "jennifer", false)
sqlite_app = App.new("sample-app", "sqlite", "slang", "jennifer", false)

describe "#database_name_base" do
it "should return a postgres compatible name" do
pg_app.database_name_base.should_not contain "-"
end

it "should return a consistent name for all db types" do
mysql_app.database_name_base.should eq pg_app.database_name_base
sqlite_app.database_name_base.should eq pg_app.database_name_base
end
it { mysql_app.database_name_base.should eq pg_app.database_name_base }
it { sqlite_app.database_name_base.should eq pg_app.database_name_base }
end
end
end
182 changes: 182 additions & 0 deletions spec/amber/cli/templates/jennifer_migration_spec.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
require "../../../spec_helper"
require "./migration_spec_helper"

module Amber::CLI::Jennifer
describe Migration do
described_class = Amber::CLI::Jennifer::Migration

describe ".build" do
context "with empty fields" do
it "builds unspecified migration for non new table migration name" do
described_class.build("add_field_to_tables", %w()).is_a?(Amber::CLI::Jennifer::Migration).should be_true
described_class.build("remove_field_from_tables", %w()).is_a?(Amber::CLI::Jennifer::Migration).should be_true
described_class.build("some_gibberish", %w()).is_a?(Amber::CLI::Jennifer::Migration).should be_true
end

it "builds new table migration for new migration name pattern" do
described_class.build("create_tables", %w()).is_a?(Amber::CLI::Jennifer::CreateTableMigration).should be_true
end
end

context "with new table migration name pattern" do
it do
described_class.build("create_tables", %w(name:string))
.is_a?(Amber::CLI::Jennifer::CreateTableMigration).should be_true
end

it "correctly sets table name" do
described_class.build("create_tables", %w(field:string))
.as(Amber::CLI::Jennifer::CreateTableMigration)
.table_name.should eq("tables")
end
end

context "with add new column migration name pattern" do
it do
migration = described_class.build("add_field_to_tables", %w(field:string))
migration.is_a?(Amber::CLI::Jennifer::ChangeColumnsMigration).should be_true
migration.as(Amber::CLI::Jennifer::ChangeColumnsMigration).add?.should be_true
end

it "correctly sets table name" do
described_class.build("add_field_to_tables", %w(field:string))
.as(Amber::CLI::Jennifer::ChangeColumnsMigration)
.table_name.should eq("tables")
end
end

context "with remove column migration name pattern" do
it do
migration = described_class.build("remove_field_from_tables", %w(field:string))
migration.is_a?(Amber::CLI::Jennifer::ChangeColumnsMigration).should be_true
migration.as(Amber::CLI::Jennifer::ChangeColumnsMigration).remove?.should be_true
end

it "correctly sets table name" do
described_class.build("add_field_to_tables", %w(field:string))
.as(Amber::CLI::Jennifer::ChangeColumnsMigration)
.table_name.should eq("tables")
end
end
end

describe "#render" do
migration = described_class.new("some_migration", %w(field:string))
migration_file = MigrationSpecHelper.text_for(migration)

it do
migration_file.should contain "class SomeMigration < Jennifer::Migration::Base"
end

it do
migration_file.should contain "def up"
end

it do
migration_file.should contain "def down"
end
end
end

describe CreateTableMigration do
describe "#render" do
migration = Amber::CLI::Jennifer::CreateTableMigration.new("create_users", %w(name:string owner:ref admin:bool))
migration_file = MigrationSpecHelper.text_for(migration)

it do
migration_file.should contain "class CreateUser < Jennifer::Migration::Base"
end

it do
migration_file.should contain <<-FILE
def up
create_table(:users) do |t|
t.string :name
t.reference :owner
t.bool :admin
t.timestamps
end
end
FILE
end

it do
migration_file.should contain <<-FILE
def down
drop_table :users
end
FILE
end
end
end

describe ChangeColumnsMigration do
describe "#render" do
describe "adding columns" do
migration = Amber::CLI::Jennifer::ChangeColumnsMigration.new("add_columns_to_users", %w(name:string owner:ref admin:bool), :add)
migration_file = MigrationSpecHelper.text_for(migration)

it do
migration_file.should contain "class AddColumnsToUser < Jennifer::Migration::Base"
end

it do
migration_file.should contain <<-FILE
def up
change_table(:users) do |t|
t.add_column :name, :string
t.add_column :owner, :reference
t.add_column :admin, :bool
end
end
FILE
end

it do
migration_file.should contain <<-FILE
def down
change_table(:users) do |t|
t.drop_column :name
t.drop_column :owner
t.drop_column :admin
end
end
FILE
end
end

describe "removing columns" do
migration = Amber::CLI::Jennifer::ChangeColumnsMigration.new("remove_columns_from_users", %w(name:string owner:ref admin:bool), :remove)
migration_file = MigrationSpecHelper.text_for(migration)

it do
migration_file.should contain "class RemoveColumnsFromUser < Jennifer::Migration::Base"
end

it do
migration_file.should contain <<-FILE
def up
change_table(:users) do |t|
t.drop_column :name
t.drop_column :owner
t.drop_column :admin
end
end
FILE
end

it do
migration_file.should contain <<-FILE
def down
change_table(:users) do |t|
t.add_column :name, :string
t.add_column :owner, :reference
t.add_column :admin, :bool
end
end
FILE
end
end
end
end
end
2 changes: 1 addition & 1 deletion spec/amber/cli/templates/migration_spec_helper.cr
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ module Amber::CLI
ensure
`rm -rf ./tmp/db`
end
return migration_text
migration_text
end

def self.sample_migration_for(migration_template_type)
Expand Down
25 changes: 25 additions & 0 deletions spec/amber/cli/templates/sam_spec.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
require "../../../spec_helper"

module Amber::CLI
module SamSpecHelper
def self.text_for(sam : Sam) : String
sam.render("./tmp/app")
File.read("./tmp/app/sam.cr")
ensure
`rm -rf ./tmp/app`
end
end

describe Sam do
describe "#render" do
context "with jennifer model" do
sam = Amber::CLI::Sam.new("jennifer")
file = SamSpecHelper.text_for(sam)

it { file.should contain("Sam.help") }
it { file.should contain(%(require "./db/migrations/*")) }
it { file.should contain(%(load_dependencies "jennifer")) }
end
end
end
end
2 changes: 1 addition & 1 deletion src/amber/cli/commands.cr
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ module Amber::CLI
help desc: "# Describe available commands and usages"
string ["-t", "--template"], desc: "# Preconfigure for selected template engine. Options: slang | ecr", default: "slang"
string ["-d", "--database"], desc: "# Preconfigure for selected database. Options: pg | mysql | sqlite", default: "pg"
string ["-m", "--model"], desc: "# Preconfigure for selected model. Options: granite | crecto", default: "granite"
string ["-m", "--model"], desc: "# Preconfigure for selected model. Options: granite | crecto | jennifer", default: "granite"
string ["-r", "--recipe"], desc: "# Use a named recipe. See documentation at https://amberframework.org.", default: nil
end
end
Expand Down
24 changes: 15 additions & 9 deletions src/amber/cli/commands/generate.cr
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ module Amber::CLI

class Generate < Command
class Options
arg "type", desc: "scaffold, model, controller, migration, mailer, socket, channel, auth, error", required: true
arg "type", desc: "scaffold, model, controller, migration, mailer, socket, channel, auth, error, sam", required: true
arg "name", desc: "name of resource", required: false
arg_array "fields", desc: "user:reference name:string body:text age:integer published:bool"
bool "--no-color", desc: "Disable colored output", default: false
Expand All @@ -20,34 +20,40 @@ module Amber::CLI

def run
CLI.toggle_colors(options.no_color?)
if args.type == "error"
template = Template.new("error", ".")
if optional_name?
template = Template.new(args.type.as(String), ".")
else
ensure_name_argument!

if recipe && Amber::Recipes::Recipe.can_generate?(args.type, recipe)
template = Amber::Recipes::Recipe.new(args.name, ".", recipe.as(String), args.fields)
else
template = Template.new(args.name, ".", args.fields)
ensure_name_argument!

if recipe && Amber::Recipes::Recipe.can_generate?(args.type, recipe)
template = Amber::Recipes::Recipe.new(args.name, ".", recipe.as(String), args.fields)
else
template = Template.new(args.name, ".", args.fields)
end
end
end
template.generate args.type
template.generate(args.type)
end

def recipe
CLI.config.recipe
end

private def optional_name?
%w(error sam).includes?(args.type)
end

private def ensure_name_argument!
unless args.name?
error "Parsing Error: The NAME argument is required."
exit! help: true, error: true
end
end

class Help
caption "# Generate Amber classes"
end
end
end
end
3 changes: 2 additions & 1 deletion src/amber/cli/commands/new.cr
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@ module Amber::CLI
arg "name", desc: "name of project", required: true
string "-d", desc: "database", any_of: %w(pg mysql sqlite), default: "pg"
string "-t", desc: "template language", any_of: %w(slang ecr), default: "slang"
string "-m", desc: "model type", any_of: %w(granite crecto), default: "granite"
string "-m", desc: "model type", any_of: %w(granite crecto jennifer), default: "granite"
string "-r", desc: "recipe"
bool "--deps", desc: "installs deps, (shards update)", default: false
bool "--sam", desc: "setup initial Sam tasks file", default: false
bool "--no-color", desc: "Disable colored output", default: false
help
end
Expand Down
35 changes: 35 additions & 0 deletions src/amber/cli/commands/sam.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
require "cli"

module Amber::CLI
class MainCommand < ::Cli::Supercommand
class Sam < Command
command_name "sam"

SAM_PATH = "sam.cr"

class Options
# NOTE: command definition is needed only to be displayed on help output
arg_array "command", desc: "Sam command to be invoked"
unknown
help
end

class Help
header <<-EOS
Invokes Sam based task. Powered by Sam (https://github.com/imdrasil/sam.cr).
To list all available tasks use:
$ amber sam help
EOS
caption "# Invoke Sam task"
end

def run
if File.exists?(SAM_PATH)
Helpers.run("crystal run sam.cr -- #{ARGV[1..-1].join(" ")}")
else
exit! "Sam file is not found.", error: true
end
end
end
end
end
Loading