knuckles 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: bb83d5d1b1dd47e62ea44595951f957304215bc2
4
+ data.tar.gz: a7ca90254ffad1b2a5c7d901ffb00bd18a0cce07
5
+ SHA512:
6
+ metadata.gz: 3f705fab0c4141190600d8c7179cb0f5ef9db0fd408fa978377ec0fb8c8e01bcb6d9b266049ba7c86bc30753eb6d4afa4586fa099396792609375122be967e4b
7
+ data.tar.gz: df014c860e15f578d98c9cdb5f6a5ab264da0451923b3647f17eca26d6ebe440f7d88f1b51c8ca61fb4a32936fbd7a2b55821f176d4d583549f87f322b8277a1
data/.gitignore ADDED
@@ -0,0 +1,15 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
15
+ TODO.md
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --require spec_helper
data/.rubocop.yml ADDED
@@ -0,0 +1,33 @@
1
+ AllCops:
2
+ Exclude:
3
+ - 'bench/**/*'
4
+ - 'bin/*'
5
+ - 'tmp/**/*'
6
+ - 'vendor/**/*'
7
+
8
+ Style/IfUnlessModifier:
9
+ Enabled: false
10
+
11
+ # Documentation is coming
12
+ Style/Documentation:
13
+ Enabled: false
14
+
15
+ # Extend self preserves private methods
16
+ Style/ModuleFunction:
17
+ Enabled: false
18
+
19
+ Style/PredicateName:
20
+ NamePrefix:
21
+ - is_
22
+ NamePrefixBlacklist:
23
+ - is_
24
+
25
+ Style/StringLiterals:
26
+ EnforcedStyle: double_quotes
27
+
28
+ Style/SpaceInsideHashLiteralBraces:
29
+ EnforcedStyle: no_space
30
+ EnforcedStyleForEmptyBraces: no_space
31
+
32
+ Style/IndentArray:
33
+ Enabled: false
data/.travis.yml ADDED
@@ -0,0 +1,10 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.2.4
5
+ - 2.3.0
6
+ - ruby-head
7
+ matrix:
8
+ allow_failures:
9
+ - rvm: ruby-head
10
+ bundler_args: --without benchmarking
data/CHANGELOG.md ADDED
@@ -0,0 +1,3 @@
1
+ ## v0.1.0 - 2016-03-21
2
+
3
+ * Initial release (third time's the charm).
data/Gemfile ADDED
@@ -0,0 +1,11 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
4
+
5
+ gem "rubocop", require: false
6
+ gem "coveralls", require: false
7
+
8
+ group :benchmarking do
9
+ gem "benchmark-ips"
10
+ gem "stackprof"
11
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Parker Selbert
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,77 @@
1
+ [![Build Status](https://travis-ci.org/sorentwo/knuckles.svg?branch=master)](https://travis-ci.org/sorentwo/knuckles)
2
+ [![Coverage Status](https://coveralls.io/repos/github/sorentwo/knuckles/badge.svg?branch=master)](https://coveralls.io/github/sorentwo/knuckles?branch=master)
3
+ [![Code Climate](https://codeclimate.com/github/sorentwo/knuckles/badges/gpa.svg)](https://codeclimate.com/github/sorentwo/knuckles)
4
+
5
+ # Knuckles (Because Sonic was Taken)
6
+
7
+ What's it all about?
8
+
9
+ * Emphasis on caching as a composable operation
10
+ * Reduced object instantiation
11
+ * Complete instrumentation of every discrete operation
12
+ * Entirely agnostic, can be dropped into any project and integrated over time
13
+ * Minimal runtime dependencies
14
+ * Explicit serializer view API with as little overhead and no DSL
15
+
16
+ ## Installation
17
+
18
+ Add this line to your application's Gemfile:
19
+
20
+ ```ruby
21
+ gem "knuckles"
22
+ ```
23
+
24
+ ## Configuration
25
+
26
+ There isn't a hard dependency on `Oj` or `Readthis`, but you'll find they are
27
+ drastically more performant.
28
+
29
+ ```ruby
30
+ require "activesupport"
31
+ require "oj"
32
+ require "readthis"
33
+
34
+ Knuckles.configure do |config|
35
+ config.cache = Readthis::Cache.new(
36
+ marshal: Oj,
37
+ compress: true,
38
+ driver: :hiredis
39
+ )
40
+
41
+ config.keygen = Readthis::Expanders
42
+ config.serializer = Oj
43
+ end
44
+ ```
45
+
46
+ With the top level module configured it is simple to jump right into rendering,
47
+ but we'll look at configuring the pipeline first.
48
+
49
+ ## Defining Views
50
+
51
+ The interface for defining serializers is largely based on Active Model
52
+ Serializers, but with a few key differences.
53
+
54
+ ```ruby
55
+ class ScoutSerializer
56
+ include Knuckles::Serializer
57
+
58
+ root 'scout'
59
+
60
+ attributes :id, :email, :display_name
61
+
62
+ has_one :thing, serializer: ThingSerializer
63
+ has_many :other, serializer: OtherThingSerializer
64
+
65
+ def display_name(object, options)
66
+ "#{object.first_name} #{object.last_name}"
67
+ end
68
+ end
69
+ ```
70
+
71
+ ## Contributing
72
+
73
+ 1. Fork it ( https://github.com/sorentwo/knuckles/fork )
74
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
75
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
76
+ 4. Push to the branch (`git push origin my-new-feature`)
77
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,9 @@
1
+ require "bundler/setup"
2
+ require "bundler/gem_tasks"
3
+ require "rubocop/rake_task"
4
+ require "rspec/core/rake_task"
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+ RuboCop::RakeTask.new
8
+
9
+ task default: [:spec, :rubocop]
@@ -0,0 +1,48 @@
1
+ require "bundler"
2
+
3
+ Bundler.setup
4
+
5
+ require "active_support/cache"
6
+ require "benchmark/ips"
7
+ require "json"
8
+ require "knuckles"
9
+ require_relative "fixtures/serializers"
10
+
11
+ class BenchModel
12
+ attr_reader :key
13
+
14
+ def initialize(key, attributes)
15
+ attributes.each do |key, value|
16
+ self.class.send(:define_method, key) { value }
17
+ end
18
+ end
19
+
20
+ def cache_key
21
+ "#{key}/#{id}/#{updated_at}"
22
+ end
23
+ end
24
+
25
+ module BenchHelper
26
+ extend self
27
+
28
+ def submissions
29
+ mapping = %w[scout responses tags]
30
+ loaded = JSON.load(IO.read("bench/fixtures/submissions.json"))
31
+
32
+ loaded.map do |object|
33
+ mapping.each do |key|
34
+ object[key] = structify(key, object[key])
35
+ end
36
+
37
+ structify('submissions', object)
38
+ end
39
+ end
40
+
41
+ def structify(key, object)
42
+ if object.is_a?(Array)
43
+ object.map { |obj| BenchModel.new(key, obj) }
44
+ else
45
+ BenchModel.new(key, object)
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,93 @@
1
+ module ScoutView
2
+ extend Knuckles::View
3
+
4
+ def self.root
5
+ :scouts
6
+ end
7
+
8
+ def self.data(object, _)
9
+ { id: object.id,
10
+ first_name: object.first_name,
11
+ gender: object.gender,
12
+ city: object.city,
13
+ state: object.state,
14
+ country: object.country,
15
+ education: object.education,
16
+ employment_status: object.employment_status,
17
+ ethnicity: object.ethnicity,
18
+ household_composition: object.household_composition,
19
+ household_income: object.household_income,
20
+ industry: object.industry,
21
+ created_at: object.created_at,
22
+ updated_at: object.updated_at }
23
+ end
24
+ end
25
+
26
+ module ResponseView
27
+ extend Knuckles::View
28
+
29
+ def self.root
30
+ :responses
31
+ end
32
+
33
+ def self.data(object, _)
34
+ { id: object.id,
35
+ answers: object.answers,
36
+ question_id: object.question_id,
37
+ respondable_id: object.respondable_id,
38
+ longitude: object.longitude,
39
+ latitude: object.latitude,
40
+ time_zone: object.time_zone,
41
+ answered_at: object.answered_at,
42
+ created_at: object.created_at,
43
+ updated_at: object.updated_at }
44
+ end
45
+ end
46
+
47
+ module TagView
48
+ extend Knuckles::View
49
+
50
+ def self.root
51
+ :tags
52
+ end
53
+
54
+ def self.data(object, _)
55
+ { id: object.id,
56
+ parent_id: object.parent_id,
57
+ name: object.name,
58
+ group: object.group,
59
+ auto_tag: object.auto_tag,
60
+ keywords: object.keywords,
61
+ created_at: object.created_at,
62
+ updated_at: object.updated_at }
63
+ end
64
+ end
65
+
66
+ module SubmissionView
67
+ extend Knuckles::View
68
+
69
+ def self.root
70
+ :submissions
71
+ end
72
+
73
+ def self.data(object, _)
74
+ { id: object.id,
75
+ screener_id: object.screener_id,
76
+ rating: object.rating,
77
+ latitude: object.latitude,
78
+ longitude: object.longitude,
79
+ source: object.source,
80
+ time_zone: object.time_zone,
81
+ bookmarks_count: object.bookmarks_count,
82
+ notes_count: object.notes_count,
83
+ finished_at: object.finished_at,
84
+ created_at: object.created_at,
85
+ updated_at: object.updated_at }
86
+ end
87
+
88
+ def self.relations(object, _)
89
+ { scouts: has_one(object.scout, ScoutView),
90
+ responses: has_many(object.responses, ResponseView),
91
+ tags: has_many(object.tags, TagView) }
92
+ end
93
+ end