model_concerns 0.0.9

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: a1862580cec74081ffda120d2e41f56fb0d4c618
4
+ data.tar.gz: 87828e6ae763df4f7abd600dbd9a13c386a76566
5
+ SHA512:
6
+ metadata.gz: 2e641e747b90c5e40797a9c42c3bd92153b5c93e3a0841d0ef33a942161c8dd3db8e4fb17f2755da6b23f5f9659bec49939cf48e957cf7dd1dfaf131a80f5fef
7
+ data.tar.gz: bf0e701ffbf30911703858de84452ed146088ed27e7ab86aa5c55d0897edca1f5a03ac176619f484ba680a78e4650d7a90a0349ca8696be95ebfe451e38416b8
@@ -0,0 +1,49 @@
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
18
+ /.config
19
+ /coverage/
20
+ /InstalledFiles
21
+ /pkg/
22
+ /spec/reports/
23
+ /test/tmp/
24
+ /test/version_tmp/
25
+ /tmp/
26
+
27
+ ## Specific to RubyMotion:
28
+ .dat*
29
+ .repl_history
30
+ build/
31
+
32
+ ## Documentation cache and generated files:
33
+ /.yardoc/
34
+ /_yardoc/
35
+ /doc/
36
+ /rdoc/
37
+
38
+ ## Environment normalisation:
39
+ /.bundle/
40
+ /lib/bundler/man/
41
+
42
+ # for a library or gem, you might want to ignore these files since the code is
43
+ # intended to run in multiple environments; otherwise, check them in:
44
+ # Gemfile.lock
45
+ # .ruby-version
46
+ # .ruby-gemset
47
+
48
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
49
+ .rvmrc
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --require spec_helper
@@ -0,0 +1,3 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.0.0
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in model_concerns.gemspec
4
+ gemspec
@@ -0,0 +1,24 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ guard :rspec do
5
+ watch(%r{^spec/.+_spec\.rb$})
6
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
7
+ watch('spec/spec_helper.rb') { "spec" }
8
+
9
+ # Rails example
10
+ watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
11
+ watch(%r{^app/(.*)(\.erb|\.haml|\.slim)$}) { |m| "spec/#{m[1]}#{m[2]}_spec.rb" }
12
+ watch(%r{^app/controllers/(.+)_(controller)\.rb$}) { |m| ["spec/routing/#{m[1]}_routing_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb"] }
13
+ watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
14
+ watch('config/routes.rb') { "spec/routing" }
15
+ watch('app/controllers/application_controller.rb') { "spec/controllers" }
16
+
17
+ # Capybara features specs
18
+ watch(%r{^app/views/(.+)/.*\.(erb|haml|slim)$}) { |m| "spec/features/#{m[1]}_spec.rb" }
19
+
20
+ # Turnip features and steps
21
+ watch(%r{^spec/acceptance/(.+)\.feature$})
22
+ watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'spec/acceptance' }
23
+ end
24
+
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2014 刘泽磊
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 liuzelei
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,35 @@
1
+ # ModelConcerns
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'model_concerns'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install model_concerns
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
30
+
31
+ model_concerns
32
+
33
+
34
+ 常用的concerns
35
+
@@ -0,0 +1,5 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rspec/core/rake_task'
3
+
4
+ task default: :spec
5
+ RSpec::Core::RakeTask.new
@@ -0,0 +1,14 @@
1
+ # encoding: utf-8
2
+ require "active_support"
3
+ require "model_concerns/version"
4
+ require "model_concerns/disable"
5
+ require "model_concerns/sequenable"
6
+ require "model_concerns/assignable"
7
+ require "model_concerns/searchable"
8
+ require "model_concerns/protectable"
9
+ require "model_concerns/array"
10
+ require "model_concerns/string"
11
+
12
+ module ModelConcerns
13
+
14
+ end
@@ -0,0 +1,9 @@
1
+ class Array
2
+ def trim_head
3
+ array_trim = Array.new(self)
4
+ while [0, nil].include?(array_trim[0]) do
5
+ array_trim.shift
6
+ end
7
+ return array_trim
8
+ end
9
+ end
@@ -0,0 +1,27 @@
1
+ module ModelConcerns
2
+ module Assignable
3
+ extend ActiveSupport::Concern
4
+
5
+ # usage has :owner, :operator
6
+ module ClassMethods
7
+ def has(*names)
8
+ names.each do |name|
9
+ belongs_to name, class_name: :User
10
+
11
+ scope "filter_by_#{name}", ->(user) { where("#{name}_id = :id or #{name}_no = :no", id: user.id, no: user.no) }
12
+
13
+ define_method "assign_#{name}" do |user|
14
+ self.send("#{name}=", user)
15
+ self.send("#{name}_id=", user.id)
16
+ self.send("#{name}_no=", user.no)
17
+ end
18
+
19
+ define_method "assign_#{name}!" do |user|
20
+ self.send("assign_#{name}", user)
21
+ self.save(validate: false)
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,40 @@
1
+ module ModelConcerns
2
+ module Disable
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ scope :disabled, -> { where "disabled_at is not null" }
7
+ scope :enabled, -> { where disabled_at: nil }
8
+ end
9
+
10
+ def disable
11
+ self.disabled_at = Time.now
12
+ end
13
+
14
+ def enable
15
+ self.disabled_at = nil
16
+ end
17
+
18
+ def disable!
19
+ self.disable
20
+ self.save(validate: false)
21
+ end
22
+
23
+ def enable!
24
+ self.enable
25
+ self.save(validate: false)
26
+ end
27
+
28
+ def disabled?
29
+ !self.disabled_at.nil?
30
+ end
31
+
32
+ def disabled=(value)
33
+ if value == "1" || value == 1 || value == true
34
+ self.disable
35
+ else
36
+ self.enable
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,57 @@
1
+ module ModelConcerns
2
+ module Protectable
3
+ extend ActiveSupport::Concern
4
+
5
+ def fake_id
6
+ return nil if self.id.nil?
7
+ @fake_id ||= self.id ^ self.class.protect_seed
8
+ end
9
+
10
+ def to_param
11
+ fake_id.to_s
12
+ end
13
+
14
+ def reload(options = nil)
15
+ options = (options || {}).merge(real_id: true)
16
+ self.id = self.fake_id
17
+ super(options)
18
+ end
19
+
20
+ module ClassMethods
21
+
22
+ def find(*args)
23
+ scope = args.slice!(0)
24
+ options = args.slice!(0) || {}
25
+ if protectable? && !options[:real_id]
26
+ if scope.is_a?(Array)
27
+ scope.map! {|a| find_id_by_fake_id(a).to_i}
28
+ else
29
+ scope = find_id_by_fake_id(scope)
30
+ end
31
+ end
32
+
33
+ super(scope)
34
+ end
35
+
36
+ def protect_seed
37
+ alphabet = Array("a".."z")
38
+ number = name.split("").collect do |char|
39
+ alphabet.index(char)
40
+ end
41
+ @protect_seed ||= number.shift(12).join.to_i
42
+ end
43
+
44
+ def find_by_fake_id(fake_id)
45
+ find_by_id(find_id_by_fake_id(fake_id.to_i))
46
+ end
47
+
48
+ def find_id_by_fake_id(fake_id)
49
+ fake_id.to_i ^ protect_seed
50
+ end
51
+
52
+ def protectable?
53
+ true
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,44 @@
1
+ module ModelConcerns
2
+ module Searchable
3
+ extend ActiveSupport::Concern
4
+
5
+ module ClassMethods
6
+ # usage: quick_search :no, :user_name
7
+ # then that class has scope with name search(keyword)
8
+ def quick_search(*columns)
9
+ scope :search, ->(keyword) { where "#{columns.map { |column| table_name + '.' + column.to_s + ' like :key' }.join(' or ')}", key: "%" + (keyword.nil? ? "" : keyword) + "%" unless keyword.blank?}
10
+ end
11
+
12
+ def respond_to?(method_id, include_private = false)
13
+ if method_id.to_s =~ /^like|between|equal_[\w]+$/
14
+ true
15
+ else
16
+ super
17
+ end
18
+ end
19
+
20
+ def method_missing(method_id, *arguments, &block)
21
+ regex = /^like|between|equal_[\w]+$/
22
+
23
+ if method_id.to_s =~ regex && self.column_names.include?(attribute_name = method_id.to_s.match(/_[\w]+$/)[0].gsub(/^_/,''))
24
+ type = /^like|between|equal/.match(method_id.to_s)[0]
25
+ case type
26
+ when 'like'
27
+ return where(" #{table_name}.#{attribute_name} like ? ", "%#{arguments[0]}%") unless arguments[0].blank?
28
+ when 'between'
29
+ sql = ''
30
+ sql = sql + " #{table_name}.%s > '%s' " % [attribute_name, arguments[0]] unless arguments[0].blank?
31
+ sql = sql + " %s #{table_name}.%s < '%s'" % [sql.blank? ? '' : 'and' , attribute_name, arguments[1]] unless arguments[1].blank?
32
+ return where(sql) unless sql.empty?
33
+ when 'equal'
34
+ return where(" #{table_name}.#{attribute_name} = ? ", "#{arguments[0]}") unless arguments[0].blank?
35
+ end
36
+
37
+ return where('')
38
+ else
39
+ super
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,31 @@
1
+ module ModelConcerns
2
+ module Sequenable
3
+ extend ActiveSupport::Concern
4
+ module ClassMethods
5
+
6
+ Dir.mkdir('/tmp/locks') unless File.exists?('/tmp/locks')
7
+
8
+ def sequence(prefix = nil)
9
+ class_eval <<-CODE, __FILE__, __LINE__ + 1
10
+ after_initialize :generate_no
11
+ validates_uniqueness_of :no
12
+
13
+ private
14
+ def generate_no
15
+ # 如果序号为空,或者已经被锁定了,就重新创建一个序号
16
+ file = File.open("/tmp/locks/" + self.class.name.underscore.pluralize + "_no.lock", "w")
17
+ file.flock(File::LOCK_EX)
18
+
19
+ if self.no.blank?
20
+ self.no = Time.now.strftime("#{prefix}%y%m%d%H%M%S%L")
21
+ sleep(0.001)
22
+ end
23
+
24
+ file.flock(File::LOCK_UN)
25
+ end
26
+
27
+ CODE
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,12 @@
1
+ require "model_concerns/array"
2
+
3
+ class String
4
+ def ^ (other)
5
+ self_binary_array = self.unpack("U*")
6
+ key_binary_array = other.unpack("U*")
7
+ longest = [self_binary_array.length, key_binary_array.length].max
8
+ self_binary_array = [0] * (longest - self_binary_array.length) + self_binary_array
9
+ key_binary_array = [0] * (longest - key_binary_array.length) + key_binary_array
10
+ return self_binary_array.zip(key_binary_array).map { |a, b| a ^ b }.trim_head.pack("U*")
11
+ end
12
+ end
@@ -0,0 +1,3 @@
1
+ module ModelConcerns
2
+ VERSION = "0.0.9"
3
+ end
@@ -0,0 +1,31 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'model_concerns/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "model_concerns"
8
+ spec.version = ModelConcerns::VERSION
9
+ spec.authors = ["liuzelei"]
10
+ spec.email = ["liuzelei@gmail.com"]
11
+ spec.description = '项目中公用的concern'
12
+ spec.summary = '主要是ActiveRecord'
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.3"
22
+ spec.add_development_dependency "rake"
23
+ spec.add_development_dependency "rspec"
24
+ spec.add_development_dependency "guard"
25
+ spec.add_development_dependency "guard-rspec"
26
+ spec.add_development_dependency "active_record_mocks"
27
+ spec.add_development_dependency "mysql2"
28
+
29
+ spec.add_runtime_dependency "activesupport"
30
+ spec.add_runtime_dependency "activerecord"
31
+ end
@@ -0,0 +1,10 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Array" do
4
+
5
+ it 'should trim head' do
6
+ array = [0, 0, nil, 1, 2, 3]
7
+ expect(array.trim_head).to eq([1, 2, 3])
8
+ expect(array).to eq([0, 0, nil, 1, 2, 3])
9
+ end
10
+ end
@@ -0,0 +1,57 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Assignable" do
4
+
5
+ it 'should assign' do
6
+ with_mocked_tables do |m|
7
+ m.create_table do |t|
8
+ t.model_name :FooAssignable
9
+
10
+ t.layout do |l|
11
+ l.integer :owner_id
12
+ l.string :owner_no
13
+ l.integer :manager_id
14
+ l.string :manager_no
15
+ l.datetime :created_at
16
+ l.datetime :updated_at
17
+ end
18
+ end
19
+
20
+ m.create_table do |t|
21
+ t.model_name :User
22
+ t.layout do |l|
23
+ l.string :no
24
+ end
25
+ end
26
+
27
+ class User < ActiveRecord::Base
28
+ end
29
+
30
+ class FooAssignable < ActiveRecord::Base
31
+ include ModelConcerns::Assignable
32
+ has :owner, :manager
33
+ end
34
+
35
+ u1 = User.create(no: "NO1")
36
+ u2 = User.create(no: "NO2")
37
+ f = FooAssignable.create(owner: u1, manager: u2)
38
+
39
+ expect(FooAssignable.filter_by_owner(u1).count).to eq(1)
40
+ expect(FooAssignable.filter_by_owner(u1).count).to eq(1)
41
+ expect(FooAssignable.filter_by_manager(u2).count).to eq(1)
42
+ expect(FooAssignable.filter_by_manager(u2).count).to eq(1)
43
+
44
+ f.assign_owner(u2)
45
+ expect(f.owner.id).to eq(u2.id)
46
+ f.reload
47
+ expect(f.owner.id).to eq(u1.id)
48
+ f.assign_owner(u2)
49
+ f.save
50
+ expect(f.owner.id).to eq(u2.id)
51
+
52
+ f.assign_owner!(u1)
53
+ f.reload
54
+ expect(f.owner.id).to eq(u1.id)
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,54 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Disable" do
4
+
5
+ it 'should disable' do
6
+ with_mocked_tables do |m|
7
+ m.create_table do |t|
8
+ t.model_name :FooDisable
9
+
10
+ t.layout do |l|
11
+ l.integer :no
12
+ l.datetime :created_at
13
+ l.datetime :updated_at
14
+ l.datetime :disabled_at
15
+ end
16
+ end
17
+
18
+ class FooDisable < ActiveRecord::Base
19
+ include ModelConcerns::Disable
20
+ end
21
+
22
+ 10.times.each do |index|
23
+ FooDisable.create(no: index)
24
+ end
25
+
26
+ 5.times.each do |index|
27
+ FooDisable.create(no: index + 10).disable!
28
+ end
29
+
30
+ expect(FooDisable.disabled.count).to eq(5)
31
+ expect(FooDisable.enabled.count).to eq(10)
32
+
33
+ f = FooDisable.find_by_no(5)
34
+ f.disable
35
+ expect(f.disabled?).to eq(true)
36
+ f.reload
37
+ expect(f.disabled?).to eq(false)
38
+ f.disable!
39
+ expect(f.disabled?).to eq(true)
40
+ f.reload
41
+ expect(f.disabled?).to eq(true)
42
+
43
+ f = FooDisable.find_by_no(11)
44
+ f.enable
45
+ expect(f.disabled?).to eq(false)
46
+ f.reload
47
+ expect(f.disabled?).to eq(true)
48
+ f.enable!
49
+ expect(f.disabled?).to eq(false)
50
+ f.reload
51
+ expect(f.disabled?).to eq(false)
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,42 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Protectable" do
4
+
5
+ it 'should Protectable' do
6
+ with_mocked_tables do |m|
7
+ m.create_table do |t|
8
+ t.model_name :FooProtectable
9
+
10
+ t.layout do |l|
11
+ end
12
+ end
13
+
14
+ class FooProtectable < ActiveRecord::Base
15
+ include ModelConcerns::Protectable
16
+ end
17
+
18
+ expect(FooProtectable.new.fake_id).to be_nil
19
+ #expect(FooProtectable.xor_key).to eq(Digest::MD5.hexdigest(FooProtectable.name))
20
+ expect(FooProtectable.protectable?).to eq(true)
21
+
22
+ #p FooProtectable.xor_key
23
+ 100.times do
24
+ model = FooProtectable.create
25
+ expect(model.fake_id).not_to be_nil
26
+ expect(model.id).to eq(FooProtectable.find_id_by_fake_id(model.fake_id))
27
+ expect(model.id).to eq(FooProtectable.find_by_fake_id(model.fake_id).id)
28
+ end
29
+
30
+ model = FooProtectable.create
31
+ model2 = FooProtectable.create
32
+ expect(model2.fake_id).not_to eq(model.fake_id)
33
+ expect(FooProtectable.find(model.fake_id)).to eq(model)
34
+ expect(FooProtectable.find(model.id, real_id: true)).to eq(model)
35
+ expect {
36
+ FooProtectable.find(model.fake_id, real_id: true)
37
+ }.to raise_error(ActiveRecord::RecordNotFound)
38
+ expect(model.reload.id).to eq(model.id)
39
+ expect(model.reload.id).not_to eq(model.fake_id)
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,31 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Searchable" do
4
+
5
+ it 'should searchable' do
6
+ with_mocked_tables do |m|
7
+ m.create_table do |t|
8
+ t.model_name :FooSearchable
9
+
10
+ t.layout do |l|
11
+ l.string :no
12
+ l.integer :count
13
+ l.datetime :created_at
14
+ l.datetime :updated_at
15
+ end
16
+ end
17
+
18
+ class FooSearchable < ActiveRecord::Base
19
+ include ModelConcerns::Searchable
20
+ quick_search :no, :count
21
+ end
22
+
23
+
24
+ 10.times do |index|
25
+ FooSearchable.create(no: "NO#{index}", count: index)
26
+ end
27
+
28
+ expect(FooSearchable.search("9").count).to eq(1)
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,53 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Sequenable" do
4
+
5
+ it 'should sequence' do
6
+ with_mocked_tables do |m|
7
+ m.create_table do |t|
8
+ t.model_name :FooSequenable
9
+
10
+ t.layout do |l|
11
+ l.string :no
12
+ l.datetime :created_at
13
+ l.datetime :updated_at
14
+ end
15
+ end
16
+
17
+ class FooSequenable < ActiveRecord::Base
18
+ include ModelConcerns::Sequenable
19
+ sequence :FO
20
+ end
21
+
22
+ puts "this test will take a long time, please wait....."
23
+ pids = []
24
+ 10.times do
25
+ ActiveRecord::Base.establish_connection(ActiveRecord::Base.connection_config)
26
+
27
+ pids << fork do
28
+
29
+ threads = []
30
+ 10.times do
31
+ threads << Thread.new do
32
+ 100.times do
33
+ FooSequenable.new.save
34
+ end
35
+ end
36
+ end
37
+
38
+ threads.each do |thread|
39
+ thread.join
40
+ end
41
+ end
42
+ end
43
+
44
+ pids.each do |pid|
45
+ Process.waitpid(pid)
46
+ end
47
+
48
+ expect(FooSequenable.all.count).to eq(10000)
49
+
50
+ expect(FooSequenable.select("count(1) as count, no").group("no").having("count(1) > 1").length).to eq(0)
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,17 @@
1
+ require 'spec_helper'
2
+
3
+ describe "String" do
4
+
5
+ it 'should xor' do
6
+ left = "LEFT_STRING"
7
+ right = "RIGHT_STRING"
8
+
9
+ left = left ^ right
10
+ expect(left).not_to eq("LEFT_STRING")
11
+ right = right ^ left
12
+ expect(right).to eq("LEFT_STRING")
13
+ left = left ^ right
14
+ expect(left).to eq("RIGHT_STRING")
15
+ expect(right).to eq("LEFT_STRING")
16
+ end
17
+ end
@@ -0,0 +1,123 @@
1
+ # This file was generated by the `rspec --init` command. Conventionally, all
2
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
3
+ # The generated `.rspec` file contains `--require spec_helper` which will cause this
4
+ # file to always be loaded, without a need to explicitly require it in any files.
5
+ #
6
+ # Given that it is always loaded, you are encouraged to keep this file as
7
+ # light-weight as possible. Requiring heavyweight dependencies from this file
8
+ # will add to the boot time of your test suite on EVERY test run, even for an
9
+ # individual file that may not need all of that loaded. Instead, make a
10
+ # separate helper file that requires this one and then use it only in the specs
11
+ # that actually need it.
12
+ #
13
+ # The `.rspec` file also contains a few flags that are not defaults but that
14
+ # users commonly want.
15
+ #
16
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
17
+ require 'bundler/setup'
18
+ require 'active_record'
19
+ require 'model_concerns'
20
+ require 'active_record_mocks'
21
+ require 'active_record_mocks/rspec'
22
+
23
+ Bundler.setup
24
+
25
+ db_cmd = "mysql -u%s -p%s -e"
26
+ db_cmd_without_password = "mysql -u%s -e"
27
+ db_drop_cmd = "'DROP DATABASE IF EXISTS %s' >/dev/null 2>&1"
28
+ db_create_cmd = "'CREATE DATABASE %s' >/dev/null 2>&1"
29
+ db_database = "active_record_mocks_testing"
30
+ db_user = "root"
31
+ db_password = nil
32
+
33
+ ActiveRecord::Base.establish_connection(
34
+ password: db_password,
35
+ database: db_database,
36
+ username: db_user,
37
+ host: "localhost",
38
+ pool: 500,
39
+ timeout: 50000,
40
+ adapter: "mysql2"
41
+ )
42
+
43
+ RSpec.configure do |config|
44
+
45
+ config.before :suite do
46
+ unless db_password.nil?
47
+ system db_cmd % [db_user, db_password] + db_drop_cmd % db_database
48
+ system db_cmd % [db_user, db_password] + db_create_cmd % db_database
49
+ else
50
+ system db_cmd_without_password % [db_user] + db_drop_cmd % db_database
51
+ system db_cmd_without_password % [db_user] + db_create_cmd % db_database
52
+ end
53
+ end
54
+
55
+ config.after :suite do
56
+ ActiveRecord::Base.connection.disconnect!
57
+ unless db_password.nil?
58
+ system db_cmd % [db_user, db_password] + db_drop_cmd % db_database
59
+ else
60
+ system db_cmd_without_password % [db_user] + db_drop_cmd % db_database
61
+ end
62
+ end
63
+ # The settings below are suggested to provide a good initial experience
64
+ # with RSpec, but feel free to customize to your heart's content.
65
+ =begin
66
+ # These two settings work together to allow you to limit a spec run
67
+ # to individual examples or groups you care about by tagging them with
68
+ # `:focus` metadata. When nothing is tagged with `:focus`, all examples
69
+ # get run.
70
+ config.filter_run :focus
71
+ config.run_all_when_everything_filtered = true
72
+
73
+ # Many RSpec users commonly either run the entire suite or an individual
74
+ # file, and it's useful to allow more verbose output when running an
75
+ # individual spec file.
76
+ if config.files_to_run.one?
77
+ # Use the documentation formatter for detailed output,
78
+ # unless a formatter has already been configured
79
+ # (e.g. via a command-line flag).
80
+ config.default_formatter = 'doc'
81
+ end
82
+
83
+ # Print the 10 slowest examples and example groups at the
84
+ # end of the spec run, to help surface which specs are running
85
+ # particularly slow.
86
+ config.profile_examples = 10
87
+
88
+ # Run specs in random order to surface order dependencies. If you find an
89
+ # order dependency and want to debug it, you can fix the order by providing
90
+ # the seed, which is printed after each run.
91
+ # --seed 1234
92
+ config.order = :random
93
+
94
+ # Seed global randomization in this process using the `--seed` CLI option.
95
+ # Setting this allows you to use `--seed` to deterministically reproduce
96
+ # test failures related to randomization by passing the same `--seed` value
97
+ # as the one that triggered the failure.
98
+ Kernel.srand config.seed
99
+
100
+ # rspec-expectations config goes here. You can use an alternate
101
+ # assertion/expectation library such as wrong or the stdlib/minitest
102
+ # assertions if you prefer.
103
+ config.expect_with :rspec do |expectations|
104
+ # Enable only the newer, non-monkey-patching expect syntax.
105
+ # For more details, see:
106
+ # - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax
107
+ expectations.syntax = :expect
108
+ end
109
+
110
+ # rspec-mocks config goes here. You can use an alternate test double
111
+ # library (such as bogus or mocha) by changing the `mock_with` option here.
112
+ config.mock_with :rspec do |mocks|
113
+ # Enable only the newer, non-monkey-patching expect syntax.
114
+ # For more details, see:
115
+ # - http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
116
+ mocks.syntax = :expect
117
+
118
+ # Prevents you from mocking or stubbing a method that does not exist on
119
+ # a real object. This is generally recommended.
120
+ mocks.verify_partial_doubles = true
121
+ end
122
+ =end
123
+ end
metadata ADDED
@@ -0,0 +1,205 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: model_concerns
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.9
5
+ platform: ruby
6
+ authors:
7
+ - liuzelei
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-02-02 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: rspec
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: guard
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
+ - !ruby/object:Gem::Dependency
70
+ name: guard-rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: active_record_mocks
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: mysql2
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: activesupport
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: activerecord
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :runtime
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ description: "项目中公用的concern"
140
+ email:
141
+ - liuzelei@gmail.com
142
+ executables: []
143
+ extensions: []
144
+ extra_rdoc_files: []
145
+ files:
146
+ - ".gitignore"
147
+ - ".rspec"
148
+ - ".travis.yml"
149
+ - Gemfile
150
+ - Guardfile
151
+ - LICENSE
152
+ - LICENSE.txt
153
+ - README.md
154
+ - Rakefile
155
+ - lib/model_concerns.rb
156
+ - lib/model_concerns/array.rb
157
+ - lib/model_concerns/assignable.rb
158
+ - lib/model_concerns/disable.rb
159
+ - lib/model_concerns/protectable.rb
160
+ - lib/model_concerns/searchable.rb
161
+ - lib/model_concerns/sequenable.rb
162
+ - lib/model_concerns/string.rb
163
+ - lib/model_concerns/version.rb
164
+ - model_concerns.gemspec
165
+ - spec/lib/model_concerns/array_spec.rb
166
+ - spec/lib/model_concerns/assignable_spec.rb
167
+ - spec/lib/model_concerns/disable_spec.rb
168
+ - spec/lib/model_concerns/protectable_spec.rb
169
+ - spec/lib/model_concerns/searchable_spec.rb
170
+ - spec/lib/model_concerns/sequenable_spec.rb
171
+ - spec/lib/model_concerns/string_spec.rb
172
+ - spec/spec_helper.rb
173
+ homepage: ''
174
+ licenses:
175
+ - MIT
176
+ metadata: {}
177
+ post_install_message:
178
+ rdoc_options: []
179
+ require_paths:
180
+ - lib
181
+ required_ruby_version: !ruby/object:Gem::Requirement
182
+ requirements:
183
+ - - ">="
184
+ - !ruby/object:Gem::Version
185
+ version: '0'
186
+ required_rubygems_version: !ruby/object:Gem::Requirement
187
+ requirements:
188
+ - - ">="
189
+ - !ruby/object:Gem::Version
190
+ version: '0'
191
+ requirements: []
192
+ rubyforge_project:
193
+ rubygems_version: 2.4.5
194
+ signing_key:
195
+ specification_version: 4
196
+ summary: "主要是ActiveRecord"
197
+ test_files:
198
+ - spec/lib/model_concerns/array_spec.rb
199
+ - spec/lib/model_concerns/assignable_spec.rb
200
+ - spec/lib/model_concerns/disable_spec.rb
201
+ - spec/lib/model_concerns/protectable_spec.rb
202
+ - spec/lib/model_concerns/searchable_spec.rb
203
+ - spec/lib/model_concerns/sequenable_spec.rb
204
+ - spec/lib/model_concerns/string_spec.rb
205
+ - spec/spec_helper.rb