schematic 0.6.2 → 0.7.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.
- checksums.yaml +7 -0
- data/.gitignore +14 -8
- data/.travis.yml +17 -0
- data/Gemfile +6 -1
- data/LICENSE +1 -1
- data/README.md +106 -0
- data/Rakefile +3 -8
- data/lib/schematic.rb +3 -42
- data/lib/schematic/exceptions.rb +13 -0
- data/lib/schematic/generator/column.rb +17 -11
- data/lib/schematic/generator/namespaces.rb +3 -3
- data/lib/schematic/generator/restrictions/base.rb +5 -5
- data/lib/schematic/generator/restrictions/custom.rb +3 -2
- data/lib/schematic/generator/restrictions/enumeration.rb +5 -2
- data/lib/schematic/generator/restrictions/length.rb +4 -2
- data/lib/schematic/generator/restrictions/numericality.rb +3 -1
- data/lib/schematic/generator/restrictions/pattern.rb +4 -3
- data/lib/schematic/generator/sandbox.rb +4 -1
- data/lib/schematic/generator/types.rb +14 -13
- data/lib/schematic/generator/uniqueness.rb +7 -8
- data/lib/schematic/generator/xsd.rb +32 -26
- data/lib/schematic/serializers/xsd.rb +6 -6
- data/lib/schematic/version.rb +1 -1
- data/schematic.gemspec +23 -24
- data/spec/schematic/generator/restrictions/custom_spec.rb +15 -18
- data/spec/schematic/generator/restrictions/enumeration_spec.rb +31 -31
- data/spec/schematic/generator/restrictions/length_spec.rb +35 -30
- data/spec/schematic/generator/restrictions/mixin_spec.rb +11 -15
- data/spec/schematic/generator/restrictions/numericality_spec.rb +11 -11
- data/spec/schematic/generator/restrictions/pattern_spec.rb +20 -21
- data/spec/schematic/generator/sandbox_spec.rb +17 -17
- data/spec/schematic/generator/uniqueness_spec.rb +38 -37
- data/spec/schematic/serializers/xsd_extend_spec.rb +11 -11
- data/spec/schematic/serializers/xsd_validation_presence_spec.rb +16 -11
- data/spec/schematic/serializers/xsd_xsd_ignore_methods_spec.rb +3 -3
- data/spec/schematic/serializers/xsd_xsd_methods_spec.rb +27 -24
- data/spec/schematic/serializers/xsd_xsd_minimum_occurrences_for_spec.rb +13 -8
- data/spec/schematic_serializers_xsd_spec.rb +70 -67
- data/spec/spec_helper.rb +8 -113
- data/spec/support/database.rb +9 -0
- data/spec/support/helpers.rb +111 -0
- data/spec/support/with_model.rb +5 -0
- data/spec/{xsd → support/xsd}/XMLSchema.xsd +0 -0
- data/spec/{xsd → support/xsd}/xml.xsd +0 -0
- metadata +54 -69
- data/.rspec +0 -1
- data/.rvmrc +0 -1
- data/README.rdoc +0 -103
- data/spec/support/extensions/active_model/validations/inclusion.rb +0 -69
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 9c76641aa454b778d4e26f79dc681629dcf6ef6a
|
4
|
+
data.tar.gz: dd47b6effb9ca6bc3036f8a71ebc840faba17fa4
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 910d7a63f610016582b3c8d0a9e569e5c0d5cb2846582c7f142dfe6fa693d024d8f149ea37dc812eecf572c8e83bcbf2b635fd6bb84c6ff81f2f91265f99952a
|
7
|
+
data.tar.gz: 0846991be161e75ac8e44c4c22b2f097ad5a2536926c11cf697603314560b6098f2936237c81919fc94af325eced78b1c139d11a423542faa8d47d83fad24710
|
data/.gitignore
CHANGED
@@ -1,11 +1,17 @@
|
|
1
|
-
.pairs
|
2
1
|
*.gem
|
3
|
-
|
4
|
-
.DS_Store
|
2
|
+
*.rbc
|
5
3
|
.bundle
|
6
|
-
.
|
7
|
-
.
|
4
|
+
.config
|
5
|
+
.yardoc
|
8
6
|
Gemfile.lock
|
9
|
-
|
10
|
-
|
11
|
-
|
7
|
+
InstalledFiles
|
8
|
+
_yardoc
|
9
|
+
coverage
|
10
|
+
doc/
|
11
|
+
lib/bundler/man
|
12
|
+
pkg
|
13
|
+
rdoc
|
14
|
+
spec/reports
|
15
|
+
test/tmp
|
16
|
+
test/version_tmp
|
17
|
+
tmp
|
data/.travis.yml
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
language: ruby
|
2
|
+
|
3
|
+
rvm:
|
4
|
+
- "1.9"
|
5
|
+
- "2.0"
|
6
|
+
- "2.1"
|
7
|
+
- "jruby-19mode"
|
8
|
+
- "rbx-2.2"
|
9
|
+
|
10
|
+
env:
|
11
|
+
- ACTIVE_RECORD_BRANCH="master"
|
12
|
+
- ACTIVE_RECORD_VERSION="~> 4.1.0"
|
13
|
+
- ACTIVE_RECORD_VERSION="~> 4.0.0"
|
14
|
+
|
15
|
+
matrix:
|
16
|
+
allow_failures:
|
17
|
+
- env: ACTIVE_RECORD_BRANCH="master"
|
data/Gemfile
CHANGED
@@ -1,4 +1,9 @@
|
|
1
|
-
source
|
1
|
+
source 'https://rubygems.org'
|
2
2
|
|
3
3
|
# Specify your gem's dependencies in schematic.gemspec
|
4
4
|
gemspec
|
5
|
+
|
6
|
+
gem 'activerecord', :github => 'rails', :branch => ENV['ACTIVE_RECORD_BRANCH'] if ENV['ACTIVE_RECORD_BRANCH']
|
7
|
+
gem 'activerecord', ENV['ACTIVE_RECORD_VERSION'] if ENV['ACTIVE_RECORD_VERSION']
|
8
|
+
gem 'activerecord-jdbcsqlite3-adapter', :platforms => :jruby
|
9
|
+
gem 'sqlite3', '1.3.8', :platforms => :ruby
|
data/LICENSE
CHANGED
data/README.md
ADDED
@@ -0,0 +1,106 @@
|
|
1
|
+
# [Schematic](http://github.com/casecommons/schematic/)
|
2
|
+
|
3
|
+
[](https://travis-ci.org/Casecommons/schematic)
|
4
|
+
[](https://codeclimate.com/github/Casecommons/schematic)
|
5
|
+
[](https://rubygems.org/gems/schematic)
|
6
|
+
|
7
|
+
Automatic XSD generation for your ActiveRecord models.
|
8
|
+
|
9
|
+
## Installation
|
10
|
+
|
11
|
+
Install as usual: `gem install schematic` or add `gem 'schematic'` to your Gemfile. See `.travis.yml` for supported (tested) Ruby versions.
|
12
|
+
|
13
|
+
## Usage
|
14
|
+
|
15
|
+
```ruby
|
16
|
+
class Post < ActiveRecord::Base
|
17
|
+
end
|
18
|
+
|
19
|
+
Post.to_xsd #=> (a bunch of xml)
|
20
|
+
```
|
21
|
+
|
22
|
+
Validations will automatically add restrictions to the XSD for fields. If a validation has a conditional if or unless option it will be skipped. However if you wish to force the inclusion of the validation in the XSD you can set: `{ :xsd => { :include => true } }` in the options e.g.
|
23
|
+
|
24
|
+
```ruby
|
25
|
+
class Post < ActiveRecord::Base
|
26
|
+
validates :category, :inclusion => { :in => ["foo", "bar"], :xsd => { :include => true } }, :if => lambda { ... }
|
27
|
+
end
|
28
|
+
```
|
29
|
+
|
30
|
+
You can include or exclude additional elements:
|
31
|
+
|
32
|
+
```ruby
|
33
|
+
class Post < ActiveRecord::Base
|
34
|
+
schematic do
|
35
|
+
element :title
|
36
|
+
element :author => [:name, :email, :url]
|
37
|
+
element :blog => { :post => { :category => nil } }
|
38
|
+
ignore :comments
|
39
|
+
ignore :attachments => [:filetype]
|
40
|
+
end
|
41
|
+
end
|
42
|
+
```
|
43
|
+
|
44
|
+
You can also change the name of the root tag:
|
45
|
+
|
46
|
+
```ruby
|
47
|
+
class Post < ActiveRecord::Base
|
48
|
+
schematic do
|
49
|
+
root "blog-post"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
```
|
53
|
+
|
54
|
+
If you want to programatically include or exclude elements use `Post#schematic_sandbox.added_elements` and `Post#schematic_sandbox.ignored_elements`.
|
55
|
+
|
56
|
+
The former is a Hash and the latter is an Array.
|
57
|
+
|
58
|
+
You can define your own custom restrictions by inheriting from the Restrictions Base class:
|
59
|
+
|
60
|
+
```ruby
|
61
|
+
class MyCustomRestriction < Schematic::Generator::Restrictions::Base
|
62
|
+
def generate(builder)
|
63
|
+
for_validator ActiveModel::BlockValidator do |validator|
|
64
|
+
builder.xs(:enumeration, "value" => "foo")
|
65
|
+
builder.xs(:enumeration, "value" => "bar")
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
```
|
70
|
+
|
71
|
+
You can have a custom pattern restriction from a custom validator:
|
72
|
+
|
73
|
+
```ruby
|
74
|
+
class MyValidator < ActiveModel::EachValidator
|
75
|
+
def validate_each(record, attribute, value)
|
76
|
+
# ...
|
77
|
+
end
|
78
|
+
|
79
|
+
def xsd_pattern_restrictions
|
80
|
+
[/foo/, /bar/]
|
81
|
+
end
|
82
|
+
end
|
83
|
+
```
|
84
|
+
|
85
|
+
You can have a custom enumeration restriction from a custom validator:
|
86
|
+
|
87
|
+
```ruby
|
88
|
+
class MyValidator < ActiveModel::EachValidator
|
89
|
+
def validate_each(record, attribute, value)
|
90
|
+
# ...
|
91
|
+
end
|
92
|
+
|
93
|
+
def xsd_field_enumeration_restrictions
|
94
|
+
["foo", "bar"]
|
95
|
+
end
|
96
|
+
end
|
97
|
+
```
|
98
|
+
|
99
|
+
## Requirements
|
100
|
+
|
101
|
+
- ActiveRecord 4.x
|
102
|
+
|
103
|
+
## License
|
104
|
+
|
105
|
+
Copyright © 2010–2014 Case Commons, LLC.
|
106
|
+
Licensed under the MIT license, available in the “LICENSE” file.
|
data/Rakefile
CHANGED
@@ -1,12 +1,7 @@
|
|
1
|
-
require '
|
2
|
-
require 'rspec/core'
|
1
|
+
require 'bundler/gem_tasks'
|
3
2
|
require 'rspec/core/rake_task'
|
4
3
|
|
5
|
-
|
6
|
-
|
4
|
+
desc 'Run specs'
|
5
|
+
RSpec::Core::RakeTask.new
|
7
6
|
|
8
7
|
task :default => :spec
|
9
|
-
|
10
|
-
desc "Run all specs in spec directory (excluding plugin specs)"
|
11
|
-
RSpec::Core::RakeTask.new(:spec)
|
12
|
-
|
data/lib/schematic.rb
CHANGED
@@ -1,44 +1,5 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
def message
|
4
|
-
"This class does not include ActiveModel::Serializers::Xml. You cannot generate an XSD from it."
|
5
|
-
end
|
6
|
-
end
|
7
|
-
|
8
|
-
class ClassMissingAttributes < Exception
|
9
|
-
def message
|
10
|
-
"This class does not implement #attributes. You cannot generate an XSD from it."
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
module Generator
|
15
|
-
autoload :Sandbox, 'schematic/generator/sandbox'
|
16
|
-
autoload :Xsd, 'schematic/generator/xsd'
|
17
|
-
autoload :Names, 'schematic/generator/names'
|
18
|
-
autoload :Namespaces, 'schematic/generator/namespaces'
|
19
|
-
autoload :Column, 'schematic/generator/column'
|
20
|
-
autoload :ColumnValidator, 'schematic/generator/column_validator'
|
21
|
-
autoload :Types, 'schematic/generator/types'
|
22
|
-
autoload :Uniqueness, 'schematic/generator/uniqueness'
|
23
|
-
|
24
|
-
module Restrictions
|
25
|
-
autoload :Base, 'schematic/generator/restrictions/base'
|
26
|
-
autoload :Custom, 'schematic/generator/restrictions/custom'
|
27
|
-
autoload :Enumeration, 'schematic/generator/restrictions/enumeration'
|
28
|
-
autoload :Length, 'schematic/generator/restrictions/length'
|
29
|
-
autoload :Pattern, 'schematic/generator/restrictions/pattern'
|
30
|
-
autoload :Numericality, 'schematic/generator/restrictions/numericality'
|
31
|
-
end
|
32
|
-
end
|
33
|
-
module Serializers
|
34
|
-
autoload :Xsd, 'schematic/serializers/xsd'
|
35
|
-
end
|
36
|
-
|
37
|
-
autoload :Version, 'schematic/version'
|
38
|
-
end
|
39
|
-
|
40
|
-
require "builder"
|
41
|
-
require 'active_support/inflector/inflections'
|
42
|
-
require 'active_support/inflections'
|
1
|
+
require 'schematic/version'
|
2
|
+
require 'schematic/serializers/xsd'
|
43
3
|
|
4
|
+
require 'active_record/base'
|
44
5
|
ActiveRecord::Base.send(:extend, Schematic::Serializers::Xsd)
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Schematic
|
2
|
+
class ClassMissingXmlSerializer < Exception
|
3
|
+
def message
|
4
|
+
'This class does not include ActiveModel::Serializers::Xml. You cannot generate an XSD from it.'
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
class ClassMissingAttributes < Exception
|
9
|
+
def message
|
10
|
+
'This class does not implement #attributes. You cannot generate an XSD from it.'
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -1,11 +1,17 @@
|
|
1
|
+
require 'active_model/validations/presence'
|
2
|
+
require 'schematic/generator/restrictions/custom'
|
3
|
+
require 'schematic/generator/restrictions/enumeration'
|
4
|
+
require 'schematic/generator/restrictions/length'
|
5
|
+
require 'schematic/generator/restrictions/numericality'
|
6
|
+
require 'schematic/generator/restrictions/pattern'
|
7
|
+
|
1
8
|
module Schematic
|
2
9
|
module Generator
|
3
10
|
class Column
|
4
11
|
attr_accessor :restriction_classes
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
end
|
12
|
+
|
13
|
+
def self.restriction_classes
|
14
|
+
Restrictions::Base.descendants.freeze
|
9
15
|
end
|
10
16
|
|
11
17
|
def initialize(klass, column, additional_methods = {}, ignored_methods = {}, required_methods = [], non_required_methods = [])
|
@@ -21,16 +27,16 @@ module Schematic
|
|
21
27
|
return if skip_generation?
|
22
28
|
|
23
29
|
options = {
|
24
|
-
|
25
|
-
|
26
|
-
|
30
|
+
'name' => @column.name.dasherize,
|
31
|
+
'minOccurs' => minimum_occurrences_for_column.to_s,
|
32
|
+
'maxOccurs' => '1'
|
27
33
|
}
|
28
|
-
options.merge!({
|
34
|
+
options.merge!({'nillable' => 'false'}) if minimum_occurrences_for_column > 0
|
29
35
|
|
30
36
|
builder.xs :element, options do |field|
|
31
37
|
field.xs :complexType do |complex_type|
|
32
38
|
complex_type.xs :simpleContent do |simple_content|
|
33
|
-
simple_content.xs :restriction,
|
39
|
+
simple_content.xs :restriction, 'base' => map_type(@column) do |restriction|
|
34
40
|
self.class.restriction_classes.each do |restriction_class|
|
35
41
|
restriction_class.new(@klass, @column).generate(restriction)
|
36
42
|
end
|
@@ -45,7 +51,7 @@ module Schematic
|
|
45
51
|
return 1 if @required_methods.include?(@column.name.to_sym)
|
46
52
|
return 0 unless @klass.respond_to?(:_validators)
|
47
53
|
@klass._validators[@column.name.to_sym].each do |column_validation|
|
48
|
-
next unless column_validation.is_a?
|
54
|
+
next unless column_validation.is_a? ActiveModel::Validations::PresenceValidator
|
49
55
|
if column_validation.options[:allow_blank] != true &&
|
50
56
|
column_validation.options[:if].nil? &&
|
51
57
|
column_validation.options[:unless].nil?
|
@@ -57,7 +63,7 @@ module Schematic
|
|
57
63
|
end
|
58
64
|
|
59
65
|
def map_type(column)
|
60
|
-
Types::COMPLEX
|
66
|
+
Types::COMPLEX.fetch(column.type)[:complex_type]
|
61
67
|
end
|
62
68
|
|
63
69
|
def skip_generation?
|
@@ -1,13 +1,13 @@
|
|
1
|
+
require 'active_support/descendants_tracker'
|
2
|
+
require 'schematic/generator/column'
|
3
|
+
require 'schematic/generator/column_validator'
|
4
|
+
|
1
5
|
module Schematic
|
2
6
|
module Generator
|
3
7
|
module Restrictions
|
4
8
|
class Base < Schematic::Generator::ColumnValidator
|
5
|
-
|
6
|
-
Schematic::Generator::Column.restriction_classes << klass unless Schematic::Generator::Column.restriction_classes.include?(klass)
|
7
|
-
end
|
9
|
+
extend ActiveSupport::DescendantsTracker
|
8
10
|
end
|
9
11
|
end
|
10
12
|
end
|
11
13
|
end
|
12
|
-
|
13
|
-
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'schematic/generator/restrictions/base'
|
2
|
+
|
1
3
|
module Schematic
|
2
4
|
module Generator
|
3
5
|
module Restrictions
|
@@ -6,7 +8,7 @@ module Schematic
|
|
6
8
|
validators_for_column.each do |validator|
|
7
9
|
if validator.respond_to?(:xsd_pattern_restrictions)
|
8
10
|
validator.xsd_pattern_restrictions.each do |restriction|
|
9
|
-
builder.xs(:pattern,
|
11
|
+
builder.xs(:pattern, 'value' => restriction.is_a?(Regexp) ? restriction.source : restriction)
|
10
12
|
end
|
11
13
|
return
|
12
14
|
end
|
@@ -16,4 +18,3 @@ module Schematic
|
|
16
18
|
end
|
17
19
|
end
|
18
20
|
end
|
19
|
-
|
@@ -1,3 +1,6 @@
|
|
1
|
+
require 'active_model/validations/inclusion'
|
2
|
+
require 'schematic/generator/restrictions/base'
|
3
|
+
|
1
4
|
module Schematic
|
2
5
|
module Generator
|
3
6
|
module Restrictions
|
@@ -11,13 +14,13 @@ module Schematic
|
|
11
14
|
valid_values = validator.options[:in]
|
12
15
|
end
|
13
16
|
valid_values.each do |value|
|
14
|
-
builder.xs(:enumeration,
|
17
|
+
builder.xs(:enumeration, 'value' => value)
|
15
18
|
end
|
16
19
|
end
|
17
20
|
enumeration_method = "xsd_#{column.name}_enumeration_restrictions".to_sym
|
18
21
|
if klass.respond_to? enumeration_method
|
19
22
|
klass.send(enumeration_method).each do |enumeration|
|
20
|
-
builder.xs(:enumeration,
|
23
|
+
builder.xs(:enumeration, 'value' => enumeration)
|
21
24
|
end
|
22
25
|
end
|
23
26
|
end
|
@@ -1,11 +1,13 @@
|
|
1
|
+
require 'schematic/generator/restrictions/base'
|
2
|
+
|
1
3
|
module Schematic
|
2
4
|
module Generator
|
3
5
|
module Restrictions
|
4
6
|
class Length < Base
|
5
7
|
def generate(builder)
|
6
8
|
for_validator ActiveModel::Validations::LengthValidator do |validator|
|
7
|
-
builder.xs(:maxLength,
|
8
|
-
builder.xs(:minLength,
|
9
|
+
builder.xs(:maxLength, 'value' => validator.options[:maximum]) if validator.options[:maximum]
|
10
|
+
builder.xs(:minLength, 'value' => validator.options[:minimum]) if validator.options[:minimum]
|
9
11
|
end
|
10
12
|
end
|
11
13
|
end
|
@@ -1,10 +1,12 @@
|
|
1
|
+
require 'schematic/generator/restrictions/base'
|
2
|
+
|
1
3
|
module Schematic
|
2
4
|
module Generator
|
3
5
|
module Restrictions
|
4
6
|
class Numericality < Base
|
5
7
|
def generate(builder)
|
6
8
|
for_validator ActiveModel::Validations::NumericalityValidator do |validator|
|
7
|
-
builder.xs(:pattern,
|
9
|
+
builder.xs(:pattern, 'value' => '\d+')
|
8
10
|
end
|
9
11
|
end
|
10
12
|
end
|
@@ -1,3 +1,6 @@
|
|
1
|
+
require 'active_model/validations/format'
|
2
|
+
require 'schematic/generator/restrictions/base'
|
3
|
+
|
1
4
|
module Schematic
|
2
5
|
module Generator
|
3
6
|
module Restrictions
|
@@ -10,7 +13,7 @@ module Schematic
|
|
10
13
|
value.gsub!(/(?:\$|\\Z|\\z)?$/, '')
|
11
14
|
value.gsub!(/\\\$/, '$')
|
12
15
|
value.gsub!(/\(\?:/, '(')
|
13
|
-
builder.xs(:pattern,
|
16
|
+
builder.xs(:pattern, 'value' => value)
|
14
17
|
end
|
15
18
|
end
|
16
19
|
end
|
@@ -18,5 +21,3 @@ module Schematic
|
|
18
21
|
end
|
19
22
|
end
|
20
23
|
end
|
21
|
-
|
22
|
-
|