gris 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (74) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +8 -0
  3. data/.rspec +3 -0
  4. data/.rubocop.yml +1 -0
  5. data/.rubocop_todo.yml +67 -0
  6. data/.ruby-gemset +1 -0
  7. data/.ruby-version +1 -0
  8. data/Gemfile +12 -0
  9. data/Gemfile.lock +203 -0
  10. data/Guardfile +82 -0
  11. data/MIT-LICENSE +20 -0
  12. data/README.md +7 -0
  13. data/Rakefile +11 -0
  14. data/bin/gris +5 -0
  15. data/gris.gemspec +40 -0
  16. data/lib/gris.rb +37 -0
  17. data/lib/gris/cli.rb +71 -0
  18. data/lib/gris/deprecations.rb +9 -0
  19. data/lib/gris/deprecations/gris_setup.rb +14 -0
  20. data/lib/gris/generators.rb +3 -0
  21. data/lib/gris/generators/api_generator.rb +31 -0
  22. data/lib/gris/generators/migration_generator.rb +228 -0
  23. data/lib/gris/generators/scaffold_generator.rb +21 -0
  24. data/lib/gris/generators/templates/api/app/apis/%name_tableize%_endpoint.rb.tt +65 -0
  25. data/lib/gris/generators/templates/api/app/models/%name_underscore%.rb.tt +2 -0
  26. data/lib/gris/generators/templates/api/app/presenters/%name_tableize%_presenter.rb.tt +5 -0
  27. data/lib/gris/generators/templates/api/app/presenters/%name_underscore%_presenter.rb.tt +10 -0
  28. data/lib/gris/generators/templates/api/spec/apis/%name_tableize%_endpoint_spec.rb.tt +70 -0
  29. data/lib/gris/generators/templates/api/spec/fabricators/%name_tableize%_fabricator.rb.tt +2 -0
  30. data/lib/gris/generators/templates/api/spec/models/%name_underscore%_spec.rb.tt +7 -0
  31. data/lib/gris/generators/templates/create_table_migration/%migration_filename%.rb.tt +19 -0
  32. data/lib/gris/generators/templates/migration/%migration_filename%.rb.tt +39 -0
  33. data/lib/gris/generators/templates/scaffold/.Procfile.tt +1 -0
  34. data/lib/gris/generators/templates/scaffold/.env.test.tt +11 -0
  35. data/lib/gris/generators/templates/scaffold/.env.tt +10 -0
  36. data/lib/gris/generators/templates/scaffold/.gitignore.tt +11 -0
  37. data/lib/gris/generators/templates/scaffold/.rspec.tt +3 -0
  38. data/lib/gris/generators/templates/scaffold/.rubocop.yml +18 -0
  39. data/lib/gris/generators/templates/scaffold/.ruby-gemset.tt +1 -0
  40. data/lib/gris/generators/templates/scaffold/.ruby-version.tt +1 -0
  41. data/lib/gris/generators/templates/scaffold/Gemfile.tt +33 -0
  42. data/lib/gris/generators/templates/scaffold/README.md.tt +3 -0
  43. data/lib/gris/generators/templates/scaffold/Rakefile +9 -0
  44. data/lib/gris/generators/templates/scaffold/app.rb +57 -0
  45. data/lib/gris/generators/templates/scaffold/app/apis/application_endpoint.rb +9 -0
  46. data/lib/gris/generators/templates/scaffold/app/presenters/root_presenter.rb +20 -0
  47. data/lib/gris/generators/templates/scaffold/config.ru.tt +6 -0
  48. data/lib/gris/generators/templates/scaffold/config/database.yml.tt +19 -0
  49. data/lib/gris/generators/templates/scaffold/config/initializers/active_record.rb +4 -0
  50. data/lib/gris/generators/templates/scaffold/db/schema.rb +11 -0
  51. data/lib/gris/generators/templates/scaffold/public/errors/404.html +11 -0
  52. data/lib/gris/generators/templates/scaffold/public/errors/500.html +11 -0
  53. data/lib/gris/generators/templates/scaffold/spec/apis/cors_spec.rb +31 -0
  54. data/lib/gris/generators/templates/scaffold/spec/spec_helper.rb +26 -0
  55. data/lib/gris/generators/templates/scaffold/spec/support/app_helper.rb +3 -0
  56. data/lib/gris/grape_extensions/crud_helpers.rb +26 -0
  57. data/lib/gris/identity.rb +50 -0
  58. data/lib/gris/middleware/app_monitor.rb +17 -0
  59. data/lib/gris/output_formatters/paginated_presenter.rb +41 -0
  60. data/lib/gris/output_formatters/presenter.rb +15 -0
  61. data/lib/gris/rspec_extensions/response_helpers.rb +57 -0
  62. data/lib/gris/setup.rb +17 -0
  63. data/lib/gris/version.rb +38 -0
  64. data/lib/tasks/db.rake +81 -0
  65. data/lib/tasks/routes.rake +11 -0
  66. data/spec/generators/api_generator_spec.rb +76 -0
  67. data/spec/generators/migration_generator_spec.rb +96 -0
  68. data/spec/generators/scaffold_generator_spec.rb +119 -0
  69. data/spec/grape_extensions/crud_helpers_spec.rb +5 -0
  70. data/spec/identity_spec.rb +86 -0
  71. data/spec/spec_helper.rb +10 -0
  72. data/spec/support/spec_generators_helper.rb +11 -0
  73. data/spec/version_spec.rb +40 -0
  74. metadata +426 -0
