lurker 0.6.12 → 1.0.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 (56) hide show
  1. checksums.yaml +5 -5
  2. data/.rspec +1 -2
  3. data/.travis.yml +30 -20
  4. data/Gemfile +0 -32
  5. data/README.md +14 -52
  6. data/Rakefile +3 -3
  7. data/cucumber.yml +1 -2
  8. data/features/atom_persistent_within_the_same_type.feature +4 -4
  9. data/features/controller_nested_schema_scaffolding.feature +7 -10
  10. data/features/controller_schema_scaffolding.feature +1 -3
  11. data/features/dereferencing_through_inlining.feature +1 -3
  12. data/features/html_generation.feature +3 -4
  13. data/features/minitest.feature +3 -5
  14. data/features/multidomain_support.feature +5 -6
  15. data/features/multitype_request_support.feature +1 -3
  16. data/features/partials.feature +3 -5
  17. data/features/request_nested_schema_scaffolding.feature +0 -2
  18. data/features/request_schema_scaffolding.feature +0 -2
  19. data/features/schema_suffixes.feature +2 -6
  20. data/features/schema_updating_within_test_suite.feature +2 -6
  21. data/features/step_definitions/additional_cli_steps.rb +8 -11
  22. data/features/support/env.rb +50 -10
  23. data/features/test_endpoint.feature +2 -6
  24. data/gemfiles/rails_4.gemfile +14 -0
  25. data/gemfiles/rails_5.gemfile +10 -0
  26. data/gemfiles/rails_6.gemfile +10 -0
  27. data/lib/lurker.rb +0 -1
  28. data/lib/lurker/cli.rb +5 -7
  29. data/lib/lurker/endpoint.rb +4 -4
  30. data/lib/lurker/json/concerns/validatable.rb +5 -1
  31. data/lib/lurker/json/parser.rb +1 -1
  32. data/lib/lurker/presenters/service_presenter.rb +2 -1
  33. data/lib/lurker/spec_helper/rspec.rb +0 -4
  34. data/lib/lurker/spy.rb +3 -1
  35. data/lib/lurker/templates/public/application.css +3 -3
  36. data/lib/lurker/templates/public/application.js +13 -2896
  37. data/lib/lurker/version.rb +1 -1
  38. data/lurker.gemspec +31 -33
  39. data/spec/spec_helper.rb +0 -1
  40. data/tasks/build.rake +5 -3
  41. data/tasks/generate.rake +25 -15
  42. data/templates/Dockerfile +26 -0
  43. data/templates/generate_stuff.rb +59 -26
  44. data/templates/lurker_app.rb +27 -47
  45. data/templates/rails4_ruby26_thread_error_fix.rb +20 -0
  46. metadata +136 -98
  47. checksums.yaml.gz.sig +0 -0
  48. data.tar.gz.sig +0 -3
  49. data/Appraisals +0 -36
  50. data/gemfiles/rails_32.gemfile +0 -31
  51. data/gemfiles/rails_40.gemfile +0 -31
  52. data/gemfiles/rails_41.gemfile +0 -31
  53. data/gemfiles/rails_42.gemfile +0 -31
  54. data/lib/lurker/validation_error.rb +0 -4
  55. data/templates/rails32_http_patch_support.rb +0 -125
  56. metadata.gz.sig +0 -0
@@ -60,8 +60,6 @@ Feature: multitype request support
60
60
  Scenario: json schema tests response parameters and update request parameters using "users/update"
61
61
  Given a file named "spec/controllers/api/v2/users_controller_spec.rb" with:
62
62
  """ruby
63
- require "spec_helper"
64
-
65
63
  describe Api::V2::UsersController, :lurker do
66
64
  render_views
67
65
 
@@ -70,7 +68,7 @@ Feature: multitype request support
70
68
  end
71
69
 
72
70
  it "updates a user surname as string" do
73
- patch :update, id: user.id, user: { surname: 'Marley' }
71
+ patch :update, params: { id: user.id, user: { surname: 'Marley' } }
74
72
  expect(response).to be_success
75
73
  end
76
74
  end
@@ -65,8 +65,6 @@ Feature: partials
65
65
 
66
66
  Given a file named "spec/requests/repo_creation_spec.rb" with:
67
67
  """ruby
