jimmy 0.5.5 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (69) hide show
  1. checksums.yaml +5 -5
  2. data/.circleci/config.yml +35 -0
  3. data/.gitignore +4 -3
  4. data/.rspec +3 -0
  5. data/.rubocop.yml +61 -0
  6. data/.ruby-version +1 -1
  7. data/.travis.yml +6 -0
  8. data/CODE_OF_CONDUCT.md +74 -0
  9. data/Gemfile +13 -0
  10. data/LICENSE +1 -1
  11. data/README.md +22 -134
  12. data/Rakefile +91 -1
  13. data/bin/console +15 -0
  14. data/bin/setup +8 -0
  15. data/jimmy.gemspec +25 -21
  16. data/lib/jimmy.rb +23 -15
  17. data/lib/jimmy/declaration.rb +150 -0
  18. data/lib/jimmy/declaration/assertion.rb +81 -0
  19. data/lib/jimmy/declaration/casting.rb +34 -0
  20. data/lib/jimmy/declaration/composites.rb +41 -0
  21. data/lib/jimmy/declaration/number.rb +27 -0
  22. data/lib/jimmy/declaration/object.rb +11 -0
  23. data/lib/jimmy/declaration/string.rb +100 -0
  24. data/lib/jimmy/declaration/types.rb +57 -0
  25. data/lib/jimmy/error.rb +9 -0
  26. data/lib/jimmy/file_map.rb +166 -0
  27. data/lib/jimmy/index.rb +78 -0
  28. data/lib/jimmy/json/array.rb +93 -0
  29. data/lib/jimmy/json/collection.rb +90 -0
  30. data/lib/jimmy/json/hash.rb +118 -0
  31. data/lib/jimmy/json/pointer.rb +119 -0
  32. data/lib/jimmy/json/uri.rb +144 -0
  33. data/lib/jimmy/loaders/base.rb +30 -0
  34. data/lib/jimmy/loaders/json.rb +15 -0
  35. data/lib/jimmy/loaders/ruby.rb +21 -0
  36. data/lib/jimmy/macros.rb +37 -0
  37. data/lib/jimmy/schema.rb +106 -87
  38. data/lib/jimmy/schema/array.rb +95 -0
  39. data/lib/jimmy/schema/casting.rb +17 -0
  40. data/lib/jimmy/schema/json.rb +40 -0
  41. data/lib/jimmy/schema/number.rb +47 -0
  42. data/lib/jimmy/schema/object.rb +108 -0
  43. data/lib/jimmy/schema/operators.rb +96 -0
  44. data/lib/jimmy/schema/string.rb +44 -0
  45. data/lib/jimmy/schema_with_uri.rb +53 -0
  46. data/lib/jimmy/schemer_factory.rb +65 -0
  47. data/lib/jimmy/version.rb +3 -1
  48. data/schema07.json +172 -0
  49. metadata +50 -101
  50. data/circle.yml +0 -11
  51. data/lib/jimmy/combination.rb +0 -34
  52. data/lib/jimmy/definitions.rb +0 -38
  53. data/lib/jimmy/domain.rb +0 -111
  54. data/lib/jimmy/link.rb +0 -93
  55. data/lib/jimmy/reference.rb +0 -39
  56. data/lib/jimmy/schema_creation.rb +0 -121
  57. data/lib/jimmy/schema_type.rb +0 -100
  58. data/lib/jimmy/schema_types.rb +0 -42
  59. data/lib/jimmy/schema_types/array.rb +0 -30
  60. data/lib/jimmy/schema_types/boolean.rb +0 -6
  61. data/lib/jimmy/schema_types/integer.rb +0 -8
  62. data/lib/jimmy/schema_types/null.rb +0 -6
  63. data/lib/jimmy/schema_types/number.rb +0 -34
  64. data/lib/jimmy/schema_types/object.rb +0 -45
  65. data/lib/jimmy/schema_types/string.rb +0 -40
  66. data/lib/jimmy/symbol_array.rb +0 -17
  67. data/lib/jimmy/transform_keys.rb +0 -39
  68. data/lib/jimmy/type_reference.rb +0 -14
  69. data/lib/jimmy/validation_error.rb +0 -20
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 189b5833da044ec29e5cf06d708960564a08a47f
4
- data.tar.gz: 30c672d61e39c2e84e131404b6efdf5c4bdcecad
2
+ SHA256:
3
+ metadata.gz: 445cebab8aa679190116902608361938ced57a678a878ff03dc8fb15182ffc55
4
+ data.tar.gz: 9c9cc22906573a9b311cc92e61a3fd584736a9b4e2aa468060d147b6f7f4c50f
5
5
  SHA512:
