service_template 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (105) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +21 -0
  3. data/.rubocop.yml +23 -0
  4. data/.travis.yml +13 -0
  5. data/CHANGELOG.md +64 -0
  6. data/Gemfile +4 -0
  7. data/LICENSE +24 -0
  8. data/README.md +217 -0
  9. data/Rakefile +9 -0
  10. data/bin/service_template +5 -0
  11. data/lib/service_template.rb +55 -0
  12. data/lib/service_template/active_record_extensions/notifications_subscriber.rb +17 -0
  13. data/lib/service_template/active_record_extensions/seeder.rb +14 -0
  14. data/lib/service_template/active_record_extensions/stats.rb +37 -0
  15. data/lib/service_template/authentication.rb +8 -0
  16. data/lib/service_template/cli.rb +111 -0
  17. data/lib/service_template/deploy.rb +98 -0
  18. data/lib/service_template/gem_dependency.rb +37 -0
  19. data/lib/service_template/generators.rb +3 -0
  20. data/lib/service_template/generators/api_generator.rb +30 -0
  21. data/lib/service_template/generators/readme_generator.rb +47 -0
  22. data/lib/service_template/generators/scaffold_generator.rb +29 -0
  23. data/lib/service_template/generators/templates/api/app/apis/%name_tableize%_api.rb.tt +40 -0
  24. data/lib/service_template/generators/templates/api/app/models/%name_underscore%.rb.tt +2 -0
  25. data/lib/service_template/generators/templates/api/app/representers/%name_underscore%_representer.rb.tt +4 -0
  26. data/lib/service_template/generators/templates/api/spec/apis/%name_tableize%_api_spec.rb.tt +16 -0
  27. data/lib/service_template/generators/templates/api/spec/models/%name_underscore%_spec.rb.tt +9 -0
  28. data/lib/service_template/generators/templates/readme/README.md.tt +55 -0
  29. data/lib/service_template/generators/templates/readme/spec/docs/readme_spec.rb +7 -0
  30. data/lib/service_template/generators/templates/scaffold/.env.development.tt +9 -0
  31. data/lib/service_template/generators/templates/scaffold/.env.test.tt +10 -0
  32. data/lib/service_template/generators/templates/scaffold/.gitignore.tt +13 -0
  33. data/lib/service_template/generators/templates/scaffold/.rubocop.yml +24 -0
  34. data/lib/service_template/generators/templates/scaffold/.ruby-version.tt +1 -0
  35. data/lib/service_template/generators/templates/scaffold/Gemfile.tt +29 -0
  36. data/lib/service_template/generators/templates/scaffold/README.md +3 -0
  37. data/lib/service_template/generators/templates/scaffold/Rakefile +21 -0
  38. data/lib/service_template/generators/templates/scaffold/app.rb +19 -0
  39. data/lib/service_template/generators/templates/scaffold/app/apis/application_api.rb +9 -0
  40. data/lib/service_template/generators/templates/scaffold/app/apis/hello_api.rb.tt +10 -0
  41. data/lib/service_template/generators/templates/scaffold/config.ru.tt +21 -0
  42. data/lib/service_template/generators/templates/scaffold/config/database.yml.tt +19 -0
  43. data/lib/service_template/generators/templates/scaffold/config/initializers/active_record.rb +5 -0
  44. data/lib/service_template/generators/templates/scaffold/db/schema.rb +11 -0
  45. data/lib/service_template/generators/templates/scaffold/lib/.keep +0 -0
  46. data/lib/service_template/generators/templates/scaffold/log/.keep +0 -0
  47. data/lib/service_template/generators/templates/scaffold/spec/apis/hello_api_spec.rb.tt +17 -0
  48. data/lib/service_template/generators/templates/scaffold/spec/factories/.gitkeep +0 -0
  49. data/lib/service_template/generators/templates/scaffold/spec/spec_helper.rb +47 -0
  50. data/lib/service_template/grape_extenders.rb +30 -0
  51. data/lib/service_template/grape_extensions/error_formatter.rb +18 -0
  52. data/lib/service_template/grape_extensions/grape_helpers.rb +27 -0
  53. data/lib/service_template/identity.rb +45 -0
  54. data/lib/service_template/json_error.rb +24 -0
  55. data/lib/service_template/logger/log_transaction.rb +17 -0
  56. data/lib/service_template/logger/logger.rb +42 -0
  57. data/lib/service_template/logger/parseable.rb +37 -0
  58. data/lib/service_template/middleware/app_monitor.rb +17 -0
  59. data/lib/service_template/middleware/authentication.rb +32 -0
  60. data/lib/service_template/middleware/database_stats.rb +15 -0
  61. data/lib/service_template/middleware/logger.rb +67 -0
  62. data/lib/service_template/middleware/request_stats.rb +42 -0
  63. data/lib/service_template/output_formatters/entity.rb +15 -0
  64. data/lib/service_template/output_formatters/include_nil.rb +16 -0
  65. data/lib/service_template/output_formatters/json_api_representer.rb +9 -0
  66. data/lib/service_template/param_sanitizer.rb +30 -0
  67. data/lib/service_template/rspec_extensions/response_helpers.rb +46 -0
  68. data/lib/service_template/setup.rb +36 -0
  69. data/lib/service_template/sortable_api.rb +17 -0
  70. data/lib/service_template/stats.rb +43 -0
  71. data/lib/service_template/stats_d_timer.rb +26 -0
  72. data/lib/service_template/version.rb +45 -0
  73. data/lib/tasks/deploy.rake +11 -0
  74. data/lib/tasks/routes.rake +11 -0
  75. data/service_template.gemspec +42 -0
  76. data/spec/active_record_extensions/filter_by_hash_spec.rb +23 -0
  77. data/spec/active_record_extensions/seeder_spec.rb +13 -0
  78. data/spec/authentication_spec.rb +17 -0
  79. data/spec/deprecations/application_api_spec.rb +19 -0
  80. data/spec/deprecations/entity_spec.rb +9 -0
  81. data/spec/deprecations/filter_by_hash_spec.rb +9 -0
  82. data/spec/deprecations/napa_setup_spec.rb +52 -0
  83. data/spec/generators/api_generator_spec.rb +63 -0
  84. data/spec/generators/migration_generator_spec.rb +105 -0
  85. data/spec/generators/readme_generator_spec.rb +35 -0
  86. data/spec/generators/scaffold_generator_spec.rb +90 -0
  87. data/spec/grape_extenders_spec.rb +50 -0
  88. data/spec/grape_extensions/error_formatter_spec.rb +29 -0
  89. data/spec/grape_extensions/include_nil_spec.rb +23 -0
  90. data/spec/identity_spec.rb +50 -0
  91. data/spec/json_error_spec.rb +33 -0
  92. data/spec/logger/log_transaction_spec.rb +34 -0
  93. data/spec/logger/logger_spec.rb +14 -0
  94. data/spec/logger/parseable_spec.rb +16 -0
  95. data/spec/middleware/authentication_spec.rb +54 -0
  96. data/spec/middleware/database_stats_spec.rb +64 -0
  97. data/spec/middleware/request_stats_spec.rb +21 -0
  98. data/spec/sortable_api_spec.rb +56 -0
  99. data/spec/spec_helper.rb +45 -0
  100. data/spec/stats_d_timer_spec.rb +23 -0
  101. data/spec/stats_spec.rb +66 -0
  102. data/spec/version_spec.rb +40 -0
  103. data/tasks/spec.rake +9 -0
  104. data/tasks/version.rake +51 -0
  105. metadata +456 -0
