json-orm 0.1.0 → 0.2.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 461557a2ba968f8defd11ef7b9d883a90b1266c2a1d6efb25efb90557934c43e
4
- data.tar.gz: fe002f32aa2023c804739b45e339cf460806bf5346861cc07e9b5b14d674f05b
3
+ metadata.gz: f67bc2b71e782a57b186e7c91bcb25c58e059c51b60e555dc7c44ea933e63f92
4
+ data.tar.gz: 605844dcf63751a0534fc78ca3d6a886f96b8e1f8d398592474eb5bdc36f4a82
5
5
  SHA512:
6
- metadata.gz: 815c89c584fbd99e2ffeafd23e2c06ca0929652b21d437cd74a50cc775ad1df6a2927191d7fb43fd958e740fac18e45c76ac67735f0d605b910c22208a0b861a
7
- data.tar.gz: d382da205f87b4374f434533c70dfc4a12facb2f9b59eeb34bdacb7c702ac9b3c5f147e5d106acd878c7a4fa932635f1993a5b99b2784bcd63db84789d4fe430
6
+ metadata.gz: 8d57af525617a2126d65130b7d31cb2bbb90ec95fd16026d8ba52337e450d0450bce534dce76a465917bd9d319b74770553822962b09c342ae4a8ffc9b1d963a
7
+ data.tar.gz: e8954174120777083c723afdad1987a8a70a07fb1b1476008893002a611232c66f0911afea9d9208dcd01e13d580e5232be7695ae85731caf148a0ac4ca2c8b3
@@ -0,0 +1,45 @@
1
+ name: Ruby Gem
2
+
3
+ on:
4
+ push:
5
+ branches: [ "main" ]
6
+ pull_request:
7
+ branches: [ "main" ]
8
+
9
+ jobs:
10
+ build:
11
+ name: Build + Publish
12
+ runs-on: ubuntu-latest
13
+ permissions:
14
+ contents: read
15
+ packages: write
16
+
17
+ steps:
18
+ - uses: actions/checkout@v4
19
+ - name: Set up Ruby 3.2.0
20
+ uses: ruby/setup-ruby@v1
21
+ with:
22
+ ruby-version: 3.2.0
23
+
24
+ - name: Publish to GPR
25
+ run: |
26
+ mkdir -p $HOME/.gem
27
+ touch $HOME/.gem/credentials
28
+ chmod 0600 $HOME/.gem/credentials
29
+ printf -- "---\n:github: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
30
+ gem build *.gemspec
31
+ gem push --KEY github --host https://rubygems.pkg.github.com/${OWNER} *.gem
32
+ env:
33
+ GEM_HOST_API_KEY: "Bearer ${{secrets.GITHUB_TOKEN}}"
34
+ OWNER: ${{ github.repository_owner }}
35
+
36
+ - name: Publish to RubyGems
37
+ run: |
38
+ mkdir -p $HOME/.gem
39
+ touch $HOME/.gem/credentials
40
+ chmod 0600 $HOME/.gem/credentials
41
+ printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
42
+ gem build *.gemspec
43
+ gem push *.gem
44
+ env:
45
+ GEM_HOST_API_KEY: "${{secrets.RUBYGEMS_AUTH_TOKEN}}"
@@ -0,0 +1,25 @@
1
+ name: Test Minitest
2
+
3
+ on:
4
+ push:
5
+ paths-ignore:
6
+ - README.md
7
+ - LICENSE
8
+
9
+ jobs:
10
+ test:
11
+ name: Run tests
12
+ runs-on: ubuntu-latest
13
+ permissions:
14
+ contents: read
15
+ packages: write
16
+
17
+ steps:
18
+ - uses: actions/checkout@v4
19
+ - name: Set up Ruby 3.2.0
20
+ uses: ruby/setup-ruby@v1
21
+ with:
22
+ ruby-version: 3.2.0
23
+
24
+ - name: Minitest
25
+ run: rake test
data/.rubocop.yml ADDED
@@ -0,0 +1,2 @@
1
+ Style/Documentation:
2
+ Enabled: false
data/README.md CHANGED
@@ -18,10 +18,11 @@ While designed for simplicity and ease of use, `json-orm` hasn't been optimized
18
18
  ## Future Plans