68
- require "spec_helper"
69
-
70
68
  describe Api::V1::ReposController, :lurker do
71
69
  let!(:user) do
72
70
  User.where(name: 'razum2um').first_or_create!
@@ -74,7 +72,7 @@ Feature: partials
74
72
 
75
73
  it "creates a new repo" do
76
74
  expect {
77
- post "/api/v1/users/#{user.id}/repos.json", repo: { name: 'new-gem' }
75
+ post "/api/v1/users/#{user.id}/repos.json", params: { repo: { name: 'new-gem' } }
78
76
  expect(response).to be_success
79
77
  expect(JSON.parse(response.body)['user']).to eq JSON.parse(user.to_json)
80
78
  }.to change { Repo.count } .by(1)
@@ -91,7 +89,7 @@ Feature: partials
91
89
  Converting lurker to html
92
90
  using lurker
93
91
 
94
- create public/lurker/index.html
95
- create public/lurker/api/v1/users/__user_id/repos-POST.html
92
+ public/lurker/index.html
93
+ public/lurker/api/v1/users/__user_id/repos-POST.html
96
94
  """
97
95
 
@@ -5,8 +5,6 @@ Feature: request nested schema scaffolding
5
5
  Scenario: scaffold a json schema for a "repos/show" in a nested controller spec
6
6
  Given a file named "spec/requests/repos_spec.rb" with:
7
7
  """ruby
8
- require "spec_helper"
9
-
10
8
  describe Api::V1::ReposController, :lurker do
11
9
  let!(:user) do
12
10
  User.where(name: 'razum2um').first_or_create!.tap do |u|
@@ -7,8 +7,6 @@ Feature: request schema scaffolding
7
7
  Scenario: scaffold a json schema for a "users/index" in request spec
8
8
  Given a file named "spec/requests/users_spec.rb" with:
9
9
  """ruby
10
- require "spec_helper"
11
-
12
10
  describe Api::V1::UsersController, :lurker do
13
11
  let!(:user) do
14
12
  User.where(name: 'razum2um', surname: 'Marley').first_or_create!
@@ -50,8 +50,6 @@ Feature: schema suffixes
50
50
  """
51
51
  And a file named "spec/requests/updating_repos_spec.rb" with:
52
52
  """ruby
53
- require "spec_helper"
54
-
55
53
  describe Api::V1::ReposController, :lurker, type: :request do
56
54
 
57
55
  let(:user) do
@@ -64,7 +62,7 @@ Feature: schema suffixes
64
62
 
65
63
  it "updates a repo name" do
66
64
  expect {
67
- patch "/api/v1/users/#{user.name}/repos/#{repo.name}.json", repo: { name: 'updated-name' }
65
+ patch "/api/v1/users/#{user.name}/repos/#{repo.name}.json", params: { repo: { name: 'updated-name' } }
68
66
  expect(response).to be_success
69
67
  }.to change { repo.reload.name } .from('lurker').to('updated-name')
70
68
  end
@@ -115,8 +113,6 @@ Feature: schema suffixes
115
113
  """
116
114
  And a file named "spec/requests/failed_updating_repos_spec.rb" with:
117
115
  """ruby
118
- require "spec_helper"
119
-
120
116
  describe Api::V1::ReposController, type: :request do
121
117
 
122
118
  let(:user) do
@@ -129,7 +125,7 @@ Feature: schema suffixes
129
125
 
130
126
  it "fails to update a repo with a blank name", lurker: 'failed' do
131
127
  expect {
132
- patch "/api/v1/users/#{user.name}/repos/#{repo.name}.json", repo: { name: '' }
128
+ patch "/api/v1/users/#{user.name}/repos/#{repo.name}.json", params: { repo: { name: '' } }
133
129
  expect(response).not_to be_success
134
130
  }.not_to change { repo.reload.name }
135
131
  end
@@ -62,8 +62,6 @@ Feature: schema updating within test suite
62
62
  Scenario: json schema tests response parameters and request parameters and show errors from both using "users/update"
63
63
  Given a file named "spec/controllers/api/v2/users_controller_blank_spec.rb" with:
64
64
  """ruby
