nazar 0.0.5 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2c111b062edbb87fb756c39dcdf5628c7a71459a0f5cc98b9ae69f41894271e4
4
- data.tar.gz: 7979ca6f048af4bd2d52ad55b62c630bbdffe570ec127bd761243c9ce88c6770
3
+ metadata.gz: f3ea71c523b3f82b6882bdcb11b842e53b4f2283bc95d1ab5e8c0e17e2b1c9b6
4
+ data.tar.gz: 97017a09da4032dd35b90e34cd49cf92e96473f7c1f001a8f9ffab1c93ae6d2f
5
5
  SHA512:
6
- metadata.gz: 37cb2ef5920b6ee84296494e7f2c6e1f13fb0f3b6736ada3eb983933d9fc7384521c4fecf9328978fd6f94a778218541b7a21e35b45df6e426374bdb7be03d6a
7
- data.tar.gz: 85047535269ef0c782451c7c3d1c04a63f99ee4a412a1f34e557c6b951f72d54088191a7cf324eac82866c0c327f2fdb3277a8f7d2921dd43f31fb25206f63a1
6
+ metadata.gz: cb511b109dc83d28057e6454a5d438e799cfbb0a6eb64d2f0c55ae53dd8e92c19f0c78b4a361452307e41999738972260e2b5b4b6dc347c05ddaf81e49b452bd
7
+ data.tar.gz: 5c0f4e67fea1a380606dd75bac52de072ac9851f70b844ee8ba1464c73592e49cde3f0449fcb208cdb912b938e067fce4a8af0a7d5f7076e244e6b78d2cfa336
checksums.yaml.gz.sig CHANGED
Binary file
@@ -35,4 +35,8 @@ jobs:
35
35
  ruby-version: 2.7
36
36
  bundler-cache: true
37
37
  - name: Specs
38
- run: bundle exec rspec
38
+ uses: paambaati/codeclimate-action@v2.7.5
39
+ env:
40
+ CC_TEST_REPORTER_ID: ${{secrets.CC_TEST_REPORTER_ID}}
41
+ with:
42
+ coverageCommand: bundle exec rspec
data/README.md CHANGED
@@ -1,10 +1,154 @@
1
- # Nazar [![Build Status](https://github.com/krzyzak/nazar/actions/workflows/main.yml/badge.svg)](https://github.com/krzyzak/nazar/actions) [![Code Climate](https://codeclimate.com/github/krzyzak/nazar/badges/gpa.svg)](https://codeclimate.com/github/krzyzak/nazar)
1
+ # Nazar [![Build Status](https://github.com/krzyzak/nazar/actions/workflows/main.yml/badge.svg)](https://github.com/krzyzak/nazar/actions) [![Gem Version](https://badge.fury.io/rb/nazar.svg)](https://badge.fury.io/rb/nazar) [![Code Climate](https://codeclimate.com/github/krzyzak/nazar/badges/gpa.svg)](https://codeclimate.com/github/krzyzak/nazar) [![Test Coverage](https://api.codeclimate.com/v1/badges/f89b8bfdf557900e1f9f/test_coverage)](https://codeclimate.com/github/krzyzak/nazar/test_coverage)
2
2
 
