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.
Files changed (49) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +14 -8
  3. data/.travis.yml +17 -0
  4. data/Gemfile +6 -1
  5. data/LICENSE +1 -1
  6. data/README.md +106 -0
  7. data/Rakefile +3 -8
  8. data/lib/schematic.rb +3 -42
  9. data/lib/schematic/exceptions.rb +13 -0
  10. data/lib/schematic/generator/column.rb +17 -11
  11. data/lib/schematic/generator/namespaces.rb +3 -3
  12. data/lib/schematic/generator/restrictions/base.rb +5 -5
  13. data/lib/schematic/generator/restrictions/custom.rb +3 -2
  14. data/lib/schematic/generator/restrictions/enumeration.rb +5 -2
  15. data/lib/schematic/generator/restrictions/length.rb +4 -2
  16. data/lib/schematic/generator/restrictions/numericality.rb +3 -1
  17. data/lib/schematic/generator/restrictions/pattern.rb +4 -3
  18. data/lib/schematic/generator/sandbox.rb +4 -1
  19. data/lib/schematic/generator/types.rb +14 -13
  20. data/lib/schematic/generator/uniqueness.rb +7 -8
  21. data/lib/schematic/generator/xsd.rb +32 -26
  22. data/lib/schematic/serializers/xsd.rb +6 -6
  23. data/lib/schematic/version.rb +1 -1
  24. data/schematic.gemspec +23 -24
  25. data/spec/schematic/generator/restrictions/custom_spec.rb +15 -18
  26. data/spec/schematic/generator/restrictions/enumeration_spec.rb +31 -31
  27. data/spec/schematic/generator/restrictions/length_spec.rb +35 -30
  28. data/spec/schematic/generator/restrictions/mixin_spec.rb +11 -15
  29. data/spec/schematic/generator/restrictions/numericality_spec.rb +11 -11
  30. data/spec/schematic/generator/restrictions/pattern_spec.rb +20 -21
  31. data/spec/schematic/generator/sandbox_spec.rb +17 -17
  32. data/spec/schematic/generator/uniqueness_spec.rb +38 -37
  33. data/spec/schematic/serializers/xsd_extend_spec.rb +11 -11
  34. data/spec/schematic/serializers/xsd_validation_presence_spec.rb +16 -11
  35. data/spec/schematic/serializers/xsd_xsd_ignore_methods_spec.rb +3 -3
  36. data/spec/schematic/serializers/xsd_xsd_methods_spec.rb +27 -24
  37. data/spec/schematic/serializers/xsd_xsd_minimum_occurrences_for_spec.rb +13 -8
  38. data/spec/schematic_serializers_xsd_spec.rb +70 -67
  39. data/spec/spec_helper.rb +8 -113
  40. data/spec/support/database.rb +9 -0
  41. data/spec/support/helpers.rb +111 -0
  42. data/spec/support/with_model.rb +5 -0
  43. data/spec/{xsd → support/xsd}/XMLSchema.xsd +0 -0
  44. data/spec/{xsd → support/xsd}/xml.xsd +0 -0
  45. metadata +54 -69
  46. data/.rspec +0 -1
  47. data/.rvmrc +0 -1
  48. data/README.rdoc +0 -103
  49. 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
- .idea
7
- .vimlog
4
+ .config
5
+ .yardoc
8
6
  Gemfile.lock
9
- doc
10
- pkg/*
11
- tags
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 "http://rubygems.org"
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
@@ -1,4 +1,4 @@
1
- Copyright (c) 2010-11 Case Commons, LLC
1
+ Copyright (c) 2010-2014 Case Commons, LLC
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining a copy
4
4
  of this software and associated documentation files (the "Software"), to deal
data/README.md ADDED
@@ -0,0 +1,106 @@
1
+ # [Schematic](http://github.com/casecommons/schematic/)
2
+
3
+ [![Build Status](https://secure.travis-ci.org/Casecommons/schematic.svg?branch=master)](https://travis-ci.org/Casecommons/schematic)
4
+ [![Code Climate](https://img.shields.io/codeclimate/github/Casecommons/schematic.svg)](https://codeclimate.com/github/Casecommons/schematic)
5
+ [![Gem Version](https://badge.fury.io/rb/schematic.svg)](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 'rake'
2
- require 'rspec/core'
1
+ require 'bundler/gem_tasks'
3
2
  require 'rspec/core/rake_task'
4
3
 
5
- require 'bundler'
6
- Bundler::GemHelper.install_tasks
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
- 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
-
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
- class << self
6
- def restriction_classes
7
- @restriction_classes ||= [Restrictions::Length, Restrictions::Enumeration, Restrictions::Numericality, Restrictions::Pattern, Restrictions::Custom]
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
- "name" => @column.name.dasherize,
25
- "minOccurs" => minimum_occurrences_for_column.to_s,
26
- "maxOccurs" => "1"
30
+ 'name' => @column.name.dasherize,
31
+ 'minOccurs' => minimum_occurrences_for_column.to_s,
32
+ 'maxOccurs' => '1'
27
33
  }
28
- options.merge!({"nillable" => "false"}) if minimum_occurrences_for_column > 0
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, "base" => map_type(@column) do |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? ActiveModel::Validations::PresenceValidator
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[column.type][:complex_type]
66
+ Types::COMPLEX.fetch(column.type)[:complex_type]
61
67
  end
62
68
 
63
69
  def skip_generation?
@@ -3,9 +3,9 @@ module Schematic
3
3
  class Namespaces
4
4
  PROVIDERS = {
5
5
  :w3 => {
6
- :schema => "http://www.w3.org/2001/XMLSchema"
7
- }
8
- }
6
+ :schema => 'http://www.w3.org/2001/XMLSchema'.freeze
7
+ }.freeze
8
+ }.freeze
9
9
  end
10
10
  end
11
11
  end
@@ -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
- def self.inherited(klass)
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, "value" => restriction.is_a?(Regexp) ? restriction.source : restriction)
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, "value" => value)
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, "value" => 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, "value" => validator.options[:maximum]) if validator.options[:maximum]
8
- builder.xs(:minLength, "value" => validator.options[:minimum]) if validator.options[:minimum]
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, "value" => "\\d+")
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, "value" => value)
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
-