6
- metadata.gz: 1e225b091d344c3c72fd660e3672821c49c2be5403a8b43db54f2f22b2b0cf3fe2ce4867c3371d6462fed1ca7395c274fed29ef7f634ebb012ba9e3ebe161204
7
- data.tar.gz: 3ee1e87f5329b4296ceaa9b664f8aa13c10ffcf7f72ffdbd1b486829e77b603a8a2e467552057e0801ccd458d566c375b914e82de62d480503fdb56c9ed3fca2
6
+ metadata.gz: '018afef0aa32e99fb30b3413107e50022df0edd72ac85f62d8be0c9fc376ff48232da2988f63dc26134a80c86ffbbe4284d33f1cba3420cb29a62c0a5bcbcbf3'
7
+ data.tar.gz: eff46b385b6b20d30c8c424fe8c8df39868cdfc214cad90628a78dd822eea17a8bd3281b2d450c637d6c8b270fb1dca07e0ce0449a5c9294365116ecf581d539
@@ -0,0 +1,35 @@
1
+ version: 2.1
2
+
3
+ jobs:
4
+ specs:
5
+ docker:
6
+ - image: cimg/ruby:2.6
7
+ steps:
8
+ - checkout
9
+ - run:
10
+ name: Bundle Install
11
+ command: bundle install --with ci
12
+ - run:
13
+ name: RSpec
14
+ command: bundle exec rspec --format documentation --format RspecJunitFormatter --out /tmp/rspec.xml
15
+ - store_test_results:
16
+ path: /tmp/rspec.xml
17
+
18
+ lint:
19
+ docker:
20
+ - image: cimg/ruby:2.6
21
+ steps:
22
+ - checkout
23
+ - run:
24
+ name: Bundle Install
25
+ command: bundle install --with ci
26
+ - run:
27
+ name: RSpec
28
+ command: bundle exec rubocop
29
+
30
+ workflows:
31
+ version: 2
32
+ test:
33
+ jobs:
34
+ - specs
35
+ - lint
data/.gitignore CHANGED
@@ -1,11 +1,12 @@
1
1
  /.bundle/
2
2
  /.yardoc
3
- /Gemfile.lock
4
3
  /_yardoc/
5
4
  /coverage/
6
5
  /doc/
7
6
  /pkg/
8
7
  /spec/reports/
9
8
  /tmp/