3
- Nazar improves defvault inspect output for console applications (supports IRB and Pry).
3
+ Turn this:
4
+ ```ruby
5
+ >> User.all
6
+ User Load (0.4ms) SELECT "users".* FROM "users" /* loading for inspect */ LIMIT ? [["LIMIT", 11]]
7
+ => #<ActiveRecord::Relation [#<User id: 1, email: "delma@goldner.co", name: "Mrs. Charis Brown", description: "Quasi atque ea. Beatae corporis quia. Eveniet veli...", created_at: "2021-09-01 05:42:24.341344000 +0000", updated_at: "2021-09-20 09:36:29.289078000 +0000", active: false, last_login_at: nil>, #<User id: 2, email: "markpfeffer@wunschbraun.info", name: "Ms. Sherice Champlin", description: "Omnis ut illum. Non velit mollitia. Expedita facil...", created_at: "2021-09-10 07:27:00.182298000 +0000", updated_at: "2021-09-20 09:36:29.292065000 +0000", active: true, last_login_at: "2021-09-19 16:25:32.094418000 +0000">, #<User id: 3, email: "nathansimonis@kunde.org", name: "Florentino Gleason", description: "Non recusandae eos. Et voluptates iusto. Commodi e...", created_at: "2021-09-07 18:24:45.608164000 +0000", updated_at: "2021-09-20 09:36:29.293572000 +0000", active: false, last_login_at: nil>, #<User id: 4, email: "edwardowilkinson@walkerschiller.info", name: "Judie Boehm", description: "Ut ea eum. Tempore voluptates praesentium. Animi s...", created_at: "2021-09-05 02:11:36.564693000 +0000", updated_at: "2021-09-20 09:36:29.295763000 +0000", active: true, last_login_at: "2021-09-19 20:17:24.074515000 +0000">, #<User id: 5, email: "isaiahebert@brauncarroll.net", name: "Mari Ullrich", description: "Aperiam quas voluptas. Autem alias quia. Aut persp...", created_at: "2021-09-09 05:23:03.229860000 +0000", updated_at: "2021-09-20 09:36:29.296928000 +0000", active: nil, last_login_at: nil>, #<User id: 6, email: "alexander@anderson.io", name: "Sam Larson DDS", description: "Sed velit consectetur. Quas cupiditate enim. Neque...", created_at: "2021-09-03 02:52:14.055696000 +0000", updated_at: "2021-09-20 09:36:29.299157000 +0000", active: true, last_login_at: "2021-09-20 05:01:39.019563000 +0000">, #<User id: 7, email: "chirunolfon@keler.io", name: "Ying Kub I", description: "Cupiditate ut consequatur. Eos ab laboriosam. Ipsa...", created_at: "2021-09-10 05:52:32.005877000 +0000", updated_at: "2021-09-20 09:36:29.301469000 +0000", active: true, last_login_at: "2021-09-19 21:30:48.854010000 +0000">, #<User id: 8, email: "johnny@anderson.net", name: "Johnie Corwin II", description: "Suscipit itaque adipisci. Assumenda ad error. Quas...", created_at: "2021-09-12 13:05:49.845361000 +0000", updated_at: "2021-09-20 09:36:29.302657000 +0000", active: nil, last_login_at: nil>, #<User id: 9, email: "yahairakuhn@schneider.com", name: "Sharie Weber", description: "Sapiente voluptatum mollitia. Dolores voluptatum a...", created_at: "2021-09-19 03:03:39.360526000 +0000", updated_at: "2021-09-20 09:36:29.304929000 +0000", active: true, last_login_at: "2021-09-20 06:46:05.846685000 +0000">, #<User id: 10, email: "tommye@schuppe.biz", name: "Yoshiko Mohr", description: "Similique laborum totam. Non cum atque. Placeat qu...", created_at: "2021-09-08 05:41:36.588541000 +0000", updated_at: "2021-09-20 09:36:29.306120000 +0000", active: nil, last_login_at: nil>, ...]>
8
+ ```
9
+ Into this:
4
10
 
