arkenstone-open 3.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/codacy-analysis.yml +46 -0
  3. data/.gitignore +19 -0
  4. data/.rubocop.yml +5 -0
  5. data/.ruby-version +1 -0
  6. data/.travis.yml +16 -0
  7. data/Gemfile +21 -0
  8. data/Gemfile.lock +101 -0
  9. data/LICENSE.txt +11 -0
  10. data/README.md +87 -0
  11. data/Rakefile +36 -0
  12. data/arkenstone.gemspec +27 -0
  13. data/lib/arkenstone/associations/resources.rb +76 -0
  14. data/lib/arkenstone/associations.rb +389 -0
  15. data/lib/arkenstone/document.rb +289 -0
  16. data/lib/arkenstone/enumerable/query_list.rb +20 -0
  17. data/lib/arkenstone/errors/no_url_error.rb +14 -0
  18. data/lib/arkenstone/helpers.rb +18 -0
  19. data/lib/arkenstone/network/env.rb +19 -0
  20. data/lib/arkenstone/network/hook.rb +74 -0
  21. data/lib/arkenstone/network/network.rb +72 -0
  22. data/lib/arkenstone/query_builder.rb +84 -0
  23. data/lib/arkenstone/queryable.rb +38 -0
  24. data/lib/arkenstone/timestamps.rb +25 -0
  25. data/lib/arkenstone/validation/validation_error.rb +34 -0
  26. data/lib/arkenstone/validation/validations.rb +192 -0
  27. data/lib/arkenstone/version.rb +5 -0
  28. data/lib/arkenstone.rb +22 -0
  29. data/test/associations/test_document_overrides.rb +50 -0
  30. data/test/associations/test_has_and_belongs_to_many.rb +80 -0
  31. data/test/dummy/app/models/association.rb +35 -0
  32. data/test/dummy/app/models/superuser.rb +8 -0
  33. data/test/dummy/app/models/user.rb +10 -0
  34. data/test/spec_helper.rb +16 -0
  35. data/test/test_arkenstone.rb +354 -0
  36. data/test/test_arkenstone_hook_inheritance.rb +39 -0
  37. data/test/test_associations.rb +327 -0
  38. data/test/test_enumerables.rb +36 -0
  39. data/test/test_environment.rb +14 -0
  40. data/test/test_helpers.rb +18 -0
  41. data/test/test_hooks.rb +104 -0
  42. data/test/test_query_builder.rb +163 -0
  43. data/test/test_queryable.rb +59 -0
  44. data/test/test_validations.rb +197 -0
  45. metadata +133 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 8d733a53e57cd9f59167299cedd91ee37b83060f62a18afeaf8d79d9b3b4184a
