hyperlayer 0.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 +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +38 -0
- data/Rakefile +8 -0
- data/app/assets/config/manifest.js +7 -0
- data/app/assets/stylesheets/application.bootstrap.scss +2 -0
- data/app/assets/stylesheets/hyperlayer/app.css +47 -0
- data/app/assets/stylesheets/hyperlayer/application.css +18774 -0
- data/app/assets/stylesheets/hyperlayer/prism.css +3 -0
- data/app/controllers/hyperlayer/application_controller.rb +4 -0
- data/app/controllers/hyperlayer/events_controller.rb +95 -0
- data/app/controllers/hyperlayer/example_groups_controller.rb +9 -0
- data/app/controllers/hyperlayer/paths_controller.rb +18 -0
- data/app/controllers/hyperlayer/runs_controller.rb +7 -0
- data/app/controllers/hyperlayer/specs_controller.rb +8 -0
- data/app/javascript/controllers/application.js +9 -0
- data/app/javascript/controllers/index.js +11 -0
- data/app/javascript/hyperlayer/application.js +7 -0
- data/app/javascript/hyperlayer/prism.js +8 -0
- data/app/models/application_record.rb +3 -0
- data/app/models/hyperlayer/event.rb +28 -0
- data/app/models/hyperlayer/example_group.rb +6 -0
- data/app/models/hyperlayer/path.rb +35 -0
- data/app/models/hyperlayer/run.rb +5 -0
- data/app/models/hyperlayer/spec.rb +8 -0
- data/app/services/build_file_overlay.rb +26 -0
- data/app/services/callable.rb +129 -0
- data/app/services/file_builder.rb +260 -0
- data/app/services/find_method_from_event.rb +65 -0
- data/app/services/find_method_in_path.rb +98 -0
- data/app/services/generate_buffer.rb +116 -0
- data/app/services/import_events.rb +56 -0
- data/app/services/split_methods.rb +50 -0
- data/app/services/test_one.rb +34 -0
- data/app/services/update_code.rb +111 -0
- data/app/views/hyperlayer/events/_code.html.erb +36 -0
- data/app/views/hyperlayer/events/_event.html.erb +15 -0
- data/app/views/hyperlayer/events/_tree-text.html.erb +22 -0
- data/app/views/hyperlayer/events/_tree.html.erb +15 -0
- data/app/views/hyperlayer/events/index.html.erb +41 -0
- data/app/views/hyperlayer/example_groups/index.html.erb +25 -0
- data/app/views/hyperlayer/paths/_path.html.erb +52 -0
- data/app/views/hyperlayer/paths/index.html.erb +5 -0
- data/app/views/hyperlayer/paths/show.html.erb +3 -0
- data/app/views/hyperlayer/runs/index.html.erb +23 -0
- data/app/views/hyperlayer/specs/index.html.erb +24 -0
- data/app/views/layouts/_nav.html.erb +8 -0
- data/app/views/layouts/hyperlayer/application.html.erb +30 -0
- data/app/views/layouts/hyperlayer/mailer.html.erb +13 -0
- data/app/views/layouts/hyperlayer/mailer.text.erb +1 -0
- data/config/initializers/engine_migrations.rb +3 -0
- data/config/routes.rb +11 -0
- data/db/migrate/20231009165755_create_hyperlayer_events.rb +19 -0
- data/db/migrate/20231009165919_create_hyperlayer_example_groups.rb +12 -0
- data/db/migrate/20231009165952_create_hyperlayer_runs.rb +9 -0
- data/db/migrate/20231009170101_create_hyperlayer_paths.rb +10 -0
- data/db/migrate/20231009170121_create_hyperlayer_specs.rb +12 -0
- data/lib/hyperlayer/engine.rb +22 -0
- data/lib/hyperlayer/method_tracer.rb +12 -0
- data/lib/hyperlayer/tracer.rb +78 -0
- data/lib/hyperlayer/version.rb +3 -0
- data/lib/hyperlayer.rb +15 -0
- data/lib/tasks/listen.rake +8 -0
- metadata +207 -0
@@ -0,0 +1,3 @@
|
|
1
|
+
/* PrismJS 1.29.0
|
2
|
+
https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript+ruby */
|
3
|
+
code[class*=language-],pre[class*=language-]{color:#000;background:0 0;text-shadow:0 1px #fff;font-family:Consolas,Monaco,'Andale Mono','Ubuntu Mono',monospace;font-size:1em;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}code[class*=language-] ::-moz-selection,code[class*=language-]::-moz-selection,pre[class*=language-] ::-moz-selection,pre[class*=language-]::-moz-selection{text-shadow:none;background:#b3d4fc}code[class*=language-] ::selection,code[class*=language-]::selection,pre[class*=language-] ::selection,pre[class*=language-]::selection{text-shadow:none;background:#b3d4fc}@media print{code[class*=language-],pre[class*=language-]{text-shadow:none}}pre[class*=language-]{padding:1em;margin:.5em 0;overflow:auto}:not(pre)>code[class*=language-],pre[class*=language-]{background:#f5f2f0}:not(pre)>code[class*=language-]{padding:.1em;border-radius:.3em;white-space:normal}.token.cdata,.token.comment,.token.doctype,.token.prolog{color:#708090}.token.punctuation{color:#999}.token.namespace{opacity:.7}.token.boolean,.token.constant,.token.deleted,.token.number,.token.property,.token.symbol,.token.tag{color:#905}.token.attr-name,.token.builtin,.token.char,.token.inserted,.token.selector,.token.string{color:#690}.language-css .token.string,.style .token.string,.token.entity,.token.operator,.token.url{color:#9a6e3a;background:hsla(0,0%,100%,.5)}.token.atrule,.token.attr-value,.token.keyword{color:#07a}.token.class-name,.token.function{color:#dd4a68}.token.important,.token.regex,.token.variable{color:#e90}.token.bold,.token.important{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help}
|
@@ -0,0 +1,95 @@
|
|
1
|
+
module Hyperlayer
|
2
|
+
class EventsController < ApplicationController
|
3
|
+
APP_DIR = Rails.root.to_s.split('/').last
|
4
|
+
|
5
|
+
def index
|
6
|
+
@spec = Spec.find(params[:spec_id])
|
7
|
+
|
8
|
+
@example_group = @spec.example_groups.find(params[:example_group_id])
|
9
|
+
|
10
|
+
@events = @example_group.events
|
11
|
+
.call
|
12
|
+
.includes(:path)
|
13
|
+
.where(path: { spec: nil })
|
14
|
+
.order(id: :asc)
|
15
|
+
.select { |e| e.path.path.include?(APP_DIR) }
|
16
|
+
|
17
|
+
@groups = []
|
18
|
+
used_ids = []
|
19
|
+
|
20
|
+
@events.each.with_index do |event, index|
|
21
|
+
next if used_ids.flatten.include?(event.id)
|
22
|
+
|
23
|
+
batch = { event.defined_class => [] }
|
24
|
+
|
25
|
+
count = index
|
26
|
+
|
27
|
+
while true do
|
28
|
+
next_event = @events[count]
|
29
|
+
|
30
|
+
break if next_event.nil? || next_event.defined_class != event.defined_class
|
31
|
+
|
32
|
+
batch[event.defined_class] << @events[count]
|
33
|
+
|
34
|
+
count += 1
|
35
|
+
end
|
36
|
+
|
37
|
+
@groups << batch
|
38
|
+
used_ids << batch.values.flatten.map(&:id)
|
39
|
+
used_ids.flatten
|
40
|
+
end
|
41
|
+
|
42
|
+
# first_klass = @groups.first.keys.first
|
43
|
+
# first_event = @groups.first.values.first.first
|
44
|
+
|
45
|
+
# @tree = [
|
46
|
+
# {
|
47
|
+
# klass: first_klass,
|
48
|
+
# method: first_event.method,
|
49
|
+
# return_value_id: first_event.return_value_events&.id,
|
50
|
+
# children: []
|
51
|
+
# }
|
52
|
+
# ]
|
53
|
+
|
54
|
+
# @groups.each do |group|
|
55
|
+
# klass = group.keys.first
|
56
|
+
# events = group.values.first
|
57
|
+
|
58
|
+
# events.each do |event|
|
59
|
+
# while event.id < @tree.last[:return_value_id]
|
60
|
+
# {
|
61
|
+
# klass: klass,
|
62
|
+
# method: event.method,
|
63
|
+
# return_value_id: event.return_value_events&.id,
|
64
|
+
# children: []
|
65
|
+
# }
|
66
|
+
# end
|
67
|
+
# end
|
68
|
+
# end
|
69
|
+
|
70
|
+
@tree = BuildTree.call(@events)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
class BuildTree
|
75
|
+
def self.call(events, used_ids = [])
|
76
|
+
branches = []
|
77
|
+
current_branch = nil
|
78
|
+
|
79
|
+
events.each.with_index do |event, index|
|
80
|
+
if !used_ids.include?(event.id)
|
81
|
+
rest_of_events = events[(index + 1)..-1].select { |e| e.id < event.return_value_events&.id }
|
82
|
+
used_ids << event.id
|
83
|
+
|
84
|
+
current_branch = {
|
85
|
+
event => BuildTree.call(rest_of_events, used_ids)
|
86
|
+
}
|
87
|
+
|
88
|
+
branches.push(current_branch)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
branches
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Hyperlayer
|
2
|
+
class PathsController < ApplicationController
|
3
|
+
def index
|
4
|
+
# @paths = Path.includes(:events).all.limit(500).order(id: :asc)
|
5
|
+
|
6
|
+
@paths = [
|
7
|
+
{ id: '1', position: { x: 0, y: 0 }, data: { label: '1' } },
|
8
|
+
{ id: '2', position: { x: 0, y: 75 }, data: { label: '2' } },
|
9
|
+
]
|
10
|
+
|
11
|
+
render json: @paths.to_json
|
12
|
+
end
|
13
|
+
|
14
|
+
def show
|
15
|
+
@path = Path.find(params[:id])
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
// Import and register all your controllers from the importmap under controllers/*
|
2
|
+
|
3
|
+
import { application } from "controllers/application"
|
4
|
+
|
5
|
+
// Eager load all controllers defined in the import map under controllers/**/*_controller
|
6
|
+
import { eagerLoadControllersFrom } from "@hotwired/stimulus-loading"
|
7
|
+
eagerLoadControllersFrom("controllers", application)
|
8
|
+
|
9
|
+
// Lazy load controllers as they appear in the DOM (remember not to preload controllers in import map!)
|
10
|
+
// import { lazyLoadControllersFrom } from "@hotwired/stimulus-loading"
|
11
|
+
// lazyLoadControllersFrom("controllers", application)
|
@@ -0,0 +1,8 @@
|
|
1
|
+
/* PrismJS 1.29.0
|
2
|
+
https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript+ruby */
|
3
|
+
var _self="undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{},Prism=function(e){var n=/(?:^|\s)lang(?:uage)?-([\w-]+)(?=\s|$)/i,t=0,r={},a={manual:e.Prism&&e.Prism.manual,disableWorkerMessageHandler:e.Prism&&e.Prism.disableWorkerMessageHandler,util:{encode:function e(n){return n instanceof i?new i(n.type,e(n.content),n.alias):Array.isArray(n)?n.map(e):n.replace(/&/g,"&").replace(/</g,"<").replace(/\u00a0/g," ")},type:function(e){return Object.prototype.toString.call(e).slice(8,-1)},objId:function(e){return e.__id||Object.defineProperty(e,"__id",{value:++t}),e.__id},clone:function e(n,t){var r,i;switch(t=t||{},a.util.type(n)){case"Object":if(i=a.util.objId(n),t[i])return t[i];for(var l in r={},t[i]=r,n)n.hasOwnProperty(l)&&(r[l]=e(n[l],t));return r;case"Array":return i=a.util.objId(n),t[i]?t[i]:(r=[],t[i]=r,n.forEach((function(n,a){r[a]=e(n,t)})),r);default:return n}},getLanguage:function(e){for(;e;){var t=n.exec(e.className);if(t)return t[1].toLowerCase();e=e.parentElement}return"none"},setLanguage:function(e,t){e.className=e.className.replace(RegExp(n,"gi"),""),e.classList.add("language-"+t)},currentScript:function(){if("undefined"==typeof document)return null;if("currentScript"in document)return document.currentScript;try{throw new Error}catch(r){var e=(/at [^(\r\n]*\((.*):[^:]+:[^:]+\)$/i.exec(r.stack)||[])[1];if(e){var n=document.getElementsByTagName("script");for(var t in n)if(n[t].src==e)return n[t]}return null}},isActive:function(e,n,t){for(var r="no-"+n;e;){var a=e.classList;if(a.contains(n))return!0;if(a.contains(r))return!1;e=e.parentElement}return!!t}},languages:{plain:r,plaintext:r,text:r,txt:r,extend:function(e,n){var t=a.util.clone(a.languages[e]);for(var r in n)t[r]=n[r];return t},insertBefore:function(e,n,t,r){var i=(r=r||a.languages)[e],l={};for(var o in i)if(i.hasOwnProperty(o)){if(o==n)for(var s in t)t.hasOwnProperty(s)&&(l[s]=t[s]);t.hasOwnProperty(o)||(l[o]=i[o])}var u=r[e];return r[e]=l,a.languages.DFS(a.languages,(function(n,t){t===u&&n!=e&&(this[n]=l)})),l},DFS:function e(n,t,r,i){i=i||{};var l=a.util.objId;for(var o in n)if(n.hasOwnProperty(o)){t.call(n,o,n[o],r||o);var s=n[o],u=a.util.type(s);"Object"!==u||i[l(s)]?"Array"!==u||i[l(s)]||(i[l(s)]=!0,e(s,t,o,i)):(i[l(s)]=!0,e(s,t,null,i))}}},plugins:{},highlightAll:function(e,n){a.highlightAllUnder(document,e,n)},highlightAllUnder:function(e,n,t){var r={callback:t,container:e,selector:'code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code'};a.hooks.run("before-highlightall",r),r.elements=Array.prototype.slice.apply(r.container.querySelectorAll(r.selector)),a.hooks.run("before-all-elements-highlight",r);for(var i,l=0;i=r.elements[l++];)a.highlightElement(i,!0===n,r.callback)},highlightElement:function(n,t,r){var i=a.util.getLanguage(n),l=a.languages[i];a.util.setLanguage(n,i);var o=n.parentElement;o&&"pre"===o.nodeName.toLowerCase()&&a.util.setLanguage(o,i);var s={element:n,language:i,grammar:l,code:n.textContent};function u(e){s.highlightedCode=e,a.hooks.run("before-insert",s),s.element.innerHTML=s.highlightedCode,a.hooks.run("after-highlight",s),a.hooks.run("complete",s),r&&r.call(s.element)}if(a.hooks.run("before-sanity-check",s),(o=s.element.parentElement)&&"pre"===o.nodeName.toLowerCase()&&!o.hasAttribute("tabindex")&&o.setAttribute("tabindex","0"),!s.code)return a.hooks.run("complete",s),void(r&&r.call(s.element));if(a.hooks.run("before-highlight",s),s.grammar)if(t&&e.Worker){var c=new Worker(a.filename);c.onmessage=function(e){u(e.data)},c.postMessage(JSON.stringify({language:s.language,code:s.code,immediateClose:!0}))}else u(a.highlight(s.code,s.grammar,s.language));else u(a.util.encode(s.code))},highlight:function(e,n,t){var r={code:e,grammar:n,language:t};if(a.hooks.run("before-tokenize",r),!r.grammar)throw new Error('The language "'+r.language+'" has no grammar.');return r.tokens=a.tokenize(r.code,r.grammar),a.hooks.run("after-tokenize",r),i.stringify(a.util.encode(r.tokens),r.language)},tokenize:function(e,n){var t=n.rest;if(t){for(var r in t)n[r]=t[r];delete n.rest}var a=new s;return u(a,a.head,e),o(e,a,n,a.head,0),function(e){for(var n=[],t=e.head.next;t!==e.tail;)n.push(t.value),t=t.next;return n}(a)},hooks:{all:{},add:function(e,n){var t=a.hooks.all;t[e]=t[e]||[],t[e].push(n)},run:function(e,n){var t=a.hooks.all[e];if(t&&t.length)for(var r,i=0;r=t[i++];)r(n)}},Token:i};function i(e,n,t,r){this.type=e,this.content=n,this.alias=t,this.length=0|(r||"").length}function l(e,n,t,r){e.lastIndex=n;var a=e.exec(t);if(a&&r&&a[1]){var i=a[1].length;a.index+=i,a[0]=a[0].slice(i)}return a}function o(e,n,t,r,s,g){for(var f in t)if(t.hasOwnProperty(f)&&t[f]){var h=t[f];h=Array.isArray(h)?h:[h];for(var d=0;d<h.length;++d){if(g&&g.cause==f+","+d)return;var v=h[d],p=v.inside,m=!!v.lookbehind,y=!!v.greedy,k=v.alias;if(y&&!v.pattern.global){var x=v.pattern.toString().match(/[imsuy]*$/)[0];v.pattern=RegExp(v.pattern.source,x+"g")}for(var b=v.pattern||v,w=r.next,A=s;w!==n.tail&&!(g&&A>=g.reach);A+=w.value.length,w=w.next){var E=w.value;if(n.length>e.length)return;if(!(E instanceof i)){var P,L=1;if(y){if(!(P=l(b,A,e,m))||P.index>=e.length)break;var S=P.index,O=P.index+P[0].length,j=A;for(j+=w.value.length;S>=j;)j+=(w=w.next).value.length;if(A=j-=w.value.length,w.value instanceof i)continue;for(var C=w;C!==n.tail&&(j<O||"string"==typeof C.value);C=C.next)L++,j+=C.value.length;L--,E=e.slice(A,j),P.index-=A}else if(!(P=l(b,0,E,m)))continue;S=P.index;var N=P[0],_=E.slice(0,S),M=E.slice(S+N.length),W=A+E.length;g&&W>g.reach&&(g.reach=W);var z=w.prev;if(_&&(z=u(n,z,_),A+=_.length),c(n,z,L),w=u(n,z,new i(f,p?a.tokenize(N,p):N,k,N)),M&&u(n,w,M),L>1){var I={cause:f+","+d,reach:W};o(e,n,t,w.prev,A,I),g&&I.reach>g.reach&&(g.reach=I.reach)}}}}}}function s(){var e={value:null,prev:null,next:null},n={value:null,prev:e,next:null};e.next=n,this.head=e,this.tail=n,this.length=0}function u(e,n,t){var r=n.next,a={value:t,prev:n,next:r};return n.next=a,r.prev=a,e.length++,a}function c(e,n,t){for(var r=n.next,a=0;a<t&&r!==e.tail;a++)r=r.next;n.next=r,r.prev=n,e.length-=a}if(e.Prism=a,i.stringify=function e(n,t){if("string"==typeof n)return n;if(Array.isArray(n)){var r="";return n.forEach((function(n){r+=e(n,t)})),r}var i={type:n.type,content:e(n.content,t),tag:"span",classes:["token",n.type],attributes:{},language:t},l=n.alias;l&&(Array.isArray(l)?Array.prototype.push.apply(i.classes,l):i.classes.push(l)),a.hooks.run("wrap",i);var o="";for(var s in i.attributes)o+=" "+s+'="'+(i.attributes[s]||"").replace(/"/g,""")+'"';return"<"+i.tag+' class="'+i.classes.join(" ")+'"'+o+">"+i.content+"</"+i.tag+">"},!e.document)return e.addEventListener?(a.disableWorkerMessageHandler||e.addEventListener("message",(function(n){var t=JSON.parse(n.data),r=t.language,i=t.code,l=t.immediateClose;e.postMessage(a.highlight(i,a.languages[r],r)),l&&e.close()}),!1),a):a;var g=a.util.currentScript();function f(){a.manual||a.highlightAll()}if(g&&(a.filename=g.src,g.hasAttribute("data-manual")&&(a.manual=!0)),!a.manual){var h=document.readyState;"loading"===h||"interactive"===h&&g&&g.defer?document.addEventListener("DOMContentLoaded",f):window.requestAnimationFrame?window.requestAnimationFrame(f):window.setTimeout(f,16)}return a}(_self);"undefined"!=typeof module&&module.exports&&(module.exports=Prism),"undefined"!=typeof global&&(global.Prism=Prism);
|
4
|
+
Prism.languages.markup={comment:{pattern:/<!--(?:(?!<!--)[\s\S])*?-->/,greedy:!0},prolog:{pattern:/<\?[\s\S]+?\?>/,greedy:!0},doctype:{pattern:/<!DOCTYPE(?:[^>"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|<!--(?:[^-]|-(?!->))*-->)*\]\s*)?>/i,greedy:!0,inside:{"internal-subset":{pattern:/(^[^\[]*\[)[\s\S]+(?=\]>$)/,lookbehind:!0,greedy:!0,inside:null},string:{pattern:/"[^"]*"|'[^']*'/,greedy:!0},punctuation:/^<!|>$|[[\]]/,"doctype-tag":/^DOCTYPE/i,name:/[^\s<>'"]+/}},cdata:{pattern:/<!\[CDATA\[[\s\S]*?\]\]>/i,greedy:!0},tag:{pattern:/<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,greedy:!0,inside:{tag:{pattern:/^<\/?[^\s>\/]+/,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"special-attr":[],"attr-value":{pattern:/=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,inside:{punctuation:[{pattern:/^=/,alias:"attr-equals"},{pattern:/^(\s*)["']|["']$/,lookbehind:!0}]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:[{pattern:/&[\da-z]{1,8};/i,alias:"named-entity"},/&#x?[\da-f]{1,8};/i]},Prism.languages.markup.tag.inside["attr-value"].inside.entity=Prism.languages.markup.entity,Prism.languages.markup.doctype.inside["internal-subset"].inside=Prism.languages.markup,Prism.hooks.add("wrap",(function(a){"entity"===a.type&&(a.attributes.title=a.content.replace(/&/,"&"))})),Object.defineProperty(Prism.languages.markup.tag,"addInlined",{value:function(a,e){var s={};s["language-"+e]={pattern:/(^<!\[CDATA\[)[\s\S]+?(?=\]\]>$)/i,lookbehind:!0,inside:Prism.languages[e]},s.cdata=/^<!\[CDATA\[|\]\]>$/i;var t={"included-cdata":{pattern:/<!\[CDATA\[[\s\S]*?\]\]>/i,inside:s}};t["language-"+e]={pattern:/[\s\S]+/,inside:Prism.languages[e]};var n={};n[a]={pattern:RegExp("(<__[^>]*>)(?:<!\\[CDATA\\[(?:[^\\]]|\\](?!\\]>))*\\]\\]>|(?!<!\\[CDATA\\[)[^])*?(?=</__>)".replace(/__/g,(function(){return a})),"i"),lookbehind:!0,greedy:!0,inside:t},Prism.languages.insertBefore("markup","cdata",n)}}),Object.defineProperty(Prism.languages.markup.tag,"addAttribute",{value:function(a,e){Prism.languages.markup.tag.inside["special-attr"].push({pattern:RegExp("(^|[\"'\\s])(?:"+a+")\\s*=\\s*(?:\"[^\"]*\"|'[^']*'|[^\\s'\">=]+(?=[\\s>]))","i"),lookbehind:!0,inside:{"attr-name":/^[^\s=]+/,"attr-value":{pattern:/=[\s\S]+/,inside:{value:{pattern:/(^=\s*(["']|(?!["'])))\S[\s\S]*(?=\2$)/,lookbehind:!0,alias:[e,"language-"+e],inside:Prism.languages[e]},punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}}}})}}),Prism.languages.html=Prism.languages.markup,Prism.languages.mathml=Prism.languages.markup,Prism.languages.svg=Prism.languages.markup,Prism.languages.xml=Prism.languages.extend("markup",{}),Prism.languages.ssml=Prism.languages.xml,Prism.languages.atom=Prism.languages.xml,Prism.languages.rss=Prism.languages.xml;
|
5
|
+
!function(s){var e=/(?:"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n])*')/;s.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:RegExp("@[\\w-](?:[^;{\\s\"']|\\s+(?!\\s)|"+e.source+")*?(?:;|(?=\\s*\\{))"),inside:{rule:/^@[\w-]+/,"selector-function-argument":{pattern:/(\bselector\s*\(\s*(?![\s)]))(?:[^()\s]|\s+(?![\s)])|\((?:[^()]|\([^()]*\))*\))+(?=\s*\))/,lookbehind:!0,alias:"selector"},keyword:{pattern:/(^|[^\w-])(?:and|not|only|or)(?![\w-])/,lookbehind:!0}}},url:{pattern:RegExp("\\burl\\((?:"+e.source+"|(?:[^\\\\\r\n()\"']|\\\\[^])*)\\)","i"),greedy:!0,inside:{function:/^url/i,punctuation:/^\(|\)$/,string:{pattern:RegExp("^"+e.source+"$"),alias:"url"}}},selector:{pattern:RegExp("(^|[{}\\s])[^{}\\s](?:[^{};\"'\\s]|\\s+(?![\\s{])|"+e.source+")*(?=\\s*\\{)"),lookbehind:!0},string:{pattern:e,greedy:!0},property:{pattern:/(^|[^-\w\xA0-\uFFFF])(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*(?=\s*:)/i,lookbehind:!0},important:/!important\b/i,function:{pattern:/(^|[^-a-z0-9])[-a-z0-9]+(?=\()/i,lookbehind:!0},punctuation:/[(){};:,]/},s.languages.css.atrule.inside.rest=s.languages.css;var t=s.languages.markup;t&&(t.tag.addInlined("style","css"),t.tag.addAttribute("style","css"))}(Prism);
|
6
|
+
Prism.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,lookbehind:!0,greedy:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"class-name":{pattern:/(\b(?:class|extends|implements|instanceof|interface|new|trait)\s+|\bcatch\s+\()[\w.\\]+/i,lookbehind:!0,inside:{punctuation:/[.\\]/}},keyword:/\b(?:break|catch|continue|do|else|finally|for|function|if|in|instanceof|new|null|return|throw|try|while)\b/,boolean:/\b(?:false|true)\b/,function:/\b\w+(?=\()/,number:/\b0x[\da-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?/i,operator:/[<>]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,punctuation:/[{}[\];(),.:]/};
|
7
|
+
Prism.languages.javascript=Prism.languages.extend("clike",{"class-name":[Prism.languages.clike["class-name"],{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:constructor|prototype))/,lookbehind:!0}],keyword:[{pattern:/((?:^|\})\s*)catch\b/,lookbehind:!0},{pattern:/(^|[^.]|\.\.\.\s*)\b(?:as|assert(?=\s*\{)|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally(?=\s*(?:\{|$))|for|from(?=\s*(?:['"]|$))|function|(?:get|set)(?=\s*(?:[#\[$\w\xA0-\uFFFF]|$))|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,lookbehind:!0}],function:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,number:{pattern:RegExp("(^|[^\\w$])(?:NaN|Infinity|0[bB][01]+(?:_[01]+)*n?|0[oO][0-7]+(?:_[0-7]+)*n?|0[xX][\\dA-Fa-f]+(?:_[\\dA-Fa-f]+)*n?|\\d+(?:_\\d+)*n|(?:\\d+(?:_\\d+)*(?:\\.(?:\\d+(?:_\\d+)*)?)?|\\.\\d+(?:_\\d+)*)(?:[Ee][+-]?\\d+(?:_\\d+)*)?)(?![\\w$])"),lookbehind:!0},operator:/--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/}),Prism.languages.javascript["class-name"][0].pattern=/(\b(?:class|extends|implements|instanceof|interface|new)\s+)[\w.\\]+/,Prism.languages.insertBefore("javascript","keyword",{regex:{pattern:RegExp("((?:^|[^$\\w\\xA0-\\uFFFF.\"'\\])\\s]|\\b(?:return|yield))\\s*)/(?:(?:\\[(?:[^\\]\\\\\r\n]|\\\\.)*\\]|\\\\.|[^/\\\\\\[\r\n])+/[dgimyus]{0,7}|(?:\\[(?:[^[\\]\\\\\r\n]|\\\\.|\\[(?:[^[\\]\\\\\r\n]|\\\\.|\\[(?:[^[\\]\\\\\r\n]|\\\\.)*\\])*\\])*\\]|\\\\.|[^/\\\\\\[\r\n])+/[dgimyus]{0,7}v[dgimyus]{0,7})(?=(?:\\s|/\\*(?:[^*]|\\*(?!/))*\\*/)*(?:$|[\r\n,.;:})\\]]|//))"),lookbehind:!0,greedy:!0,inside:{"regex-source":{pattern:/^(\/)[\s\S]+(?=\/[a-z]*$)/,lookbehind:!0,alias:"language-regex",inside:Prism.languages.regex},"regex-delimiter":/^\/|\/$/,"regex-flags":/^[a-z]+$/}},"function-variable":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/,alias:"function"},parameter:[{pattern:/(function(?:\s+(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)?\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\))/,lookbehind:!0,inside:Prism.languages.javascript},{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i,lookbehind:!0,inside:Prism.languages.javascript},{pattern:/(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/,lookbehind:!0,inside:Prism.languages.javascript},{pattern:/((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*\{)/,lookbehind:!0,inside:Prism.languages.javascript}],constant:/\b[A-Z](?:[A-Z_]|\dx?)*\b/}),Prism.languages.insertBefore("javascript","string",{hashbang:{pattern:/^#!.*/,greedy:!0,alias:"comment"},"template-string":{pattern:/`(?:\\[\s\S]|\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}|(?!\$\{)[^\\`])*`/,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}/,lookbehind:!0,inside:{"interpolation-punctuation":{pattern:/^\$\{|\}$/,alias:"punctuation"},rest:Prism.languages.javascript}},string:/[\s\S]+/}},"string-property":{pattern:/((?:^|[,{])[ \t]*)(["'])(?:\\(?:\r\n|[\s\S])|(?!\2)[^\\\r\n])*\2(?=\s*:)/m,lookbehind:!0,greedy:!0,alias:"property"}}),Prism.languages.insertBefore("javascript","operator",{"literal-property":{pattern:/((?:^|[,{])[ \t]*)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*:)/m,lookbehind:!0,alias:"property"}}),Prism.languages.markup&&(Prism.languages.markup.tag.addInlined("script","javascript"),Prism.languages.markup.tag.addAttribute("on(?:abort|blur|change|click|composition(?:end|start|update)|dblclick|error|focus(?:in|out)?|key(?:down|up)|load|mouse(?:down|enter|leave|move|out|over|up)|reset|resize|scroll|select|slotchange|submit|unload|wheel)","javascript")),Prism.languages.js=Prism.languages.javascript;
|
8
|
+
!function(e){e.languages.ruby=e.languages.extend("clike",{comment:{pattern:/#.*|^=begin\s[\s\S]*?^=end/m,greedy:!0},"class-name":{pattern:/(\b(?:class|module)\s+|\bcatch\s+\()[\w.\\]+|\b[A-Z_]\w*(?=\s*\.\s*new\b)/,lookbehind:!0,inside:{punctuation:/[.\\]/}},keyword:/\b(?:BEGIN|END|alias|and|begin|break|case|class|def|define_method|defined|do|each|else|elsif|end|ensure|extend|for|if|in|include|module|new|next|nil|not|or|prepend|private|protected|public|raise|redo|require|rescue|retry|return|self|super|then|throw|undef|unless|until|when|while|yield)\b/,operator:/\.{2,3}|&\.|===|<?=>|[!=]?~|(?:&&|\|\||<<|>>|\*\*|[+\-*/%<>!^&|=])=?|[?:]/,punctuation:/[(){}[\].,;]/}),e.languages.insertBefore("ruby","operator",{"double-colon":{pattern:/::/,alias:"punctuation"}});var n={pattern:/((?:^|[^\\])(?:\\{2})*)#\{(?:[^{}]|\{[^{}]*\})*\}/,lookbehind:!0,inside:{content:{pattern:/^(#\{)[\s\S]+(?=\}$)/,lookbehind:!0,inside:e.languages.ruby},delimiter:{pattern:/^#\{|\}$/,alias:"punctuation"}}};delete e.languages.ruby.function;var t="(?:"+["([^a-zA-Z0-9\\s{(\\[<=])(?:(?!\\1)[^\\\\]|\\\\[^])*\\1","\\((?:[^()\\\\]|\\\\[^]|\\((?:[^()\\\\]|\\\\[^])*\\))*\\)","\\{(?:[^{}\\\\]|\\\\[^]|\\{(?:[^{}\\\\]|\\\\[^])*\\})*\\}","\\[(?:[^\\[\\]\\\\]|\\\\[^]|\\[(?:[^\\[\\]\\\\]|\\\\[^])*\\])*\\]","<(?:[^<>\\\\]|\\\\[^]|<(?:[^<>\\\\]|\\\\[^])*>)*>"].join("|")+")",i='(?:"(?:\\\\.|[^"\\\\\r\n])*"|(?:\\b[a-zA-Z_]\\w*|[^\\s\0-\\x7F]+)[?!]?|\\$.)';e.languages.insertBefore("ruby","keyword",{"regex-literal":[{pattern:RegExp("%r"+t+"[egimnosux]{0,6}"),greedy:!0,inside:{interpolation:n,regex:/[\s\S]+/}},{pattern:/(^|[^/])\/(?!\/)(?:\[[^\r\n\]]+\]|\\.|[^[/\\\r\n])+\/[egimnosux]{0,6}(?=\s*(?:$|[\r\n,.;})#]))/,lookbehind:!0,greedy:!0,inside:{interpolation:n,regex:/[\s\S]+/}}],variable:/[@$]+[a-zA-Z_]\w*(?:[?!]|\b)/,symbol:[{pattern:RegExp("(^|[^:]):"+i),lookbehind:!0,greedy:!0},{pattern:RegExp("([\r\n{(,][ \t]*)"+i+"(?=:(?!:))"),lookbehind:!0,greedy:!0}],"method-definition":{pattern:/(\bdef\s+)\w+(?:\s*\.\s*\w+)?/,lookbehind:!0,inside:{function:/\b\w+$/,keyword:/^self\b/,"class-name":/^\w+/,punctuation:/\./}}}),e.languages.insertBefore("ruby","string",{"string-literal":[{pattern:RegExp("%[qQiIwWs]?"+t),greedy:!0,inside:{interpolation:n,string:/[\s\S]+/}},{pattern:/("|')(?:#\{[^}]+\}|#(?!\{)|\\(?:\r\n|[\s\S])|(?!\1)[^\\#\r\n])*\1/,greedy:!0,inside:{interpolation:n,string:/[\s\S]+/}},{pattern:/<<[-~]?([a-z_]\w*)[\r\n](?:.*[\r\n])*?[\t ]*\1/i,alias:"heredoc-string",greedy:!0,inside:{delimiter:{pattern:/^<<[-~]?[a-z_]\w*|\b[a-z_]\w*$/i,inside:{symbol:/\b\w+/,punctuation:/^<<[-~]?/}},interpolation:n,string:/[\s\S]+/}},{pattern:/<<[-~]?'([a-z_]\w*)'[\r\n](?:.*[\r\n])*?[\t ]*\1/i,alias:"heredoc-string",greedy:!0,inside:{delimiter:{pattern:/^<<[-~]?'[a-z_]\w*'|\b[a-z_]\w*$/i,inside:{symbol:/\b\w+/,punctuation:/^<<[-~]?'|'$/}},string:/[\s\S]+/}}],"command-literal":[{pattern:RegExp("%x"+t),greedy:!0,inside:{interpolation:n,command:{pattern:/[\s\S]+/,alias:"string"}}},{pattern:/`(?:#\{[^}]+\}|#(?!\{)|\\(?:\r\n|[\s\S])|[^\\`#\r\n])*`/,greedy:!0,inside:{interpolation:n,command:{pattern:/[\s\S]+/,alias:"string"}}}]}),delete e.languages.ruby.string,e.languages.insertBefore("ruby","number",{builtin:/\b(?:Array|Bignum|Binding|Class|Continuation|Dir|Exception|FalseClass|File|Fixnum|Float|Hash|IO|Integer|MatchData|Method|Module|NilClass|Numeric|Object|Proc|Range|Regexp|Stat|String|Struct|Symbol|TMS|Thread|ThreadGroup|Time|TrueClass)\b/,constant:/\b[A-Z][A-Z0-9_]*(?:[?!]|\b)/}),e.languages.rb=e.languages.ruby}(Prism);
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Hyperlayer
|
2
|
+
class Event < ApplicationRecord
|
3
|
+
belongs_to :path
|
4
|
+
belongs_to :example_group
|
5
|
+
|
6
|
+
scope :call, -> { where(event_type: 'call') }
|
7
|
+
scope :return, -> { where(event_type: 'return') }
|
8
|
+
|
9
|
+
def return_value_events
|
10
|
+
Event.where(
|
11
|
+
'id > ?', id
|
12
|
+
).find_by(
|
13
|
+
event_type: 'return',
|
14
|
+
defined_class: defined_class,
|
15
|
+
method: method,
|
16
|
+
example_group: example_group
|
17
|
+
)
|
18
|
+
end
|
19
|
+
|
20
|
+
def spec
|
21
|
+
Hashie::Mash.new(self[:spec])
|
22
|
+
end
|
23
|
+
|
24
|
+
def method_code
|
25
|
+
FindMethodFromEvent.call(self)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Hyperlayer
|
2
|
+
class Path < ApplicationRecord
|
3
|
+
has_many :events
|
4
|
+
|
5
|
+
before_create :set_spec
|
6
|
+
|
7
|
+
def set_spec
|
8
|
+
return unless path.include?('spec')
|
9
|
+
|
10
|
+
self.spec = true
|
11
|
+
end
|
12
|
+
|
13
|
+
def overlay
|
14
|
+
BuildFileOverlay.call(path: self)
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_one
|
18
|
+
TestOne.call(path: self)
|
19
|
+
end
|
20
|
+
|
21
|
+
def edited
|
22
|
+
Ast.call(id)
|
23
|
+
end
|
24
|
+
|
25
|
+
def overlay_code
|
26
|
+
@code = ''
|
27
|
+
|
28
|
+
events.where(event_type: 'return').each do |event|
|
29
|
+
@code = UpdateCode.call(id, @code, event.method)
|
30
|
+
end
|
31
|
+
|
32
|
+
@code
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
class BuildFileOverlay
|
2
|
+
include Callable
|
3
|
+
expects :path
|
4
|
+
|
5
|
+
def call
|
6
|
+
@file = []
|
7
|
+
@raw_file = File.readlines(path.path)
|
8
|
+
|
9
|
+
@display_file = @raw_file.map.with_index(1) do |line, index|
|
10
|
+
@file << "#{index}: #{line}"
|
11
|
+
|
12
|
+
events = path.events.where(event_type: 'return', line_number: index)
|
13
|
+
|
14
|
+
events.each do |event|
|
15
|
+
item = " <i style='color: #ccc'>>>> #{event.method} = #{event.return_value.inspect}</i>"
|
16
|
+
|
17
|
+
next if @file.include?(item)
|
18
|
+
|
19
|
+
@file << item
|
20
|
+
@file << "\n"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
@file.join
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,129 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# BOILERPLATE SERVICE SETUP
|
4
|
+
#
|
5
|
+
# I know we are using interactors a lot at the moment but not
|
6
|
+
# _all_ things are an interactor and there are times where we
|
7
|
+
# still need to use a good ol' fashion ruby class.
|
8
|
+
#
|
9
|
+
# What this _does_ give us however is at least the setup portion
|
10
|
+
# of an Interactor, simply include this class in a ruby class
|
11
|
+
# and you'll get:
|
12
|
+
#
|
13
|
+
# class SomeClass
|
14
|
+
# def self.call(some:, args:, here:)
|
15
|
+
# new(some, args, here).call
|
16
|
+
# end
|
17
|
+
|
18
|
+
# def inititalize(some, args, here)
|
19
|
+
# @some = some
|
20
|
+
# @args = args
|
21
|
+
# @here = here
|
22
|
+
# end
|
23
|
+
|
24
|
+
# def call
|
25
|
+
# do some stuff in here
|
26
|
+
# end
|
27
|
+
|
28
|
+
# private
|
29
|
+
|
30
|
+
# attr_reader :some, :args, :here
|
31
|
+
# end
|
32
|
+
|
33
|
+
# You can now:
|
34
|
+
|
35
|
+
# class SomeClass
|
36
|
+
# include Callable
|
37
|
+
|
38
|
+
# expects :some, :args, :here
|
39
|
+
|
40
|
+
# def call
|
41
|
+
# do some stuff in here
|
42
|
+
# end
|
43
|
+
# end
|
44
|
+
#
|
45
|
+
module Callable # rubocop:disable
|
46
|
+
extend ActiveSupport::Concern
|
47
|
+
|
48
|
+
class_methods do
|
49
|
+
concerning :ExpectedValues do
|
50
|
+
def expects(*keys)
|
51
|
+
@expected_keys = keys
|
52
|
+
end
|
53
|
+
|
54
|
+
def received_expected_keys(kwargs)
|
55
|
+
kwargs.keys.map(&:to_sym) - Array(@optional_keys)
|
56
|
+
end
|
57
|
+
|
58
|
+
def validate_expectations_met!(kwargs)
|
59
|
+
missing_keys = Array(@expected_keys) - received_expected_keys(kwargs)
|
60
|
+
|
61
|
+
return unless missing_keys.any?
|
62
|
+
|
63
|
+
raise ArgumentError, "Expectations not met - missing keys: #{missing_keys}"
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
concerning :OptionalValues do
|
68
|
+
def optional(*keys)
|
69
|
+
@optional_keys = keys
|
70
|
+
end
|
71
|
+
|
72
|
+
def missing_optional_keys(kwargs)
|
73
|
+
@optional_keys&.select do |k, _v|
|
74
|
+
!kwargs.keys.include?(k)
|
75
|
+
end || []
|
76
|
+
end
|
77
|
+
|
78
|
+
def missing_optionals(kwargs)
|
79
|
+
missing_optional_keys(kwargs).index_with { |_k| nil }
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def readable_attributes(kwargs)
|
84
|
+
kwargs.merge(missing_optionals(kwargs))
|
85
|
+
end
|
86
|
+
|
87
|
+
def call(kwargs)
|
88
|
+
kwargs.deep_symbolize_keys!
|
89
|
+
|
90
|
+
validate_expectations_met!(kwargs)
|
91
|
+
|
92
|
+
new(readable_attributes(kwargs)).call
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
# OVERRIDING VALUES IN INITIALIZE
|
97
|
+
#
|
98
|
+
# If you want to override values in initialize then you can put this in your
|
99
|
+
# calling class and it will let you transform one of the values:
|
100
|
+
#
|
101
|
+
# def initialize(args)
|
102
|
+
# super
|
103
|
+
#
|
104
|
+
# @quantity = args[:quantity].to_i
|
105
|
+
# end
|
106
|
+
#
|
107
|
+
# Its not super clean, but there might be times it needs to be done.
|
108
|
+
#
|
109
|
+
def initialize(kwargs)
|
110
|
+
# Set each of them as an instance var, i.e.
|
111
|
+
# @something = something
|
112
|
+
readable_attributes = self.class.readable_attributes(kwargs)
|
113
|
+
|
114
|
+
readable_attributes.each do |key, value|
|
115
|
+
instance_variable_set("@#{key}", value)
|
116
|
+
end
|
117
|
+
|
118
|
+
@context = Hashie::Mash.new(kwargs)
|
119
|
+
|
120
|
+
# Then we set them as attr_readers so we can call them
|
121
|
+
# i.e. something
|
122
|
+
class_eval do
|
123
|
+
private
|
124
|
+
|
125
|
+
attr_reader(*readable_attributes.keys.map(&:to_sym))
|
126
|
+
attr_reader(:context)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|