@@ -0,0 +1,46 @@
1
+ module ServiceTemplate
2
+ module RspecExtensions
3
+ module ResponseHelpers
4
+ def parsed_response
5
+ Hashie::Mash.new(JSON.parse(last_response.body))
6
+ end
7
+
8
+ def response_code
9
+ last_response.status
10
+ end
11
+
12
+ def response_body
13
+ last_response.body
14
+ end
15
+
16
+ def result_count
17
+ parsed_response.data.count
18
+ end
19
+
20
+ def first_result
21
+ parsed_response.data.first
22
+ end
23
+
24
+ def result_with_id(id)
25
+ parsed_response.data.select { |r| r.id == id }.first
26
+ end
27
+
28
+ def expect_count_of(count)
29
+ expect(result_count).to eq(count)
30
+ end
31
+
32
+ def expect_only(object)
33
+ expect_count_of 1
34
+ expect(first_result.id).to eq(object.id)
35
+ end
36
+
37
+ def expect_to_have(object)
38
+ expect(!!result_with_id(object.id)).to be_truthy
39
+ end
40
+
41
+ def expect_to_not_have(object)
42
+ expect(!!result_with_id(object.id)).to be_falsy
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,36 @@
1
+ # setup for service_template
2
+ # require the files that are required before everything else in service_template
3
+ # useful if you want to use any variables/methods defined here without loading the rest of service_template immediately
4
+ require 'active_support'
5
+
6
+ module ServiceTemplate
7
+ class << self
8
+ def load_environment
9
+ Dotenv.load(ServiceTemplate.env.test? ? '.env.test' : '.env')
10
+ end
11
+
12
+ def skip_initialization
13
+ @_skip_initialization || false
14
+ end
15
+
16
+ def skip_initialization=(value)
17
+ @_skip_initialization = value if [TrueClass, FalseClass].include?(value.class)
18
+ end
19
+
20
+ def env
21
+ @_env ||= ActiveSupport::StringInquirer.new(ENV['RACK_ENV'] || 'development')
22
+ end
23
+
24
+ def env=(environment)
25
+ @_env = ActiveSupport::StringInquirer.new(environment)
26
+ end
27
+
28
+ def cache
29
+ @_cache ||= ActiveSupport::Cache.lookup_store(:memory_store)
30
+ end
31
+
32
+ def cache=(store_option)
33
+ @_cache = ActiveSupport::Cache.lookup_store(store_option)
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,17 @@
1
+ if defined?(ActiveRecord)
2
+ module ServiceTemplate
3
+ module SortableApi
4
+ def sort_from_params(objects, sort_params)
5
+ return objects if sort_params.nil?
6
+
7
+ sort_fields = sort_params.split(",")
8
+ sort_fields.each do |sort_field|
9
+ sort_field = (sort_field[1..-1] + " DESC") if sort_field.start_with?("-")
10
+ objects = objects.order(sort_field)
11
+ end
12
+
13
+ return objects
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,43 @@
1
+ require 'statsd'
2
+ module ServiceTemplate
3
+ class Stats
4
+ class << self
5
+ def emitter=(emitter)
6
+ @emitter = emitter
7
+ end
8
+
9
+ def emitter
10
+ unless @emitter
11
+ # Log an error if StatsD settings are not configured
12
+ message = 'StatsD host and port not configured in environment variables, using default settings'
13
+ ServiceTemplate::Logger.logger.warn message unless ENV['STATSD_HOST'] && ENV['STATSD_PORT']
14
+
15
+ # Create a new StatsD emitter with the service name as the namespace
16
+ # Defaults to localhost port 8125 if env vars are nil
17
+ @emitter = Statsd.new(ENV['STATSD_HOST'], ENV['STATSD_PORT']).tap { |sd| sd.namespace = namespace }
18
+ end
19
+ @emitter
20
+ end
21
+
22
+ def namespace
23
+ environment = ENV['RACK_ENV'] || 'development'
24
+
25
+ if ENV['STATSD_API_KEY'].present?
26
+ "#{ENV['STATSD_API_KEY']}.#{ServiceTemplate::Identity.name}.#{environment}"
27
+ else
28
+ "#{ServiceTemplate::Identity.name}.#{environment}"
29
+ end
30
+ end
31
+
32
+ def path_to_key(method, path)
33
+ # split the path on forward slash
34
+ # remove any elements that are empty
35
+ # replace any number strings with _
36
+ # join all parts with a .
37
+ # prepend with the method
38
+ # downcase the whole thing
39
+ "#{method}.#{path.split(/\//).reject{|p| p.empty?}.collect{|p| p.gsub(/\d+/,'_')}.join('.')}".downcase
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,26 @@
1
+ module ServiceTemplate
2
+ module StatsDTimer
3
+ def report_time(timer_name, sample_rate: 1)
4
+ if (Time.now.to_f * 1000).to_i % sample_rate == 0
5
+ start_time = Time.now
6
+ yield
7
+ response_time = (Time.now - start_time) * 1000 # statsd reports timers in milliseconds
8
+ ServiceTemplate::Stats.emitter.timing(timer_name, response_time)
9
+ else
10
+ yield
11
+ end
12
+ end
13
+
14
+ module ClassMethods
15
+ def report_time(timer_name, sample_rate: 1)
16
+ new.report_time(timer_name, sample_rate: sample_rate) do
17
+ yield
18
+ end
19
+ end
20
+ end
21
+
22
+ def self.included(base)
23
+ base.extend(ClassMethods)
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,45 @@
1
+ module ServiceTemplate
2
+ VERSION = '0.5.0'
3
+
4
+ class Version
5
+ class << self
6
+ def next_major
7
+ next_level(:major)
8
+ end
9
+
10
+ def next_minor
11
+ next_level(:minor)
12
+ end
13
+
14
+ def next_patch
15
+ next_level(:patch)
16
+ end
17
+
18
+ def next_level(level)
19
+ fail 'Unidentified Level' unless [:major, :minor, :patch].include?(level)
20
+
21
+ parts = ServiceTemplate::VERSION.split('.').map { |p| p.to_i }
22
+
23
+ if level == :major
24
+ parts[0] += 1
25
+ significant_index = 1
26
+ end
27
+
28
+ if level == :minor
29
+ parts[1] += 1
30
+ significant_index = 2
31
+ end
32
+
33
+ if level == :patch
34
+ parts[2] += 1
35
+ significant_index = 3
36
+ end
37
+
38
+ parts.map.with_index { |p, i| parts[i] = 0 if i >= significant_index }
39
+
40
+ parts.join('.')
41
+ end
42
+
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,11 @@
1
+ namespace :deploy do
2
+ desc "Deploy to production"
3
+ task :production do
4
+ puts "\033[31mrake deploy:production is deprecated, please use 'service_template deploy production'\033[0m"
5
+ end
6
+
7
+ desc "Deploy to staging"
8
+ task :staging do
9
+ puts "\033[31mrake deploy:staging is deprecated, please use 'service_template deploy staging'\033[0m"
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ unless defined?(Rails)
2
+ desc "display all routes for Grape"
3
+ task :routes do
4
+ ApplicationApi.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,42 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/service_template/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Jay OConnor"]
6
+ gem.email = ["jay@jayoconnor.com"]
7
+ gem.description = %q{An opiniated lib and generator for building APIs with Grape}
8
+ gem.summary = %q{An easy-ish way of quickly generating an API using Grape}
9
+ gem.homepage = "https://github.com/jdoconnor/service_template"
10
+ gem.licenses = ['MIT']
11
+
12
+ gem.files = `git ls-files`.split($\)
13
+ gem.executables << 'service_template'
14
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
15
+ gem.name = "service_template"
16
+ gem.require_paths = ["lib"]
17
+ gem.version = ServiceTemplate::VERSION
18
+ gem.required_ruby_version = '>= 2.0'
19
+
20
+
21
+ gem.add_dependency 'rake', '~> 10.3'
22
+ gem.add_dependency 'logging', '~> 1.8'
23
+ gem.add_dependency 'dotenv', '~> 1.0'
24
+ gem.add_dependency 'octokit', '~> 3.5'
25
+ gem.add_dependency 'thor', '~> 0.19'
26
+ gem.add_dependency 'virtus', '~> 1.0'
27
+ gem.add_dependency 'grape', '~> 0.11.0'
28
+ gem.add_dependency 'grape-swagger', '~> 0.8'
29
+ gem.add_dependency 'roar', '~> 1.0.0'
30
+ gem.add_dependency 'statsd-ruby', '~> 1.2'
31
+ gem.add_dependency 'racksh', '~> 1.0'
32
+ gem.add_dependency 'git', '~> 1.2'
33
+ gem.add_dependency 'actionpack', '~> 4.2.0'
34
+
35
+ gem.add_development_dependency 'rspec', '~> 3.1'
36
+ gem.add_development_dependency 'pry', '~> 0.10'
37
+ gem.add_development_dependency 'rubocop', '~> 0.25'
38
+ gem.add_development_dependency 'activerecord', '~> 4.2.0'
39
+ gem.add_development_dependency 'sqlite3', '~> 1.3'
40
+ gem.add_development_dependency 'acts_as_fu', '~> 0'
41
+ gem.add_development_dependency 'codeclimate-test-reporter'
42
+ end
@@ -0,0 +1,23 @@
1
+ require 'active_record'
2
+ require 'spec_helper'
3
+ require 'service_template/active_record_extensions/filter_by_hash'
4
+
5
+
6
+ describe ServiceTemplate::FilterByHash do
7
+ before do
8
+ expect(ActiveSupport::Deprecation).to receive(:warn)
9
+ class Foo < ActiveRecord::Base; include ServiceTemplate::FilterByHash; end
10
+ end
11
+
12
+ context 'when a hash is provided' do
13
+ it 'returns an AR relation' do
14
+ expect(Foo.filter).to be_a(ActiveRecord::Relation)
15
+ end
16
+ end
17
+
18
+ context 'when nothing is provided' do
19
+ it 'returns an AR relation' do
20
+ expect(Foo.filter).to be_a(ActiveRecord::Relation)
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,13 @@
1
+ require 'active_record'
2
+ require 'spec_helper'
3
+ require 'service_template/active_record_extensions/seeder'
4
+
5
+ describe ServiceTemplate::ActiveRecordSeeder do
6
+
7
+ context 'when a valid file is not provided' do
8
+ it 'raises an exception' do
9
+ expect{ServiceTemplate::ActiveRecordSeeder.load_file 'not-a-file'}.to raise_error
10
+ end
11
+ end
12
+
13
+ end
@@ -0,0 +1,17 @@
1
+ require 'spec_helper'
2
+ require 'service_template/authentication'
3
+
4
+ describe ServiceTemplate::Authentication do
5
+ context '#password_header' do
6
+ it "returns a password hash for the request header" do
7
+ ENV['HEADER_PASSWORD'] = 'foo'
8
+ expect(ServiceTemplate::Authentication.password_header.class).to eq(Hash)
9
+ expect(ServiceTemplate::Authentication.password_header).to eq('Password' => 'foo')
10
+ end
11
+
12
+ it 'raises when the HEADER_PASSWORD env var is not defined' do
13
+ ENV['HEADER_PASSWORD'] = nil
14
+ expect{ServiceTemplate::Authentication.password_header}.to raise_error
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+ require 'active_support'
3
+ require 'service_template/deprecations/application_api'
4
+
5
+ describe ServiceTemplate::Deprecations do
6
+ describe '.application_api_check' do
7
+ it 'does not raise a deprecation warning if the file exists' do
8
+ allow(File).to receive(:exists?).and_return(true)
9
+ expect(ActiveSupport::Deprecation).to_not receive(:warn)
10
+ ServiceTemplate::Deprecations.application_api_check
11
+ end
12
+
13
+ it 'raises a deprecation warning if the file is missing' do
14
+ allow(File).to receive(:exists?).and_return(false)
15
+ expect(ActiveSupport::Deprecation).to receive(:warn)
16
+ ServiceTemplate::Deprecations.application_api_check
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,9 @@
1
+ require 'spec_helper'
2
+ require 'active_support'
3
+
4
+ describe "ServiceTemplate::Entity Deprecation" do
5
+ it 'raises a deprecation warning when a class inherits' do
6
+ expect(ActiveSupport::Deprecation).to receive(:warn)
7
+ class FooEntity < ServiceTemplate::Entity; end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ require 'spec_helper'
2
+
3
+ describe "ServiceTemplate::FilterByHash Deprecation" do
4
+ it 'raises a deprecation warning when mixed in to a class' do
5
+ expect(ActiveSupport::Deprecation).to receive(:warn)
6
+ class FooModel; include ServiceTemplate::FilterByHash; end
7
+ ActiveSupport::Deprecation.silenced = false
8
+ end
9
+ end
@@ -0,0 +1,52 @@
1
+ require 'spec_helper'
2
+ require 'active_support'
3
+ require 'service_template/deprecations/service_template_setup'
4
+
5
+ describe ServiceTemplate::Deprecations do
6
+ before do
7
+ allow(File).to receive(:exists?).and_return(true)
8
+
9
+ @apprb_stub = [
10
+ "require 'bundler/setup'",
11
+ "Bundler.setup(:default)",
12
+ "require 'service_template/setup'",
13
+ "Bundler.require(:default, ServiceTemplate.env.to_sym)",
14
+ "require 'service_template'",
15
+ "ServiceTemplate.load_environment",
16
+ "Dir['./config/initializers/**/*.rb'].map { |file| require file }",
17
+ "Dir['./config/middleware/**/*.rb'].map { |file| require file }",
18
+ "relative_load_paths = %w(app/apis app/entities app/models app/workers app/representers lib)",
19
+ "ActiveSupport::Dependencies.autoload_paths += relative_load_paths"
20
+ ]
21
+ end
22
+
23
+ describe '.service_template_setup_check' do
24
+ it 'does not raise a deprecation warning if all the required_patterns are matched' do
25
+ allow(File).to receive(:readlines).with('./app.rb').and_return(@apprb_stub)
26
+ expect(ActiveSupport::Deprecation).to_not receive(:warn)
27
+ ServiceTemplate::Deprecations.service_template_setup_check
28
+ end
29
+
30
+ it 'raises a deprecation warning if any of the required_patterns are missing' do
31
+ (0..@apprb_stub.count - 1).each do |line_num|
32
+ apprb_missing_line = @apprb_stub
33
+ apprb_missing_line.delete_at(line_num)
34
+ allow(File).to receive(:readlines).with('./app.rb').and_return(apprb_missing_line)
35
+ expect(ActiveSupport::Deprecation).to receive(:warn)
36
+
37
+ ServiceTemplate::Deprecations.service_template_setup_check
38
+ end
39
+ end
40
+
41
+ it 'raises a deprecation warning if any of the expired_patterns are matched' do
42
+ ServiceTemplate::Deprecations::EXPIRED_PATTERNS.each do |pattern|
43
+ app_rb_stub = [pattern]
44
+
45
+ allow(File).to receive(:readlines).with('./app.rb').and_return(app_rb_stub)
46
+ expect(ActiveSupport::Deprecation).to receive(:warn)
47
+
48
+ ServiceTemplate::Deprecations.service_template_setup_check
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,63 @@
1
+ require 'spec_helper'
2
+ require 'service_template/generators/api_generator'
3
+ require 'service_template/cli'
4
+
5
+ describe ServiceTemplate::Generators::ApiGenerator do
6
+ let(:api_name) { 'foo' }
7
+ let(:test_api_directory) { 'spec/tmp' }
8
+
9
+ before do
10
+ allow_any_instance_of(described_class).to receive(:output_directory).and_return(test_api_directory)
11
+ ServiceTemplate::CLI::Base.new.generate("api", api_name)
12
+ end
13
+
14
+ after do
15
+ FileUtils.rm_rf(test_api_directory)
16
+ end
17
+
18
+ describe 'app' do
19
+ it 'creates an api class' do
20
+ expected_api_file = File.join(test_api_directory, 'app/apis/foos_api.rb')
21
+ api_code = File.read(expected_api_file)
22
+
23
+ expect(api_code).to match(/class FoosApi/)
24
+ end
25
+
26
+ it 'creates a model class' do
27
+ expected_model_file = File.join(test_api_directory, 'app/models/foo.rb')
28
+ model_code = File.read(expected_model_file)
29
+
30
+ expect(model_code).to match(/class Foo/)
31
+ end
32
+
33
+ it 'creates a representer class' do
34
+ expected_representer_file = File.join(test_api_directory, 'app/representers/foo_representer.rb')
35
+ representer_code = File.read(expected_representer_file)
36
+
37
+ expect(representer_code).to match(/class FooRepresenter/)
38
+ end
39
+
40
+ it 'representers should inherit from ServiceTemplate::Representer' do
41
+ representer_file = File.join(test_api_directory, 'app/representers/foo_representer.rb')
42
+ require "./#{representer_file}"
43
+ expect(FooRepresenter.superclass).to be(ServiceTemplate::Representer)
44
+ end
45
+ end
46
+
47
+ describe 'spec' do
48
+ it 'creates an api spec' do
49
+ expected_api_file = File.join(test_api_directory, 'spec/apis/foos_api_spec.rb')
50
+ api_code = File.read(expected_api_file)
51
+
52
+ expect(api_code).to match(/describe FoosApi/)
53
+ end
54
+
55
+ it 'creates a model spec' do
56
+ expected_model_file = File.join(test_api_directory, 'spec/models/foo_spec.rb')
57
+ model_code = File.read(expected_model_file)
58
+
59
+ expect(model_code).to match(/describe Foo/)
60
+ end
61
+ end
62
+
63
+ end