5
- **Nazar is under heavy development now. Expect bumpy ride or wait until the API will stabilise a bit ;)**
11
+ ```ruby
12
+ >> User.all
13
+ (0.6ms) SELECT sqlite_version(*)
14
+ User Load (0.8ms) SELECT "users".* FROM "users"
15
+ ┏━━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━┯━━━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━┓
16
+ ┃ id │ email │ name │ description │ created_at │ updated_at │ active │ last_login_at ┃
17
+ ┣═══════╪══════════════════════════════════════╪═══════════════════════╪═════════════════════════════════════════════════════════════════════════════════════════╪═════════════════════════╪═════════════════════════╪════════╪═════════════════════════┫
18
+ ┃ 1 │ delma@goldner.co │ Mrs. Charis Brown │ Quasi atque ea. Beatae corporis quia. Eveniet velit ad. │ 2021-09-01 05:42:24 UTC │ 2021-09-20 09:36:29 UTC │ ✗ │ ∅ ┃
19
+ ┃ 2 │ markpfeffer@wunschbraun.info │ Ms. Sherice Champlin │ Omnis ut illum. Non velit mollitia. Expedita facilis dignissimos. │ 2021-09-10 07:27:00 UTC │ 2021-09-20 09:36:29 UTC │ ✓ │ 2021-09-19 16:25:32 UTC ┃
20
+ ┃ 3 │ nathansimonis@kunde.org │ Florentino Gleason │ Non recusandae eos. Et voluptates iusto. Commodi est in. │ 2021-09-07 18:24:45 UTC │ 2021-09-20 09:36:29 UTC │ ✗ │ ∅ ┃
21
+ ┃ 4 │ edwardowilkinson@walkerschiller.info │ Judie Boehm │ Ut ea eum. Tempore voluptates praesentium. Animi sapiente distinctio. │ 2021-09-05 02:11:36 UTC │ 2021-09-20 09:36:29 UTC │ ✓ │ 2021-09-19 20:17:24 UTC ┃
22
+ ┃ 5 │ isaiahebert@brauncarroll.net │ Mari Ullrich │ Aperiam quas voluptas. Autem alias quia. Aut perspiciatis eos. │ 2021-09-09 05:23:03 UTC │ 2021-09-20 09:36:29 UTC │ ∅ │ ∅ ┃
23
+ ┃ 6 │ alexander@anderson.io │ Sam Larson DDS │ Sed velit consectetur. Quas cupiditate enim. Neque facere harum. │ 2021-09-03 02:52:14 UTC │ 2021-09-20 09:36:29 UTC │ ✓ │ 2021-09-20 05:01:39 UTC ┃
24
+ ┃ 7 │ chirunolfon@keler.io │ Ying Kub I │ Cupiditate ut consequatur. Eos ab laboriosam. Ipsam ut veritatis. │ 2021-09-10 05:52:32 UTC │ 2021-09-20 09:36:29 UTC │ ✓ │ 2021-09-19 21:30:48 UTC ┃
25
+ ┃ 8 │ johnny@anderson.net │ Johnie Corwin II │ Suscipit itaque adipisci. Assumenda ad error. Quas enim beatae. │ 2021-09-12 13:05:49 UTC │ 2021-09-20 09:36:29 UTC │ ∅ │ ∅ ┃
26
+ ┃ 9 │ yahairakuhn@schneider.com │ Sharie Weber │ Sapiente voluptatum mollitia. Dolores voluptatum accusamus. Veniam voluptatem deserunt. │ 2021-09-19 03:03:39 UTC │ 2021-09-20 09:36:29 UTC │ ✓ │ 2021-09-20 06:46:05 UTC ┃
27
+ ┃ 10 │ tommye@schuppe.biz │ Yoshiko Mohr │ Similique laborum totam. Non cum atque. Placeat quia velit. │ 2021-09-08 05:41:36 UTC │ 2021-09-20 09:36:29 UTC │ ∅ │ ∅ ┃
28
+ ┃ 11 │ derekbeier@hermankuhlman.co │ Lavern Feil │ Itaque molestias et. Iure tempora minus. Dolore autem omnis. │ 2021-09-05 04:04:51 UTC │ 2021-09-20 09:36:29 UTC │ ✗ │ ∅ ┃
29
+ ┃ 12 │ lavernwillms@runolfsdottirbogan.org │ Marcy Gottlieb Sr. │ Mollitia quia dolor. Libero laborum aperiam. Velit est eum. │ 2021-09-08 19:22:49 UTC │ 2021-09-20 09:36:29 UTC │ ✗ │ ∅ ┃
30
+ ┃ 13 │ earlhills@mclaughlingreenholt.info │ Adina Luettgen │ In qui rem. Illum itaque dignissimos. Enim vitae tenetur. │ 2021-09-08 10:16:12 UTC │ 2021-09-20 09:36:29 UTC │ ✗ │ ∅ ┃
31
+ ┃ 14 │ larry@rice.com │ Carolina Kuhlman II │ Ipsum ut fuga. Sunt id a. Rerum nulla sint. │ 2021-09-03 23:11:42 UTC │ 2021-09-20 09:36:29 UTC │ ∅ │ ∅ ┃
32
+ ┃ 15 │ randy@kuhicfritsch.name │ Harvey Runolfsdottir │ Dolorum officiis sed. Ut recusandae culpa. Odit aut nostrum. │ 2021-09-08 04:28:38 UTC │ 2021-09-20 09:36:29 UTC │ ∅ │ ∅ ┃
33
+ ┃ 16 │ lashaun@mooreleannon.co │ Lucio Raynor │ Et expedita rerum. Autem nesciunt labore. Suscipit aut eum. │ 2021-09-06 20:47:51 UTC │ 2021-09-20 09:36:29 UTC │ ✗ │ ∅ ┃
34
+ ┃ 17 │ omeryost@becker.com │ Rocky Hettinger │ Ut deleniti voluptas. Explicabo voluptas rerum. Illum sapiente quo. │ 2021-09-14 23:05:33 UTC │ 2021-09-20 09:36:29 UTC │ ✓ │ 2021-09-20 09:35:14 UTC ┃
35
+ ┃ 18 │ nilsa@corwinkub.name │ Serena Brakus │ Qui non provident. Omnis excepturi quasi. Ratione suscipit dolor. │ 2021-09-14 01:06:02 UTC │ 2021-09-20 09:36:29 UTC │ ✗ │ ∅ ┃
36
+ ┃ 19 │ berniebednar@spinkamiller.co │ Merlin Predovic │ Omnis et minus. Tempore in laboriosam. Molestiae aut eveniet. │ 2021-09-16 18:34:20 UTC │ 2021-09-20 09:36:29 UTC │ ✓ │ 2021-09-19 12:01:59 UTC ┃
37
+ ┃ 20 │ claude@smithamhaley.io │ Claudette Thompson MD │ Aut consectetur soluta. Laborum quia qui. Vel incidunt minima. │ 2021-09-10 03:53:24 UTC │ 2021-09-20 09:36:29 UTC │ ∅ │ ∅ ┃
38
+ ┃ 21 │ matilde@cormierstroman.name │ Dalton Witting │ Voluptatum provident earum. Ad esse odit. Quasi non ut. │ 2021-09-10 04:51:53 UTC │ 2021-09-20 09:36:29 UTC │ ✗ │ ∅ ┃
39
+ ┃ 22 │ randistrosin@littel.io │ Miss Lucio Kub │ Ea quia sapiente. Reprehenderit esse ut. Veritatis magnam quia. │ 2021-08-31 18:33:02 UTC │ 2021-09-20 09:36:29 UTC │ ✗ │ ∅ ┃
40
+ ┃ 23 │ noah@kuphal.co │ Alonzo Stroman │ Officia fugit eos. Qui quo et. Ducimus harum dignissimos. │ 2021-09-13 14:36:31 UTC │ 2021-09-20 09:36:29 UTC │ ✗ │ ∅ ┃
41
+ ┃ 24 │ cristinaschneider@cole.biz │ Dr. Newton Ritchie │ Corporis suscipit recusandae. Voluptas voluptas quo. Non perferendis fugiat. │ 2021-09-02 20:54:38 UTC │ 2021-09-20 09:36:29 UTC │ ✓ │ 2021-09-20 02:35:39 UTC ┃
42
+ ┃ 25 │ mirtha@spinkabayer.co │ Kory Cummings │ Aut ut aut. Quis voluptas sit. Consequatur quia voluptatibus. │ 2021-09-17 08:45:02 UTC │ 2021-09-20 09:36:29 UTC │ ✗ │ ∅ ┃
43
+ ┠───────┼──────────────────────────────────────┴───────────────────────┴─────────────────────────────────────────────────────────────────────────────────────────┴─────────────────────────┴─────────────────────────┴────────┴─────────────────────────┨
44
+ ┃ Total │ 25 ┃
45
+ ┗━━━━━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
46
+ ```
6
47
 