@@ -0,0 +1,11 @@
1
+ unless defined?(Rails)
2
+ desc 'display all routes for Grape'
3
+ task :routes do
4
+ ApplicationEndpoint.routes.each do |api|
5
+ method = api.route_method.ljust(10)
6
+ path = api.route_path.ljust(40)
7
+ description = api.route_description
8
+ puts " #{method} #{path} # #{description}"
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,76 @@
1
+ require 'spec_helper'
2
+ require 'gris/generators/api_generator'
3
+ require 'gris/cli'
4
+
5
+ describe Gris::Generators::ApiGenerator do
6
+ include_context 'with generator'
7
+ let(:api_name) { 'foo' }
8
+
9
+ before do
10
+ Gris::CLI::Base.new.generate('api', api_name)
11
+ end
12
+
13
+ describe 'app' do
14
+ it 'creates an endpoint class' do
15
+ expected_api_file = File.join(generator_tmp_directory, 'app/apis/foos_endpoint.rb')
16
+ api_code = File.read(expected_api_file)
17
+ expect(api_code).to match(/class FoosEndpoint/)
18
+ end
19
+
20
+ it 'creates a model class' do
21
+ expected_model_file = File.join(generator_tmp_directory, 'app/models/foo.rb')
22
+ model_code = File.read(expected_model_file)
23
+ expect(model_code).to match(/class Foo/)
24
+ end
25
+
26
+ it 'creates an item presenter module' do
27
+ expected_presenter_file = File.join(generator_tmp_directory, 'app/presenters/foo_presenter.rb')
28
+ presenter_code = File.read(expected_presenter_file)
29
+ expect(presenter_code).to match(/module FooPresenter/)
30
+ end
31
+
32
+ it 'item presenter includes Gris::Presenter' do
33
+ presenter_file = File.join(generator_tmp_directory, 'app/presenters/foo_presenter.rb')
34
+ require "./#{presenter_file}"
35
+ expect(FooPresenter).to include(Gris::Presenter)
36
+ end
37
+
38
+ it 'creates a collection presenter module' do
39
+ expected_presenter_file = File.join(generator_tmp_directory, 'app/presenters/foos_presenter.rb')
40
+ presenter_code = File.read(expected_presenter_file)
41
+ expect(presenter_code).to match(/module FoosPresenter/)
42
+ end
43
+
44
+ it 'collection presenter includes Gris::Presenter' do
45
+ presenter_file = File.join(generator_tmp_directory, 'app/presenters/foos_presenter.rb')
46
+ require "./#{presenter_file}"
47
+ expect(FoosPresenter).to include(Gris::Presenter)
48
+ end
49
+
50
+ it 'collection presenter includes Gris::PaginatedPresenter' do
51
+ presenter_file = File.join(generator_tmp_directory, 'app/presenters/foos_presenter.rb')
52
+ require "./#{presenter_file}"
53
+ expect(FoosPresenter).to include(Gris::PaginatedPresenter)
54
+ end
55
+ end
56
+
57
+ describe 'spec' do
58
+ it 'creates an api spec' do
59
+ expected_api_file = File.join(generator_tmp_directory, 'spec/apis/foos_endpoint_spec.rb')
60
+ api_code = File.read(expected_api_file)
61
+ expect(api_code).to match(/describe FoosEndpoint/)
62
+ end
63
+
64
+ it 'creates a fabricator' do
65
+ expected_fabricator_file = File.join(generator_tmp_directory, 'spec/fabricators/foos_fabricator.rb')
66
+ fabricator_code = File.read(expected_fabricator_file)
67
+ expect(fabricator_code).to include 'Fabricator(:foo) do'
68
+ end
69
+
70
+ it 'creates a model spec' do
71
+ expected_model_file = File.join(generator_tmp_directory, 'spec/models/foo_spec.rb')
72
+ model_code = File.read(expected_model_file)
73
+ expect(model_code).to match(/describe Foo/)
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,96 @@
1
+ require 'spec_helper'
2
+ require 'gris/generators/migration_generator'
3
+ require 'gris/cli'
4
+
5
+ describe Gris::Generators::MigrationGenerator do
6
+ include_context 'with generator'
7
+ let(:migration_filename) { 'foo' }
8
+
9
+ before do
10
+ allow_any_instance_of(described_class).to receive(:migration_filename).and_return(migration_filename)
11
+ end
12
+
13
+ describe 'AddFooToBar flew:string:index brew:integer' do
14
+ before do
15
+ Gris::CLI::Base.new.generate('migration', 'AddFooToBar', 'flew:string:index', 'brew:integer')
16
+ expected_migration_file = File.join(generator_tmp_directory, 'foo.rb')
17
+ @migration_code = File.read(expected_migration_file)
18
+ end
19
+
20
+ it 'creates a camelized migration class' do
21
+ expect(@migration_code).to match(/class AddFooToBar/)
22
+ end
23
+
24
+ it 'adds the columns' do
25
+ expect(@migration_code).to match(/add_column :bars, :flew, :string/)
26
+ expect(@migration_code).to match(/add_column :bars, :brew, :integer/)
27
+ end
28
+
29
+ it 'adds the index on the correct column' do
30
+ expect(@migration_code).to match(/add_index :bars, :flew/)
31
+ end
32
+ end
33
+
34
+ describe 'RemoveFooFromBar flew:string brew:integer' do
35
+ before do
36
+ Gris::CLI::Base.new.generate('migration', 'RemoveFooFromBar', 'flew:string', 'brew:integer')
37
+ expected_migration_file = File.join(generator_tmp_directory, 'foo.rb')
38
+ @migration_code = File.read(expected_migration_file)
39
+ end
40
+
41
+ it 'creates a camelized migration class' do
42
+ expect(@migration_code).to match(/class RemoveFooFromBar/)
43
+ end
44
+
45
+ it 'removes the columns' do
46
+ expect(@migration_code).to match(/remove_column :bars, :flew, :string/)
47
+ expect(@migration_code).to match(/remove_column :bars, :brew, :integer/)
48
+ end
49
+ end
50
+
51
+ describe 'CreateJoinTableFooBar foo bar' do
52
+ before do
53
+ Gris::CLI::Base.new.generate('migration', 'CreateJoinTableFooBar', 'foo', 'bar')
54
+ expected_migration_file = File.join(generator_tmp_directory, 'foo.rb')
55
+ @migration_code = File.read(expected_migration_file)
56
+ end
57
+
58
+ it 'creates a camelized migration class' do
59
+ expect(@migration_code).to match(/class CreateJoinTableFooBar/)
60
+ end
61
+
62
+ it 'creates the join table' do
63
+ expect(@migration_code).to match(/create_join_table :foos, :bars/)
64
+ end
65
+
66
+ it 'adds placeholders for the indexing' do
67
+ expect(@migration_code).to match(/# t.index \[:foo_id, :bar_id\]/)
68
+ expect(@migration_code).to match(/# t.index \[:bar_id, :foo_id\]/)
69
+ end
70
+ end
71
+
72
+ describe 'CreateSkrillex drops:integer hair:string:index' do
73
+ before do
74
+ Gris::CLI::Base.new.generate('migration', 'CreateSkrillex', 'drops:integer', 'hair:string:index')
75
+ expected_migration_file = File.join(generator_tmp_directory, 'foo.rb')
76
+ @migration_code = File.read(expected_migration_file)
77
+ end
78
+
79
+ it 'creates a camelized migration class' do
80
+ expect(@migration_code).to match(/class CreateSkrillex/)
81
+ end
82
+
83
+ it 'creates the table' do
84
+ expect(@migration_code).to match(/create_table :skrillexes/)
85
+ end
86
+
87
+ it 'adds the columns' do
88
+ expect(@migration_code).to match(/t.integer :drops/)
89
+ expect(@migration_code).to match(/t.string :hair/)
90
+ end
91
+
92
+ it 'adds the index on the correct column' do
93
+ expect(@migration_code).to match(/add_index :skrillexes, :hair/)
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,119 @@
1
+ require 'spec_helper'
2
+ require 'gris/generators/scaffold_generator'
3
+ require 'gris/cli'
4
+
5
+ describe Gris::Generators::ScaffoldGenerator do
6
+ let(:app_name) { 'my_test_app' }
7
+ let(:app_path) { 'spec/my_different_directory' }
8
+ let(:options) { {} }
9
+
10
+ before do
11
+ scaffold = Gris::CLI::Base.new(args, options)
12
+ scaffold.invoke(:new)
13
+ end
14
+
15
+ after do
16
+ if args[1] # if app_path exists, delete dir at app_path
17
+ FileUtils.rm_rf(args[1])
18
+ else # otherwise delete dir at app_name
19
+ FileUtils.rm_rf(args[0])
20
+ end
21
+ end
22
+
23
+ context 'given only an app name' do
24
+ let(:args) { [app_name] }
25
+
26
+ it 'creates a scaffold app in a directory that mirrors the app name' do
27
+ expect(Dir).to exist(app_name)
28
+ end
29
+ end
30
+
31
+ context 'given an app name and a directory' do
32
+ let(:args) { [app_name, app_path] }
33
+
34
+ it 'creates a scaffold app in a directory of my choosing' do
35
+ expect(Dir).to exist(app_path)
36
+ end
37
+
38
+ it 'creates a .env file with with a development database name' do
39
+ expect(File).to exist("#{app_path}/.env")
40
+ env_file = File.read("#{app_path}/.env")
41
+ expect(env_file).to match(/#{app_name}_development/)
42
+ end
43
+
44
+ it 'creates a .Procfile file with puma ' do
45
+ expect(File).to exist("#{app_path}/.Procfile")
46
+ env_file = File.read("#{app_path}/.Procfile")
47
+ expect(env_file).to match(/web: bundle exec puma/)
48
+ end
49
+
50
+ it 'creates a .env.test file with a test database name' do
51
+ expect(File).to exist("#{app_path}/.env.test")
52
+ env_test_file = File.read("#{app_path}/.env.test")
53
+ expect(env_test_file).to match(/#{app_name}_test/)
54
+ end
55
+
56
+ it 'selects postgresql as the default database adapter' do
57
+ database_config_file = File.read("#{app_path}/config/database.yml")
58
+ expect(database_config_file).to match(/adapter: postgresql/)
59
+ end
60
+
61
+ it 'adds the pg gem in the Gemfile' do
62
+ gemfile = File.read("#{app_path}/Gemfile")
63
+ expect(gemfile).to match(/gem 'pg'/)
64
+ end
65
+
66
+ it 'adds the puma gem in the Gemfile' do
67
+ gemfile = File.read("#{app_path}/Gemfile")
68
+ expect(gemfile).to match(/gem 'puma'/)
69
+ end
70
+
71
+ it 'generates an application endpoint' do
72
+ expect(File).to exist("#{app_path}/app/apis/application_endpoint.rb")
73
+ end
74
+
75
+ context 'application_endpoint' do
76
+ let(:application_api_file) { File.read("#{app_path}/app/apis/application_endpoint.rb") }
77
+
78
+ it 'the application endpoint inherits from Grape::API' do
79
+ expect(application_api_file).to match(/class ApplicationEndpoint < Grape::API/)
80
+ end
81
+
82
+ it 'mounts the RootPresenter' do
83
+ expect(application_api_file).to match(/present self, with: RootPresenter/)
84
+ end
85
+
86
+ it 'uses Grape::Formatter::Roar json formatter' do
87
+ expect(application_api_file).to match(/formatter :json, Grape::Formatter::Roar/)
88
+ end
89
+ end
90
+
91
+ it 'generates a root presenter' do
92
+ expect(File).to exist("#{app_path}/app/presenters/root_presenter.rb")
93
+ end
94
+
95
+ context 'root_presenter' do
96
+ let(:root_presenter_file) { File.read("#{app_path}/app/presenters/root_presenter.rb") }
97
+
98
+ before do
99
+ require "./#{app_path}/app/presenters/root_presenter.rb"
100
+ end
101
+
102
+ it 'defines RootPresenter module' do
103
+ expect(root_presenter_file).to match(/module RootPresenter/)
104
+ end
105
+
106
+ it 'includes Grape::Roar::Representer' do
107
+ expect(RootPresenter).to include(Grape::Roar::Representer)
108
+ end
109
+
110
+ it 'includes Roar::Hypermedia' do
111
+ expect(RootPresenter).to include(Roar::Hypermedia)
112
+ end
113
+
114
+ it 'includes Roar::JSON::HAL' do
115
+ expect(RootPresenter).to include(Roar::JSON::HAL)
116
+ end
117
+ end
118
+ end
119
+ end
@@ -0,0 +1,5 @@
1
+ require 'spec_helper'
2
+ require 'gris/grape_extensions/crud_helpers'
3
+
4
+ describe Gris::CrudHelpers do
5
+ end
@@ -0,0 +1,86 @@
1
+ require 'spec_helper'
2
+ require 'gris/identity'
3
+
4
+ describe Gris::Identity do
5
+ before do
6
+ allow(Process).to receive(:pid).and_return(123)
7
+ allow(Gris::Identity).to receive(:hostname).and_return('system-hostname')
8
+ allow(Gris::Identity).to receive(:`).with('git rev-parse HEAD').and_return('12345')
9
+ end
10
+
11
+ context '#health' do
12
+ it 'includes name' do
13
+ expect(Gris::Identity.health[:name]).to eq(Gris::Identity.name)
14
+ end
15
+ it 'includes base_url' do
16
+ expect(Gris::Identity.health[:base_url]).to eq(Gris::Identity.base_url)
17
+ end
18
+ it 'includes hostname' do
19
+ expect(Gris::Identity.health[:hostname]).to eq(Gris::Identity.hostname)
20
+ end
21
+ it 'includes revision' do
22
+ expect(Gris::Identity.health[:revision]).to eq(Gris::Identity.revision)
23
+ end
24
+ it 'includes pid' do
25
+ expect(Gris::Identity.health[:pid]).to eq(Gris::Identity.pid)
26
+ end
27
+ it 'includes parent_pid' do
28
+ expect(Gris::Identity.health[:parent_pid]).to eq(Gris::Identity.parent_pid)
29
+ end
30
+ it 'includes platform' do
31
+ expect(Gris::Identity.health[:platform]).to eq(Gris::Identity.platform)
32
+ end
33
+ end
34
+
35
+ context '#name' do
36
+ it "returns 'api-service' if no ENV['SERVICE_NAME'] is set" do
37
+ ENV['SERVICE_NAME'] = nil
38
+ expect(Gris::Identity.name).to eq('api-service')
39
+ end
40
+
41
+ it "returns the ENV['SERVICE_NAME'] when specified" do
42
+ ENV['SERVICE_NAME'] = nil
43
+ ENV['SERVICE_NAME'] = 'my-service'
44
+ expect(Gris::Identity.name).to eq('my-service')
45
+ end
46
+ end
47
+
48
+ context '#hostname' do
49
+ it 'returns the value of the hostname system call and doesn\'t make a second system call' do
50
+ expect(Gris::Identity).to_not receive(:`).with('hostname')
51
+ expect(Gris::Identity.hostname).to eq('system-hostname')
52
+ end
53
+ end
54
+
55
+ context '#revision' do
56
+ it 'returns the value of the \'git rev-parse HEAD\' system call and doesn\'t make a second system call' do
57
+ expect(Gris::Identity).to_not receive(:`).with('git rev-parse HEAD')
58
+ expect(Gris::Identity.revision).to eq('12345')
59
+ end
60
+ end
61
+
62
+ context '#pid' do
63
+ it 'returns the process ID value' do
64
+ expect(Gris::Identity.pid).to eq(123)
65
+ end
66
+ end
67
+
68
+ context '#platform_revision' do
69
+ it 'returns the current version of the platform gem' do
70
+ expect(Gris::Identity.platform_revision).to eq(Gris::VERSION)
71
+ end
72
+ end
73
+
74
+ context '#base_url' do
75
+ it 'returns http://localhost:9292 by default' do
76
+ ENV['BASE_URL'] = nil
77
+ expect(Gris::Identity.base_url).to eq('http://localhost:9292')
78
+ end
79
+
80
+ it "returns the env['BASE_URL'] when specied" do
81
+ ENV['BASE_URL'] = nil
82
+ ENV['BASE_URL'] = 'my-base-url'
83
+ expect(Gris::Identity.base_url).to eq('my-base-url')
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,10 @@
1
+ ENV['RACK_ENV'] = 'test'
2
+
3
+ require 'gris/setup'
4
+ require 'gris'
5
+
6
+ require 'byebug'
7
+
8
+ # Requires supporting ruby files with custom matchers and macros, etc,
9
+ # in spec/support/ and its subdirectories.
10
+ Dir['./spec/support/**/*.rb'].sort.each { |f| require f }
@@ -0,0 +1,11 @@
1
+ shared_context 'with generator' do
2
+ let(:generator_tmp_directory) { 'spec/tmp' }
3
+
4
+ before do
5
+ allow_any_instance_of(described_class).to receive(:output_directory).and_return(generator_tmp_directory)
6
+ end
7
+
8
+ after do
9
+ FileUtils.rm_rf(generator_tmp_directory)
10
+ end
11
+ end
@@ -0,0 +1,40 @@
1
+ require 'spec_helper'
2
+ require 'gris/version'
3
+
4
+ describe Gris::Version do
5
+ context '#major_bump' do
6
+ it 'should set the major revision value, and the rest should be 0' do
7
+ stub_const('Gris::VERSION', '1.2.3')
8
+ expect(Gris::Version.next_major).to eq('2.0.0')
9
+ end
10
+
11
+ it 'should set the major revision value, and the rest should be 0' do
12
+ stub_const('Gris::VERSION', '5.0.0')
13
+ expect(Gris::Version.next_major).to eq('6.0.0')
14
+ end
15
+ end
16
+
17
+ context '#minor_bump' do
18
+ it 'should set the minor revision value, leaving the major value unchanged and the patch value to 0' do
19
+ stub_const('Gris::VERSION', '1.2.3')
20
+ expect(Gris::Version.next_minor).to eq('1.3.0')
21
+ end
22
+
23
+ it 'should set the minor revision value, leaving the major value unchanged and the patch value to 0' do
24
+ stub_const('Gris::VERSION', '0.5.0')
25
+ expect(Gris::Version.next_minor).to eq('0.6.0')
26
+ end
27
+ end
28
+
29
+ context 'patch_bump' do
30
+ it 'should set the patch revision value, leaving the major and minor values unchanged' do
31
+ stub_const('Gris::VERSION', '1.2.3')
32
+ expect(Gris::Version.next_patch).to eq('1.2.4')
33
+ end
34
+
35
+ it 'should set the patch revision value, leaving the major and minor values unchanged' do
36
+ stub_const('Gris::VERSION', '5.5.5')
37
+ expect(Gris::Version.next_patch).to eq('5.5.6')
38
+ end
39
+ end
40
+ end