class2 0.5.2 → 0.6.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: 49d91ca721e5cefa4ee9663e3e4ca8edbb584315300888561fa2b70e49eb7923
4
- data.tar.gz: 486025e1a89a034b49dc9a5c243d5bae341e4880d10d2a204e07898acd5a0e21
3
+ metadata.gz: 9e33244884d5c16ee2b4d8b43195e2247bfc88ad9d829cfcdaf32efc25195a72
4
+ data.tar.gz: c1e550bf7044f09d66930f09a859f0bf6713e83a3f648d5fb511d0deef8ba9f1
5
5
  SHA512:
6
- metadata.gz: 9d85ef46fefd99c440a1fe0aa92724a3b217c8d14a6473d2ff025705604a40e40f234a0d0cbc730921301783d28f6ac5cfa2435bf631994bfc714fe649907d97
7
- data.tar.gz: 46e2460f0924ce6c17413d7a15b0c6fc8685b0784e87a173ab6d51464a1b9a535e4d82f742c3c8b7c263a5ec7afe67c8514a12d7938dae549fa531c87b56142a
6
+ metadata.gz: 9959d03761af0652265bb53e65d75614ddd47bdf0315ffe1f91d7a31396124d31b2bc3369272ebd64667b51792ef543f9ec99c800b963ed9680fc409a78d35f1
7
+ data.tar.gz: 9ca603b6e2dfc257d26d8e6e31aebcc6ef08af5c46c0bfc53fdc0552a15a926c1f3a86e1fa439c55cd487ef4d0ce86c6207a101d5f44688391fe0d2d340325ae
@@ -0,0 +1,25 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: ["**"]
6
+ pull_request:
7
+
8
+ jobs:
9
+ test:
10
+ runs-on: ubuntu-latest
11
+
12
+ strategy:
13
+ fail-fast: false
14
+ matrix:
15
+ ruby: ["2.7", "3.0", "3.1", "3.2", "3.3", "3.4", "4.0"]
16
+
17
+ steps:
18
+ - uses: actions/checkout@v7
19
+ - name: Set up Ruby
20
+ uses: ruby/setup-ruby@v1
21
+ with:
22
+ ruby-version: ${{ matrix.ruby }}
23
+ bundler-cache: true
24
+ - name: Run the default task
25
+ run: bundle exec rake
data/Changes CHANGED
@@ -1,3 +1,13 @@
1
+ 2026-09-16 v0.6.1
2
+ --------------------
3
+ * Add Class2::Inflector wrapper
4
+
5
+ 2024-10-15 v0.6.0
6
+ --------------------
7
+ * Bug fix: autoloading in data section with namespace
8
+ * Add support for Time conversion
9
+ * Remove use of deprecated Fixnum
10
+
1
11
  2020-04-24 v0.5.2
2
12
  --------------------
3
13
  * Bug fix: Fix NoMethodError in ActiveSupport 6's Module.parent
data/README.md CHANGED
@@ -2,8 +2,6 @@
2
2
 
3
3
  Easily create class hierarchies that support nested attributes, type conversion, equality, and more.
4
4
 
