chatty_error 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 1ee6c167ded044fc0f026fbb193fb7a3e1766c7f
4
+ data.tar.gz: fe0e92dd3fc3ff62aa9739865309fd55c966c7d3
5
+ SHA512:
6
+ metadata.gz: 8f43c037fc81a0802b62cb0b3c9a86504850f24c56e669c313a48961c10a0458e315564070464938ba2dafc963e0a1fc9ff72a0ac4a6da1da5cae4d5363148f4
7
+ data.tar.gz: a977da3e3455b0099490a412e87bb2cb60d86344509743090e7d308924e54f9770f85f9d941fdb0c825203115bd770226bbde42871cd6faa051af58a6c94e74c
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
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/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in chatty_error.gemspec
4
+ gemspec
@@ -0,0 +1,31 @@
1
+ Copyright (c) 2013, Synergy Marketing, Inc.
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without
5
+ modification, are permitted provided that the following conditions
6
+ are met:
7
+
8
+ Redistributions of source code must retain the above copyright notice,
9
+ this list of conditions and the following disclaimer.
10
+
11
+ Redistributions in binary form must reproduce the above copyright
12
+ notice, this list of conditions and the following disclaimer in the
13
+ documentation and/or other materials provided with the distribution.
14
+
15
+ Neither the name of the Synergy Marketing, Inc. nor the names of its
16
+ contributors may be used to endorse or promote products derived from
17
+ this software without specific prior written permission.
18
+
19
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23
+ COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
24
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
25
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
26
+ OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
27
+ AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
29
+ THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
30
+ DAMAGE.
31
+
@@ -0,0 +1,68 @@
1
+ # ChattyError
2
+
3
+ 'chatty_error' helps you create error with message easily. An error message is loaded from i18n locale file.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'chatty_error'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install chatty_error
18
+
19
+ ## Examples
20
+
21
+ my_error.rb
22
+
23
+ class MyError < StandardError
24
+ include ChattyError
25
+
26
+ caused_by :file_not_found, :user_disabled
27
+ end
28
+
29
+ en.yml
30
+
31
+ en:
32
+ chatty_errors:
33
+ my_error:
34
+ file_not_found: "File not found!!!"
35
+ user_disabled: "User disabled!!!"
36
+
37
+ model.rb
38
+
39
+ class Model
40
+ def exist?(file_path)
41
+ unless File.exist?(file_path)
42
+ raise MyError.file_not_found
43
+ end
44
+
45
+ # some code ...
46
+
47
+ rescue MyError => e
48
+ puts e.message # => File not found!!! (autoload from en.yml)
49
+ end
50
+
51
+ def authenticate(user)
52
+ if user.disabled?
53
+ raise MyError.user_disabled
54
+ end
55
+
56
+ # some code ...
57
+ rescue MyError => e
58
+ puts e.message # => User disabled!!! (autoload from en.yml)
59
+ end
60
+ end
61
+
62
+ ## Contributing
63
+
64
+ 1. Fork it
65
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
66
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
67
+ 4. Push to the branch (`git push origin my-new-feature`)
68
+ 5. Create new Pull Request
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,27 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'chatty_error/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "chatty_error"
8
+ spec.version = ChattyError::VERSION
9
+ spec.authors = ["Kentaro Kawano"]
10
+ spec.email = ["info@techscore.com"]
11
+ spec.description = %q{'chatty_error' helps you create error with message easily. An error message is loaded from i18n locale file.}
12
+ spec.summary = %q{'chatty_error' helps you create error with message easily.}
13
+ spec.homepage = "https://github.com/techscore/chatty_error"
14
+ spec.license = "The BSD 3-Clause License"
15
+
16
+ spec.required_ruby_version = '>= 1.9.3'
17
+
18
+ spec.files = `git ls-files`.split($/)
19
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
20
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
21
+ spec.require_paths = ["lib"]
22
+
23
+ spec.add_development_dependency "bundler", "~> 1.3"
24
+ spec.add_development_dependency "rake"
25
+ spec.add_development_dependency "i18n"
26
+ spec.add_development_dependency "rspec"
27
+ end
@@ -0,0 +1,75 @@
1
+ require "chatty_error/version"
2
+ require "chatty_error/configuration"
3
+ require "i18n"
4
+
5
+ module ChattyError
6
+ def cause
7
+ @cause
8
+ end
9
+
10
+ def cause=(cause)
11
+ @cause = cause
12
+ end
13
+
14
+ def options
15
+ @options
16
+ end
17
+
18
+ def options=(options)
19
+ @options = options
20
+ end
21
+
22
+ module ClassMethods
23
+ def configuration
24
+ if @configuration.nil? && self.superclass.methods.include?(:configuration)
25
+ @configuration = self.superclass.configuration.clone
26
+ else
27
+ @configuration ||= Configuration.new
28
+ end
29
+ end
30
+
31
+ def configuration=(conf)
32
+ @configuration = conf
33
+ end
34
+
35
+ def configure
36
+ yield configuration if block_given?
37
+ end
38
+
39
+ def underscore(string)
40
+ string.gsub(/::/, '.') \
41
+ .gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2') \
42
+ .gsub(/([a-z\d])([A-Z])/,'\1_\2') \
43
+ .tr("-", "_").downcase
44
+ end
45
+
46
+ def generate_key(class_name, method_name)
47
+ [underscore(class_name), method_name.to_s.downcase].join('.')
48
+ end
49
+
50
+ def error_message(name, method_name, options={})
51
+ key = generate_key(name, method_name)
52
+ I18n.t(key,
53
+ :scope => configuration.default_scope,
54
+ :default => [:default, configuration.default_message],
55
+ :locale => options[:locale])
56
+ end
57
+
58
+ def caused_by(*args)
59
+ args.each do |method_name|
60
+ class_name = self.name
61
+ define_singleton_method method_name do |options={}|
62
+ message = self.error_message(class_name, method_name, options)
63
+ e = self.new(message)
64
+ e.cause = method_name
65
+ e.options = options
66
+ return e
67
+ end
68
+ end
69
+ end
70
+ end
71
+
72
+ def self.included(klass)
73
+ klass.extend ChattyError::ClassMethods
74
+ end
75
+ end
@@ -0,0 +1,14 @@
1
+ # coding: utf-8
2
+
3
+ module ChattyError
4
+
5
+ class Configuration
6
+ attr_accessor :default_scope, :default_message
7
+
8
+ def initialize
9
+ @default_scope = 'chatty_errors'
10
+ @default_message = ''
11
+ end
12
+ end
13
+
14
+ end
@@ -0,0 +1,3 @@
1
+ module ChattyError
2
+ VERSION = "1.0.0"
3
+ end
@@ -0,0 +1,139 @@
1
+ # coding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe ChattyError do
6
+ describe '#included' do
7
+ context 'methods defined' do
8
+ it { expect(FooError.methods.include?(:configuration)).to be true }
9
+ it { expect(FooError.methods.include?(:configuration=)).to be true }
10
+ it { expect(FooError.methods.include?(:configure)).to be true }
11
+ it { expect(FooError.methods.include?(:generate_key)).to be true }
12
+ it { expect(FooError.methods.include?(:error_message)).to be true }
13
+ it { expect(FooError.methods.include?(:caused_by)).to be true }
14
+ it { expect(FooError.new.methods.include?(:cause)).to be true }
15
+ it { expect(FooError.new.methods.include?(:cause=)).to be true }
16
+ it { expect(FooError.new.methods.include?(:options)).to be true }
17
+ it { expect(FooError.new.methods.include?(:options=)).to be true }
18
+ end
19
+ end
20
+
21
+ describe '#configure' do
22
+ context 'return nil unless block_given' do
23
+ it { expect(BarError.configure).to be nil}
24
+ end
25
+
26
+ context 'configure default scope' do
27
+ it { expect(BarError.configuration.default_scope).to eq :other_scope }
28
+ end
29
+
30
+ context 'configure default message' do
31
+ it { expect(BarError.configuration.default_message).to eq "error" }
32
+ end
33
+ end
34
+
35
+ describe '#configuration' do
36
+ context 'inherit from parent' do
37
+ it { expect(FooFooError.configuration.default_scope).to eq "fooooo" }
38
+ it { expect(FooFooError.configuration.default_message).to eq "foo error" }
39
+ end
40
+
41
+ context 'configure' do
42
+ it { expect(FooError.configuration.default_scope).to eq "fooooo" }
43
+ it { expect(FooError.configuration.default_message).to eq "foo error" }
44
+ it { expect(Foo2Error.configuration.default_scope).to eq "foo2" }
45
+ it { expect(Foo2Error.configuration.default_message).to eq "foo2 error" }
46
+ end
47
+ end
48
+
49
+ describe '#undercase' do
50
+ it { expect(BazError.underscore('A')).to eq 'a' }
51
+ it { expect(BazError.underscore('Abc')).to eq 'abc' }
52
+ it { expect(BazError.underscore('AbcD')).to eq 'abc_d' }
53
+ it { expect(BazError.underscore('AbcDef')).to eq 'abc_def' }
54
+ it { expect(BazError.underscore('ABCD')).to eq 'abcd' }
55
+ it { expect(BazError.underscore('ABcDe')).to eq 'a_bc_de' }
56
+ it { expect(BazError.underscore('A::BCD')).to eq 'a.bcd' }
57
+ it { expect(BazError.underscore('A::B::CD')).to eq 'a.b.cd' }
58
+ it { expect(BazError.underscore('A::B::C::D')).to eq 'a.b.c.d' }
59
+ it { expect(BazError.underscore('AAA::BBB::CCC::DDD')).to eq 'aaa.bbb.ccc.ddd' }
60
+ it { expect(BazError.underscore('AaaBbb::CccDdd')).to eq 'aaa_bbb.ccc_ddd' }
61
+ end
62
+
63
+ describe '#generate_key' do
64
+ it { expect(FooError.generate_key(FooError.name, :foo)).to eq 'foo_error.foo' }
65
+ it { expect(BarError.generate_key(BarError.name, :bar)).to eq 'bar_error.bar' }
66
+ it { expect(Boo::Error.generate_key(Boo::Error.name, :boo)).to eq 'boo.error.boo' }
67
+ it { expect(Boo::Foo::Error.generate_key(Boo::Foo::Error.name, :boofoo)).to eq 'boo.foo.error.boofoo' }
68
+ it { expect(Boo::Foo::Woo::Error.generate_key(Boo::Foo::Woo::Error.name, :boofoo_woo)).to eq 'boo.foo.woo.error.boofoo_woo' }
69
+ it { expect(Boo::Foo::Woo::Error2.generate_key(Boo::Foo::Woo::Error2.name, :boofoo_woo)).to eq 'boo.foo.woo.error2.boofoo_woo' }
70
+ end
71
+
72
+ describe '#error_message' do
73
+ context 'default configuration' do
74
+ let (:default_error_message) { I18n.t('chatty_errors.default') }
75
+ it { expect(HogeError.error_message(HogeError.name, :base)).to eq default_error_message }
76
+ it { expect(HogeError.error_message(HogeError.name, :hoge1)).to eq default_error_message }
77
+ it { expect(HogeError.error_message(HogeError.name, :hoge2)).to eq default_error_message }
78
+ end
79
+
80
+ context 'specific configuration' do
81
+ context 'in yml' do
82
+ it { expect(BaseError.error_message(BaseError.name, :base)).to eq I18n.t('chatty_errors.base_error.base') }
83
+ it { expect(PiyoError.error_message(PiyoError.name, :piyopiyo)).to eq I18n.t('my_errors.piyo_error.piyopiyo') }
84
+
85
+ end
86
+
87
+ context 'not in yml' do
88
+ it { expect(PiyoError.error_message(PiyoError.name, :piyopiyo2)).to eq 'p_error' }
89
+ end
90
+ end
91
+ end
92
+
93
+ describe '#caused_by' do
94
+ context 'defined method' do
95
+ it { expect(BaseError.methods.include?(:base)).to be true }
96
+ it { expect(HogeError.methods.include?(:base)).to be true }
97
+ it { expect(HogeError.methods.include?(:hoge1)).to be true }
98
+ it { expect(HogeError.methods.include?(:hoge2)).to be true }
99
+ it { expect(PiyoError.methods.include?(:piyopiyo)).to be true }
100
+ end
101
+
102
+ context 'initialize self instance' do
103
+ it { expect(HogeError.base).to be_an_instance_of HogeError }
104
+ it { expect(HogeError.hoge1).to be_an_instance_of HogeError }
105
+ it { expect(HogeError.hoge2).to be_an_instance_of HogeError }
106
+
107
+ it { expect(PiyoError.piyopiyo).to be_an_instance_of PiyoError }
108
+ end
109
+
110
+ context 'raise error' do
111
+ it { expect{raise HogeError.base}.to raise_error(HogeError) }
112
+ it { expect{raise HogeError.hoge1}.to raise_error(HogeError) }
113
+ it { expect{raise HogeError.hoge2}.to raise_error(HogeError) }
114
+ it { expect{raise PiyoError.piyopiyo}.to raise_error(PiyoError) }
115
+ end
116
+
117
+ context 'error message' do
118
+ it { expect(BaseError.base.message).to eq I18n.t('chatty_errors.base_error.base') }
119
+ it { expect(HogeError.base.message).to eq I18n.t('chatty_errors.base_error.base') }
120
+ it { expect(HogeError.hoge1.message).to eq I18n.t('chatty_errors.default') }
121
+ it { expect(HogeError.hoge2.message).to eq I18n.t('chatty_errors.default') }
122
+ it { expect(HogeHogeError.base.message).to eq I18n.t('chatty_errors.hoge_hoge_error.base') }
123
+ it { expect(HogeHogeError.hoge1.message).to eq I18n.t('chatty_errors.default') }
124
+ it { expect(HogeHogeError.hoge2.message).to eq I18n.t('chatty_errors.default') }
125
+ it { expect(PiyoError.base.message).to eq I18n.t('my_errors.base_error.base') }
126
+ it { expect(PiyoError.piyopiyo.message).to eq I18n.t('my_errors.piyo_error.piyopiyo') }
127
+ it { expect(PiyoPiyoError.base.message).to eq I18n.t('my_errors.piyo_piyo_error.base') }
128
+ it { expect(PiyoPiyoError.piyopiyo.message).to eq I18n.t('my_errors.piyo_error.piyopiyo') }
129
+ it { expect(PiyoPiyoError.piyoooo.message).to eq I18n.t('my_errors.piyo_piyo_error.piyoooo') }
130
+ it { expect(PiyoPiyoError.piyoooo(:locale => :en).message).to eq \
131
+ I18n.t('my_errors.piyo_piyo_error.piyoooo', :locale => :en) }
132
+ end
133
+
134
+ context 'cause' do
135
+ it { expect(BaseError.base.cause).to eq :base }
136
+ it { expect(HogeError.hoge1.cause).to eq :hoge1 }
137
+ end
138
+ end
139
+ end
@@ -0,0 +1,5 @@
1
+ en:
2
+ my_errors:
3
+ piyo_piyo_error:
4
+ piyoooo: "error: piyoooo"
5
+
@@ -0,0 +1,17 @@
1
+ ja:
2
+ chatty_errors:
3
+ default: "エラーが発生しました"
4
+ base_error:
5
+ base: "エラー: base(base_error)"
6
+ hoge_hoge_error:
7
+ base: "エラー: base(hoge_hoge_error)"
8
+ my_errors:
9
+ base_error:
10
+ base: "エラー: base(piyo_error)"
11
+ hoge_error:
12
+ hoge1: "エラー: hoge1"
13
+ piyo_error:
14
+ piyopiyo: "エラー: piyopiyo"
15
+ piyo_piyo_error:
16
+ base: "エラー: base(piyo_piyo_error)"
17
+ piyoooo: "error: piyoooo"
@@ -0,0 +1,14 @@
1
+ require 'chatty_error'
2
+
3
+ Dir["#{File.dirname(__FILE__)}/support/*.rb"].each {|f| require f}
4
+
5
+ RSpec.configure do |config|
6
+ config.treat_symbols_as_metadata_keys_with_true_values = true
7
+ config.run_all_when_everything_filtered = true
8
+ config.filter_run :focus
9
+
10
+ config.order = 'random'
11
+ end
12
+
13
+ I18n.default_locale = :ja
14
+ I18n.load_path = Dir["#{File.dirname(__FILE__)}/locales/*.yml"]
@@ -0,0 +1,80 @@
1
+ # coding: utf-8
2
+
3
+ class FooError < StandardError
4
+ include ChattyError
5
+
6
+ configure do |c|
7
+ c.default_scope = 'fooooo'
8
+ c.default_message = 'foo error'
9
+ end
10
+ end
11
+
12
+ class FooFooError < FooError
13
+ end
14
+
15
+ class Foo2Error < FooError
16
+ configure do |c|
17
+ c.default_scope = 'foo2'
18
+ c.default_message = 'foo2 error'
19
+ end
20
+ end
21
+
22
+ class BarError < StandardError
23
+ include ChattyError
24
+
25
+ configure do |c|
26
+ c.default_scope = :other_scope
27
+ c.default_message = "error"
28
+ end
29
+ end
30
+
31
+ class BazError < StandardError
32
+ include ChattyError
33
+ end
34
+
35
+ module Boo
36
+ class Error < StandardError
37
+ include ChattyError
38
+ end
39
+
40
+ module Foo
41
+ class Error < StandardError
42
+ include ChattyError
43
+ end
44
+
45
+ module Woo
46
+ class Error < StandardError
47
+ include ChattyError
48
+ end
49
+
50
+ class Error2 < Error
51
+ end
52
+ end
53
+ end
54
+ end
55
+
56
+ class BaseError < StandardError
57
+ include ChattyError
58
+ caused_by :base
59
+ end
60
+
61
+ class HogeError < BaseError
62
+ caused_by :hoge1, :hoge2
63
+ end
64
+
65
+ class HogeHogeError < HogeError
66
+ caused_by :base
67
+ end
68
+
69
+ class PiyoError < BaseError
70
+ caused_by :piyopiyo
71
+
72
+ configure do |c|
73
+ c.default_scope = 'my_errors'
74
+ c.default_message = 'p_error'
75
+ end
76
+ end
77
+
78
+ class PiyoPiyoError < PiyoError
79
+ caused_by :base, :piyoooo
80
+ end
metadata ADDED
@@ -0,0 +1,120 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: chatty_error
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Kentaro Kawano
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-09-12 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: i18n
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description: '''chatty_error'' helps you create error with message easily. An error
70
+ message is loaded from i18n locale file.'
71
+ email:
72
+ - info@techscore.com
73
+ executables: []
74
+ extensions: []
75
+ extra_rdoc_files: []
76
+ files:
77
+ - .gitignore
78
+ - Gemfile
79
+ - LICENSE.txt
80
+ - README.md
81
+ - Rakefile
82
+ - chatty_error.gemspec
83
+ - lib/chatty_error.rb
84
+ - lib/chatty_error/configuration.rb
85
+ - lib/chatty_error/version.rb
86
+ - spec/chatty_error_spec.rb
87
+ - spec/locales/en.yml
88
+ - spec/locales/ja.yml
89
+ - spec/spec_helper.rb
90
+ - spec/support/models.rb
91
+ homepage: https://github.com/techscore/chatty_error
92
+ licenses:
93
+ - The BSD 3-Clause License
94
+ metadata: {}
95
+ post_install_message:
96
+ rdoc_options: []
97
+ require_paths:
98
+ - lib
99
+ required_ruby_version: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - '>='
102
+ - !ruby/object:Gem::Version
103
+ version: 1.9.3
104
+ required_rubygems_version: !ruby/object:Gem::Requirement
105
+ requirements:
106
+ - - '>='
107
+ - !ruby/object:Gem::Version
108
+ version: '0'
109
+ requirements: []
110
+ rubyforge_project:
111
+ rubygems_version: 2.0.3
112
+ signing_key:
113
+ specification_version: 4
114
+ summary: '''chatty_error'' helps you create error with message easily.'
115
+ test_files:
116
+ - spec/chatty_error_spec.rb
117
+ - spec/locales/en.yml
118
+ - spec/locales/ja.yml
119
+ - spec/spec_helper.rb
120
+ - spec/support/models.rb