10
- .rspec
11
- *.gem
9
+ Gemfile.lock
10
+
11
+ # rspec failure tracking
12
+ .rspec_status
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format progress
2
+ --color
3
+ --require spec_helper
@@ -0,0 +1,61 @@
1
+ # See https://github.com/rubocop-hq/rubocop/blob/master/manual/configuration.md
2
+ # See https://docs.rubocop.org/en/stable/
3
+
4
+ AllCops:
5
+ NewCops: enable
6
+
7
+ Layout/HashAlignment:
8
+ EnforcedHashRocketStyle: table
9
+ EnforcedColonStyle: table
10
+
11
+ Layout/LineLength:
12
+ Max: 80
13
+ IgnoredPatterns:
14
+ - '\A\s*# {3}' # Examples in YARD
15
+
16
+ Layout/MultilineMethodCallIndentation:
17
+ EnforcedStyle: indented
18
+
19
+ Lint/AmbiguousBlockAssociation:
20
+ Enabled: false
21
+
22
+ Lint/AmbiguousOperator:
23
+ Enabled: false
24
+
25
+ Lint/AmbiguousRegexpLiteral:
26
+ Enabled: false
27
+
28
+ Metrics/BlockLength:
29
+ Exclude:
30
+ - spec/**/*_spec.rb
31
+
32
+ Metrics/ModuleLength:
33
+ Exclude:
34
+ - spec/**/*_spec.rb
35
+
36
+ Naming/MethodParameterName:
37
+ AllowedNames: ['as', 'id']
38
+
39
+ Style/AndOr:
40
+ EnforcedStyle: conditionals
41
+
42
+ Style/Documentation:
43
+ Exclude:
44
+ - spec/**/*_spec.rb
45
+ - lib/jimmy/schema/**/*.rb
46
+ - lib/jimmy/declaration/**/*.rb
47
+
48
+ Style/DocumentationMethod:
49
+ Enabled: true
50
+
51
+ Style/FormatString:
52
+ EnforcedStyle: percent
53
+
54
+ Style/FormatStringToken:
55
+ EnforcedStyle: unannotated
56
+
57
+ Style/NestedParenthesizedCalls:
58
+ Enabled: false
59
+
60
+ Style/PerlBackrefs:
61
+ Enabled: false
@@ -1 +1 @@
1
- 2.1.5
1
+ 2.6.3
@@ -0,0 +1,6 @@
1
+ ---
2
+ language: ruby
3
+ cache: bundler
4
+ rvm:
5
+ - 2.6.3
6
+ before_install: gem install bundler -v 2.1.4
@@ -0,0 +1,74 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ In the interest of fostering an open and welcoming environment, we as
6
+ contributors and maintainers pledge to making participation in our project and
7
+ our community a harassment-free experience for everyone, regardless of age, body
8
+ size, disability, ethnicity, gender identity and expression, level of experience,
9
+ nationality, personal appearance, race, religion, or sexual identity and
10
+ orientation.
11
+
12
+ ## Our Standards
13
+
14
+ Examples of behavior that contributes to creating a positive environment
15
+ include:
16
+
17
+ * Using welcoming and inclusive language
18
+ * Being respectful of differing viewpoints and experiences
19
+ * Gracefully accepting constructive criticism
20
+ * Focusing on what is best for the community
21
+ * Showing empathy towards other community members
22
+
23
+ Examples of unacceptable behavior by participants include:
24
+
25
+ * The use of sexualized language or imagery and unwelcome sexual attention or
26
+ advances
27
+ * Trolling, insulting/derogatory comments, and personal or political attacks
28
+ * Public or private harassment
29
+ * Publishing others' private information, such as a physical or electronic
30
+ address, without explicit permission
31
+ * Other conduct which could reasonably be considered inappropriate in a
32
+ professional setting
33
+
34
+ ## Our Responsibilities
35
+
36
+ Project maintainers are responsible for clarifying the standards of acceptable
37
+ behavior and are expected to take appropriate and fair corrective action in
38
+ response to any instances of unacceptable behavior.
39
+
40
+ Project maintainers have the right and responsibility to remove, edit, or
41
+ reject comments, commits, code, wiki edits, issues, and other contributions
42
+ that are not aligned to this Code of Conduct, or to ban temporarily or
43
+ permanently any contributor for other behaviors that they deem inappropriate,
44
+ threatening, offensive, or harmful.
45
+
46
+ ## Scope
47
+
48
+ This Code of Conduct applies both within project spaces and in public spaces
49
+ when an individual is representing the project or its community. Examples of
50
+ representing a project or community include using an official project e-mail
51
+ address, posting via an official social media account, or acting as an appointed
52
+ representative at an online or offline event. Representation of a project may be
53
+ further defined and clarified by project maintainers.
54
+
55
+ ## Enforcement
56
+
57
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
58
+ reported by contacting the project team at neil.pearson@bigcommerce.com. All
59
+ complaints will be reviewed and investigated and will result in a response that
60
+ is deemed necessary and appropriate to the circumstances. The project team is
61
+ obligated to maintain confidentiality with regard to the reporter of an incident.
62
+ Further details of specific enforcement policies may be posted separately.
63
+
64
+ Project maintainers who do not follow or enforce the Code of Conduct in good
65
+ faith may face temporary or permanent repercussions as determined by other
66
+ members of the project's leadership.
67
+
68
+ ## Attribution
69
+
70
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71
+ available at [https://contributor-covenant.org/version/1/4][version]
72
+
73
+ [homepage]: https://contributor-covenant.org
74
+ [version]: https://contributor-covenant.org/version/1/4/
data/Gemfile CHANGED
@@ -1,3 +1,16 @@
1
+ # frozen_string_literal: true
2
+
1
3
  source 'https://rubygems.org'
2
4
 
5
+ # Specify your gem's dependencies in jimmy.gemspec
3
6
  gemspec
7
+
8
+ gem 'json_schemer', '~> 0.2.11'
9
+ gem 'rake', '~> 12.0'
10
+ gem 'rspec', '~> 3.9'
11
+ gem 'rubocop', '0.84'
12
+ gem 'simplecov', '~> 0.18.5'
13
+
14
+ group :ci do
15
+ gem 'rspec_junit_formatter', '~> 0.4.1'
16
+ end
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright 2015 OrionVM Pty Ltd
1
+ Copyright 2015–2020 Neil E. Pearson
2
2
 
3
3
  Licensed under the Apache License, Version 2.0 (the "License");
4
4
  you may not use this file except in compliance with the License.
data/README.md CHANGED
@@ -1,151 +1,39 @@
1
- # Jimmy the Gem
1
+ # Jimmy
2
2
 
3
- Meet your mate Jimmy. He's a top bloke.
3
+ Version 2 of the Ruby gem for making JSON schemas the nice way.
4
4
 
5
- Writing JSON schemas is as tedious as a tax audit. But now, thanks to everyone's new best friend Jimmy, it's easier than shooting the side of a barn with a very easy-to-use projectile weapon.
5
+ [![CircleCI](https://circleci.com/gh/hx/jimmy/tree/master.svg?style=svg)](https://circleci.com/gh/hx/jimmy)
6
6
 
7
- ## Getting hooked up
7
+ ## Installation
8
8
 
9
- You guessed it:
9
+ Add this line to your application's Gemfile:
10
10
 
11
- ```bash
12
- $ gem install jimmy
11
+ ```ruby
12
+ gem 'jimmy'
13
13
  ```
14
14
 
15
- Here's another doozy:
15
+ And then execute:
16
16
 
17
- ```ruby
18
- require 'jimmy'
19
- ```
17
+ $ bundle install
20
18
 
21
- Wasn't that a shock. Let's move on.
19
+ Or install it yourself as:
22
20
 
23
- ## The DSL
21
+ $ gem install jimmy
24
22
 
25
- Jimmy replaces `.json` JSON schemas files with `.rb` files. Here's a simple example:
23
+ ## Usage
26
24
 
27
- ```ruby
28
- # city.rb
29
- object do
30
- string :name, min_length: 2
31
- string :postcode, /^\d{4}$/
25
+ Check the [docs](https://rubydoc.info/gems/jimmy).
32
26
 
33
- require all
34
- end
35
- ```
27
+ ## Development
36
28
 
37
- This compiles to:
38
-
39
- ```json
40
- {
41
- "$schema": "https://my.domain.kom/city#",
42
- "type": "object",
43
- "properties": {
44
- "name": {
45
- "type": "string",
46
- "minLength": 2
47
- },
48
- "postcode": {
49
- "type": "string",
50
- "pattern": "^\\d{4}$"
51
- },
52
- "required": ["name", "zipcode"],
53
- "additionalProperties": false
54
- }
55
- }
56
- ```
29
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
57
30
 
58
- Crikey! That's a bit of a difference. Let's take a look at a more complex (and contrived) example:
31
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
59
32
 
60
- ```ruby
61
- # types/country_code.rb
62
- string /^[A-Z]{2}$/
63
-
64
- # types/geopoint.rb
65
- object do
66
- number :latitude, -90..90
67
- number :longitude, -180..180
68
- end
69
-
70
- # city.rb
71
- object do
72
- string :name, min_length: 2
73
- string :postcode, /^\d{4}$/
74
- integer :population
75
- geopoint :location
76
- country_code :country
77
- array :points_of_interest do
78
- object do
79
- string :title, 3..150
80
- integer :popularity, [1, 3, 5, 7]
81
- geopoint :location
82
- boolean :featured
83
- require :title
84
- end
85
- end
86
- require all - :location
87
- end
88
- ```
33
+ ## Contributing
34
+
35
+ Bug reports and pull requests are welcome on GitHub at https://github.com/hx/jimmy. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/hx/jimmy/blob/master/CODE_OF_CONDUCT.md).
36
+
37
+ ## Code of Conduct
89
38
 
90
- Here's the full result (though we expect you get the gist of it by now):
91
-
92
- ```json
93
- {
94
- "$schema": "https://my.domain.kom/city#",
95
- "type": "object",
96
- "properties": {
97
- "name": {
98
- "type": "string",
99
- "minLength": 2
100
- },
101
- "postcode": {
102
- "type": "string",
103
- "pattern": "^\\d{4}$"
104
- },
105
- "population": {
106
- "type": "integer"
107
- },
108
- "location": {
109
- "$ref": "/types/geopoint#"
110
- },
111
- "country": {
112
- "$ref": "/types/country_code#"
113
- },
114
- "points_of_interest": {
115
- "type": "array",
116
- "items": {
117
- "type": "object",
118
- "properties": {
119
- "title": {
120
- "type": "string",
121
- "minLength": 3,
122
- "maxLength": 150
123
- },
124
- "popularity": {
125
- "type": "integer",
126
- "enum": [1, 3, 5, 7]
127
- },
128
- "location": {
129
- "$ref": "/types/geopoint#"
130
- },
131
- "featured": {
132
- "type": "boolean"
133
- }
134
- },
135
- "required": [
136
- "title"
137
- ],
138
- "additionalProperties": false
139
- }
140
- }
141
- },
142
- "required": [
143
- "name",
144
- "postcode",
145
- "population",
146
- "country",
147
- "points_of_interest"
148
- ],
149
- "additionalProperties": false
150
- }
151
- ```
39
+ Everyone interacting in the Jimmy project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/hx/jimmy/blob/master/CODE_OF_CONDUCT.md).
data/Rakefile CHANGED
@@ -1,4 +1,94 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'bundler/gem_tasks'
2
4
  require 'rspec/core/rake_task'
3
5
 
4
- RSpec::Core::RakeTask.new :spec
6
+ require 'tempfile'
7
+
8
+ RSpec::Core::RakeTask.new(:spec)
9
+
10
+ task default: :spec
11
+
12
+ # rubocop:disable all
13
+ class Documentator
14
+ DELIMITER = '# Generated by `rake yard`. Do not modify anything below here.'
15
+
16
+ def self.update(path, &block)
17
+ new(path).update(&block)
18
+ end
19
+
20
+ def initialize(path)
21
+ @path = Jimmy::ROOT.join(*path)
22
+ end
23
+
24
+ def update(&block)
25
+ @indent = ''
26
+ mute = false
27
+
28
+ File.foreach(@path) do |line|
29
+ if line.match? /^#{@indent}(class|module) /
30
+ @indent += ' '
31
+ elsif line == @indent + DELIMITER + "\n"
32
+ mute = true
33
+ render &block
34
+ elsif line == @indent[0..-3] + "end\n"
35
+ render "\n", &block unless mute
36
+ mute = false
37
+ end
38
+ write line unless mute
39
+ end
40
+
41
+ tempfile.close
42
+ @path.unlink
43
+ File.rename tempfile.path, @path.to_s
44
+ rescue
45
+ tempfile.unlink
46
+ raise
47
+ end
48
+
49
+ def <<(str)
50
+ lines = str.lines
51
+ lines.each { |line| write "#{@indent}# #{line}" }
52
+ end
53
+
54
+ private
55
+
56
+ def write(line)
57
+ tempfile.write line
58
+ end
59
+
60
+ def render(prefix = '')
61
+ write "%s%s%s\n%s#\n" % [prefix, @indent, DELIMITER, @indent]
62
+ yield self
63
+ end
64
+
65
+ def tempfile
66
+ @tempfile ||= Tempfile.new('documented')
67
+ end
68
+ end
69
+ # rubocop:enable all
70
+
71
+ desc 'Generate YARD for some runtime-defined methods'
72
+ task :yard do
73
+ require 'jimmy'
74
+
75
+ Documentator.update %w[lib jimmy declaration string.rb] do |y|
76
+ Jimmy::Declaration::FORMATS.each do |format|
77
+ y << <<~YARD
78
+ @!method #{format.gsub '-', '_'}()
79
+ Validate a string with format "#{format}".
80
+ @return [Schema]
81
+ YARD
82
+ end
83
+ end
84
+
85
+ Documentator.update %w[lib jimmy declaration types.rb] do |y|
86
+ Jimmy::Declaration::SIMPLE_TYPES.each do |type|
87
+ y << <<~YARD
88
+ @!method #{type}()
89
+ Make the schema allow type "#{type}".
90
+ @return [Schema]
91
+ YARD
92
+ end
93
+ end
94
+ end