scriba 0.0.1.alpha1

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 9a528ea559e6201610d1acf1c5089f8bd283aa0e
4
+ data.tar.gz: 292212ef584125ff89a62ad102b6234ec1662d2c
5
+ SHA512:
6
+ metadata.gz: 91d0bdad1416952999202d06d0473f04c2f89cb426c7c3bc5a54f6c31aed2130bf2c2ae21faa0649fa7c7a418b9531251f3d30c4e6e7a5c9f485856e9fba4e5b
7
+ data.tar.gz: b6556347da194c438ce0077533c6bf2289c33aa5cc5b4ec7c942f897c37ec820af5e1f917e43b1afe323fc573ba2208b20d56ad2b14350b74cf96bc87eca164c
data/.gems ADDED
@@ -0,0 +1 @@
1
+ cutest -v 1.2.2
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011-2015 Michel Martens
2
+ Copyright (c) 2011-2015 Francesco Rodríguez
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ of this software and associated documentation files (the "Software"), to deal
6
+ in the Software without restriction, including without limitation the rights
7
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the Software is
9
+ furnished to do so, subject to the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be included in
12
+ all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,2 @@
1
+ scriba
2
+ ======
@@ -0,0 +1,56 @@
1
+ module Scriba::Assertions
2
+ protected
3
+
4
+ EMAIL = /\A([\w\!\#$\%\&\'\*\+\-\/\=\?\^\end\|\}\~]+\.)*
5
+ [\w\!\#$\%\&\'\*\+\-\/\=\?\^\end\|\}\~]+@
6
+ ((((([a-z0-9]{1}[a-z0-9\-]{0,62}[a-z0-9]{1})|[a-z])\.)+
7
+ [a-z]{2,12})|(\d{1,3}\.){3}\d{1,3}(\:\d{1,5})?)\z/ix
8
+
9
+ def assert_email(att, message = :not_email)
10
+ assert_format(att, EMAIL, message: message)
11
+ end
12
+
13
+ def assert_equal(att, value, message = :not_equal)
14
+ assert(value === send(att), att, message: message)
15
+ end
16
+
17
+ def assert_format(att, format, message = :not_valid)
18
+ assert(format === send(att).to_s, att, message: message)
19
+ end
20
+
21
+ def assert_length(att, length, message = :wrong_length)
22
+ assert(send(att).to_s.length == length, att, message: message, length: length)
23
+ end
24
+
25
+ def assert_maximum_length(att, length, message = :too_long)
26
+ assert(send(att).to_s.length <= length, att, message: message, length: length)
27
+ end
28
+
29
+ def assert_minimum_length(att, length, message = :too_short)
30
+ assert(send(att).to_s.length >= length, att, message: message, length: length)
31
+ end
32
+
33
+ BLANK = /\A[[:space:]]*\z/
34
+
35
+ def assert_present(att, message = :not_present)
36
+ assert(!(BLANK === send(att).to_s), att, message: message)
37
+ end
38
+
39
+ URL = /\A(http|https):\/\/([a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,12}|(2
40
+ 5[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}
41
+ |localhost)(:[0-9]{1,5})?(\/.*)?\z/ix
42
+
43
+ def assert_url(att, message = :not_url)
44
+ assert_format(att, URL, message: message)
45
+ end
46
+
47
+ private
48
+
49
+ def assert(value, att, options = {})
50
+ value or add_error(att, options) && false
51
+ end
52
+
53
+ def add_error(att, options)
54
+ @errors[att] << generate_message(options)
55
+ end
56
+ end
@@ -0,0 +1,25 @@
1
+ module Scriba::Messages
2
+ DEFAULTS = {
3
+ not_email: "must be a valid email",
4
+ not_equal: "doesn't match",
5
+ not_present: "is required",
6
+ not_unique: "is already taken",
7
+ not_url: "is an invalid URL",
8
+ not_valid: "is invalid",
9
+ too_long: "must be maximum %{length} characters",
10
+ too_short: "must be minimum %{length} characters",
11
+ wrong_length: "must be %{length} characters"
12
+ }
13
+
14
+ private
15
+
16
+ def generate_message(options)
17
+ message = options.delete(:message) || :not_valid
18
+
19
+ if message.is_a?(Symbol)
20
+ return sprintf(DEFAULTS[message], options)
21
+ else
22
+ return message
23
+ end
24
+ end
25
+ end
data/lib/scriba.rb ADDED
@@ -0,0 +1,57 @@
1
+ class Scriba
2
+ require_relative "scriba/assertions"
3
+ require_relative "scriba/messages"
4
+
5
+ include Scriba::Assertions
6
+ include Scriba::Messages
7
+
8
+ def self.inherited(subclass)
9
+ subclass.attribute(*attributes)
10
+ end
11
+
12
+ def self.attribute(*atts)
13
+ attributes.replace(attributes | atts)
14
+ attr_accessor(*atts)
15
+ end
16
+
17
+ def self.attributes
18
+ @attributes ||= []
19
+ end
20
+
21
+ attr :errors
22
+
23
+ def initialize(atts = {})
24
+ atts.each do |att, value|
25
+ accessor = "#{att}="
26
+
27
+ if respond_to?(accessor)
28
+ send(accessor, value)
29
+ end
30
+ end
31
+
32
+ @errors = Hash.new { |hash, key| hash[key] = [] }
33
+ end
34
+
35
+ def attributes
36
+ return slice(*self.class.attributes)
37
+ end
38
+
39
+ def slice(*atts)
40
+ return atts.each_with_object({}) { |att, hash| hash[att] = send(att) }
41
+ end
42
+
43
+ def valid?
44
+ @errors.clear
45
+
46
+ validate
47
+
48
+ return @errors.empty?
49
+ end
50
+
51
+ def invalid?
52
+ return !valid?
53
+ end
54
+
55
+ def validate
56
+ end
57
+ end
data/makefile ADDED
@@ -0,0 +1,7 @@
1
+ .PHONY: test
2
+
3
+ gem:
4
+ gem build *.gemspec
5
+
6
+ test:
7
+ cutest test/*.rb
data/scriba.gemspec ADDED
@@ -0,0 +1,14 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = "scriba"
3
+ s.version = "0.0.1.alpha1"
4
+ s.summary = "Validation frontend for models."
5
+ s.description = s.summary + " Inspired by the scrivener gem."
6
+ s.authors = ["Francesco Rodríguez"]
7
+ s.email = ["frodsan@me.com"]
8
+ s.homepage = "https://github.com/harmoni/scriba"
9
+ s.license = "MIT"
10
+
11
+ s.files = `git ls-files`.split("\n")
12
+
13
+ s.add_development_dependency "cutest", "~> 1.2"
14
+ end
@@ -0,0 +1,162 @@
1
+ require_relative "helper"
2
+
3
+ test "email assertion" do
4
+ class A < Scriba
5
+ attribute :email
6
+
7
+ def validate
8
+ assert_email :email
9
+ end
10
+ end
11
+
12
+ filter = A.new(email: "wrong@email")
13
+
14
+ assert !filter.valid?
15
+ assert filter.errors.key?(:email)
16
+
17
+ filter.email = "me@me.com"
18
+
19
+ assert filter.valid?
20
+ assert filter.errors.empty?
21
+ end
22
+
23
+ test "equal assertion" do
24
+ class A < Scriba
25
+ attribute :password
26
+ attribute :password_confirmation
27
+
28
+ def validate
29
+ assert_equal :password, password_confirmation
30
+ end
31
+ end
32
+
33
+ filter = A.new(password: "123", password_confirmation: "1234")
34
+
35
+ assert !filter.valid?
36
+ assert filter.errors.key?(:password)
37
+
38
+ filter.password_confirmation = "123"
39
+
40
+ assert filter.valid?
41
+ assert filter.errors.empty?
42
+ end
43
+
44
+ test "format assertion" do
45
+ class A < Scriba
46
+ attribute :name
47
+
48
+ def validate
49
+ assert_format :name, /\A[a-zA-Z\d\s]*\z/
50
+ end
51
+ end
52
+
53
+ filter = A.new(name: "wr/ngname")
54
+
55
+ assert !filter.valid?
56
+ assert filter.errors.key?(:name)
57
+
58
+ filter.name = "mememe"
59
+
60
+ assert filter.valid?
61
+ assert filter.errors.empty?
62
+ end
63
+
64
+ test "exact length assertion" do
65
+ class A < Scriba
66
+ attribute :id
67
+
68
+ def validate
69
+ assert_length :id, 8
70
+ end
71
+ end
72
+
73
+ filter = A.new(id: "")
74
+
75
+ assert !filter.valid?
76
+ assert filter.errors.key?(:id)
77
+
78
+ filter.id = "12345678"
79
+
80
+ assert filter.valid?
81
+ assert filter.errors.empty?
82
+ end
83
+
84
+ test "maximum length assertion" do
85
+ class A < Scriba
86
+ attribute :name
87
+
88
+ def validate
89
+ assert_maximum_length :name, 1
90
+ end
91
+ end
92
+
93
+ filter = A.new(name: "12")
94
+
95
+ assert !filter.valid?
96
+ assert filter.errors.key?(:name)
97
+
98
+ filter.name = "1"
99
+
100
+ assert filter.valid?
101
+ assert filter.errors.empty?
102
+ end
103
+
104
+ test "minimum length assertion" do
105
+ class A < Scriba
106
+ attribute :name
107
+
108
+ def validate
109
+ assert_minimum_length :name, 1
110
+ end
111
+ end
112
+
113
+ filter = A.new(name: "")
114
+
115
+ assert !filter.valid?
116
+ assert filter.errors.key?(:name)
117
+
118
+ filter.name = "mememe"
119
+
120
+ assert filter.valid?
121
+ assert filter.errors.empty?
122
+ end
123
+
124
+ test "presence assertion" do
125
+ class A < Scriba
126
+ attribute :name
127
+
128
+ def validate
129
+ assert_present :name
130
+ end
131
+ end
132
+
133
+ filter = A.new(name: " \r \t \n ")
134
+
135
+ assert !filter.valid?
136
+ assert filter.errors.key?(:name)
137
+
138
+ filter.name = "mememe"
139
+
140
+ assert filter.valid?
141
+ assert filter.errors.empty?
142
+ end
143
+
144
+ test "url assertion" do
145
+ class A < Scriba
146
+ attribute :url
147
+
148
+ def validate
149
+ assert_url :url
150
+ end
151
+ end
152
+
153
+ filter = A.new(url: "masds.@me.com")
154
+
155
+ assert !filter.valid?
156
+ assert filter.errors.key?(:url)
157
+
158
+ filter.url = "http://harmoni.io"
159
+
160
+ assert filter.valid?
161
+ assert filter.errors.empty?
162
+ end
@@ -0,0 +1,37 @@
1
+ require_relative "helper"
2
+
3
+ class Signup < Scriba
4
+ attribute :username
5
+ attribute :password
6
+ end
7
+
8
+ test "return defined attributes" do
9
+ attrs = { username: "me", password: "100%sexy" }
10
+ signup = Signup.new(attrs)
11
+
12
+ assert_equal attrs, signup.attributes
13
+ end
14
+
15
+ test "ignore extra fields" do
16
+ signup = Signup.new(username: "me", not_exists: 1)
17
+
18
+ assert signup.attributes.key?(:username)
19
+ assert !signup.attributes.key?(:not_exists)
20
+ end
21
+
22
+ test "filter required attributes" do
23
+ signup = Signup.new(username: "me", password: "123456")
24
+ attrs = signup.slice(:username)
25
+
26
+ assert [:username] == attrs.keys
27
+ end
28
+
29
+ test "attributes are inheritable" do
30
+ class SpecialSignup < Signup
31
+ attribute :referral
32
+ end
33
+
34
+ attrs = Signup.attributes + [:referral]
35
+
36
+ assert_equal attrs, SpecialSignup.attributes
37
+ end
data/test/helper.rb ADDED
@@ -0,0 +1 @@
1
+ require_relative "../lib/scriba"
metadata ADDED
@@ -0,0 +1,69 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: scriba
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1.alpha1
5
+ platform: ruby
6
+ authors:
7
+ - Francesco Rodríguez
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-04-30 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: cutest
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.2'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.2'
27
+ description: Validation frontend for models. Inspired by the scrivener gem.
28
+ email:
29
+ - frodsan@me.com
30
+ executables: []
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - ".gems"
35
+ - LICENSE
36
+ - README.md
37
+ - lib/scriba.rb
38
+ - lib/scriba/assertions.rb
39
+ - lib/scriba/messages.rb
40
+ - makefile
41
+ - scriba.gemspec
42
+ - test/assertions.rb
43
+ - test/attributes.rb
44
+ - test/helper.rb
45
+ homepage: https://github.com/harmoni/scriba
46
+ licenses:
47
+ - MIT
48
+ metadata: {}
49
+ post_install_message:
50
+ rdoc_options: []
51
+ require_paths:
52
+ - lib
53
+ required_ruby_version: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: '0'
58
+ required_rubygems_version: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">"
61
+ - !ruby/object:Gem::Version
62
+ version: 1.3.1
63
+ requirements: []
64
+ rubyforge_project:
65
+ rubygems_version: 2.4.5
66
+ signing_key:
67
+ specification_version: 4
68
+ summary: Validation frontend for models.
69
+ test_files: []