19
19
 
20
20
  - [ ] Refactor logging
21
- - [ ] Add tests to DB class
22
- - [ ] Clean up better after test
23
- - [ ] Improve test to validate reliability
24
- - [ ] Add Validations class
21
+ - [x] Add tests to DB class
22
+ - [] Add RuboCop to GitHub Actions
23
+ - [] Clean up better after test
24
+ - [x] Improve test to validate reliability
25
+ - [x] Add Validations class
25
26
 
26
27
  ## Installation 🔧
27
28
 
@@ -53,14 +54,114 @@ orm.begin_transaction
53
54
  orm.commit_transaction
54
55
  ```
55
56
 
56
- ### Custom Validations
57
+ ### JSONORM::Validations
58
+
59
+ The `JSONORM::Validations` module provides a flexible way to add validations to your Ruby objects. Here's how to use the newly added validators:
60
+
61
+ #### Length Validator
62
+ Checks if the length of a value is within a specified range.
63
+
64
+ **Usage:**
65
+
66
+ ```ruby
67
+ validate :attribute_name, :length, minimum: 5, maximum: 10
68
+ ```
69
+
70
+ **Example:**
71
+
72
+ ```ruby
73
+ class User
74
+ include JSONORM::Validations
75
+
76
+ attr_accessor :name
77
+
78
+ validate :name, :length, minimum: 3, maximum: 50
79
+ end
80
+
81
+ user = User.new
82
+ user.name = "Jo"
83
+ user.validate! # Raises "Validation failed: name is too short (minimum is 3 characters)"
84
+ ```
85
+
86
+ #### Inclusion Validator
87
+ Ensures a value is included in a specified set.
88
+
89
+ **Usage:**
57
90
 
58
91
  ```ruby
59
- JSONORM.register_validator(:email) do |value|
60
- # Validation logic...
92
+ validate :attribute_name, :inclusion, in: [set_of_values]
93
+ ```
94
+
95
+ **Example:**
96
+
97
+ ```ruby
98
+ class Product
99
+ include JSONORM::Validations
100
+
101
+ attr_accessor :category
102
+
103
+ validate :category, :inclusion, in: ['book', 'electronics', 'clothing']
61
104
  end
105
+
106
+ product = Product.new
107
+ product.category = "food"
108
+ product.validate! # Raises "Validation failed: category is not included in the list"
62
109
  ```
63
110
 
111
+ #### Exclusion Validator
112
+ Ensures a value is not included in a specified set.
113
+
114
+ **Usage:**
115
+
116
+ ```ruby
117
+ validate :attribute_name, :exclusion, in: [set_of_values]
118
+ ```
119
+
120
+ **Example:**
121
+
122
+ ```ruby
123
+ class Account
124
+ include JSONORM::Validations
125
+
126
+ attr_accessor :username
127
+
128
+ validate :username, :exclusion, in: ['admin', 'root']
129
+ end
130
+
131
+ account = Account.new
132
+ account.username = "admin"
133
+ account.validate! # Raises "Validation failed: username is reserved"
134
+ ```
135
+
136
+ #### Custom Validator
137
+ Allows for custom validation logic through a lambda or proc.
138
+
139
+ **Usage:**
140
+
141
+ ```ruby
142
+ validate :attribute_name, :custom, with: lambda { |value| some_custom_condition }
143
+ ```
144
+
145
+ **Example:**
146
+
147
+ ```ruby
148
+ class Order
149
+ include JSONORM::Validations
150
+
151
+ attr_accessor :total_price
152
+
153
+ validate :total_price, :custom, with: ->(value) { value > 0 && value < 10000 }
154
+ end
155
+
156
+ order = Order.new
157
+ order.total_price = -5
158
+ order.validate! # Raises "Validation failed: total_price is not valid"
159
+ ```
160
+
161
+ #### Integrating Validators
162
+
163
+ To integrate these validators into your `validate!` method, simply add the cases as shown in the initial response to handle each validation type. Ensure that your `validate!` method checks for each validator type and applies the corresponding validation logic.
164
+
64
165
  ### Query Chaining
65
166
 
66
167
  ```ruby
