Skip to content

Commit

Permalink
Use without inheritance (#3)
Browse files Browse the repository at this point in the history
  • Loading branch information
leonovk committed Dec 3, 2023
1 parent 75b1244 commit 17361ed
Show file tree
Hide file tree
Showing 11 changed files with 121 additions and 37 deletions.
2 changes: 1 addition & 1 deletion .examples/example.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
yaml:
start:
kek:
lol: 'text'
cheburek: 'cheburek'
Expand Down
2 changes: 1 addition & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
PATH
remote: .
specs:
activeyaml (1.1.1)
activeyaml (1.2.0)
psych (~> 5.1)

GEM
Expand Down
29 changes: 23 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ require 'active_yaml'
You can create models that will take data from your Yaml files. Suppose you have the following Yaml file: `examples/example.yaml`. With the following content:

```yaml
yaml:
start:
kek:
lol: 'text'
cheburek: 'cheburek'
Expand All @@ -49,14 +49,14 @@ You can then create instances of your model and use call chains to retrieve data

```ruby
user = User.new
user.yaml.kek.lol # output: 'text'
user.yaml.kek.users.first # output: '1'
user.start.kek.lol # output: 'text'
user.start.kek.users.first # output: '1'
```

If you complete the chain not to the final value. You will get an object like a hash. It won't respond to []. However, you can use a dot to go through the values further. This object also has a “hash” method, which returns the current received hash.

```ruby
h = user.yaml.kek.hash
h = user.start.kek.hash
h == {'lok' => 'text'} # true
h.is_a?(Hash) # true
```
Expand All @@ -69,7 +69,7 @@ class User < ActiveYaml::BaseModel

# The method will return "text"
def test_method
yaml.kek.lol
start.kek.lol
end
end
```
Expand All @@ -81,11 +81,28 @@ user.yaml_data # will return a hash with the contents from the Yaml file
```

### Usage without model

You can add class methods to your class to work with Yaml files directly without creating class instances

```ruby
class User
extend ActiveYaml::ClassMethods
yaml 'examples/example.yaml'
end
```

After this, you can use class methods to make chains of calls.
```ruby
User.start.kek.lol # output: 'text'
```
With this use case, method `yaml_data` is also supported.


You also don't have to create models to use this framework. After that, an object will be instantiated in the user variable, allowing chains of calls to be made. To do this you can do the following:

```ruby
user = ActiveYaml.create('examples/example.yaml')
user.yaml.kek.lol # output: 'text'
user.start.kek.lol # output: 'text'
```

### Contribution
Expand Down
21 changes: 4 additions & 17 deletions lib/active_yaml.rb
Original file line number Diff line number Diff line change
@@ -1,35 +1,22 @@
# frozen_string_literal: true

require_relative 'active_yaml/parser'
require_relative 'active_yaml/yaml_hash'
require_relative 'active_yaml/method_mapper'
require_relative 'active_yaml/factory_hash'
require_relative 'active_yaml/class_methods'

# The main module from which work with gem begins
module ActiveYaml
extend FactoryHash

# Base class to inherit from to create models
class BaseModel
include MethodMapper

def self.yaml(file_path)
define_method(:yaml_data) do
@yaml_data = Parser.parse(file_path)
end
end

def method_missing(method, *args, &)
value = yaml_data[method.to_s]

if value
return value unless value.is_a?(Hash)

YamlHash.new(value)
else
super
end
end

def respond_to_missing?(method, include_private = false)
yaml_data[method.to_s] || super
end
end
end
17 changes: 17 additions & 0 deletions lib/active_yaml/class_methods.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# frozen_string_literal: true

require_relative 'method_mapper'
require_relative 'parser'

module ActiveYaml
# no doc
module ClassMethods
include MethodMapper

def yaml(file_path)
define_singleton_method(:yaml_data) do
@yaml_data = Parser.parse(file_path)
end
end
end
end
24 changes: 24 additions & 0 deletions lib/active_yaml/method_mapper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# frozen_string_literal: true

require_relative 'yaml_hash'

module ActiveYaml
# no doc
module MethodMapper
def method_missing(method, *args, &)
value = yaml_data[method.to_s]

if value
return value unless value.is_a?(Hash)

YamlHash.new(value)
else
super
end
end

def respond_to_missing?(method, include_private = false)
yaml_data[method.to_s] || super
end
end
end
2 changes: 1 addition & 1 deletion lib/active_yaml/version.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# frozen_string_literal: true

module ActiveYaml
VERSION = '1.1.1'
VERSION = '1.2.0'
end
12 changes: 6 additions & 6 deletions test/lib/active_yaml/base_model_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ class SomeUser < ActiveYaml::BaseModel
yaml '.examples/example.yaml'

def some_method
yaml.kek.lol
start.kek.lol
end
end

Expand All @@ -18,11 +18,11 @@ def setup

# rubocop:disable Naming/VariableNumber
def test_call_chain
result_1 = @user.yaml.kek.lol
result_1 = @user.start.kek.lol

assert_equal 'text', result_1

result_2 = @user.yaml.kek.users.first
result_2 = @user.start.kek.users.first

assert_equal '1', result_2
end
Expand All @@ -33,14 +33,14 @@ def test_some_method
end

def test_incomplete_call
result = @user.yaml.kek
result = @user.start.kek

assert result.is_a?(ActiveYaml::YamlHash)
end

def test_yaml_data
expect_hash = { 'yaml' => { 'kek' => { 'lol' => 'text', 'cheburek' => 'cheburek',
'users' => { 'first' => '1' } } } }
expect_hash = { 'start' => { 'kek' => { 'lol' => 'text', 'cheburek' => 'cheburek',
'users' => { 'first' => '1' } } } }

assert_equal @user.yaml_data, expect_hash
end
Expand Down
37 changes: 37 additions & 0 deletions test/lib/active_yaml/class_methods_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# frozen_string_literal: true

require_relative '../../test_helper'

class SomeUser
extend ActiveYaml::ClassMethods
yaml '.examples/example.yaml'
end

module ActiveYaml
class ClassMethodsTest < Minitest::Test
# rubocop:disable Naming/VariableNumber
def test_call_chain
result_1 = SomeUser.start.kek.lol

assert_equal 'text', result_1

result_2 = SomeUser.start.kek.users.first

assert_equal '1', result_2
end
# rubocop:enable Naming/VariableNumber

def test_incomplete_call
result = SomeUser.start.kek

assert result.is_a?(ActiveYaml::YamlHash)
end

def test_yaml_data
expect_hash = { 'start' => { 'kek' => { 'lol' => 'text', 'cheburek' => 'cheburek',
'users' => { 'first' => '1' } } } }

assert_equal SomeUser.yaml_data, expect_hash
end
end
end
4 changes: 2 additions & 2 deletions test/lib/active_yaml/parser_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
module ActiveYaml
class ParserTest < Minitest::Test
def test_parse
expect_hash = { 'yaml' => { 'kek' => { 'lol' => 'text', 'cheburek' => 'cheburek',
'users' => { 'first' => '1' } } } }
expect_hash = { 'start' => { 'kek' => { 'lol' => 'text', 'cheburek' => 'cheburek',
'users' => { 'first' => '1' } } } }
result = Parser.parse('.examples/example.yaml')

assert_equal result, expect_hash
Expand Down
8 changes: 5 additions & 3 deletions test/lib/active_yaml_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

require_relative '../test_helper'

# This test essentially covers:
# lib/active_yaml/factory_hash.rb
class ActiveYamlTest < Minitest::Test
def setup
@test_data = ActiveYaml.create('.examples/example.yaml')
Expand All @@ -10,18 +12,18 @@ def setup

# rubocop:disable Naming/VariableNumber
def test_call_chain
result_1 = @test_data.yaml.kek.lol
result_1 = @test_data.start.kek.lol

assert_equal 'text', result_1

result_2 = @test_data.yaml.kek.users.first
result_2 = @test_data.start.kek.users.first

assert_equal '1', result_2
end
# rubocop:enable Naming/VariableNumber

def test_incomplete_call
result = @test_data.yaml.kek
result = @test_data.start.kek

assert result.is_a?(ActiveYaml::YamlHash)
end
Expand Down

0 comments on commit 17361ed

Please sign in to comment.