65
- require "spec_helper"
66
-
67
65
  describe Api::V2::UsersController, :lurker do
68
66
  render_views
69
67
 
@@ -72,7 +70,7 @@ Feature: schema updating within test suite
72
70
  end
73
71
 
74
72
  it "updates a user surname as string" do
75
- patch :update, id: user.id, user: { name: '', surname: 'Marley' }
73
+ patch :update, params: { id: user.id, user: { name: '', surname: 'Marley' } }
76
74
  expect(response).not_to be_success
77
75
  end
78
76
  end
@@ -93,8 +91,6 @@ Feature: schema updating within test suite
93
91
  Scenario: json schema tests response parameters and update request parameters using "users/update"
94
92
  Given a file named "spec/controllers/api/v2/users_controller_spec.rb" with:
95
93
  """ruby
96
- require "spec_helper"
97
-
98
94
  describe Api::V2::UsersController, :lurker do
99
95
  render_views
100
96
 
@@ -103,7 +99,7 @@ Feature: schema updating within test suite
103
99
  end
104
100
 
105
101
  it "updates a user surname as string" do
106
- patch :update, id: user.id, user: { surname: 'Marley' }
102
+ patch :update, params: { id: user.id, user: { surname: 'Marley' } }
107
103
  expect(response).to be_success
108
104
  end
109
105
  end
@@ -2,17 +2,14 @@ Given /^a checked file "([^"]*)" with:$/ do |file_name, file_content|
2
2
  write_file(file_name, file_content)
3
3
 
4
4
  @files ||= {}
5
- in_current_dir { @files[md5(file_name)] = checksum(file_name) }
6
- end
7
-
8
- Given /^an empty directory named "([^"]*)"$/ do |dir_name|
9
- in_current_dir { _rm_rf(dir_name) }
10
- create_dir(dir_name)
5
+ in_current_directory { @files[md5(file_name)] = checksum(file_name) }
11
6
  end
12
7
 
13
8
  Given /^a service file with:$/ do |file_content|
14
- in_current_dir do
15
- write_file("#{Lurker::DEFAULT_SERVICE_PATH}/#{Rails.application.class.parent_name}#{Lurker::Service::SUFFIX}", file_content)
9
+ in_current_directory do
10
+ rails_app_class = Rails.application.class
11
+ rails_app_name = rails_app_class.respond_to?(:module_parent_name) ? rails_app_class.module_parent_name : rails_app_class.parent_name
12
+ write_file("#{Lurker::DEFAULT_SERVICE_PATH}/#{rails_app_name}#{Lurker::Service::SUFFIX}", file_content)
16
13
  end
17
14
  end
18
15
 
@@ -83,7 +80,7 @@ end
83
80
  Then /^the output should contain (failures|these lines):$/ do |_, lines|
84
81
  out = all_output.dup
85
82
  lines.split(/\n/).map(&:strip).each do |line|
86
- next if line.blank?
83
+ next if line.strip!.blank?
87
84
  expect(out).to match /#{Regexp.escape(line)}/
88
85
  out.gsub!(/.*?#{Regexp.escape(line)}/m, '')
89
86
  end
@@ -105,13 +102,13 @@ Then(/^I should see JSON response with "([^"]*)"$/) do |name|
105
102
  end
106
103
 
107
104
  Then /(?:a|the) checked file "([^"]*)" should not change$/ do |file_name|
108
- in_current_dir do
105
+ in_current_directory do
109
106
  expect(@files.try(:[], md5(file_name))).to eq checksum(file_name)
110
107
  end
111
108
  end
112
109
 
113
110
  Then /(?:a|the) checked file "([^"]*)" should change$/ do |file_name|
114
- in_current_dir do
111
+ in_current_directory do
115
112
  expect(@files.try(:[], md5(file_name))).not_to eq checksum(file_name)
116
113
  end
117
114
  end
@@ -6,11 +6,19 @@ SimpleCov.start do
6
6
  end
7
7
  end
8
8
 
9
+ def relative_example_path
10
+ if rails_version = ENV['BUNDLE_GEMFILE'].to_s.match(/rails_\d+/)
11
+ "tmp/lurker_app_#{rails_version}"
12
+ else
13
+ raise "Export BUNDLE_GEMFILE=gemfiles/rails... explicitly"
14
+ end
15
+ end
16
+
9
17
  def example_path
10
- if rails_version = ENV['BUNDLE_GEMFILE'].to_s.match(/rails_\d\d/)
18
+ if rails_version = ENV['BUNDLE_GEMFILE'].to_s.match(/rails_\d+/)
11
19
  File.expand_path("../../../tmp/lurker_app_#{rails_version}", __FILE__)
12
20
  else
13
- raise "Use `appraisal rails-XY cucumber ...` or export BUNDLE_GEMFILE=gemfiles/... explicitly"
21
+ raise "Export BUNDLE_GEMFILE=gemfiles/rails... explicitly"
14
22
  end
15
23
  end
16
24
 
@@ -23,21 +31,53 @@ World(RSpec::Matchers)
23
31
  require 'capybara'
24
32
  require 'capybara/dsl'
25
33
  require 'capybara/cucumber'
26
- require 'capybara/poltergeist'
34
+ require 'webdrivers/chromedriver'
27
35
  require "#{example_path}/config/environment"
28
36
  require 'database_cleaner'
29
37
  require 'database_cleaner/cucumber'
30
38
 
31
- Capybara.app = Rails.application
32
- Capybara.javascript_driver = :poltergeist
39
+ Capybara.register_driver :chrome do |app|
40
+ Capybara::Selenium::Driver.new(app, browser: :chrome)
41
+ end
33
42
 
43
+ Capybara.register_driver :headless_chrome do |app|
44
+ Selenium::WebDriver.logger.level = :debug if ENV['CAPYBARA_DEBUG'].present?
45
+ browser_capabilities = Selenium::WebDriver::Remote::Capabilities.chrome(loggingPrefs: { browser: 'ALL' })
46
+ browser_options = Selenium::WebDriver::Chrome::Options.new(args: %w[headless disable-gpu no-sandbox disable-dev-shm-usage window-size=1900,1080])
47
+ browser_options.add_argument('--ignore-certificate-errors')
48
+ # Disable w3c mode (default as of Chrome 75) to allow for logging
49
+ browser_options.add_option(:w3c, false)
50
+ Capybara::Selenium::Driver.new app,
51
+ browser: :chrome,
52
+ options: browser_options,
53
+ desired_capabilities: browser_capabilities
54
+ end
55
+
56
+ Capybara.app = Rails.application
57
+ Capybara.server = :puma, { Silent: true, Threads: '1:1' }
58
+ Capybara.javascript_driver = ENV['CAPYBARA_JS_DRIVER']&.to_sym || :headless_chrome
34
59
  DatabaseCleaner.strategy = :truncation
35
60
 
61
+ # otherwise it cleans up all rails folder
62
+ # https://github.com/cucumber/aruba/blob/bf612766ac51e28ca354e735980cd8a5d7eb296f/lib/aruba/setup.rb#L27L31
63
+ # it force deletes the working_directory,
64
+ # but it has to be working_directory to cd in and run `bin/rspec`
65
+ # this forces @no-clobber everywhere
66
+ # use CLEAN=1 env var to clean proper places
67
+ module ArubaSetupNoClobber
68
+ def working_directory(clobber = true)
69
+ super(false)
70
+ end
71
+ end
72
+ Aruba::Setup.prepend(ArubaSetupNoClobber)
73
+
36
74
  # see: https://github.com/colszowka/simplecov/issues/234
37
75
  Aruba.configure do |config|
38
- config.before_cmd do |cmd|
39
- set_env 'SIMPLECOV_CMDNAME', Digest::MD5.hexdigest(cmd)
40
- set_env 'SIMPLECOV_ROOT', File.expand_path('../../..', __FILE__)
76
+ config.working_directory = relative_example_path # Aruba::Contracts::RelativePath
77
+ config.activate_announcer_on_command_failure = [:stdout]
78
+ config.before :command do |cmd|
79
+ set_environment_variable 'SIMPLECOV_CMDNAME', Digest::MD5.hexdigest(cmd.object_id.to_s)
80
+ set_environment_variable 'SIMPLECOV_ROOT', File.expand_path('../../..', __FILE__)
41
81
  end
42
82
  end
43
83
 
@@ -47,8 +87,8 @@ Before do
47
87
  DatabaseCleaner.start
48
88
  if ENV['CLEAN']
49
89
  system "bin/spring stop"
50
- %w[lurker html public/lurker spec/requests spec/controllers].each do |dir_name|
51
- in_current_dir { _rm_rf(dir_name) }
90
+ %w[lurker public/lurker spec/requests spec/controllers].each do |dir_name|
91
+ in_current_directory { remove(dir_name, force: true) }
52
92
  end
53
93
  end
54
94
  end
@@ -53,8 +53,6 @@ Feature: test endpoint
53
53
  Scenario: json schema tests request and response using "users/update"
54
54
  Given a file named "spec/controllers/api/v1/users_controller_spec.rb" with:
55
55
  """ruby