5
- [![Build Status](https://travis-ci.org/sshaw/class2.svg?branch=master)](https://travis-ci.org/sshaw/class2)
6
-
7
5
  ## Usage
8
6
 
9
7
  ```rb
@@ -126,6 +124,32 @@ For more info on accessor formats and JSON see:
126
124
  * [`Class2::UpperCamelCase`](https://www.rubydoc.info/gems/class2/Class2/UpperCamelCase)
127
125
  * [`Class2::LowerCamelCase`](https://www.rubydoc.info/gems/class2/Class2/LowerCamelCase)
128
126
 
127
+ [Using Ruby-specific JSON extensions](https://github.com/ruby/json?tab=readme-ov-file#usage) you can define
128
+ Ruby types in the JSON class2 will use for type conversion:
129
+
130
+ ```json
131
+ {
132
+ "your_class": {
133
+ "id": 0,
134
+ "name": "string",
135
+ "updated_at": {"json_class":"Time","s":0,"n":0},
136
+ }
137
+ }
138
+ ```
139
+
140
+ Then require the appropriate JSON conversion class:
141
+
142
+ ```rb
143
+ require "json/add/time"
144
+ ```
145
+
146
+ This will result in class2 creating a `MyClass` class with the following:
147
+
148
+ - `#id` returning an `Integer` instance
149
+ - `#name` returning a `String` instance
150
+ - `#updated_at` returning a `Time` instance
151
+
152
+ This will work for any [supported conversions](#conversions).
129
153
 
130
154
  You can also autoload a definition from a DATA section:
131
155
 
@@ -193,6 +217,7 @@ You can use any of these classes or their instances in your class definitions:
193
217
  * `Float`
194
218
  * `Hash`
195
219
  * `Integer`
220
+ * `Time`
196
221
  * `TrueClass`/`FalseClass` - either one will cause a boolean conversion
197
222
 
198
223
  Custom conversions are possible, just add the conversion to
data/class2.gemspec CHANGED
@@ -18,10 +18,10 @@ Gem::Specification.new do |spec|
18
18
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
19
19
  spec.require_paths = ["lib"]
20
20
 
21
- spec.add_dependency "activesupport", ">= 3.2", "< 7"
21
+ spec.add_dependency "activesupport", ">= 3.2", "< 9"
22
22
 
23
23
  spec.add_development_dependency "bundler"
24
- spec.add_development_dependency "rake", "~> 10.0"
24
+ spec.add_development_dependency "rake", "~> 13"
25
25
  spec.add_development_dependency "appraisal"
26
26
  spec.add_development_dependency "minitest"
27
27
  end
@@ -6,4 +6,4 @@ end
6
6
 
7
7
  source = $1
8
8
  namespace = source =~ %r{/lib/(.+?)(?:\.rb)?\z} ? $1 : File.basename(source, File.extname(source))
9
- Class2.autoload(namespace.camelize)
9
+ Class2.autoload(namespace.camelize, caller.unshift(caller[0]))
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/inflector"
4
+
5
+ class Class2
6
+ #
7
+ # String inflection used to convert attribute names into class names, method
8
+ # names, and JSON keys.
9
+ #
10
+ # A lightweight wrapper around ActiveSupport::Inflector. Class2 calls this
11
+ # instead of ActiveSupport's String and Module extensions so that the
12
+ # inflection library can be replaced without changing the rest of Class2.
13
+ #
14
+ module Inflector
15
+ extend self
16
+
17
+ def pluralize(word)
18
+ ActiveSupport::Inflector.pluralize(word.to_s)
19
+ end
20
+
21
+ def singularize(word)
22
+ ActiveSupport::Inflector.singularize(word.to_s)
23
+ end
24
+
25
+ #
26
+ # Convert a table, attribute, or method name into a class name.
27
+ # "user_statuses" => "UserStatus", "admin/user" => "Admin::User".
28
+ #
29
+ def classify(word)
30
+ ActiveSupport::Inflector.classify(word.to_s)
31
+ end
32
+
33
+ #
34
+ # "some_value" => "SomeValue", "some_value", true => "someValue".
35
+ # "/" becomes "::".
36
+ #
37
+ # ActiveSupport's second argument is the opposite of `lower`: it is true
38
+ # when the first letter should be upper cased.
39
+ #
40
+ def camelize(word, lower = false)
41
+ ActiveSupport::Inflector.camelize(word.to_s, !lower)
42
+ end
43
+
44
+ #
45
+ # "SomeValue" => "some_value", "Admin::User" => "admin/user".
46
+ #
47
+ def underscore(word)
48
+ ActiveSupport::Inflector.underscore(word.to_s)
49
+ end
50
+ end
51
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Class2
4
- VERSION = "0.5.2"
4
+ VERSION = "0.6.1"
5
5
  end
data/lib/class2.rb CHANGED
@@ -1,11 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "date"
4
+ require "time" # for parse()
4
5
  require "json"
6
+ require "rbconfig" # for autoload()
5
7
  require "active_support/core_ext/module"
6
8
  require "active_support/inflector"
7
9
 
8
10
  require "class2/version"
11
+ require "class2/inflector"
9
12
 
10
13
  no_export = ENV["CLASS2_NO_EXPORT"]
11
14
 
@@ -32,13 +35,13 @@ class Class2
32
35
  Hash => lambda { |v| sprintf "%s.respond_to?(:to_h) ? %s.to_h : %s", v, v, v },
33
36
  Integer => lambda { |v| "#{v} && Integer(#{v})" },
34
37
  String => lambda { |v| "#{v} && String(#{v})" },
38
+ Time => lambda { |v| "#{v} && Time.parse(#{v})" },
35
39
  TrueClass => lambda do |v|
36
40
  sprintf '["1", 1, 1.0, true].freeze.include?(%s.is_a?(String) ? %s.strip : %s)', v, v, v
37
41
  end
38
42
  }
39
43
 
40
44
  CONVERSIONS[FalseClass] = CONVERSIONS[TrueClass]
41
- CONVERSIONS[Fixnum] = CONVERSIONS[Integer]
42
45
  CONVERSIONS.default = lambda { |v| v }
43
46
 
44
47
  class << self
@@ -58,11 +61,19 @@ class Class2
58
61
  nil
59
62
  end
60
63
 
61
- def autoload(namespace = Object) # :nodoc:
64
+ def autoload(namespace = Object, stack = nil) # :nodoc:
62
65
  failure = lambda { |message| abort "class2: cannot autoload class definitions: #{message}" }
63
- failure["cannot find the right caller"] unless caller.find do |line|
64
- # Ignore our autoload file and require()
65
- line.index("/class2/autoload.rb:").nil? && line.index("/kernel_require.rb:").nil? && line =~ /(.+):\d+:in\s+`\S/
66
+ #
67
+ # Ignore our autoload file and require()'s internals. Both their file
68
+ # names and the backtrace format change between Rubies: kernel_require.rb
69
+ # and bundled_gems.rb (3.3+) are where the frames come from, and since
70
+ # 3.4 frames are quoted with ' instead of `. Some Rubies report the
71
+ # rubygems frames as <internal:...>, which is not a readable path.
72
+ #
73
+ libdir = RbConfig::CONFIG["rubylibdir"]
74
+ failure["cannot find the right caller"] unless (stack || caller).find do |line|
75
+ line =~ /(.+):\d+:in\s+[`']\S/ && $1.index("/class2/autoload.rb").nil? &&
76
+ !$1.start_with?(libdir, "<internal:")
66
77
  end
67
78
 
68
79
  # Give this precedence over global DATA constant
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: class2
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.2
4
+ version: 0.6.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Skye Shaw
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-04-25 00:00:00.000000000 Z
11
+ date: 2026-09-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -19,7 +19,7 @@ dependencies:
19
19
  version: '3.2'
20
20
  - - "<"
21
21
  - !ruby/object:Gem::Version
22
- version: '7'
22
+ version: '9'
23
23
  type: :runtime
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
@@ -29,7 +29,7 @@ dependencies:
29
29
  version: '3.2'
30
30
  - - "<"
31
31
  - !ruby/object:Gem::Version
32
- version: '7'
32
+ version: '9'
33
33
  - !ruby/object:Gem::Dependency
34
34
  name: bundler
35
35
  requirement: !ruby/object:Gem::Requirement
@@ -50,14 +50,14 @@ dependencies:
50
50
  requirements:
51
51
  - - "~>"
52
52
  - !ruby/object:Gem::Version
53
- version: '10.0'
53
+ version: '13'
54
54
  type: :development
55
55
  prerelease: false
56
56
  version_requirements: !ruby/object:Gem::Requirement
57
57
  requirements:
58
58
  - - "~>"
59
59
  - !ruby/object:Gem::Version
60
- version: '10.0'
60
+ version: '13'
61
61
  - !ruby/object:Gem::Dependency
62
62
  name: appraisal
63
63
  requirement: !ruby/object:Gem::Requirement
@@ -86,15 +86,15 @@ dependencies:
86
86
  - - ">="
87
87
  - !ruby/object:Gem::Version
88
88
  version: '0'
89
- description:
89
+ description:
90
90
  email:
91
91
  - skye.shaw@gmail.com
92
92
  executables: []
93
93
  extensions: []
94
94
  extra_rdoc_files: []
95
95
  files:
96
+ - ".github/workflows/ci.yml"
96
97
  - ".gitignore"
97
- - ".travis.yml"
98
98
  - Appraisals
99
99
  - Changes
100
100
  - Gemfile
@@ -108,12 +108,13 @@ files:
108
108
  - lib/class2.rb
109
109
  - lib/class2/autoload.rb
110
110
  - lib/class2/autoload/namespaced.rb
111
+ - lib/class2/inflector.rb
111
112
  - lib/class2/version.rb
112
113
  homepage: https://github.com/sshaw/class2
113
114
  licenses:
114
115
  - MIT
115
116
  metadata: {}
116
- post_install_message:
117
+ post_install_message:
117
118
  rdoc_options: []
118
119
  require_paths:
119
120
  - lib
@@ -128,9 +129,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
128
129
  - !ruby/object:Gem::Version
129
130
  version: '0'
130
131
  requirements: []
131
- rubyforge_project:
132
- rubygems_version: 2.7.6
133
- signing_key:
132
+ rubygems_version: 3.3.27
133
+ signing_key:
134
134
  specification_version: 4
135
135
  summary: Easily create hierarchies of classes that support nested attributes, type
136
136
  conversion, equality, and more.
data/.travis.yml DELETED
@@ -1,30 +0,0 @@
1
- sudo: false
2
- language: ruby
3
- cache: bundler
4
- rvm:
5
- - jruby-9
6
- - 2.3
7
- - 2.4
8
- - 2.5
9
- - 2.6
10
- - 2.7
11
-
12
- before_install:
13
- - gem install bundler
14
-
15
- gemfile:
16
- - gemfiles/as4.gemfile
17
- - gemfiles/as5.gemfile
18
- - gemfiles/as6.gemfile
19
-
20
- matrix:
21
- exclude:
22
- - rvm: 2.3
23
- gemfile: gemfiles/as6.gemfile
24
- - rvm: 2.4
25
- gemfile: gemfiles/as6.gemfile
26
- - rvm: 2.7
27
- gemfile: gemfiles/as4.gemfile
28
-
29
- notifications:
30
- email: false