service_template 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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