diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 18b3fcb..dfda277 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,6 +7,12 @@ jobs: - uses: ruby/setup-ruby@v1 - run: gem install rufo - run: rufo --check . + rubocop: + steps: + - uses: actions/checkout@v2 + - uses: ruby/setup-ruby@v1 + - run: gem install rubocop rubocop-performance rubocop-rspec + - run: rubocop --parallel rspec: strategy: fail-fast: false diff --git a/.gitignore b/.gitignore index b04a8c8..ff40d90 100644 --- a/.gitignore +++ b/.gitignore @@ -7,5 +7,10 @@ /spec/reports/ /tmp/ +Gemfile.lock + # rspec failure tracking .rspec_status + +# Cached inherited rubocop files +.rubocop-http* diff --git a/.rubocop.yml b/.rubocop.yml new file mode 100644 index 0000000..c1a8709 --- /dev/null +++ b/.rubocop.yml @@ -0,0 +1,5 @@ +inherit_from: + - https://raw.githubusercontent.com/zweitag/code-style/main/rubocop/.rubocop.yml + +AllCops: + TargetRubyVersion: 2.5 diff --git a/README.md b/README.md index 54455ee..d657420 100644 --- a/README.md +++ b/README.md @@ -70,11 +70,12 @@ They generally correspond to one public `GeoFaker` method and pass the query par Bug reports and pull requests are welcome on GitHub at https://github.com/zweitag/GeoFaker. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct. -We use [Rufo](https://github.com/ruby-formatter/rufo) to ensure a consistent code style. You can check your code locally by running: +We use [Rufo](https://github.com/ruby-formatter/rufo) and [Rubocop](https://rubocop.org/) to ensure a consistent code style. You can check your code locally by running: ```ruby gem install rufo rubocop rubocop-performance rubocop-rspec rufo --check . # Or `rufo .` for auto-correction +rubocop --parallel ``` ## License diff --git a/Rakefile b/Rakefile index b7e9ed5..c92b11e 100644 --- a/Rakefile +++ b/Rakefile @@ -3,4 +3,4 @@ require "rspec/core/rake_task" RSpec::Core::RakeTask.new(:spec) -task :default => :spec +task default: :spec diff --git a/demo/demo.rb b/demo/demo.rb index 99d7e59..87f877a 100644 --- a/demo/demo.rb +++ b/demo/demo.rb @@ -1,7 +1,7 @@ require "sinatra" require "geo_faker" -set :public_folder, File.dirname(__FILE__) + "/public" +set :public_folder, "#{File.dirname(__FILE__)}/public" get "/api/within" do content_type :json @@ -56,5 +56,5 @@ get "/*" do pass if request.path_info.start_with?("/api") content_type :html - send_file(File.dirname(__FILE__) + "/public/index.html") + send_file("#{File.dirname(__FILE__)}/public/index.html") end diff --git a/geo_faker.gemspec b/geo_faker.gemspec index b07db92..d2f0a00 100644 --- a/geo_faker.gemspec +++ b/geo_faker.gemspec @@ -2,7 +2,8 @@ lib = File.expand_path("lib", __dir__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) require "geo_faker/version" -Gem::Specification.new do |spec| +Gem::Specification.new do |spec| # rubocop:disable Metrics/BlockLength + spec.required_ruby_version = '>= 2.5.0' spec.name = "geo_faker" spec.version = GeoFaker::VERSION spec.authors = ["Simon Bungartz", "Tim Landwerth"] @@ -14,14 +15,12 @@ Gem::Specification.new do |spec| # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host' # to allow pushing to a single host or delete this section to allow pushing to any host. - if spec.respond_to?(:metadata) - # spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'" - spec.metadata["homepage_uri"] = spec.homepage - spec.metadata["source_code_uri"] = "https://github.com/zweitag/GeoFaker" - # spec.metadata["changelog_uri"] = "TODO: Put your gem's CHANGELOG.md URL here." - else - raise "RubyGems 2.0 or newer is required to protect against public gem pushes." - end + raise "RubyGems 2.0 or newer is required to protect against public gem pushes." unless spec.respond_to?(:metadata) + + # spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'" + spec.metadata["homepage_uri"] = spec.homepage + spec.metadata["source_code_uri"] = "https://github.com/zweitag/GeoFaker" + # spec.metadata["changelog_uri"] = "TODO: Put your gem's CHANGELOG.md URL here." # Specify which files should be added to the gem when it is released. # The `git ls-files -z` loads the files in the RubyGem that have been added into git. @@ -35,9 +34,9 @@ Gem::Specification.new do |spec| spec.add_dependency "rest-client" spec.add_development_dependency "bundler" + spec.add_development_dependency "pry" spec.add_development_dependency "rake" spec.add_development_dependency "rspec" - spec.add_development_dependency "pry" spec.add_development_dependency "sinatra" spec.add_development_dependency "vcr" spec.add_development_dependency "webmock" diff --git a/lib/geo_faker.rb b/lib/geo_faker.rb index 5bdf8c7..227b5c5 100644 --- a/lib/geo_faker.rb +++ b/lib/geo_faker.rb @@ -8,19 +8,17 @@ require "pry" module GeoFaker - BASE_URL = "https://nominatim.openstreetmap.org/search" + BASE_URL = "https://nominatim.openstreetmap.org/search".freeze - @@geo_data = {} + @geo_data = {} def self.geo_data(query, with_polygon: false) - @@geo_data[query] ||= load_geo_data(query, with_polygon: with_polygon) - if with_polygon && !@@geo_data[query].key?("geojson") - @@geo_data[query] = load_geo_data(query, with_polygon: with_polygon) - end - @@geo_data[query] + @geo_data[query] ||= load_geo_data(query, with_polygon: with_polygon) + @geo_data[query] = load_geo_data(query, with_polygon: with_polygon) if with_polygon && !@geo_data[query].key?("geojson") + @geo_data[query] end - def self.load_geo_data(query, with_polygon: false) + def self.load_geo_data(query, with_polygon: false) # rubocop:disable Metrics/MethodLength response = RestClient.get( BASE_URL, params: { @@ -38,15 +36,15 @@ def self.load_geo_data(query, with_polygon: false) data.first end - def self.around(query, radius_in_km:) + def self.around(query, radius_in_km:) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength data = geo_data(query) lat = data["lat"].to_f lon = data["lon"].to_f - angle = 2 * Math::PI * rand() + angle = 2 * Math::PI * rand distance = nil loop do - distance = radius_in_km * gaussian_rand() + distance = radius_in_km * gaussian_rand break if distance.abs < 3 * radius_in_km end @@ -62,9 +60,7 @@ def self.around(query, radius_in_km:) def self.gaussian_rand theta = 2 * Math::PI * rand rho = Math.sqrt(-2 * Math.log(1 - rand)) - x = rho * Math.cos(theta) - #y = rho * Math.sin(theta) - x + rho * Math.cos(theta) end def self.within_bounds(query) @@ -82,7 +78,7 @@ def self.within_bounds(query) ) end - def self.within(query) + def self.within(query) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength data = geo_data(query, with_polygon: true) bounds = data["boundingbox"].map(&:to_f) @@ -92,7 +88,7 @@ def self.within(query) east = bounds[3] geojson = data["geojson"] - raise "geojson must be either Polygon or MultiPolygon" unless ["Polygon", "MultiPolygon"].include?(geojson["type"]) + raise "geojson must be either Polygon or MultiPolygon" unless %w[Polygon MultiPolygon].include?(geojson["type"]) multi_polygon = MultiPolygon.from_geojson(geojson) loop do diff --git a/lib/geo_faker/polygon_with_holes.rb b/lib/geo_faker/polygon_with_holes.rb index ccdf47b..435a100 100644 --- a/lib/geo_faker/polygon_with_holes.rb +++ b/lib/geo_faker/polygon_with_holes.rb @@ -14,7 +14,7 @@ def contains_point?(point) private - def point_in_polygon(polygon, point) + def point_in_polygon(polygon, point) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength point_in_polygon = false last_point = polygon[-1] @@ -26,10 +26,7 @@ def point_in_polygon(polygon, point) xi = p[1] yj = last_point[0] xj = last_point[1] - if yi < y && yj >= y || - yj < y && yi >= y - point_in_polygon = !point_in_polygon if xi + (y - yi) / (yj - yi) * (xj - xi) < x - end + point_in_polygon = !point_in_polygon if (yi < y && yj >= y || yj < y && yi >= y) && (xi + (y - yi) / (yj - yi) * (xj - xi) < x) last_point = p end diff --git a/lib/geo_faker/version.rb b/lib/geo_faker/version.rb index ce76f9f..7de7024 100644 --- a/lib/geo_faker/version.rb +++ b/lib/geo_faker/version.rb @@ -1,3 +1,3 @@ module GeoFaker - VERSION = "0.1.0" + VERSION = "0.1.0".freeze end diff --git a/spec/geo_faker/multi_polygon_spec.rb b/spec/geo_faker/multi_polygon_spec.rb index 32c5445..755e890 100644 --- a/spec/geo_faker/multi_polygon_spec.rb +++ b/spec/geo_faker/multi_polygon_spec.rb @@ -4,7 +4,7 @@ # Test data taken from https://en.wikipedia.org/wiki/GeoJSON # on 6th of December 2018. The different polygons are drawn there. -module GeoFaker +module GeoFaker # rubocop:disable Metrics/ModuleLength RSpec.describe MultiPolygon do shared_examples "a factory method" do it "returns a MultiPolygon object" do