4
+ data.tar.gz: 9d68710e72885419899b52471cdd8cc09e9725bbe940f56a17e500d6207f7b45
5
+ SHA512:
6
+ metadata.gz: db74e65147e8d87b57a6a90cde59eca88651a87882846eecf04d038777fa69c1b76bf07d84757c77e3d32b5b81a0b66875a831d41d1809f5f568d758306cb38e
7
+ data.tar.gz: 756ae9b10fce7f54d5487e8215a82ef186318f720977af6488041a18235cc3ec53b09767871f981ed5f7b2a88bfe468a54913b69a4f6adfe8ed06ca817715c64
@@ -0,0 +1,46 @@
1
+ # This workflow checks out code, performs a Codacy security scan
2
+ # and integrates the results with the
3
+ # GitHub Advanced Security code scanning feature. For more information on
4
+ # the Codacy security scan action usage and parameters, see
5
+ # https://github.com/codacy/codacy-analysis-cli-action.
6
+ # For more information on Codacy Analysis CLI in general, see
7
+ # https://github.com/codacy/codacy-analysis-cli.
8
+
9
+ name: Codacy Security Scan
10
+
11
+ on:
12
+ push:
13
+ branches: ["development", "main"]
14
+ pull_request:
15
+ branches: ["development", "main"]
16
+
17
+ jobs:
18
+ codacy-security-scan:
19
+ name: Codacy Security Scan
20
+ runs-on: ubuntu-latest
21
+ steps:
22
+ # Checkout the repository to the GitHub Actions runner
23
+ - name: Checkout code
24
+ uses: actions/checkout@v2
25
+
26
+ # Execute Codacy Analysis CLI and generate a SARIF output with the security issues identified during the analysis
27
+ - name: Run Codacy Analysis CLI
28
+ uses: codacy/codacy-analysis-cli-action@1.1.0
29
+ with:
30
+ # Check https://github.com/codacy/codacy-analysis-cli#project-token to get your project token from your Codacy repository
31
+ # You can also omit the token and run the tools that support default configurations
32
+ project-token: ${{ secrets.CODACY_PROJECT_TOKEN }}
33
+ verbose: true
34
+ output: results.sarif
35
+ format: sarif
36
+ # Adjust severity of non-security issues
37
+ gh-code-scanning-compat: true
38
+ # Force 0 exit code to allow SARIF file generation
39
+ # This will handover control about PR rejection to the GitHub side
40
+ max-allowed-issues: 2147483647
41
+
42
+ # Upload the SARIF file generated in the previous step
43
+ - name: Upload SARIF results file
44
+ uses: github/codeql-action/upload-sarif@v1
45
+ with:
46
+ sarif_file: results.sarif
data/.gitignore ADDED
@@ -0,0 +1,19 @@
1
+ *.DS_Store
2
+ *.gem
3
+ *.rbc
4
+ *.swp
5
+ *.swo
6
+ .bundle
7
+ .config
8
+ .yardoc
9
+ InstalledFiles
10
+ _yardoc
11
+ coverage
12
+ doc/
13
+ lib/bundler/man
14
+ pkg
15
+ rdoc
16
+ spec/reports
17
+ test/tmp
18
+ test/version_tmp
19
+ tmp
data/.rubocop.yml ADDED
@@ -0,0 +1,5 @@
1
+ AllCops:
2
+ NewCops: enable
3
+ Lint/MissingSuper:
4
+ Exclude:
5
+ - lib/arkenstone/enumerable/query_list.rb
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 3.1.2
data/.travis.yml ADDED
@@ -0,0 +1,16 @@
1
+ dist: focal
2
+ env:
3
+ global:
4
+ - CC_TEST_REPORTER_ID=8d9ccf963273f583d380d4e2b97da731c25d77bb4784151ea4a6ec27bbbdaf22
5
+ language: ruby
6
+ rvm:
7
+ - 3.0.2
8
+ branches:
9
+ except:
10
+ - documentation
11
+ before_script:
12
+ - curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
13
+ - chmod +x ./cc-test-reporter
14
+ - ./cc-test-reporter before-build
15
+ after_script:
16
+ - ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT
data/Gemfile ADDED
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ group :test do
6
+ gem 'minitest'
7
+ gem 'pry'
8
+ gem 'pry-nav'
9
+ gem 'simplecov', require: false
10
+ gem 'test-unit' # test-unit was removed from ruby in version 2.2.0
11
+ gem 'webmock', '~> 3.9.3'
12
+ end
13
+
14
+ group :development do
15
+ gem 'flog'
16
+ gem 'rubocop'
17
+ gem 'yard'
18
+ end
19
+
20
+ # Specify your gem's dependencies in arkenstone.gemspec
21
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,101 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ arkenstone (3.0.0)
5
+ activesupport (>= 5.0)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ activesupport (7.0.4.3)
11
+ concurrent-ruby (~> 1.0, >= 1.0.2)
12
+ i18n (>= 1.6, < 2)
13
+ minitest (>= 5.1)
14
+ tzinfo (~> 2.0)
15
+ addressable (2.8.1)
16
+ public_suffix (>= 2.0.2, < 6.0)
17
+ ast (2.4.2)
18
+ coderay (1.1.3)
19
+ concurrent-ruby (1.2.2)
20
+ crack (0.4.5)
21
+ rexml
22
+ docile (1.4.0)
23
+ flog (4.6.6)
24
+ path_expander (~> 1.0)
25
+ ruby_parser (~> 3.1, > 3.1.0)
26
+ sexp_processor (~> 4.8)
27
+ hashdiff (1.0.1)
28
+ i18n (1.12.0)
29
+ concurrent-ruby (~> 1.0)
30
+ json (2.6.3)
31
+ method_source (1.0.0)
32
+ minitest (5.18.0)
33
+ parallel (1.22.1)
34
+ parser (3.2.1.1)
35
+ ast (~> 2.4.1)
36
+ path_expander (1.1.1)
37
+ power_assert (2.0.3)
38
+ pry (0.14.2)
39
+ coderay (~> 1.1)
40
+ method_source (~> 1.0)
41
+ pry-nav (1.0.0)
42
+ pry (>= 0.9.10, < 0.15)
43
+ public_suffix (5.0.1)
44
+ rainbow (3.1.1)
45
+ rake (13.0.6)
46
+ regexp_parser (2.7.0)
47
+ rexml (3.2.5)
48
+ rubocop (1.48.1)
49
+ json (~> 2.3)
50
+ parallel (~> 1.10)
51
+ parser (>= 3.2.0.0)
52
+ rainbow (>= 2.2.2, < 4.0)
53
+ regexp_parser (>= 1.8, < 3.0)
54
+ rexml (>= 3.2.5, < 4.0)
55
+ rubocop-ast (>= 1.26.0, < 2.0)
56
+ ruby-progressbar (~> 1.7)
57
+ unicode-display_width (>= 2.4.0, < 3.0)
58
+ rubocop-ast (1.27.0)
59
+ parser (>= 3.2.1.0)
60
+ ruby-progressbar (1.13.0)
61
+ ruby_parser (3.20.0)
62
+ sexp_processor (~> 4.16)
63
+ sexp_processor (4.16.1)
64
+ simplecov (0.22.0)
65
+ docile (~> 1.1)
66
+ simplecov-html (~> 0.11)
67
+ simplecov_json_formatter (~> 0.1)
68
+ simplecov-html (0.12.3)
69
+ simplecov_json_formatter (0.1.4)
70
+ test-unit (3.5.7)
71
+ power_assert
72
+ tzinfo (2.0.6)
73
+ concurrent-ruby (~> 1.0)
74
+ unicode-display_width (2.4.2)
75
+ webmock (3.9.5)
76
+ addressable (>= 2.3.6)
77
+ crack (>= 0.3.2)
78
+ hashdiff (>= 0.4.0, < 2.0.0)
79
+ webrick (1.7.0)
80
+ yard (0.9.28)
81
+ webrick (~> 1.7.0)
82
+
83
+ PLATFORMS
84
+ ruby
85
+
86
+ DEPENDENCIES
87
+ arkenstone!
88
+ bundler (>= 2.1)
89
+ flog
90
+ minitest
91
+ pry
92
+ pry-nav
93
+ rake (>= 13.0.1)
94
+ rubocop
95
+ simplecov
96
+ test-unit
97
+ webmock (~> 3.9.3)
98
+ yard
99
+
100
+ BUNDLED WITH
101
+ 2.2.22
data/LICENSE.txt ADDED
@@ -0,0 +1,11 @@
1
+ The MIT License (MIT)
2
+
3
+ Arkenstone: a lightweight json active model like framework.
4
+
5
+ Copyright (C) 2020 Michael Christenson II
6
+
7
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
8
+
9
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
10
+
11
+ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,87 @@
1
+ # Arkenstone [![Build Status](https://app.travis-ci.com/m3talsmith/arkenstone.svg?branch=development&status=passed)](https://app.travis-ci.com/m3talsmith/arkenstone) [![Maintainability](https://api.codeclimate.com/v1/badges/a0f3b07d272fcf220475/maintainability)](https://codeclimate.com/github/m3talsmith/arkenstone/maintainability) [![Test Coverage](https://api.codeclimate.com/v1/badges/a0f3b07d272fcf220475/test_coverage)](https://codeclimate.com/github/m3talsmith/arkenstone/test_coverage)
2
+
3
+ Arkenstone is a replacement for [ActiveRecord](http://api.rubyonrails.org/classes/ActiveRecord/Base.html) that uses RESTful services to get and store data.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'arkenstone'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install arkenstone
18
+
19
+ ## Usage
20
+
21
+ Include the `Arkenstone::Document` module in your class, set the `url` and `attributes` and away you go.
22
+
23
+ class User
24
+ include Arkenstone::Document
25
+
26
+ url 'http://example.com/users/'
27
+ attributes :name, :age, :gender
28
+ end
29
+
30
+ `User` instances will have accessor properties for `:name`, `:age`, and `:gender`. You can also `save`, and `update_attributes` as well:
31
+
32
+ my_user = User.create(name: 'Thorin', age: 195, gender: 'M', bearded: true)
33
+
34
+ This will make a `POST` to `http://example.com/users/`. If json data is returned from the server, it will be applied to the attributes of the object.
35
+
36
+ How about updating?
37
+
38
+ # Assuming Thorin has an id of 1
39
+ thorin = User.find(1)
40
+
41
+ # Thorin lost a bet and shaved... well you know how bets go!
42
+ thorin.update_attribute :bearded, false
43
+
44
+ This does a `PUT` to `http://example.com/users/1`. Again, returning json is translated back into a usable Thorin.
45
+
46
+ You can also change attributes using `#update_attributes` or setting them at a field level and saving.
47
+
48
+ # Thorin didn't shave for a day
49
+ thorin = User.find(1)
50
+ thorin.bearded = true
51
+ thorin.save
52
+
53
+ `Arkenstone` knows if you're a new object or not and properly uses `POST` or `PUT` where needed.
54
+
55
+ Here is a list of `RESTful` expectations that come with the library:
56
+
57
+ ```ruby
58
+ Model.find(1) # => GET http://example.com/1
59
+ Model.all # => GET http://example.com
60
+ Model.new.save # => POST http://example.com
61
+ Model.find(1).save # => PUT http://example.com/1
62
+ Model.find(1).update_attribute(:attribute, 'value') # => PUT http://example.com/1
63
+ Model.find(1).update_attributes(attribute1: 'value1', attribute2: 'value2') # => PUT http://example.com/1
64
+ Model.find(1).destroy # => DELETE http://example.com/1
65
+ ```
66
+
67
+ ## Contributing
68
+
69
+ 1. Fork it
70
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
71
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
72
+ 4. Push to the branch (`git push origin my-new-feature`)
73
+ 5. Create new Pull Request
74
+
75
+ ## License
76
+
77
+ The MIT License (MIT)
78
+
79
+ Arkenstone: a lightweight json active model like framework.
80
+
81
+ Copyright (C) 2020 Michael Christenson II
82
+
83
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
84
+
85
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
86
+
87
+ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ if RUBY_VERSION.split('.')
4
+ .first.to_i < 3
5
+ abort 'Arkenstone development requires Ruby >= 3.0.2. ' \
6
+ 'Please upgrade to a newer version of Ruby'
7
+ end
8
+ require 'rake/testtask'
9
+ require './lib/arkenstone/version'
10
+
11
+ task :build do
12
+ system 'gem build arkenstone.gemspec'
13
+ end
14
+
15
+ task package: :build do
16
+ system "gem push arkenstone-open-#{Arkenstone::VERSION}.gem"
17
+ end
18
+
19
+ task :analyze do
20
+ system 'rubocop -A'
21
+ system 'flog -g lib'
22
+ end
23
+
24
+ task :docs do
25
+ system 'yard doc'
26
+ end
27
+
28
+ Rake::TestTask.new do |t|
29
+ t.libs << 'test'
30
+ t.libs << 'test/test_associations'
31
+ t.verbose = false
32
+ t.warning = false
33
+ end
34
+
35
+ desc 'Run tests'
36
+ task default: :test
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path('lib', __dir__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+ require 'arkenstone/version'
6
+
7
+ Gem::Specification.new do |spec|
8
+ spec.name = 'arkenstone-open'
9
+ spec.version = Arkenstone::VERSION
10
+ spec.authors = ['Michael Christenson II', 'Steve Young', 'Scott Williams', 'Brett Byler']
11
+ spec.email = ['m3talsmith@gmail.com']
12
+ spec.description = 'An Open Source ActiveRecord replacement over REST'
13
+ spec.summary = 'A drop-in replacement for ActiveRecord that performs CRUD operations over RESTful URLs.'
14
+ spec.homepage = 'https://github.com/m3talsmith/arkenstone'
15
+ spec.license = 'MIT'
16
+
17
+ spec.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
18
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
19
+ spec.require_paths = ['lib']
20
+
21
+ spec.add_development_dependency 'bundler', '>= 2.1'
22
+ spec.add_development_dependency 'rake', '>= 13.0.1'
23
+ spec.add_runtime_dependency 'activesupport', '>= 5.0'
24
+
25
+ spec.required_ruby_version = '>= 3.0'
26
+ spec.metadata['rubygems_mfa_required'] = 'true'
27
+ end
@@ -0,0 +1,76 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Arkenstone
4
+ module Associations
5
+ module Resources
6
+ class << self
7
+ def included(base)
8
+ base.send :include, InstanceMethods
9
+ base.extend ClassMethods
10
+ end
11
+ end
12
+
13
+ module ClassMethods
14
+ end
15
+
16
+ module InstanceMethods
17
+ ### Attaches singleton methods for has_many relationships
18
+ def attach_nested_has_many_resource_methods(nested_resources, nested_resource_name,
19
+ nested_resource_class_name = nested_resource_name)
20
+ parent_instance = self
21
+ parent_instance.extend HasManyParentSingletonMethods
22
+ parent_instance.add_resource_methods(nested_resource_name)
23
+
24
+ nested_klass = prefix_with_class_module(nested_resource_class_name.to_s.classify)
25
+ nested_klass = Kernel.const_get(nested_klass)
26
+ nested_klass.url build_nested_url(nested_resource_name)
27
+
28
+ nested_resources.define_singleton_method(:arkenstone_parent_instance) { parent_instance }
29
+ nested_resources.define_singleton_method(:arkenstone_nested_class) { nested_klass }
30
+ nested_resources.define_singleton_method(:arkenstone_nested_resource_name) { nested_resource_name }
31
+ nested_resources.extend HasManySingletonMethods
32
+ nested_resources
33
+ end
34
+ end
35
+
36
+ module HasManyParentSingletonMethods
37
+ def add_resource_methods(nested_resource_name)
38
+ parent_instance = self
39
+ resource_name_pluralized = nested_resource_name.to_s.pluralize
40
+
41
+ parent_instance.define_singleton_method "#{resource_name_pluralized}=" do |resources|
42
+ resources.each do |resource|
43
+ resource.send "#{parent_instance.class.to_s.demodulize.downcase}_id=", parent_instance.id
44
+ end
45
+
46
+ parent_instance.arkenstone_data[resource_name_pluralized.to_sym] = resources
47
+ resources
48
+ end
49
+ end
50
+ end
51
+
52
+ module HasManySingletonMethods
53
+ def <<(resource)
54
+ push resource
55
+ arkenstone_parent_instance.send "#{arkenstone_nested_resource_name}=", self
56
+ end
57
+
58
+ def build(options)
59
+ parent_id = "#{arkenstone_parent_instance.class.to_s.demodulize.underscore}_id"
60
+ new_resource = arkenstone_nested_class.build(options.merge({ parent_id => arkenstone_parent_instance.id }))
61
+ parent_resource_instances = arkenstone_parent_instance.send arkenstone_nested_resource_name.to_sym
62
+
63
+ parent_resource_instances << new_resource
64
+ arkenstone_parent_instance.send "#{arkenstone_nested_resource_name}=", parent_resource_instances
65
+
66
+ new_resource
67
+ end
68
+
69
+ def create(options)
70
+ new_resource = build(options)
71
+ new_resource.save
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end