data/Rakefile ADDED
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
4
+ require 'rake/testtask'
5
+
6
+ Rake::TestTask.new(:test) do |t|
7
+ t.libs << 'test'
8
+ t.test_files = FileList['test/**/test_*.rb']
9
+ t.verbose = true
10
+ t.warning = true
11
+ t.ruby_opts = ['-I"test"', '-r./test/helper']
12
+ end
13
+
14
+ # Set the default task to :test if you want `rake` to run tests by default
15
+ task default: :test
16
+
17
+ desc 'Tag the current version and push tags to remote'
18
+ task :tag do
19
+ version = File.read(File.join(File.dirname(__FILE__), 'lib', 'json-orm',
20
+ 'version.rb')).match(/VERSION = ['"](.*)['"]/)[1]
21
+ `git tag -a v#{version} -m "Release version #{version}"`
22
+ `git push origin v#{version}`
23
+ end
data/json-orm.gemspec CHANGED
@@ -1,20 +1,25 @@
1
+ # frozen_string_literal: true
2
+
1
3
  Gem::Specification.new do |spec|
2
- spec.name = "json-orm"
3
- spec.version = File.read(File.join(File.dirname(__FILE__), 'lib', 'json-orm', 'version.rb')).match(/VERSION = ['"](.*)['"]/)[1]
4
- spec.authors = ["Damir Mukimov"]
5
- spec.email = ["mukimov.d@gmail.com"]
4
+ spec.name = 'json-orm'
5
+ required_ruby_version = '>= 3.2.0'
6
+ spec.version = File.read(File.join(File.dirname(__FILE__), 'lib', 'json-orm',
7
+ 'version.rb')).match(/VERSION = ['"](.*)['"]/)[1]
8
+ spec.authors = ['Damir Mukimov']
9
+ spec.email = ['mukimov.d@gmail.com']
6
10
 
7
- spec.summary = %q{A lightweight, JSON-based ORM for Ruby}
8
- spec.description = %q{Provides basic ORM functionalities like CRUD operations, transaction support, and custom validations.}
9
- spec.homepage = "https://www.glowing-pixels.com/json-orm"
10
- spec.license = "MIT"
11
+ spec.summary = 'A lightweight, JSON-based ORM for Ruby'
12
+ spec.description = 'Provides basic ORM functionalities like CRUD operations, transaction support, and custom validations.'
13
+ spec.homepage = 'https://www.glowing-pixels.com/json-orm'
14
+ spec.license = 'MIT'
11
15
 
12
16
  spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
13
- spec.bindir = "exe"
17
+ spec.bindir = 'exe'
14
18
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
15
- spec.require_paths = ["lib"]
19
+ spec.require_paths = ['lib']
16
20
 
17
- spec.add_development_dependency "bundler", "~> 2.0"
18
- spec.add_development_dependency "rake", "~> 13.0"
19
- spec.add_development_dependency "minitest", "~> 5.0"
21
+ spec.add_development_dependency 'bundler', '~> 2.0'
22
+ spec.add_development_dependency 'minitest', '~> 5.0'
23
+ spec.add_development_dependency 'rake', '~> 13.0'
24
+ spec.add_development_dependency 'rubocop'
20
25
  end
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'logger'
4
+
5
+ module JSONORM
6
+ class BaseModel
7
+ include Validations
8
+ class << self
9
+ attr_accessor :attributes_list, :orm_instance
10
+
11
+ def attributes(*names)
12
+ @attributes_list ||= []
13
+ names.each do |name|
14
+ attr_accessor name unless method_defined?(name)
15
+ @attributes_list << name unless @attributes_list.include?(name)
16
+ end
17
+ attr_accessor :id unless method_defined?(:id)
18
+ @attributes_list << :id unless @attributes_list.include?(:id)
19
+ end
20
+ end
21
+
22
+ def self.inherited(subclass)
23
+ subclass.attributes_list = []
24
+ subclass.orm_instance = nil
25
+ end
26
+
27
+ def initialize(attributes = {}, orm_instance:)
28
+ raise 'ORM instance is required' unless orm_instance
29
+
30
+ self.class.orm_instance = orm_instance
31
+ @orm_instance = orm_instance
32
+ attributes.each do |attr, value|
33
+ send("#{attr}=", value) if self.class.attributes_list.include?(attr.to_sym)
34
+ end
35
+ end
36
+
37
+ def save
38
+ validate!
39
+ data = self.class.attributes_list.each_with_object({}) do |attr, hash|
40
+ hash[attr] = send(attr)
41
+ end
42
+
43
+ result = if id.nil? || id.to_s.empty?
44
+ @orm_instance.create(data)
45
+ else
46
+ @orm_instance.update(id, data)
47
+ end
48
+ self.id = result[:id] if result.is_a?(Hash) && result.key?(:id)
49
+ true
50
+ rescue StandardError => e
51
+ logger.error("Failed to save record for #{self.class.name}, Error: #{e.message}")
52
+ raise "Failed to save record: #{e.message}"
53
+ end
54
+
55
+ private
56
+
57
+ def logger
58
+ @logger ||= Logger.new($stdout)
59
+ end
60
+ end
61
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module JSONORM
2
4
  class ChainableQuery
3
5
  def initialize(orm, data)
@@ -14,4 +16,4 @@ module JSONORM
14
16
  @data
15
17
  end
16
18
  end
17
- end
19
+ end
data/lib/json-orm/db.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'json'
2
4
  require 'fileutils'
3
5
  require 'logger'
@@ -20,18 +22,17 @@ module JSONORM
20
22
  end
21
23
  end
22
24
 
23
- def write(data)
24
- with_lock do
25
- create_backup
26
- File.open(file_path, 'w') { |f| f.write(JSON.pretty_generate(data)) }
27
- logger.info("Data written successfully")
28
- rescue IOError => e
29
- restore_backup
30
- logger.error("Error writing to file: #{e.message}")
31
- raise "Error writing to file: #{e.message}"
25
+ def write(data)
26
+ with_lock do
27
+ create_backup
28
+ File.open(file_path, 'w') { |f| f.write(JSON.pretty_generate(data)) }
29
+ logger.info('Data written successfully')
30
+ rescue IOError => e
31
+ restore_backup
32
+ logger.error("Error writing to file: #{e.message}")
33
+ raise "Error writing to file: #{e.message}"
34
+ end
32
35
  end
33
- end
34
-
35
36
 
36
37
  private
37
38
 
@@ -40,22 +41,21 @@ module JSONORM
40
41
  end
41
42
 
42
43
  def create_backup
43
- logger.info("Creating backup")
44
+ logger.info('Creating backup')
44
45
  FileUtils.cp(file_path, backup_path)
45
- rescue => e
46
+ rescue StandardError => e
46
47
  logger.error("Failed to create backup: #{e.message}")
47
48
  raise "Failed to create backup: #{e.message}"
48
49
  end
49
50
 
50
51
  def restore_backup
51
- logger.info("Restoring from backup")
52
+ logger.info('Restoring from backup')
52
53
  FileUtils.cp(backup_path, file_path)
53
- rescue => e
54
+ rescue StandardError => e
54
55
  logger.error("Failed to restore backup: #{e.message}")
55
56
  raise "Failed to restore backup: #{e.message}"
56
57
  end
57
58
 
58
-
59
59
  def with_lock
60
60
  File.open("#{file_path}.lock", 'w') do |f|
61
61
  f.flock(File::LOCK_EX)
@@ -66,4 +66,3 @@ module JSONORM
66
66
  end
67
67
  end
68
68
  end
69
-
data/lib/json-orm/orm.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module JSONORM
2
4
  class ORM
3
5
  attr_reader :database, :transaction_data, :logger
@@ -41,7 +43,7 @@ module JSONORM
41
43
  end
42
44
 
43
45
  def create(attributes)
44
- attributes[:id] = next_id unless attributes.key?(:id)
46
+ attributes[:id] = next_id unless attributes.key?(:id) && attributes[:id]
45
47
  validate_attributes!(attributes)
46
48
  transaction_data.push(attributes)
47
49
  attributes
@@ -69,10 +71,10 @@ module JSONORM
69
71
  end
70
72
 
71
73
  def commit_transaction
72
- logger.info("Starting transaction commit")
74
+ logger.info('Starting transaction commit')
73
75
  database.write(transaction_data)
74
- logger.info("Transaction committed successfully")
75
- rescue => e
76
+ logger.info('Transaction committed successfully')
77
+ rescue StandardError => e
76
78
  logger.error("Failed to commit transaction: #{e.message}")
77
79
  raise "Failed to commit transaction: #{e.message}"
78
80
  ensure
@@ -95,20 +97,17 @@ module JSONORM
95
97
  end
96
98
 
97
99
  def validate_attributes!(attributes, check_id = true)
98
- raise "Record must have an id" if check_id && !attributes[:id]
100
+ raise 'Record must have an id' if check_id && !attributes[:id]
99
101
 
100
102
  attributes.each do |key, value|
101
103
  validate_attribute(key, value)
102
104
  end
103
105
  end
104
106
 
105
- # Update the validation method
106
107
  def validate_attribute(key, value)
107
- if self.class.custom_validators[key]
108
- self.class.custom_validators[key].call(value)
109
- else
110
- # Default validations (if any)
111
- end
108
+ return unless self.class.custom_validators.key?(key)
109
+
110
+ self.class.custom_validators[key].call(value)
112
111
  end
113
112
  end
114
- end
113
+ end
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ module JSONORM
4
+ module Validations
5
+ def self.included(base)
6
+ base.extend(ClassMethods)
7
+ end
8
+
9
+ module ClassMethods
10
+ def validate(attribute, validation_type, options = {})
11
+ @validators ||= {}
12
+ @validators[attribute] ||= []
13
+ @validators[attribute] << { type: validation_type, options: options }
14
+ end
15
+
16
+ def validators
17
+ @validators || {}
18
+ end
19
+ end
20
+
21
+ def validate!
22
+ self.class.validators.each do |attribute, validators|
23
+ validators.each do |validator|
24
+ value = send(attribute)
25
+ case validator[:type]
26
+ when :presence
27
+ raise "Validation failed: #{attribute} can't be blank" if value.nil? || value.to_s.empty?
28
+ when :format
29
+ regex = validator[:options][:with]
30
+ raise "Validation failed: #{attribute} is invalid" unless value.match?(regex)
31
+ when :numericality
32
+ raise "Validation failed: #{attribute} is not a number" unless value.is_a?(Numeric)
33
+ when :length
34
+ min_length = validator[:options][:minimum] || 0
35
+ max_length = validator[:options][:maximum] || Float::INFINITY
36
+ actual_length = value.to_s.length
37
+ if actual_length < min_length
38
+ raise "Validation failed: #{attribute} is too short (minimum is #{min_length} characters)"
39
+ elsif actual_length > max_length
40
+ raise "Validation failed: #{attribute} is too long (maximum is #{max_length} characters)"
41
+ end
42
+ when :inclusion
43
+ in_set = validator[:options][:in]
44
+ raise "Validation failed: #{attribute} is not included in the list" unless in_set.include?(value)
45
+ when :exclusion
46
+ in_set = validator[:options][:in]
47
+ raise "Validation failed: #{attribute} is reserved" if in_set.include?(value)
48
+ when :custom
49
+ custom_validation = validator[:options][:with]
50
+ raise "Validation failed: #{attribute} is not valid" unless custom_validation.call(value)
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module JSONORM
2
- VERSION = "0.1.0"
4
+ VERSION = '0.2.1'
3
5
  end
data/lib/json-orm.rb CHANGED
@@ -1,9 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'logger'
2
4
  require_relative 'json-orm/version'
3
5
  require_relative 'json-orm/db'
4
6
  require_relative 'json-orm/orm'
5
7
  require_relative 'json-orm/chainable-query'
8
+ require_relative 'json-orm/validations'
6
9
 
7
10
  module JSONORM
8
- # Your gem's core logic or namespace setup
9
- end
11
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: json-orm
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Damir Mukimov
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-02-11 00:00:00.000000000 Z
11
+ date: 2024-02-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '2.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: minitest
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '5.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '5.0'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: rake
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -39,19 +53,19 @@ dependencies:
39
53
  - !ruby/object:Gem::Version
40
54
  version: '13.0'
41
55
  - !ruby/object:Gem::Dependency
42
- name: minitest
56
+ name: rubocop
43
57
  requirement: !ruby/object:Gem::Requirement
44
58
  requirements:
45
- - - "~>"
59
+ - - ">="
46
60
  - !ruby/object:Gem::Version
47
- version: '5.0'
61
+ version: '0'
48
62
  type: :development
49
63
  prerelease: false
50
64
  version_requirements: !ruby/object:Gem::Requirement
51
65
  requirements:
52
- - - "~>"
66
+ - - ">="
53
67
  - !ruby/object:Gem::Version
54
- version: '5.0'
68
+ version: '0'
55
69
  description: Provides basic ORM functionalities like CRUD operations, transaction
56
70
  support, and custom validations.
57
71
  email:
@@ -60,16 +74,21 @@ executables: []
60
74
  extensions: []
61
75
  extra_rdoc_files: []
62
76
  files:
77
+ - ".github/workflows/gem-push.yml"
78
+ - ".github/workflows/test.yml"
63
79
  - ".gitignore"
80
+ - ".rubocop.yml"
64
81
  - LICENSE
65
82
  - README.md
83
+ - Rakefile
66
84
  - json-orm.gemspec
67
85
  - lib/json-orm.rb
86
+ - lib/json-orm/base_model.rb
68
87
  - lib/json-orm/chainable-query.rb
69
88
  - lib/json-orm/db.rb
70
89
  - lib/json-orm/orm.rb
90
+ - lib/json-orm/validations.rb
71
91
  - lib/json-orm/version.rb
72
- - test_jsorm.rb
73
92
  homepage: https://www.glowing-pixels.com/json-orm
74
93
  licenses:
75
94
  - MIT
@@ -89,7 +108,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
89
108
  - !ruby/object:Gem::Version
90
109
  version: '0'
91
110
  requirements: []
92
- rubygems_version: 3.4.1
111
+ rubygems_version: 3.5.6
93
112
  signing_key:
94
113
  specification_version: 4
95
114
  summary: A lightweight, JSON-based ORM for Ruby
data/test_jsorm.rb DELETED
@@ -1,109 +0,0 @@
1
- require 'minitest/autorun'
2
- require_relative 'lib/json-orm'
3
-
4
- class JSONORMTest < Minitest::Test
5
- def setup
6
- @db = JSONORM::DB.new('test_data.json', 'orm.test.log')
7
- @orm = JSONORM::ORM.new(@db, 'orm.test.log')
8
- @orm.begin_transaction
9
- end
10
-
11
- def after_tests
12
- File.delete('test_data.json.backup') if File.exist?('test_data.backup')
13
- end
14
-
15
- def teardown
16
- @orm.rollback_transaction
17
- File.delete('test_data.json') if File.exist?('test_data.json')
18
- File.delete('test_data.json.lock') if File.exist?('test_data.json.lock')
19
- File.delete('test_data.json.backup') if File.exist?('test_data.backup')
20
- end
21
-
22
- def test_create
23
- record = @orm.create({"name": "John Doe", "email": "john@example.com"})
24
- assert_equal "John Doe", record[:name]
25
- assert_equal "john@example.com", record[:email]
26
- end
27
-
28
- def test_read
29
- record = @orm.create({"name": "Jane Doe", "email": "jane@example.com"})
30
- found = @orm.find(record[:id])
31
- assert_equal "Jane Doe", found[:name]
32
- assert_equal "jane@example.com", found[:email]
33
- end
34
-
35
- def test_update
36
- record = @orm.create({"name": "Jim Doe", "email": "jim@example.com"})
37
- @orm.update(record[:id], {name: "James Doe"})
38
- updated = @orm.find(record[:id])
39
-
40
- assert_equal "James Doe", updated[:name]
41
- assert_equal "jim@example.com", updated[:email]
42
- end
43
-
44
- def test_delete
45
- record = @orm.create({"name": "Jack Doe", "email": "jack@example.com"})
46
- @orm.delete(record[:id])
47
-
48
- assert_nil @orm.find(record[:id])
49
- end
50
-
51
- def test_transaction_commit
52
- @orm.begin_transaction
53
- record = @orm.create({"name": "Jill Doe", "email": "jill@example.com"})
54
- @orm.commit_transaction
55
- assert_equal "Jill Doe", @orm.find(record[:id])[:name]
56
- end
57
-
58
- def test_transaction_rollback
59
- record = @orm.create({"name": "Joe Doe", "email": "joe@example.com"})
60
- @orm.rollback_transaction
61
- assert_nil @orm.find(record[:id])
62
- end
63
-
64
- def test_valid_email
65
- JSONORM::ORM.register_validator(:email) do |value|
66
- raise "Invalid email format" unless value.match?(/\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i)
67
- end
68
-
69
- assert_raises("Invalid email format") do
70
- @orm.create({"name": "Invalid Email", "email": "invalid"})
71
- end
72
- end
73
-
74
- def test_valid_age
75
- JSONORM::ORM.register_validator(:age) do |value|
76
- raise "Invalid age" unless value.is_a?(Integer) && value >= 0
77
- end
78
-
79
- assert_raises(RuntimeError) do
80
- @orm.create({"name": "Invalid Age", "age": -5})
81
- end
82
- end
83
-
84
- def test_query_chaining
85
- @orm.create({"name": "Alice", "age": 30, "city": "Wonderland"})
86
- @orm.create({"name": "Bob", "age": 30, "city": "Gotham"})
87
- @orm.create({"name": "Charlie", "age": 40, "city": "Wonderland"})
88
-
89
- results = @orm.where(:age, 30).where(:city, "Wonderland").execute
90
- assert_equal 1, results.size
91
- assert_equal "Alice", results.first[:name]
92
- end
93
-
94
-
95
- def test_error_handling_on_write
96
- # Simulate an error during write operation, e.g., invalid data format
97
- @orm.create({"name": "Test", "email": "test@example.com"})
98
- @orm.database.stub :write, ->(_data) { raise IOError, "Write error" } do
99
- assert_raises(RuntimeError) { @orm.commit_transaction }
100
- end
101
- end
102
-
103
- def test_file_locking
104
- # Test to ensure file locking is working (may require mocking)
105
- # Mock file locking and simulate concurrent access
106
- end
107
-
108
- # Additional tests for other features or edge cases
109
- end