version_record 0.0.0 → 1.0.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 +4 -4
- data/lib/version_record.rb +8 -0
- data/lib/version_record/core_ext/string.rb +5 -0
- data/lib/version_record/finder.rb +18 -0
- data/lib/version_record/gem_version.rb +1 -1
- data/lib/version_record/macros.rb +17 -0
- data/lib/version_record/macros/versioned.rb +25 -0
- data/lib/version_record/prerelease.rb +69 -0
- data/lib/version_record/sorting/simple.rb +34 -0
- data/lib/version_record/type/version.rb +15 -0
- data/lib/version_record/version.rb +108 -0
- data/spec/rails_helper.rb +7 -0
- data/spec/spec_helper.rb +37 -0
- data/spec/support/apps/rails5_0.rb +48 -0
- data/spec/support/apps/rails5_1.rb +50 -0
- data/spec/support/model_spawner.rb +22 -0
- data/spec/version_record/finder_spec.rb +30 -0
- data/spec/version_record/macros/versioned_spec.rb +230 -0
- data/spec/version_record/prerelease_spec.rb +49 -0
- data/spec/version_record/sorting/simple_spec.rb +24 -0
- data/spec/version_record/string_spec.rb +7 -0
- data/spec/version_record/type/version_spec.rb +14 -0
- data/spec/version_record/version_spec.rb +157 -0
- metadata +133 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c085b6ca09746df9c01cb7895ed0f8cf7010a422
|
4
|
+
data.tar.gz: c468a447fe0c4046698c8281e90435b79e389c60
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 96e263bf3b4cad106f37cec3ba5167ca533e6783413734097566f1b27df8c466f00ec15b454a7f1773990a12620b98a993f1c6022ebd76686ea607c29b610fa8
|
7
|
+
data.tar.gz: 9de8c9c1c270d4999112e8bcf9b129a9bdb9224d3787a8a3c412711fab40522fcf5520dd051b09a521040cc2341113ba92d6ee5e1f1f43daef7bed53e52b0a3c
|
data/lib/version_record.rb
CHANGED
@@ -0,0 +1,8 @@
|
|
1
|
+
require 'version_record/finder'
|
2
|
+
require 'version_record/macros'
|
3
|
+
require 'version_record/prerelease'
|
4
|
+
require 'version_record/version'
|
5
|
+
require 'version_record/core_ext/string'
|
6
|
+
require 'version_record/macros/versioned'
|
7
|
+
require 'version_record/sorting/simple'
|
8
|
+
require 'version_record/type/version'
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module VersionRecord
|
2
|
+
class Finder
|
3
|
+
def initialize(klass, version_column)
|
4
|
+
@klass = klass
|
5
|
+
@version_column = version_column
|
6
|
+
end
|
7
|
+
|
8
|
+
def find_latest
|
9
|
+
by_version.last
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def by_version
|
15
|
+
@klass.public_send("by_#{@version_column}")
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module VersionRecord
|
2
|
+
module Macros
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
module ClassMethods
|
6
|
+
def versioned(column_name: :version)
|
7
|
+
VersionRecord::Macros::Versioned.def_versioned(self, column_name)
|
8
|
+
VersionRecord::Macros::Versioned.def_by_version(self, column_name)
|
9
|
+
VersionRecord::Macros::Versioned.def_latest_version(self, column_name)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
ActiveSupport.on_load :active_record do
|
16
|
+
include VersionRecord::Macros
|
17
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module VersionRecord
|
2
|
+
module Macros
|
3
|
+
class Versioned
|
4
|
+
|
5
|
+
class << self
|
6
|
+
|
7
|
+
def def_versioned(klass, version_column)
|
8
|
+
klass.attribute version_column, :version
|
9
|
+
end
|
10
|
+
|
11
|
+
def def_by_version(klass, version_column)
|
12
|
+
klass.define_singleton_method("by_#{version_column}") do |direction = :asc|
|
13
|
+
Sorting::Simple.new(klass, version_column).by_version(direction)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def def_latest_version(klass, version_column)
|
18
|
+
klass.define_singleton_method("latest_#{version_column}") do
|
19
|
+
Finder.new(klass, version_column).find_latest
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
module VersionRecord
|
2
|
+
class Prerelease
|
3
|
+
include Comparable
|
4
|
+
|
5
|
+
def self.build(string)
|
6
|
+
new(".#{string}") if string.present?
|
7
|
+
end
|
8
|
+
|
9
|
+
def initialize(string)
|
10
|
+
@string = string
|
11
|
+
end
|
12
|
+
|
13
|
+
def to_s
|
14
|
+
@string
|
15
|
+
end
|
16
|
+
|
17
|
+
def name
|
18
|
+
@string[1..-1]
|
19
|
+
end
|
20
|
+
|
21
|
+
def tail
|
22
|
+
@tail ||= self.class.build(at(1..-1).join('.'))
|
23
|
+
end
|
24
|
+
|
25
|
+
def first_segment
|
26
|
+
@first_segment ||= at(0)
|
27
|
+
end
|
28
|
+
|
29
|
+
def <=>(other)
|
30
|
+
return unless other.is_a?(Prerelease)
|
31
|
+
|
32
|
+
if first_segment == other.first_segment
|
33
|
+
compare_by_tail(other)
|
34
|
+
else
|
35
|
+
compare_by_first_segment(other)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def at(index)
|
42
|
+
to_a[index]
|
43
|
+
end
|
44
|
+
|
45
|
+
def to_a
|
46
|
+
name.split('.')
|
47
|
+
end
|
48
|
+
|
49
|
+
def compare_by_tail(other)
|
50
|
+
return 1 if self.tail && other.tail.nil?
|
51
|
+
return -1 if self.tail.nil? && other.tail
|
52
|
+
self.tail <=> other.tail
|
53
|
+
end
|
54
|
+
|
55
|
+
def compare_by_first_segment(other)
|
56
|
+
if int?(first_segment) && int?(other.first_segment)
|
57
|
+
first_segment.to_i <=> other.first_segment.to_i
|
58
|
+
else
|
59
|
+
first_segment <=> other.first_segment
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def int?(str)
|
64
|
+
!!Integer(str)
|
65
|
+
rescue ArgumentError, TypeError
|
66
|
+
false
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module VersionRecord
|
2
|
+
module Sorting
|
3
|
+
|
4
|
+
# Handles sorting a collection of AR objects.
|
5
|
+
#
|
6
|
+
# This implementation uses in-memory sorting.
|
7
|
+
#
|
8
|
+
class Simple
|
9
|
+
def initialize(klass, version_column)
|
10
|
+
@klass = klass
|
11
|
+
@version_column = version_column
|
12
|
+
end
|
13
|
+
|
14
|
+
def by_version(direction = :asc)
|
15
|
+
collection = @klass.all
|
16
|
+
direction.to_sym == :asc ? sort_asc(collection) : sort_desc(collection)
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def sort_asc(collection)
|
22
|
+
collection.sort_by { |object| version(object) }
|
23
|
+
end
|
24
|
+
|
25
|
+
def sort_desc(collection)
|
26
|
+
collection.sort { |obj_1, obj_2| version(obj_2) <=> version(obj_1) }
|
27
|
+
end
|
28
|
+
|
29
|
+
def version(object)
|
30
|
+
object.public_send(@version_column)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module VersionRecord
|
2
|
+
module Type
|
3
|
+
class Version < ActiveRecord::Type::String
|
4
|
+
def cast(value)
|
5
|
+
value.nil? ? super : value.to_version
|
6
|
+
end
|
7
|
+
|
8
|
+
def serialize(value)
|
9
|
+
value.nil? ? super : super(value.to_s)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
ActiveRecord::Type.register(:version, VersionRecord::Type::Version)
|
@@ -0,0 +1,108 @@
|
|
1
|
+
module VersionRecord
|
2
|
+
class Version
|
3
|
+
include Comparable
|
4
|
+
|
5
|
+
attr_accessor :major, :minor, :patch
|
6
|
+
|
7
|
+
def initialize(version)
|
8
|
+
@major, @minor, @patch, @prerelease = Parser.new(version.to_s).parse
|
9
|
+
end
|
10
|
+
|
11
|
+
def to_s
|
12
|
+
"#{@major}.#{@minor}.#{@patch}#{@prerelease}"
|
13
|
+
end
|
14
|
+
|
15
|
+
def to_version
|
16
|
+
self
|
17
|
+
end
|
18
|
+
|
19
|
+
def bump(segment = :minor)
|
20
|
+
send("bump_#{segment}") if [:major, :minor, :patch].include?(segment)
|
21
|
+
self
|
22
|
+
end
|
23
|
+
|
24
|
+
def prerelease
|
25
|
+
@prerelease.name if @prerelease
|
26
|
+
end
|
27
|
+
|
28
|
+
def <=>(other)
|
29
|
+
return unless other.respond_to?(:to_version)
|
30
|
+
other = other.to_version
|
31
|
+
|
32
|
+
if same_segments?(other, :major, :minor, :patch, :prerelease)
|
33
|
+
0
|
34
|
+
elsif same_segments?(other, :major, :minor, :patch)
|
35
|
+
compare_by(other, :prerelease)
|
36
|
+
elsif same_segments?(other, :major, :minor)
|
37
|
+
compare_by(other, :patch)
|
38
|
+
elsif same_segments?(other, :major)
|
39
|
+
compare_by(other, :minor)
|
40
|
+
else
|
41
|
+
compare_by(other, :major)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def bump_major
|
48
|
+
@major += 1
|
49
|
+
@minor = @patch = 0
|
50
|
+
end
|
51
|
+
|
52
|
+
def bump_minor
|
53
|
+
@minor += 1
|
54
|
+
@patch = 0
|
55
|
+
end
|
56
|
+
|
57
|
+
def bump_patch
|
58
|
+
@patch += 1
|
59
|
+
end
|
60
|
+
|
61
|
+
# Checks if all the segments in other are equal to the ones passed as a
|
62
|
+
# parameter.
|
63
|
+
#
|
64
|
+
# For example, calling same_segments?(other, :major, :minor) will check:
|
65
|
+
#
|
66
|
+
# self.major == other.major && self.minor == other.minor
|
67
|
+
#
|
68
|
+
def same_segments?(other, *segments)
|
69
|
+
segments.all? { |segment| send(segment) == other.send(segment) }
|
70
|
+
end
|
71
|
+
|
72
|
+
def compare_by(other, segment)
|
73
|
+
if [:major, :minor, :patch].include?(segment)
|
74
|
+
send(segment) <=> other.send(segment)
|
75
|
+
else
|
76
|
+
compare_by_prerelease(other)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def compare_by_prerelease(other)
|
81
|
+
return 1 if @prerelease.nil? && other.prerelease
|
82
|
+
return -1 if @prerelease && other.prerelease.nil?
|
83
|
+
|
84
|
+
@prerelease <=> Prerelease.build(other.prerelease)
|
85
|
+
end
|
86
|
+
|
87
|
+
class Parser
|
88
|
+
VERSION_PATTERN = /^(\d+)\.(\d+)\.(\d+)(([\.-][0-9A-Za-z-]+)*)$/
|
89
|
+
|
90
|
+
def initialize(version)
|
91
|
+
@version = version
|
92
|
+
end
|
93
|
+
|
94
|
+
def parse
|
95
|
+
error! unless match = @version.match(VERSION_PATTERN)
|
96
|
+
prerelease = Prerelease.new(match[4]) if match[4].present?
|
97
|
+
|
98
|
+
[match[1].to_i, match[2].to_i, match[3].to_i, prerelease]
|
99
|
+
end
|
100
|
+
|
101
|
+
private
|
102
|
+
|
103
|
+
def error!
|
104
|
+
raise ArgumentError, "Malformed version number string #{@version}"
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
ENV['RAILS_ENV'] = 'test'
|
2
|
+
ENV['DATABASE_URL'] = 'sqlite3://localhost/tmp/version_record_test'
|
3
|
+
|
4
|
+
require 'bundler/setup'
|
5
|
+
require 'rails'
|
6
|
+
require 'byebug'
|
7
|
+
if Rails.version.start_with?('5.0')
|
8
|
+
require 'support/apps/rails5_0'
|
9
|
+
elsif Rails.version.start_with?('5.1')
|
10
|
+
require 'support/apps/rails5_1'
|
11
|
+
end
|
12
|
+
require 'support/model_spawner'
|
13
|
+
require 'version_record'
|
14
|
+
|
15
|
+
RSpec.configure do |config|
|
16
|
+
config.expect_with :rspec do |expectations|
|
17
|
+
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
|
18
|
+
end
|
19
|
+
|
20
|
+
config.mock_with :rspec do |mocks|
|
21
|
+
mocks.verify_partial_doubles = true
|
22
|
+
end
|
23
|
+
|
24
|
+
config.shared_context_metadata_behavior = :apply_to_host_groups
|
25
|
+
|
26
|
+
config.include VersionRecord::Testing::ModelSpawner
|
27
|
+
|
28
|
+
config.before :each do
|
29
|
+
@spawned_models = []
|
30
|
+
end
|
31
|
+
|
32
|
+
config.after :each do
|
33
|
+
@spawned_models.each do |model|
|
34
|
+
Object.instance_eval { remove_const model } if Object.const_defined?(model)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'rails/all'
|
2
|
+
|
3
|
+
module Rails50
|
4
|
+
class Application < Rails::Application
|
5
|
+
# The test environment is used exclusively to run your application's
|
6
|
+
# test suite. You never need to work with it otherwise. Remember that
|
7
|
+
# your test database is "scratch space" for the test suite and is wiped
|
8
|
+
# and recreated between test runs. Don't rely on the data there!
|
9
|
+
config.cache_classes = true
|
10
|
+
|
11
|
+
# Do not eager load code on boot. This avoids loading your whole application
|
12
|
+
# just for the purpose of running a single test. If you are using a tool that
|
13
|
+
# preloads Rails for running tests, you may have to set it to true.
|
14
|
+
config.eager_load = false
|
15
|
+
|
16
|
+
# Configure public file server for tests with Cache-Control for performance.
|
17
|
+
config.public_file_server.enabled = true
|
18
|
+
config.public_file_server.headers = {
|
19
|
+
'Cache-Control' => 'public, max-age=3600'
|
20
|
+
}
|
21
|
+
|
22
|
+
# Show full error reports and disable caching.
|
23
|
+
config.consider_all_requests_local = true
|
24
|
+
config.action_controller.perform_caching = false
|
25
|
+
|
26
|
+
# Raise exceptions instead of rendering exception templates.
|
27
|
+
config.action_dispatch.show_exceptions = false
|
28
|
+
|
29
|
+
# Disable request forgery protection in test environment.
|
30
|
+
config.action_controller.allow_forgery_protection = false
|
31
|
+
config.action_mailer.perform_caching = false
|
32
|
+
|
33
|
+
# Tell Action Mailer not to deliver emails to the real world.
|
34
|
+
# The :test delivery method accumulates sent emails in the
|
35
|
+
# ActionMailer::Base.deliveries array.
|
36
|
+
config.action_mailer.delivery_method = :test
|
37
|
+
|
38
|
+
# Print deprecation notices to the stderr.
|
39
|
+
config.active_support.deprecation = :stderr
|
40
|
+
|
41
|
+
# Raises error for missing translations
|
42
|
+
# config.action_view.raise_on_missing_translations = true
|
43
|
+
|
44
|
+
config.secret_key_base = '49837489qkuweoiuoqwehisuakshdjksadhaisdy78o34y138974xyqp9rmye8yrpiokeuioqwzyoiuxftoyqiuxrhm3iou1hrzmjk'
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
Rails.application.initialize!
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'rails/all'
|
2
|
+
|
3
|
+
module Rails51
|
4
|
+
class Application < Rails::Application
|
5
|
+
# Settings specified here will take precedence over those in config/application.rb.
|
6
|
+
|
7
|
+
# The test environment is used exclusively to run your application's
|
8
|
+
# test suite. You never need to work with it otherwise. Remember that
|
9
|
+
# your test database is "scratch space" for the test suite and is wiped
|
10
|
+
# and recreated between test runs. Don't rely on the data there!
|
11
|
+
config.cache_classes = true
|
12
|
+
|
13
|
+
# Do not eager load code on boot. This avoids loading your whole application
|
14
|
+
# just for the purpose of running a single test. If you are using a tool that
|
15
|
+
# preloads Rails for running tests, you may have to set it to true.
|
16
|
+
config.eager_load = false
|
17
|
+
|
18
|
+
# Configure public file server for tests with Cache-Control for performance.
|
19
|
+
config.public_file_server.enabled = true
|
20
|
+
config.public_file_server.headers = {
|
21
|
+
'Cache-Control' => "public, max-age=#{1.hour.seconds.to_i}"
|
22
|
+
}
|
23
|
+
|
24
|
+
# Show full error reports and disable caching.
|
25
|
+
config.consider_all_requests_local = true
|
26
|
+
config.action_controller.perform_caching = false
|
27
|
+
|
28
|
+
# Raise exceptions instead of rendering exception templates.
|
29
|
+
config.action_dispatch.show_exceptions = false
|
30
|
+
|
31
|
+
# Disable request forgery protection in test environment.
|
32
|
+
config.action_controller.allow_forgery_protection = false
|
33
|
+
config.action_mailer.perform_caching = false
|
34
|
+
|
35
|
+
# Tell Action Mailer not to deliver emails to the real world.
|
36
|
+
# The :test delivery method accumulates sent emails in the
|
37
|
+
# ActionMailer::Base.deliveries array.
|
38
|
+
config.action_mailer.delivery_method = :test
|
39
|
+
|
40
|
+
# Print deprecation notices to the stderr.
|
41
|
+
config.active_support.deprecation = :stderr
|
42
|
+
|
43
|
+
# Raises error for missing translations
|
44
|
+
# config.action_view.raise_on_missing_translations = true
|
45
|
+
|
46
|
+
config.secret_key_base = '49837489qkuweoiuoqwehisuakshdjksadhaisdy78o34y138974xyqp9rmye8yrpiokeuioqwzyoiuxftoyqiuxrhm3iou1hrzmjk'
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
Rails.application.initialize!
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module VersionRecord
|
2
|
+
module Testing
|
3
|
+
module ModelSpawner
|
4
|
+
def spawn_model(klass, &block)
|
5
|
+
Object.instance_eval { remove_const klass } if Object.const_defined?(klass)
|
6
|
+
Object.const_set klass, Class.new(ActiveRecord::Base)
|
7
|
+
Object.const_get(klass).class_eval(&block) if block_given?
|
8
|
+
@spawned_models << klass.to_sym
|
9
|
+
end
|
10
|
+
|
11
|
+
def create_table(table_name)
|
12
|
+
ActiveRecord::Migration.suppress_messages do
|
13
|
+
ActiveRecord::Schema.define do
|
14
|
+
create_table table_name, force: true do |t|
|
15
|
+
yield(t)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
describe VersionRecord::Finder do
|
2
|
+
describe "#find_latest" do
|
3
|
+
subject(:finder) { VersionRecord::Finder.new(Document, :version) }
|
4
|
+
|
5
|
+
before do
|
6
|
+
create_table(:documents) do |t|
|
7
|
+
t.string :title
|
8
|
+
t.string :version
|
9
|
+
end
|
10
|
+
|
11
|
+
spawn_model(:Document) do
|
12
|
+
versioned
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
context 'when data exists' do
|
17
|
+
before do
|
18
|
+
@document_1 = Document.create!(title: 'Title 1', version: '1.1.0')
|
19
|
+
@document_2 = Document.create!(title: 'Title 2', version: '1.0.0')
|
20
|
+
@document_3 = Document.create!(title: 'Title 3', version: '1.1.1')
|
21
|
+
end
|
22
|
+
|
23
|
+
it { expect(finder.find_latest).to eq @document_3 }
|
24
|
+
end
|
25
|
+
|
26
|
+
context 'with no data' do
|
27
|
+
it { expect(finder.find_latest).to be_nil }
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,230 @@
|
|
1
|
+
describe VersionRecord::Macros::Versioned do
|
2
|
+
|
3
|
+
describe '#versioned' do
|
4
|
+
context 'with default options' do
|
5
|
+
before do
|
6
|
+
create_table(:documents) do |t|
|
7
|
+
t.string :title
|
8
|
+
t.string :version
|
9
|
+
end
|
10
|
+
|
11
|
+
spawn_model(:Document) do
|
12
|
+
versioned
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
context 'reading attribute' do
|
17
|
+
context 'when version column has values' do
|
18
|
+
let(:document) { Document.create!(title: 'Terms of service', version: '1.0.0') }
|
19
|
+
it { expect(document.version).to eq VersionRecord::Version.new('1.0.0') }
|
20
|
+
end
|
21
|
+
|
22
|
+
context 'when version column is nil' do
|
23
|
+
let(:document) { Document.create!(title: 'Terms of service', version: nil) }
|
24
|
+
it { expect(document.version).to be_nil }
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
context 'setting new values' do
|
29
|
+
context 'when version column has values' do
|
30
|
+
let(:document) { Document.create!(title: 'Terms of service', version: '1.0.0') }
|
31
|
+
|
32
|
+
it 'should accept a string' do
|
33
|
+
document.version = '1.1.0'
|
34
|
+
expect(document.version).to eq VersionRecord::Version.new('1.1.0')
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'should accept a Version object' do
|
38
|
+
document.version = VersionRecord::Version.new('1.1.0')
|
39
|
+
expect(document.version).to eq VersionRecord::Version.new('1.1.0')
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'should save to db with a string' do
|
43
|
+
document.update(version: '1.1.0')
|
44
|
+
expect(document.reload.version).to eq VersionRecord::Version.new('1.1.0')
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'should save to db with a Version object' do
|
48
|
+
document.update(version: VersionRecord::Version.new('1.1.0'))
|
49
|
+
expect(document.reload.version).to eq VersionRecord::Version.new('1.1.0')
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'should raise if malformed version' do
|
53
|
+
expect { document.update(version: '1.1.1.') }.to raise_error(ArgumentError)
|
54
|
+
expect(document.reload.version).to eq VersionRecord::Version.new('1.0.0')
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'should allow setting the version to nil' do
|
58
|
+
document.version = nil
|
59
|
+
document.save!
|
60
|
+
expect(document.reload.version).to be_nil
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
context 'when version column is nil' do
|
65
|
+
let(:document) { Document.create!(title: 'Terms of service', version: nil) }
|
66
|
+
|
67
|
+
it 'should accept a string' do
|
68
|
+
document.version = '1.1.0'
|
69
|
+
expect(document.version).to eq VersionRecord::Version.new('1.1.0')
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'should accept a Version object' do
|
73
|
+
document.version = VersionRecord::Version.new('1.1.0')
|
74
|
+
expect(document.version).to eq VersionRecord::Version.new('1.1.0')
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'should save to db with a string' do
|
78
|
+
document.update(version: '1.1.0')
|
79
|
+
expect(document.reload.version).to eq VersionRecord::Version.new('1.1.0')
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'should save to db with a Version object' do
|
83
|
+
document.update(version: VersionRecord::Version.new('1.1.0'))
|
84
|
+
expect(document.reload.version).to eq VersionRecord::Version.new('1.1.0')
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'should raise if malformed version' do
|
88
|
+
expect { document.update(version: '1.1.1.') }.to raise_error(ArgumentError)
|
89
|
+
expect(document.reload.version).to be_nil
|
90
|
+
end
|
91
|
+
|
92
|
+
it 'should allow setting the version to nil' do
|
93
|
+
document.version = nil
|
94
|
+
document.save!
|
95
|
+
expect(document.reload.version).to be_nil
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
context 'querying' do
|
101
|
+
let!(:document_1) { Document.create!(title: 'Terms of service', version: '1.0.0') }
|
102
|
+
let!(:document_2) { Document.create!(title: 'Terms of service', version: '1.1.0') }
|
103
|
+
let!(:document_3) { Document.create!(title: 'Terms of service', version: '1.1.1') }
|
104
|
+
let!(:document_4) { Document.create!(title: 'Terms of service', version: nil) }
|
105
|
+
|
106
|
+
it { expect(Document.where(version: '1.1.1')).to eq [document_3] }
|
107
|
+
it { expect(Document.where(version: VersionRecord::Version.new('1.1.1'))).to eq [document_3] }
|
108
|
+
it { expect(Document.where(version: nil)).to eq [document_4] }
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
context 'with custom options' do
|
113
|
+
before do
|
114
|
+
create_table(:releases) do |t|
|
115
|
+
t.string :tag
|
116
|
+
t.string :semantic_version
|
117
|
+
end
|
118
|
+
|
119
|
+
spawn_model(:Release) do
|
120
|
+
versioned column_name: :semantic_version
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
context 'reading attribute' do
|
125
|
+
let(:release) { Release.create!(tag: 'jb23hj412', semantic_version: '1.0.0') }
|
126
|
+
it { expect(release.semantic_version).to eq VersionRecord::Version.new('1.0.0') }
|
127
|
+
end
|
128
|
+
|
129
|
+
context 'setting new values' do
|
130
|
+
context 'when version column has values' do
|
131
|
+
let(:release) { Release.create!(tag: 'jb23hj412', semantic_version: '1.0.0') }
|
132
|
+
|
133
|
+
it 'should save to db with a Version object' do
|
134
|
+
release.update(semantic_version: VersionRecord::Version.new('1.1.0'))
|
135
|
+
expect(release.reload.semantic_version).to eq VersionRecord::Version.new('1.1.0')
|
136
|
+
end
|
137
|
+
|
138
|
+
it 'should allow setting the version to nil' do
|
139
|
+
release.semantic_version = nil
|
140
|
+
release.save!
|
141
|
+
expect(release.reload.semantic_version).to be_nil
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
context 'querying' do
|
147
|
+
let!(:release_1) { Release.create!(tag: 'jb23hj412', semantic_version: '1.0.0') }
|
148
|
+
let!(:release_2) { Release.create!(tag: 'jb23hj412', semantic_version: '1.1.0') }
|
149
|
+
let!(:release_3) { Release.create!(tag: 'jb23hj412', semantic_version: '1.1.1') }
|
150
|
+
let!(:release_4) { Release.create!(tag: 'jb23hj412', semantic_version: nil) }
|
151
|
+
|
152
|
+
it { expect(Release.where(semantic_version: '1.1.1')).to eq [release_3] }
|
153
|
+
it { expect(Release.where(semantic_version: VersionRecord::Version.new('1.1.1'))).to eq [release_3] }
|
154
|
+
it { expect(Release.where(semantic_version: nil)).to eq [release_4] }
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
describe '#by_version' do
|
160
|
+
context 'with default options' do
|
161
|
+
before do
|
162
|
+
create_table(:documents) do |t|
|
163
|
+
t.string :title
|
164
|
+
t.string :version
|
165
|
+
end
|
166
|
+
|
167
|
+
spawn_model(:Document) do
|
168
|
+
versioned
|
169
|
+
end
|
170
|
+
|
171
|
+
@document = Document.create!(title: 'Title 1', version: '1.1.0')
|
172
|
+
end
|
173
|
+
|
174
|
+
it { expect(Document.by_version).to eq [@document] }
|
175
|
+
end
|
176
|
+
|
177
|
+
context 'with custom options' do
|
178
|
+
before do
|
179
|
+
create_table(:releases) do |t|
|
180
|
+
t.string :tag
|
181
|
+
t.string :semantic_version
|
182
|
+
end
|
183
|
+
|
184
|
+
spawn_model(:Release) do
|
185
|
+
versioned column_name: :semantic_version
|
186
|
+
end
|
187
|
+
|
188
|
+
@release = Release.create!(tag: 'jb23hj412', semantic_version: '1.0.0')
|
189
|
+
end
|
190
|
+
|
191
|
+
it { expect(Release.by_semantic_version).to eq [@release] }
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
describe '#latest_version' do
|
196
|
+
context 'with default options' do
|
197
|
+
before do
|
198
|
+
create_table(:documents) do |t|
|
199
|
+
t.string :title
|
200
|
+
t.string :version
|
201
|
+
end
|
202
|
+
|
203
|
+
spawn_model(:Document) do
|
204
|
+
versioned
|
205
|
+
end
|
206
|
+
|
207
|
+
@document = Document.create!(title: 'Title 1', version: '1.1.0')
|
208
|
+
end
|
209
|
+
|
210
|
+
it { expect(Document.latest_version).to eq @document }
|
211
|
+
end
|
212
|
+
|
213
|
+
context 'with custom options' do
|
214
|
+
before do
|
215
|
+
create_table(:releases) do |t|
|
216
|
+
t.string :tag
|
217
|
+
t.string :semantic_version
|
218
|
+
end
|
219
|
+
|
220
|
+
spawn_model(:Release) do
|
221
|
+
versioned column_name: :semantic_version
|
222
|
+
end
|
223
|
+
|
224
|
+
@release = Release.create!(tag: 'jb23hj412', semantic_version: '1.0.0')
|
225
|
+
end
|
226
|
+
|
227
|
+
it { expect(Release.latest_semantic_version).to eq @release }
|
228
|
+
end
|
229
|
+
end
|
230
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
describe VersionRecord::Prerelease do
|
2
|
+
|
3
|
+
subject(:prerelease) { VersionRecord::Prerelease.new('.beta') }
|
4
|
+
|
5
|
+
describe '.build' do
|
6
|
+
it { expect(VersionRecord::Prerelease.build('beta')).to eq VersionRecord::Prerelease.new('.beta') }
|
7
|
+
end
|
8
|
+
|
9
|
+
describe '#to_s' do
|
10
|
+
it { expect(prerelease.to_s).to eq '.beta' }
|
11
|
+
end
|
12
|
+
|
13
|
+
describe '#name' do
|
14
|
+
it { expect(prerelease.name).to eq 'beta' }
|
15
|
+
end
|
16
|
+
|
17
|
+
describe '#tail' do
|
18
|
+
it { expect(VersionRecord::Prerelease.new('.beta.1.alpha').tail).to eq VersionRecord::Prerelease.new('.1.alpha') }
|
19
|
+
it { expect(VersionRecord::Prerelease.new('.1.alpha').tail).to eq VersionRecord::Prerelease.new('.alpha') }
|
20
|
+
it { expect(VersionRecord::Prerelease.new('.alpha').tail).to be_nil }
|
21
|
+
end
|
22
|
+
|
23
|
+
describe '#first_segment' do
|
24
|
+
it { expect(VersionRecord::Prerelease.new('.beta.1.alpha').first_segment).to eq 'beta' }
|
25
|
+
it { expect(VersionRecord::Prerelease.new('.1.alpha').first_segment).to eq '1' }
|
26
|
+
it { expect(VersionRecord::Prerelease.new('.alpha').first_segment).to eq 'alpha' }
|
27
|
+
end
|
28
|
+
|
29
|
+
describe '#<=>' do
|
30
|
+
it { expect(VersionRecord::Prerelease.new('-alpha')).to be < VersionRecord::Prerelease.new('-alpha.1') }
|
31
|
+
it { expect(VersionRecord::Prerelease.new('-alpha.1')).to be < VersionRecord::Prerelease.new('-alpha.beta') }
|
32
|
+
it { expect(VersionRecord::Prerelease.new('-alpha.beta')).to be < VersionRecord::Prerelease.new('-beta') }
|
33
|
+
it { expect(VersionRecord::Prerelease.new('-beta')).to be < VersionRecord::Prerelease.new('-beta.2') }
|
34
|
+
it { expect(VersionRecord::Prerelease.new('-beta.2')).to be < VersionRecord::Prerelease.new('-beta.11') }
|
35
|
+
it { expect(VersionRecord::Prerelease.new('-beta.11')).to be < VersionRecord::Prerelease.new('-rc.1') }
|
36
|
+
it { expect(VersionRecord::Prerelease.new('.beta.9')).to be < VersionRecord::Prerelease.new('.beta.10') }
|
37
|
+
it { expect(VersionRecord::Prerelease.new('.beta')).to be < VersionRecord::Prerelease.new('.beta.1') }
|
38
|
+
it { expect(VersionRecord::Prerelease.new('.beta')).to eq VersionRecord::Prerelease.new('.beta') }
|
39
|
+
it { expect(VersionRecord::Prerelease.new('.beta.1')).to be > VersionRecord::Prerelease.new('.beta') }
|
40
|
+
it { expect(VersionRecord::Prerelease.new('.beta.10')).to be > VersionRecord::Prerelease.new('.beta.9') }
|
41
|
+
it { expect(VersionRecord::Prerelease.new('-rc.1')).to be > VersionRecord::Prerelease.new('-beta.11') }
|
42
|
+
it { expect(VersionRecord::Prerelease.new('-beta.11')).to be > VersionRecord::Prerelease.new('-beta.2') }
|
43
|
+
it { expect(VersionRecord::Prerelease.new('-beta.2')).to be > VersionRecord::Prerelease.new('-beta') }
|
44
|
+
it { expect(VersionRecord::Prerelease.new('-beta')).to be > VersionRecord::Prerelease.new('-alpha.beta') }
|
45
|
+
it { expect(VersionRecord::Prerelease.new('-alpha.beta')).to be > VersionRecord::Prerelease.new('-alpha.1') }
|
46
|
+
it { expect(VersionRecord::Prerelease.new('-alpha.1')).to be > VersionRecord::Prerelease.new('-alpha') }
|
47
|
+
it { expect(VersionRecord::Prerelease.new('-alpha.1')).not_to eq nil }
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
describe VersionRecord::Sorting::Simple do
|
2
|
+
describe "#by_version" do
|
3
|
+
subject(:sorting_strategy) { VersionRecord::Sorting::Simple.new(Document, :version) }
|
4
|
+
|
5
|
+
before do
|
6
|
+
create_table(:documents) do |t|
|
7
|
+
t.string :title
|
8
|
+
t.string :version
|
9
|
+
end
|
10
|
+
|
11
|
+
spawn_model(:Document) do
|
12
|
+
versioned
|
13
|
+
end
|
14
|
+
|
15
|
+
@document_1 = Document.create!(title: 'Title 1', version: '1.1.0')
|
16
|
+
@document_2 = Document.create!(title: 'Title 2', version: '1.0.0')
|
17
|
+
@document_3 = Document.create!(title: 'Title 3', version: '1.1.1')
|
18
|
+
end
|
19
|
+
|
20
|
+
it { expect(sorting_strategy.by_version).to eq [@document_2, @document_1, @document_3] }
|
21
|
+
it { expect(sorting_strategy.by_version(:asc)).to eq [@document_2, @document_1, @document_3] }
|
22
|
+
it { expect(sorting_strategy.by_version(:desc)).to eq [@document_3, @document_1, @document_2] }
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,7 @@
|
|
1
|
+
describe String do
|
2
|
+
describe '#to_version' do
|
3
|
+
it { expect('2.2.1'.to_version).to eq VersionRecord::Version.new('2.2.1') }
|
4
|
+
it { expect('2.2.1.beta'.to_version).to eq VersionRecord::Version.new('2.2.1.beta') }
|
5
|
+
it { expect { 'invalid_version'.to_version }.to raise_error(ArgumentError) }
|
6
|
+
end
|
7
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
describe VersionRecord::Type::Version do
|
2
|
+
subject(:version_type) { VersionRecord::Type::Version.new }
|
3
|
+
|
4
|
+
it { is_expected.to be_an ActiveRecord::Type::String }
|
5
|
+
|
6
|
+
describe '#cast' do
|
7
|
+
it { expect(version_type.cast('1.1.2')).to eq VersionRecord::Version.new('1.1.2') }
|
8
|
+
it { expect { version_type.cast('1.1.2.') }.to raise_error ArgumentError }
|
9
|
+
end
|
10
|
+
|
11
|
+
describe '#serialize' do
|
12
|
+
it { expect(version_type.serialize(VersionRecord::Version.new('1.1.2'))).to eq '1.1.2' }
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,157 @@
|
|
1
|
+
describe VersionRecord::Version do
|
2
|
+
|
3
|
+
subject(:version) { VersionRecord::Version.new('1.1.2') }
|
4
|
+
|
5
|
+
describe '.new' do
|
6
|
+
context '2.3.1' do
|
7
|
+
let(:version) { VersionRecord::Version.new('2.3.1') }
|
8
|
+
|
9
|
+
it { expect(version.major).to eq 2 }
|
10
|
+
it { expect(version.minor).to eq 3 }
|
11
|
+
it { expect(version.patch).to eq 1 }
|
12
|
+
it { expect(version.prerelease).to be_nil }
|
13
|
+
end
|
14
|
+
|
15
|
+
context '1.0.0-alpha' do
|
16
|
+
let (:version) { VersionRecord::Version.new('1.0.0-alpha') }
|
17
|
+
|
18
|
+
it { expect(version.major).to eq 1 }
|
19
|
+
it { expect(version.minor).to eq 0 }
|
20
|
+
it { expect(version.patch).to eq 0 }
|
21
|
+
it { expect(version.prerelease).to eq 'alpha' }
|
22
|
+
end
|
23
|
+
|
24
|
+
context '1.0.0.alpha' do
|
25
|
+
let (:version) { VersionRecord::Version.new('1.0.0.alpha') }
|
26
|
+
|
27
|
+
it { expect(version.major).to eq 1 }
|
28
|
+
it { expect(version.minor).to eq 0 }
|
29
|
+
it { expect(version.patch).to eq 0 }
|
30
|
+
it { expect(version.prerelease).to eq 'alpha' }
|
31
|
+
end
|
32
|
+
|
33
|
+
context '1.0.0-alpha.1' do
|
34
|
+
let (:version) { VersionRecord::Version.new('1.0.0-alpha.1') }
|
35
|
+
|
36
|
+
it { expect(version.major).to eq 1 }
|
37
|
+
it { expect(version.minor).to eq 0 }
|
38
|
+
it { expect(version.patch).to eq 0 }
|
39
|
+
it { expect(version.prerelease).to eq 'alpha.1' }
|
40
|
+
end
|
41
|
+
|
42
|
+
context '1.0.0.alpha.1' do
|
43
|
+
let (:version) { VersionRecord::Version.new('1.0.0.alpha.1') }
|
44
|
+
|
45
|
+
it { expect(version.major).to eq 1 }
|
46
|
+
it { expect(version.minor).to eq 0 }
|
47
|
+
it { expect(version.patch).to eq 0 }
|
48
|
+
it { expect(version.prerelease).to eq 'alpha.1' }
|
49
|
+
end
|
50
|
+
|
51
|
+
context '1.0.0-alpha.beta' do
|
52
|
+
let (:version) { VersionRecord::Version.new('1.0.0-alpha.beta') }
|
53
|
+
|
54
|
+
it { expect(version.major).to eq 1 }
|
55
|
+
it { expect(version.minor).to eq 0 }
|
56
|
+
it { expect(version.patch).to eq 0 }
|
57
|
+
it { expect(version.prerelease).to eq 'alpha.beta' }
|
58
|
+
end
|
59
|
+
|
60
|
+
context '1.0.0.alpha.beta' do
|
61
|
+
let (:version) { VersionRecord::Version.new('1.0.0.alpha.beta') }
|
62
|
+
|
63
|
+
it { expect(version.major).to eq 1 }
|
64
|
+
it { expect(version.minor).to eq 0 }
|
65
|
+
it { expect(version.patch).to eq 0 }
|
66
|
+
it { expect(version.prerelease).to eq 'alpha.beta' }
|
67
|
+
end
|
68
|
+
|
69
|
+
context '1.0.0-beta.11' do
|
70
|
+
let (:version) { VersionRecord::Version.new('1.0.0-beta.11') }
|
71
|
+
|
72
|
+
it { expect(version.major).to eq 1 }
|
73
|
+
it { expect(version.minor).to eq 0 }
|
74
|
+
it { expect(version.patch).to eq 0 }
|
75
|
+
it { expect(version.prerelease).to eq 'beta.11' }
|
76
|
+
end
|
77
|
+
|
78
|
+
context '1.0.0.beta.11' do
|
79
|
+
let (:version) { VersionRecord::Version.new('1.0.0.beta.11') }
|
80
|
+
|
81
|
+
it { expect(version.major).to eq 1 }
|
82
|
+
it { expect(version.minor).to eq 0 }
|
83
|
+
it { expect(version.patch).to eq 0 }
|
84
|
+
it { expect(version.prerelease).to eq 'beta.11' }
|
85
|
+
end
|
86
|
+
|
87
|
+
context 'unsupported format' do
|
88
|
+
it { expect { VersionRecord::Version.new('2') }.to raise_error(ArgumentError) }
|
89
|
+
it { expect { VersionRecord::Version.new('2.1') }.to raise_error(ArgumentError) }
|
90
|
+
it { expect { VersionRecord::Version.new('2..1') }.to raise_error(ArgumentError) }
|
91
|
+
it { expect { VersionRecord::Version.new('2.') }.to raise_error(ArgumentError) }
|
92
|
+
it { expect { VersionRecord::Version.new('.1') }.to raise_error(ArgumentError) }
|
93
|
+
it { expect { VersionRecord::Version.new('fdsdfa') }.to raise_error(ArgumentError) }
|
94
|
+
it { expect { VersionRecord::Version.new('2.x.1') }.to raise_error(ArgumentError) }
|
95
|
+
it { expect { VersionRecord::Version.new('a.b.c') }.to raise_error(ArgumentError) }
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
describe '#to_s' do
|
100
|
+
context 'without prerelease' do
|
101
|
+
let(:version) { VersionRecord::Version.new('1.1.0') }
|
102
|
+
it { expect(version.to_s).to eq '1.1.0' }
|
103
|
+
end
|
104
|
+
|
105
|
+
context 'with prerelease' do
|
106
|
+
let(:version) { VersionRecord::Version.new('1.1.0.rc1') }
|
107
|
+
it { expect(version.to_s).to eq '1.1.0.rc1' }
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
describe '#bump' do
|
112
|
+
context 'bump major' do
|
113
|
+
it { expect(version.bump(:major).to_s).to eq '2.0.0' }
|
114
|
+
end
|
115
|
+
|
116
|
+
context 'bump minor' do
|
117
|
+
it { expect(version.bump(:minor).to_s).to eq '1.2.0' }
|
118
|
+
it { expect(version.bump.to_s).to eq '1.2.0' }
|
119
|
+
end
|
120
|
+
|
121
|
+
context 'bump patch' do
|
122
|
+
it { expect(version.bump(:patch).to_s).to eq '1.1.3' }
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
describe '#<=>' do
|
127
|
+
it { expect(VersionRecord::Version.new('1.0.0')).to be < VersionRecord::Version.new('2.0.0') }
|
128
|
+
it { expect(VersionRecord::Version.new('2.0.0')).to be < VersionRecord::Version.new('2.1.0') }
|
129
|
+
it { expect(VersionRecord::Version.new('2.1.0')).to be < VersionRecord::Version.new('2.1.1') }
|
130
|
+
it { expect(VersionRecord::Version.new('2.1.1')).to eq VersionRecord::Version.new('2.1.1') }
|
131
|
+
it { expect(VersionRecord::Version.new('2.1.1')).to be > VersionRecord::Version.new('2.1.0') }
|
132
|
+
it { expect(VersionRecord::Version.new('2.1.0')).to be > VersionRecord::Version.new('2.0.0') }
|
133
|
+
it { expect(VersionRecord::Version.new('2.0.0')).to be > VersionRecord::Version.new('1.0.0') }
|
134
|
+
it { expect(VersionRecord::Version.new('3.1.0')).not_to eq nil }
|
135
|
+
it { expect(VersionRecord::Version.new('1.0.9')).to be < VersionRecord::Version.new('1.0.10') }
|
136
|
+
it { expect(VersionRecord::Version.new('1.9.0')).to be < VersionRecord::Version.new('1.10.0') }
|
137
|
+
it { expect(VersionRecord::Version.new('9.0.0')).to be < VersionRecord::Version.new('10.0.0') }
|
138
|
+
|
139
|
+
context 'with prerelease' do
|
140
|
+
it { expect(VersionRecord::Version.new('1.0.0-alpha')).to be < VersionRecord::Version.new('1.0.0-alpha.1') }
|
141
|
+
it { expect(VersionRecord::Version.new('1.0.0-alpha.1')).to be < VersionRecord::Version.new('1.0.0-alpha.beta') }
|
142
|
+
it { expect(VersionRecord::Version.new('1.0.0-alpha.beta')).to be < VersionRecord::Version.new('1.0.0-beta') }
|
143
|
+
it { expect(VersionRecord::Version.new('1.0.0-beta')).to be < VersionRecord::Version.new('1.0.0-beta.2') }
|
144
|
+
it { expect(VersionRecord::Version.new('1.0.0-beta.2')).to be < VersionRecord::Version.new('1.0.0-beta.11') }
|
145
|
+
it { expect(VersionRecord::Version.new('1.0.0-beta.11')).to be < VersionRecord::Version.new('1.0.0-rc.1') }
|
146
|
+
it { expect(VersionRecord::Version.new('1.0.0-rc.1')).to be < VersionRecord::Version.new('1.0.0') }
|
147
|
+
it { expect(VersionRecord::Version.new('1.0.0.beta.9')).to be < VersionRecord::Version.new('1.0.0.beta.10') }
|
148
|
+
it { expect(VersionRecord::Version.new('1.0.0.beta.1')).to be > VersionRecord::Version.new('1.0.0.beta') }
|
149
|
+
it { expect(VersionRecord::Version.new('1.0.0.beta')).to be < VersionRecord::Version.new('1.0.0.beta.1') }
|
150
|
+
it { expect(VersionRecord::Version.new('1.0.0.beta')).to eq VersionRecord::Version.new('1.0.0.beta') }
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
describe '#to_version' do
|
155
|
+
it { expect(version.to_version).to eq version }
|
156
|
+
end
|
157
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: version_record
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Marcelo Casiraghi
|
@@ -10,6 +10,34 @@ bindir: bin
|
|
10
10
|
cert_chain: []
|
11
11
|
date: 2017-12-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: activesupport
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '5'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '5'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: activerecord
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '5'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '5'
|
13
41
|
- !ruby/object:Gem::Dependency
|
14
42
|
name: bundler
|
15
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -24,6 +52,76 @@ dependencies:
|
|
24
52
|
- - "~>"
|
25
53
|
- !ruby/object:Gem::Version
|
26
54
|
version: '1'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: byebug
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '9'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '9'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec-rails
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '3'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '3'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: sqlite3
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '1'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '1'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rails
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '5'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '5'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: appraisal
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '2'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '2'
|
27
125
|
description:
|
28
126
|
email: marcelo@cedarcode.com
|
29
127
|
executables: []
|
@@ -31,7 +129,27 @@ extensions: []
|
|
31
129
|
extra_rdoc_files: []
|
32
130
|
files:
|
33
131
|
- lib/version_record.rb
|
132
|
+
- lib/version_record/core_ext/string.rb
|
133
|
+
- lib/version_record/finder.rb
|
34
134
|
- lib/version_record/gem_version.rb
|
135
|
+
- lib/version_record/macros.rb
|
136
|
+
- lib/version_record/macros/versioned.rb
|
137
|
+
- lib/version_record/prerelease.rb
|
138
|
+
- lib/version_record/sorting/simple.rb
|
139
|
+
- lib/version_record/type/version.rb
|
140
|
+
- lib/version_record/version.rb
|
141
|
+
- spec/rails_helper.rb
|
142
|
+
- spec/spec_helper.rb
|
143
|
+
- spec/support/apps/rails5_0.rb
|
144
|
+
- spec/support/apps/rails5_1.rb
|
145
|
+
- spec/support/model_spawner.rb
|
146
|
+
- spec/version_record/finder_spec.rb
|
147
|
+
- spec/version_record/macros/versioned_spec.rb
|
148
|
+
- spec/version_record/prerelease_spec.rb
|
149
|
+
- spec/version_record/sorting/simple_spec.rb
|
150
|
+
- spec/version_record/string_spec.rb
|
151
|
+
- spec/version_record/type/version_spec.rb
|
152
|
+
- spec/version_record/version_spec.rb
|
35
153
|
homepage: https://github.com/cedarcode/version_record
|
36
154
|
licenses:
|
37
155
|
- MIT
|
@@ -55,5 +173,17 @@ rubyforge_project:
|
|
55
173
|
rubygems_version: 2.6.10
|
56
174
|
signing_key:
|
57
175
|
specification_version: 4
|
58
|
-
summary:
|
59
|
-
test_files:
|
176
|
+
summary: Semantic version management for database records using ActiveRecord
|
177
|
+
test_files:
|
178
|
+
- spec/rails_helper.rb
|
179
|
+
- spec/spec_helper.rb
|
180
|
+
- spec/support/apps/rails5_0.rb
|
181
|
+
- spec/support/apps/rails5_1.rb
|
182
|
+
- spec/support/model_spawner.rb
|
183
|
+
- spec/version_record/finder_spec.rb
|
184
|
+
- spec/version_record/macros/versioned_spec.rb
|
185
|
+
- spec/version_record/prerelease_spec.rb
|
186
|
+
- spec/version_record/sorting/simple_spec.rb
|
187
|
+
- spec/version_record/string_spec.rb
|
188
|
+
- spec/version_record/type/version_spec.rb
|
189
|
+
- spec/version_record/version_spec.rb
|