7
- [![asciicast](https://asciinema.org/a/436814.png)](https://asciinema.org/a/436814)
48
+ ## Installation
49
+
50
+ ### Per-project installation
51
+
52
+ While nothing stops you from adding Nazar to each project separately, I find it cumbersome to add it to every project I'm working on - it also alters REPL behaviour for other teammates, which is another reason why personally I don't recommend that approach. Anyway, here's quick how-to:
53
+
54
+ Add `nazar` to Gemfile:
55
+ ```ruby
56
+ group :development, :test do
57
+ gem 'nazar', require: false
58
+ end
59
+ ```
60
+ Then, you have to call `Nazar.enable!`. If you're using Rails, you might want to add this snippet to `config/application.rb`:
61
+
62
+ ```ruby
63
+ console do
64
+ require 'nazar'
65
+
66
+ Nazar.enable! # See configuration section for more options and
67
+ # Opt-in setup section if you don't want to enable it for every item
68
+ end
69
+ ```
70
+ Otherwise, call it in `bin/console` or any other script that launches your REPL.
71
+
72
+ ### Global installation
73
+
74
+ This is my recommended way to install this gem - that way it works automatically in all your projects, even in standalone `irb` or `pry` sessions.
75
+
76
+ - **Create global gems path**
77
+
78
+ `mkdir -p ~/.gem/ruby/global` - You're welcome to use any other path for your global gemset
79
+ - **Install nazar in your global gemset**
80
+
81
+ `gem install nazar -i ~/.gem/ruby/global`
82
+ - **Load Nazar in your REPL rc file**
83
+ Add following snippet to your `.irbrc` or `.pryrc`:
84
+
85
+ ```ruby
86
+ global_gemset_path = File.expand_path('~/.gem/ruby/global/gems')
87
+
88
+ if Dir.exist?(global_gemset_path)
89
+ global_gems_path = Dir.glob("#{global_gemset_path}/*/lib")
90
+
91
+ $LOAD_PATH.unshift(*global_gems_path)
92
+ end
93
+
94
+ %w[nazar].each do |gem|
95
+ begin
96
+ require gem
97
+ rescue LoadError
98
+ end
99
+ end
100
+
101
+ Nazar.enable! if defined?(Nazar)
102
+ ```
103
+
104
+ ## Shorthand method
105
+
106
+ Nazar defines top level `__(data)` method, that can be useful for two things:
107
+
108
+ ### Inspecting (array of) Hashes/Structs
109
+
110
+ Nazar by design won't enhance output for any collection that does not consist of supported (eg. ActiveRecord/Sequel) items. If you have a data that is structurally compatible (ie: all items consists of the same keys), and want to enahance the output, you can simply use `#__` method:
111
+
112
+ ```ruby
113
+ __ [{foo: :bar, test: 123},{foo: :baz, test: 456}]
114
+ ┏━━━━━━━┯━━━━━━┓
115
+ ┃ foo │ test ┃
116
+ ┣═══════╪══════┫
117
+ ┃ :bar │ 123 ┃
118
+ ┃ :baz │ 456 ┃
119
+ ┠───────┼──────┨
120
+ ┃ Total │ 2 ┃
121
+ ┗━━━━━━━┷━━━━━━┛
122
+ ```
123
+
124
+ It works with Structs and Hashes (or, more specifically - with any object that reponds to `#keys` and `#values`)
125
+
126
+ ### Opt-in setup
127
+
128
+ If you use `Nazar.load!` instead of `Nazar.enable!`, it would not enhance output for every element in the console. Instead, you have to call `#__` for each item that you want to enhance output
129
+
130
+ ```ruby
131
+
132
+ Nazar.load!
133
+ User.all # Returns default output
134
+ __ User.all # Returns output enhanced by Nazar
135
+ ```
136
+
137
+
138
+ ## Configuration
139
+
140
+ By default, Nazar improves output for ActiveRecord (both collections and a single item) and for CSV Tables. You can configure that by calling `#enable!` with optional argument:
141
+
142
+ `Nazar.enable!(extensions: [:active_record, :csv, :sequel])` will enhance output for <a href="https://github.com/jeremyevans/sequel/">Sequel</a> as well.
143
+
144
+ You can also configure behaviour of Nazar:
145
+
146
+ | Config | Default | Description |
147
+ | ------ | ------- | ----------- |
148
+ | `Nazar.config.colors.enabled` | true | Determines whether the output should be colorised or not |
149
+ | `Nazar.config.formatter.nil` | `∅` | Sets character printed if the value was nil |
150
+ | `Nazar.config.formatter.boolean` | ['✓', '✗'] | First item in array is a character for `true`, second for `false` |
151
+ | `Nazar.config.enable_shorthand_method` | true | Determines if shorthand method should be defined. See <a href="#opt-in-setup">Opt-in setup</a> for more details |
8
152
 
9
153
  ## Contributing
10
154
 
@@ -10,11 +10,11 @@ module Nazar
10
10
  def format
11
11
  case type
12
12
  when :boolean
13
- format_boolean(value)
13
+ format_boolean
14
14
  when :integer
15
- Pastel.new(enabled: Nazar.config.colors.enabled).bright_blue(value)
15
+ format_number
16
16
  else
17
- value.nil? ? format_nil : value.to_s
17
+ value.nil? ? format_nil : inteligent_format
18
18
  end
19
19
  end
20
20
 
@@ -22,7 +22,7 @@ module Nazar
22
22
 
23
23
  attr_reader :value, :type
24
24
 
25
- def format_boolean(value)
25
+ def format_boolean
26
26
  return format_nil if value.nil?
27
27
 
28
28
  true_value, false_value = Nazar.config.formatter.boolean
@@ -30,7 +30,26 @@ module Nazar
30
30
  end
31
31
 
32
32
  def format_nil
33
- Pastel.new(enabled: Nazar.config.colors.enabled).dim(Nazar.config.formatter.nil)
33
+ pastel.dim(Nazar.config.formatter.nil)
34
+ end
35
+
36
+ def format_number
37
+ pastel.bright_blue(value)
38
+ end
39
+
40
+ def inteligent_format
41
+ case value
42
+ when Symbol
43
+ pastel.magenta(":#{value}")
44
+ when Numeric
45
+ format_number
46
+ else
47
+ value.to_s
48
+ end
49
+ end
50
+
51
+ def pastel
52
+ @pastel ||= Pastel.new(enabled: Nazar.config.colors.enabled)
34
53
  end
35
54
  end
36
55
  end
@@ -15,6 +15,12 @@ module Nazar
15
15
  @klass = collection.first&.class
16
16
  end
17
17
 
18
+ def self.valid?(data)
19
+ data.is_a?(ActiveRecord::Associations::CollectionProxy) ||
20
+ data.is_a?(ActiveRecord::Relation) ||
21
+ (data.is_a?(Enumerable) && data.first.is_a?(ActiveRecord::Base))
22
+ end
23
+
18
24
  def summary
19
25
  collection.size
20
26
  end
@@ -13,6 +13,10 @@ module Nazar
13
13
  @klass = item.class
14
14
  end
15
15
 
16
+ def self.valid?(data)
17
+ data.is_a?(ActiveRecord::Base)
18
+ end
19
+
16
20
  def summary
17
21
  false
18
22
  end
@@ -9,6 +9,10 @@ module Nazar
9
9
  @collection = collection
10
10
  end
11
11
 
12
+ def self.valid?(data)
13
+ data.is_a?(CSV::Table)
14
+ end
15
+
12
16
  def valid?
13
17
  !!collection && !collection.empty?
14
18
  end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Nazar
4
+ module Formatter
5
+ class Generic
6
+ attr_reader :collection
7
+
8
+ def initialize(collection)
9
+ @collection = Array(collection)
10
+ @item = collection.first
11
+ end
12
+
13
+ def headers
14
+ HeadersFormatter.new(raw_headers).format
15
+ end
16
+
17
+ def cells
18
+ @cells ||= collection.map do |item|
19
+ item.values.map do |value|
20
+ CellFormatter.new(value).format
21
+ end
22
+ end
23
+ end
24
+
25
+ def summary
26
+ collection.size
27
+ end
28
+
29
+ def self.valid?(data)
30
+ item = data.first
31
+ compatible = item.respond_to?(:keys) && item.respond_to?(:values)
32
+
33
+ data.is_a?(Enumerable) && (item.is_a?(Struct) || compatible)
34
+ end
35
+
36
+ def valid?
37
+ !!item && !raw_headers.empty?
38
+ end
39
+
40
+ private
41
+
42
+ attr_reader :item
43
+
44
+ def raw_headers
45
+ @raw_headers ||= if item.is_a?(Struct)
46
+ item.members
47
+ elsif item.respond_to?(:keys)
48
+ item.keys
49
+ else
50
+ []
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'nazar/formatter/sequel_interface'
4
+
5
+ module Nazar
6
+ module Formatter
7
+ class SequelCollection
8
+ include SequelInterface
9
+
10
+ def initialize(collection)
11
+ @collection = collection
12
+ @attributes = collection.first&.values
13
+ end
14
+
15
+ def self.valid?(data)
16
+ (data.is_a?(Enumerable) && data.first.is_a?(Sequel::Model)) || data.is_a?(Sequel::Dataset)
17
+ end
18
+
19
+ def summary
20
+ collection.size
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Nazar
4
+ module Formatter
5
+ module SequelInterface
6
+ attr_reader :collection, :klass, :attributes
7
+
8
+ def valid?
9
+ !!attributes
10
+ end
11
+
12
+ def headers
13
+ HeadersFormatter.new(attributes.keys).format
14
+ end
15
+
16
+ def cells
17
+ @cells ||= begin
18
+ schema = collection.first.db_schema
19
+
20
+ collection.map do |item|
21
+ item.values.map do |column, value|
22
+ CellFormatter.new(value, type: schema.dig(column, :type)).format
23
+ end
24
+ end
25
+ end
26
+ end
27
+
28
+ def summary
29
+ collection.size
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'nazar/formatter/sequel_interface'
4
+
5
+ module Nazar
6
+ module Formatter
7
+ class SequelItem
8
+ include SequelInterface
9
+
10
+ def initialize(item)
11
+ @collection = [item]
12
+ @attributes = item.values
13
+ @klass = item.class
14
+ end
15
+
16
+ def self.valid?(data)
17
+ data.is_a?(Sequel::Model)
18
+ end
19
+
20
+ def summary
21
+ false
22
+ end
23
+ end
24
+ end
25
+ end
@@ -2,12 +2,18 @@
2
2
 
3
3
  module Nazar
4
4
  class Renderer
5
- def initialize(data)
5
+ def initialize(data, use_generic_formatter: false)
6
6
  @data = data
7
+ @use_generic_formatter = use_generic_formatter
7
8
  end
8
9
 
9
10
  def render
10
- pager.page(view.render) if view.supported_data?
11
+ pager.page(view.render)
12
+ nil
13
+ end
14
+
15
+ def valid?
16
+ view.supported_data?
11
17
  end
12
18
 
13
19
  def pager
@@ -19,7 +25,7 @@ module Nazar
19
25
  attr_reader :data
20
26
 
21
27
  def view
22
- @view ||= View.new(data)
28
+ @view ||= View.new(data, use_generic_formatter: @use_generic_formatter)
23
29
  end
24
30
  end
25
31
  end
data/lib/nazar/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Nazar
4
- VERSION = '0.0.5'
4
+ VERSION = '0.1.1'
5
5
  end
data/lib/nazar/view.rb CHANGED
@@ -6,8 +6,9 @@ module Nazar
6
6
 
7
7
  def_delegators :formatter, :headers, :cells, :summary
8
8
 
9
- def initialize(data)
9
+ def initialize(data, use_generic_formatter: false)
10
10
  @data = data
11
+ @use_generic_formatter = use_generic_formatter
11
12
  end
12
13
 
13
14
  def render
@@ -24,49 +25,20 @@ module Nazar
24
25
 
25
26
  private
26
27
 
27
- attr_reader :data
28
+ attr_reader :data, :use_generic_formatter
28
29
 
29
- def formatter_klass
30
- @formatter_klass ||= case data
31
- when boolean?
32
- nil
33
- when acttive_record_collection?
34
- Formatter::ActiveRecordCollection
35
- when active_record_item?
36
- Formatter::ActiveRecordItem
37
- when csv_table?
38
- Formatter::CSVTable
39
- end
40
- end
41
-
42
- def formatter
43
- @formatter ||= formatter_klass.new(data)
44
- end
45
-
46
- def boolean?
47
- proc { data === true || data === false } # rubocop:disable Style/CaseEquality
48
- end
49
-
50
- def acttive_record_collection?
51
- return false unless Nazar.extensions.include?(:active_record)
52
-
53
- proc do
54
- data.is_a?(ActiveRecord::Associations::CollectionProxy) ||
55
- data.is_a?(ActiveRecord::Relation) ||
56
- (data.is_a?(Array) && data.first.is_a?(ActiveRecord::Base))
30
+ def formatters
31
+ @formatters ||= Nazar.formatters.tap do |formatters|
32
+ formatters << Nazar::Formatter::Generic if use_generic_formatter
57
33
  end
58
34
  end
59
35
 
60
- def active_record_item?
61
- return false unless Nazar.extensions.include?(:active_record)
62
-
63
- proc { data.is_a?(ActiveRecord::Base) }
36
+ def formatter_klass
37
+ @formatter_klass ||= formatters.find { |klass| klass.valid?(data) }
64
38
  end
65
39
 
66
- def csv_table?
67
- return false unless Nazar.extensions.include?(:csv)
68
-
69
- proc { data.is_a?(CSV::Table) }
40
+ def formatter
41
+ @formatter ||= formatter_klass.new(data)
70
42
  end
71
43
 
72
44
  def add_summary
data/lib/nazar.rb CHANGED
@@ -10,9 +10,10 @@ require 'nazar/cell_formatter'
10
10
  require 'nazar/headers_formatter'
11
11
  require 'nazar/renderer'
12
12
  require 'nazar/formatter'
13
+ require 'nazar/formatter/generic'
13
14
  require 'nazar/view'
14
15
 
15
- module Nazar
16
+ module Nazar # rubocop:disable Metrics/ModuleLength
16
17
  extend Dry::Configurable
17
18
 
18
19
  setting :formatter do
@@ -24,60 +25,130 @@ module Nazar
24
25
  setting :enabled, default: ENV.fetch('ENABLE_TTY_COLORS') { TTY::Color.color? ? 'true' : 'false' } == 'true'
25
26
  end
26
27
 
28
+ setting :enable_shorthand_method, default: true
29
+
27
30
  class << self
28
- def extensions
29
- @extensions ||= Set.new
31
+ def formatters
32
+ @formatters ||= Set.new
30
33
  end
31
34
 
32
35
  def enable!(extensions: [:active_record, :csv])
33
36
  return if @enabled
34
37
 
35
- load_active_record! if extensions.include?(:active_record)
36
- load_csv! if extensions.include?(:csv)
38
+ load_extensions!(extensions)
39
+ enable_repl!
37
40
 
38
- enable_for_irb! if defined?(IRB)
39
- enable_for_pry! if defined?(Pry)
41
+ enable_shorthand_method! if Nazar.config.enable_shorthand_method
40
42
 
41
43
  @enabled = true
42
44
  end
43
45
 
44
- def load_csv!
45
- extensions << :csv
46
+ def load!(extensions: [:active_record, :csv])
47
+ load_extensions!(extensions)
48
+ enable_shorthand_method! if Nazar.config.enable_shorthand_method
46
49
 
50
+ true
51
+ end
52
+
53
+ def load_csv!
47
54
  require 'csv'
48
- load 'nazar/formatter/csv_table.rb'
55
+
56
+ register_formatter!('CSVTable', 'nazar/formatter/csv_table')
49
57
  end
50
58
 
51
59
  def load_active_record!
52
- extensions << :active_record
53
-
54
60
  require 'active_record'
55
- load 'nazar/formatter/active_record_collection.rb'
56
- load 'nazar/formatter/active_record_item.rb'
61
+
62
+ register_formatter!('ActiveRecordCollection', 'nazar/formatter/active_record_collection')
63
+ register_formatter!('ActiveRecordItem', 'nazar/formatter/active_record_item')
64
+ end
65
+
66
+ def load_sequel!
67
+ require 'sequel'
68
+
69
+ register_formatter!('SequelCollection', 'nazar/formatter/sequel_collection')
70
+ register_formatter!('SequelItem', 'nazar/formatter/sequel_item')
71
+ end
72
+
73
+ def register_formatter!(klass_name, path)
74
+ require path
75
+
76
+ formatters << Nazar::Formatter.const_get(klass_name)
77
+ end
78
+
79
+ def pry_proc
80
+ return unless defined?(Pry)
81
+
82
+ proc do |output, value, instance|
83
+ renderer = Nazar::Renderer.new(value)
84
+ renderer.valid? ? renderer.render : @__original_pry_print.call(output, value, instance)
85
+ end
86
+ end
87
+
88
+ def disable!
89
+ disable_shorthand_method! if @defined_shorthand_method
90
+
91
+ return unless @enabled
92
+
93
+ disable_for_irb! if defined?(IRB)
94
+ disable_for_pry! if defined?(Pry)
95
+
96
+ @enabled = false
97
+ end
98
+
99
+ private
100
+
101
+ def load_extensions!(extensions)
102
+ load_active_record! if extensions.include?(:active_record)
103
+ load_csv! if extensions.include?(:csv)
104
+ load_sequel! if extensions.include?(:sequel)
105
+ end
106
+
107
+ def enable_repl!
108
+ enable_for_irb! if defined?(IRB)
109
+ enable_for_pry! if defined?(Pry)
57
110
  end
58
111
 
59
112
  def enable_for_irb!
60
113
  ::IRB::Irb.class_eval do
61
114
  alias_method :__original_output_value__, :output_value
62
115
  def output_value(omit = false) # rubocop:disable Style/OptionalBooleanParameter
63
- ::Nazar::Renderer.new(@context.last_value).render || __original_output_value__(omit)
116
+ renderer = Nazar::Renderer.new(@context.last_value)
117
+ renderer.valid? ? renderer.render : __original_output_value__(omit)
64
118
  end
65
119
  end
66
120
  end
67
121
 
68
122
  def enable_for_pry!
69
- @__original_pry_print = Pry.config.print
70
- Pry.config.print = proc do |output, value, instance|
71
- output.puts Nazar::Renderer.new(value).render || @__original_pry_print.call(output, value, instance)
123
+ @__original_pry_print ||= Pry.config.print
124
+
125
+ if Pry.toplevel_binding.local_variable_defined?(:pry_instance)
126
+ Pry.toplevel_binding.eval('pry_instance.config.print = Nazar.pry_proc', __FILE__, __LINE__)
127
+ else
128
+ Pry.config.print = Nazar.pry_proc
72
129
  end
73
130
  end
74
131
 
75
- def disable!
76
- return unless @enabled
132
+ def enable_shorthand_method!
133
+ if Object.respond_to?(:__)
134
+ return warn Pastel.new.red("Already defined Object#__() method, Nazar won't redefine it.")
135
+ end
77
136
 
78
- disable_for_irb! if defined?(IRB)
137
+ @defined_shorthand_method = true
79
138
 
80
- @enabled = false
139
+ Object.class_eval do
140
+ def __(item)
141
+ Nazar::Renderer.new(item, use_generic_formatter: true).render
142
+ end
143
+ end
144
+ end
145
+
146
+ def disable_shorthand_method!
147
+ @defined_shorthand_method = nil
148
+
149
+ Object.class_eval do
150
+ undef_method :__
151
+ end
81
152
  end
82
153
 
83
154
  def disable_for_irb!
@@ -85,7 +156,11 @@ module Nazar
85
156
  end
86
157
 
87
158
  def disable_for_pry!
88
- nil
159
+ Pry.toplevel_binding.eval(
160
+ 'pry_instance.config.print = Nazar.instance_variable_get(:@__original_pry_print)',
161
+ __FILE__,
162
+ __LINE__
163
+ )
89
164
  end
90
165
  end
91
166
  end
data/nazar.gemspec CHANGED
@@ -28,7 +28,9 @@ Gem::Specification.new do |spec|
28
28
 
29
29
  spec.add_development_dependency 'activerecord', '>= 3.0', '< 6.2'
30
30
  spec.add_development_dependency 'rubocop', '~> 1.21'
31
- spec.add_development_dependency 'sqlite3'
31
+ spec.add_development_dependency 'sequel', '~> 5.0'
32
+ spec.add_development_dependency 'simplecov', '~> 0.20'
33
+ spec.add_development_dependency 'sqlite3', '~> 1.0'
32
34
 
33
35
  spec.add_runtime_dependency 'dry-configurable', '~> 0.12'
34
36
  spec.add_runtime_dependency 'pastel', '~> 0.8'
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nazar
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michał Krzyżanowski
@@ -36,7 +36,7 @@ cert_chain:
36
36
  FlwFUDGjWAe8lcsjyGp1dox0FK91TAHdZW1op8LYnOcO2DM8Mgzu4Gp7mibATEnx
37
37
  ooN2pwmH
38
38
  -----END CERTIFICATE-----
39
- date: 2021-09-23 00:00:00.000000000 Z
39
+ date: 2021-10-06 00:00:00.000000000 Z
40
40
  dependencies:
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: activerecord
@@ -72,20 +72,48 @@ dependencies:
72
72
  - - "~>"
73
73
  - !ruby/object:Gem::Version
74
74
  version: '1.21'
75
+ - !ruby/object:Gem::Dependency
76
+ name: sequel
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: '5.0'
82
+ type: :development
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: '5.0'
89
+ - !ruby/object:Gem::Dependency
90
+ name: simplecov
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - "~>"
94
+ - !ruby/object:Gem::Version
95
+ version: '0.20'
96
+ type: :development
97
+ prerelease: false
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - "~>"
101
+ - !ruby/object:Gem::Version
102
+ version: '0.20'
75
103
  - !ruby/object:Gem::Dependency
76
104
  name: sqlite3
77
105
  requirement: !ruby/object:Gem::Requirement
78
106
  requirements:
79
- - - ">="
107
+ - - "~>"
80
108
  - !ruby/object:Gem::Version
81
- version: '0'
109
+ version: '1.0'
82
110
  type: :development
83
111
  prerelease: false
84
112
  version_requirements: !ruby/object:Gem::Requirement
85
113
  requirements:
86
- - - ">="
114
+ - - "~>"
87
115
  - !ruby/object:Gem::Version
88
- version: '0'
116
+ version: '1.0'
89
117
  - !ruby/object:Gem::Dependency
90
118
  name: dry-configurable
91
119
  requirement: !ruby/object:Gem::Requirement
@@ -167,6 +195,10 @@ files:
167
195
  - lib/nazar/formatter/active_record_interface.rb
168
196
  - lib/nazar/formatter/active_record_item.rb
169
197
  - lib/nazar/formatter/csv_table.rb
198
+ - lib/nazar/formatter/generic.rb
199
+ - lib/nazar/formatter/sequel_collection.rb
200
+ - lib/nazar/formatter/sequel_interface.rb
201
+ - lib/nazar/formatter/sequel_item.rb
170
202
  - lib/nazar/headers_formatter.rb
171
203
  - lib/nazar/renderer.rb
172
204
  - lib/nazar/version.rb
metadata.gz.sig CHANGED
Binary file