56
- require "spec_helper"
57
-
58
56
  describe Api::V1::UsersController, :lurker do
59
57
  render_views
60
58
 
@@ -63,7 +61,7 @@ Feature: test endpoint
63
61
  end
64
62
 
65
63
  it "updates a user" do
66
- patch :update, id: user.id, user: { name: 'Bob' }
64
+ patch :update, params: { id: user.id, user: { name: 'Bob' } }
67
65
  expect(response).to be_success
68
66
  end
69
67
  end
@@ -75,8 +73,6 @@ Feature: test endpoint
75
73
  Scenario: json schema tests response parameters and tell what fails using "users/update"
76
74
  Given a file named "spec/controllers/api/v1/users_controller_blank_spec.rb" with:
77
75
  """ruby
78
- require "spec_helper"
79
-
80
76
  describe Api::V1::UsersController, :lurker do
81
77
  render_views
82
78
 
@@ -85,7 +81,7 @@ Feature: test endpoint
85
81
  end
86
82
 
87
83
  it "updates a user" do
88
- patch :update, id: user.id, user: { name: '' }, format: 'json'
84
+ patch :update, params: { id: user.id, user: { name: '' }, format: 'json' }
89
85
  expect(response).not_to be_success
90
86
  end
91
87
  end
@@ -0,0 +1,14 @@
1
+ source "https://rubygems.org"
2
+
3
+ gem "rails", "~> 4.2"
4
+ gem "bigdecimal", "~> 1.4"
5
+ gem "pg", "<= 0.20" # doesnt use 1.0 by install, 0.21 too many warnings
6
+
7
+ gem "rails-forward_compatible_controller_tests", "> 0"
8
+
9
+ gem "jquery-rails"
10
+ gem "bootstrap-sass"
11
+ gem "remotipart"
12
+ gem "uglifier"
13
+
14
+ gemspec :path => "../"
@@ -0,0 +1,10 @@
1
+ source "https://rubygems.org"
2
+
3
+ gem "rails", "~> 5.2"
4
+
5
+ gem "jquery-rails"
6
+ gem "bootstrap-sass"
7
+ gem "remotipart"
8
+ gem "uglifier"
9
+
10
+ gemspec :path => "../"
@@ -0,0 +1,10 @@
1
+ source "https://rubygems.org"
2
+
3
+ gem "rails", "~> 6.0"
4
+
5
+ gem "jquery-rails"
6
+ gem "bootstrap-sass"
7
+ gem "remotipart"
8
+ gem "uglifier"
9
+
10
+ gemspec :path => "../"
@@ -60,7 +60,6 @@ require 'lurker/ref_object'
60
60
  require 'lurker/erb_schema_context'
61
61
  require 'lurker/service'
62
62
  require 'lurker/validator'
63
- require 'lurker/validation_error'
64
63
  require 'lurker/utils'
65
64
  require 'lurker/endpoint'
66
65
  require 'lurker/rendering_controller'
@@ -18,7 +18,7 @@ module Lurker
18
18
  attr_accessor :content
19
19
 
20
20
  def self.templates_root
21
- options[:template].present? ? Pathname.new(options[:templates]).expand_path : Lurker::BUNDLED_TEMPLATES_PATH
21
+ Lurker::BUNDLED_TEMPLATES_PATH
22
22
  end
23
23
 
24
24
  def self.assets_root
@@ -106,7 +106,10 @@ module Lurker
106
106
 
107
107
  def setup_rendering_engine!
108
108
  I18n.config.enforce_available_locales = true
109
- Lurker::RenderingController.prepend_view_path templates_root
109
+ Lurker::RenderingController.prepend_view_path Lurker::Cli.templates_root
110
+ if options[:templates].present?
111
+ Lurker::RenderingController.prepend_view_path Pathname.new(options[:templates]).expand_path
112
+ end
110
113
  Lurker::RenderingController.config.assets_dir = assets_root
111
114
  end
112
115
 
@@ -159,7 +162,6 @@ module Lurker
159
162
  @html_options ||= {
160
163
  static_html: true,
161
164
  url_base_path: url_base_path.prepend('/'),
162
- template_directory: templates_root,
163
165
  assets_directory: assets_root,
164
166
  assets: assets,
165
167
  html_directory: output_path,
@@ -197,10 +199,6 @@ module Lurker
197
199
  Lurker::Cli.assets_root
198
200
  end
199
201
 
200
- def templates_root
201
- Lurker::Cli.templates_root
202
- end
203
-
204
202
  def asset_logical_path(path)
205
203
  path = Pathname.new(path) unless path.is_a? Pathname
206
204
  path.sub %r{-[0-9a-f]{40}\.}, '.'
@@ -192,15 +192,15 @@ module Lurker
192
192
  def word_wrap(text)
193
193
  # strip .json# | .json.yml# | .json.yml.erb#
194
194
  text = text.reverse
195
- text.gsub!(/(\n|^)#bre\./, "\nbre.")
196
- text.gsub!(/(\n|^)#lmy\./, "\nlmy.")
197
- text.gsub!(/(\n|^)#nosj\./, "\nnosj.")
195
+ text.gsub!(/(\n|^)#bre\./, "\nbre.") # erb
196
+ text.gsub!(/(\n|^)#lmy\./, "\nlmy.") # yml
197
+ text.gsub!(/(\n|^)#nosj\./, "\nnosj.") # json
198
198
  text.strip!
199
199
  text = text.reverse
200
200
 
201
201
  text.gsub!(/\s+in schema/m, "\n in schema")
202
202
  if defined?(Rails)
203
- text.gsub!(/file:\/\/#{Rails.root}\//m, "")
203
+ text.gsub!(Regexp.new("#{Rails.root}\/"), "")
204
204
  end
205
205
  text
206
206
  end
@@ -9,7 +9,11 @@ module Lurker
9
9
 
10
10
  def to_validation_schema
11
11
  set_additional_properties_false_on(to_hash).tap do |schema|
12
- schema[Json::ID] = "file://#{uri}"
12
+ if uri.class == URI::Generic
13
+ schema[Json::ID] = uri.path
14
+ else
15
+ schema[Json::ID] = uri.to_s
16
+ end
13
17
  end
14
18
  end
15
19
 
@@ -16,7 +16,7 @@ module Lurker
16
16
  @parent_schema = options[:parent_schema]
17
17
  @parent_property = options[:parent_property]
18
18
  @polymorph_if_empty = options.fetch(:polymorph_if_empty, false)
19
- @uri = options[:uri] || @parent_schema.try(:uri)
19
+ @uri = options[:uri] || @parent_schema&.uri
20
20
  @strategy = nil
21
21
  end
22
22
 
@@ -1,4 +1,5 @@
1
1
  require 'active_support/inflector'
2
+ require 'active_support/hash_with_indifferent_access'
2
3
 
3
4
  # An BasePresenter for Lurker::Service
4
5
  class Lurker::ServicePresenter < Lurker::BasePresenter
@@ -62,7 +63,7 @@ class Lurker::ServicePresenter < Lurker::BasePresenter
62
63
  end
63
64
 
64
65
  def url_name
65
- @url_name ||= ActiveSupport::Inflector.parameterize(name, '_')
66
+ @url_name ||= name.gsub(/[^a-z0-9\-_]+/i, '_')
66
67
  end
67
68
 
68
69
  def url(extension = ".html")