reflekt 0.3.1 → 0.7.2

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: 7eecfaacf0ed26a06a1ab774a55f5ecf62713a71a685162a0da0fbd40696afec
4
- data.tar.gz: 8a64d9fc0c39102423e6c95cfbdecbc53d9510097b63c35cb2f4cb4fb89d8870
3
+ metadata.gz: d92d12a27556a25c258f83cf2983ffc2758a70c5cd359f4e7beafb862e88e68c
4
+ data.tar.gz: be5fa824eb0e6cd3bd15e03da504c40a65e471687881a5fbfcebc0d0906399fd
5
5
  SHA512:
6
- metadata.gz: d6029337485e9d149bd225e1a2786a37f7646115f3ea2adb6835adc8f686a1f93d090e7f68a3787ec37870f724f1a47dddf2df8b4ca58ad8dd6e7f0bda504c7c
7
- data.tar.gz: da9b95e714e27bc6b96475784129aa66c8468657544d6bc368fb89edee5b4fbc2c4022770482b0d1fa3095bb310ec215c72fd2a63221b897c307748f2eff80cd
6
+ metadata.gz: 9ffb39bc278932fd985731c7e509767e79c3356da41d7114a57cfe47a774bb97742ae283837859e2ff158ff84121e2b565c2bf25aff1ae0e8345671b9bd8da22
7
+ data.tar.gz: 3db51deab75140780e718e3536ab06696a1d0ef5308b1cbfcf2fb8a56dc9144905f22f2f53e918afcd7d1e962416134fc41a07676e17c4a16b935c70aece19fb
@@ -1,13 +1,7 @@
1
1
  require 'set'
2
-
3
- # Production.
2
+ require 'erb'
4
3
  require 'rowdb'
5
4
 
6
- # Development.
7
- #require_relative '../../rowdb/lib/rowdb.rb'
8
- #require_relative '../../rowdb/lib/adapters/Adapter.rb'
9
- #require_relative '../../rowdb/lib/adapters/FileSystem.rb'
10
-
11
5
  ################################################################################
12
6
  # REFLEKT
13
7
  #
@@ -19,27 +13,55 @@ require 'rowdb'
19
13
 
20
14
  module Reflekt
21
15
 
22
- @@clone_count = 5
16
+ # Reflection keys.
17
+ REFLEKT_TIME = "t"
18
+ REFLEKT_INPUT = "i"
19
+ REFLEKT_OUTPUT = "o"
20
+ REFLEKT_TYPE = "T"
21
+ REFLEKT_COUNT = "C"
22
+ REFLEKT_VALUE = "V"
23
+ REFLEKT_STATUS = "s"
24
+ REFLEKT_MESSAGE = "m"
25
+ # Reflection values.
26
+ REFLEKT_PASS = "p"
27
+ REFLEKT_FAIL = "f"
28
+
29
+ @@reflekt_clone_count = 5
23
30
 
24
31
  def initialize(*args)
25
32
 
26
33
  @reflekt_forked = false
27
34
  @reflekt_clones = []
28
35
 
36
+ # Limit the amount of clones that can be created per instance.
37
+ # A method called thousands of times doesn't need that many reflections.
38
+ @reflekt_limit = 5
39
+ @reflekt_count = 0
40
+
29
41
  # Override methods.
30
42
  self.class.instance_methods(false).each do |method|
31
43
  self.define_singleton_method(method) do |*args|
32
44
 
33
45
  # When method called in flow.
34
46
  if @reflekt_forked
35
- unless self.class.deflekted?(method)
36
- # Reflekt on method.
37
- @reflekt_clones.each do |clone|
38
- reflekt_action(clone, method, *args)
47
+
48
+ if @reflekt_count < @reflekt_limit
49
+ unless self.class.deflekted?(method)
50
+
51
+ # Reflekt on method.
52
+ @reflekt_clones.each do |clone|
53
+ reflekt_action(clone, method, *args)
54
+ end
55
+
56
+ # Save results.
57
+ @@reflekt_db.write()
58
+
59
+ reflekt_render()
60
+
39
61
  end
40
- # Save results.
41
- @@db.write()
62
+ @reflekt_count = @reflekt_count + 1
42
63
  end
64
+
43
65
  end
44
66
 
45
67
  # Continue method flow.
@@ -58,7 +80,7 @@ module Reflekt
58
80
 
59
81
  def reflekt_fork()
60
82
 
61
- @@clone_count.times do |clone|
83
+ @@reflekt_clone_count.times do |clone|
62
84
  @reflekt_clones << self.clone
63
85
  end
64
86
 
@@ -71,83 +93,171 @@ module Reflekt
71
93
  class_name = clone.class.to_s
72
94
  method_name = method.to_s
73
95
 
74
- # Create new arguments.
75
- new_args = []
96
+ # TODO: Create control fork. Get good value. Check against it.
97
+
98
+ # Create new arguments that are deviations on inputted type.
99
+ input = []
100
+
76
101
  args.each do |arg|
77
102
  case arg
78
103
  when Integer
79
- new_args << rand(9999)
104
+ input << rand(9999)
80
105
  else
81
- new_args << arg
106
+ input << arg
82
107
  end
83
108
  end
84
109
 
85
110
  # Action method with new arguments.
86
111
  begin
87
- clone.send(method, *new_args)
112
+ output = clone.send(method, *input)
88
113
 
89
114
  # Build reflection.
90
115
  reflection = {
91
- "time" => Time.now.to_i,
116
+ REFLEKT_TIME => Time.now.to_i,
117
+ REFLEKT_INPUT => reflekt_normalize_input(input),
118
+ REFLEKT_OUTPUT => reflekt_normalize_output(output)
92
119
  }
93
- # When error.
94
- rescue StandardError => error
95
- reflection["status"] = "error"
96
- reflection["error"] = error
97
- # When success.
120
+
121
+ # When fail.
122
+ rescue StandardError => message
123
+ reflection[REFLEKT_STATUS] = REFLEKT_MESSAGE
124
+ reflection[REFLEKT_MESSAGE] = message
125
+ # When pass.
98
126
  else
99
- reflection["status"] = "success"
127
+ reflection[REFLEKT_STATUS] = REFLEKT_PASS
100
128
  end
101
129
 
102
130
  # Save reflection.
103
- @@db.get("#{class_name}.#{method_name}")
104
- .push(reflection)
131
+ @@reflekt_db.get("#{class_name}.#{method_name}").push(reflection)
132
+
133
+ end
134
+
135
+ ##
136
+ # Normalize inputs.
137
+ #
138
+ # @param args - The actual inputs.
139
+ # @return - A generic inputs representation.
140
+ ##
141
+ def reflekt_normalize_input(args)
142
+ inputs = []
143
+ args.each do |arg|
144
+ input = {
145
+ REFLEKT_TYPE => arg.class.to_s,
146
+ REFLEKT_VALUE => reflekt_normalize_value(arg)
147
+ }
148
+ if (arg.class == Array)
149
+ input[REFLEKT_COUNT] = arg.count
150
+ end
151
+ inputs << input
152
+ end
153
+ inputs
154
+ end
155
+
156
+ ##
157
+ # Normalize output.
158
+ #
159
+ # @param output - The actual output.
160
+ # @return - A generic output representation.
161
+ ##
162
+ def reflekt_normalize_output(output)
163
+
164
+ o = {
165
+ REFLEKT_TYPE => output.class.to_s,
166
+ REFLEKT_VALUE => reflekt_normalize_value(output)
167
+ }
168
+
169
+ if (output.class == Array || output.class == Hash)
170
+ o[REFLEKT_COUNT] = output.count
171
+ elsif (output.class == TrueClass || output.class == FalseClass)
172
+ o[REFLEKT_TYPE] = :Boolean
173
+ end
174
+
175
+ return o
176
+
177
+ end
178
+
179
+ def reflekt_normalize_value(value)
180
+
181
+ unless value.nil?
182
+ value = value.to_s.gsub(/\r?\n/, " ").to_s
183
+ if value.length >= 30
184
+ value = value[0, value.rindex(/\s/,30)].rstrip() + '...'
185
+ end
186
+ end
187
+
188
+ return value
189
+
190
+ end
191
+
192
+ def reflekt_render()
193
+
194
+ # Render results.
195
+ @@reflekt_json = File.read("#{@@reflekt_output_path}/db.json")
196
+ template = File.read("#{@@reflekt_path}/web/template.html.erb")
197
+ rendered = ERB.new(template).result(binding)
198
+ File.open("#{@@reflekt_output_path}/index.html", 'w+') do |f|
199
+ f.write rendered
200
+ end
201
+
202
+ # Add JS.
203
+ javascript = File.read("#{@@reflekt_path}/web/script.js")
204
+ File.open("#{@@reflekt_output_path}/script.js", 'w+') do |f|
205
+ f.write javascript
206
+ end
207
+
208
+ # Add CSS.
209
+ stylesheet = File.read("#{@@reflekt_path}/web/style.css")
210
+ File.open("#{@@reflekt_output_path}/style.css", 'w+') do |f|
211
+ f.write stylesheet
212
+ end
105
213
 
106
214
  end
107
215
 
108
216
  private
109
217
 
110
- # Prepend Klass to the instance's singleton class.
111
218
  def self.prepended(base)
112
- base.singleton_class.prepend(Klass)
219
+ # Prepend class methods to the instance's singleton class.
220
+ base.singleton_class.prepend(SingletonClassMethods)
113
221
 
114
- @@setup ||= setup_klass
222
+ @@reflekt_setup ||= reflekt_setup_class
115
223
  end
116
224
 
117
- # Setup Klass.
118
- def self.setup_klass()
225
+ # Setup class.
226
+ def self.reflekt_setup_class()
119
227
 
120
228
  # Receive configuration from host application.
121
229
  $ENV ||= {}
122
230
  $ENV[:reflekt] ||= $ENV[:reflekt] = {}
123
231
 
232
+ @@reflekt_path = File.dirname(File.realpath(__FILE__))
233
+
124
234
  # Create "reflections" directory in configured path.
125
235
  if $ENV[:reflekt][:output_path]
126
- dir_path = File.join($ENV[:reflekt][:output_path], 'reflections')
236
+ @@reflekt_output_path = File.join($ENV[:reflekt][:output_path], 'reflections')
127
237
  # Create "reflections" directory in current execution path.
128
238
  else
129
- dir_path = File.join(Dir.pwd, 'reflections')
239
+ @@reflekt_output_path = File.join(Dir.pwd, 'reflections')
130
240
  end
131
241
 
132
- unless Dir.exist? dir_path
133
- Dir.mkdir(dir_path)
242
+ unless Dir.exist? @@reflekt_output_path
243
+ Dir.mkdir(@@reflekt_output_path)
134
244
  end
135
245
 
136
246
  # Create database.
137
- @@db = Rowdb.new(dir_path + '/db.json')
138
- @@db.defaults({"reflections" => []})
247
+ @@reflekt_db = Rowdb.new(@@reflekt_output_path + '/db.json')
248
+ @@reflekt_db.defaults({ :reflekt => { :api_version => 1 }}).write()
139
249
 
140
250
  return true
141
251
  end
142
252
 
143
- module Klass
253
+ module SingletonClassMethods
144
254
 
145
255
  @@deflekted_methods = Set.new
146
256
 
147
257
  ##
148
258
  # Skip a method.
149
259
  #
150
- # method - A symbol representing the method name.
260
+ # @param method - A symbol representing the method name.
151
261
  ##
152
262
  def reflekt_skip(method)
153
263
  @@deflekted_methods.add(method)
@@ -158,6 +268,10 @@ module Reflekt
158
268
  false
159
269
  end
160
270
 
271
+ def reflekt_limit(amount)
272
+ @reflekt_limit = amount
273
+ end
274
+
161
275
  end
162
276
 
163
277
  end
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Minified by jsDelivr using Terser v3.14.1.
3
+ * Original file: /gh/alpinejs/alpine@2.6.0/dist/alpine.js
4
+ *
5
+ * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files
6
+ */
7
+ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e=e||self).Alpine=t()}(this,function(){"use strict";function e(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function t(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,i)}return n}function n(n){for(var i=1;i<arguments.length;i++){var r=null!=arguments[i]?arguments[i]:{};i%2?t(Object(r),!0).forEach(function(t){e(n,t,r[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(n,Object.getOwnPropertyDescriptors(r)):t(Object(r)).forEach(function(e){Object.defineProperty(n,e,Object.getOwnPropertyDescriptor(r,e))})}return n}function i(e){return Array.from(new Set(e))}function r(){return navigator.userAgent.includes("Node.js")||navigator.userAgent.includes("jsdom")}function s(e,t){"template"!==e.tagName.toLowerCase()?console.warn(`Alpine: [${t}] directive should only be added to <template> tags. See https://github.com/alpinejs/alpine#${t}`):1!==e.content.childElementCount&&console.warn(`Alpine: <template> tag with [${t}] encountered with multiple element roots. Make sure <template> only has a single child node.`)}function o(e){return e.toLowerCase().replace(/-(\w)/g,(e,t)=>t.toUpperCase())}function a(e,t){var n;return function(){var i=this,r=arguments;clearTimeout(n),n=setTimeout(function(){n=null,e.apply(i,r)},t)}}function l(e,t,n={}){return"function"==typeof e?e.call(t):new Function(["$data",...Object.keys(n)],`var __alpine_result; with($data) { __alpine_result = ${e} }; return __alpine_result`)(t,...Object.values(n))}const c=/^x-(on|bind|data|text|html|model|if|for|show|cloak|transition|ref|spread)\b/;function u(e){const t=m(e.name);return c.test(t)}function d(e,t,n){let i=Array.from(e.attributes).filter(u).map(f),r=i.filter(e=>"spread"===e.type)[0];if(r){let e=l(r.expression,t.$data);i=i.concat(Object.entries(e).map(([e,t])=>f({name:e,value:t})))}return n?i.filter(e=>e.type===n):function(e){let t=["bind","model","show","catch-all"];return e.sort((e,n)=>{let i=-1===t.indexOf(e.type)?"catch-all":e.type,r=-1===t.indexOf(n.type)?"catch-all":n.type;return t.indexOf(i)-t.indexOf(r)})}(i)}function f({name:e,value:t}){const n=m(e),i=n.match(c),r=n.match(/:([a-zA-Z0-9\-:]+)/),s=n.match(/\.[^.\]]+(?=[^\]]*$)/g)||[];return{type:i?i[1]:null,value:r?r[1]:null,modifiers:s.map(e=>e.replace(".","")),expression:t}}function m(e){return e.startsWith("@")?e.replace("@","x-on:"):e.startsWith(":")?e.replace(":","x-bind:"):e}function p(e,t=Boolean){return e.split(" ").filter(t)}const h="in",v="out";function b(e,t,n,i=!1){if(i)return t();if(e.__x_transition&&e.__x_transition.type===h)return;const r=d(e,n,"transition"),s=d(e,n,"show")[0];if(s&&s.modifiers.includes("transition")){let n=s.modifiers;if(n.includes("out")&&!n.includes("in"))return t();const i=n.includes("in")&&n.includes("out");(function(e,t,n){const i={duration:g(t,"duration",150),origin:g(t,"origin","center"),first:{opacity:0,scale:g(t,"scale",95)},second:{opacity:1,scale:100}};x(e,t,n,()=>{},i,h)})(e,n=i?n.filter((e,t)=>t<n.indexOf("out")):n,t)}else r.some(e=>["enter","enter-start","enter-end"].includes(e.value))?function(e,t,n,i){let r=n=>"function"==typeof n?t.evaluateReturnExpression(e,n):n;const s=p(r((n.find(e=>"enter"===e.value)||{expression:""}).expression)),o=p(r((n.find(e=>"enter-start"===e.value)||{expression:""}).expression)),a=p(r((n.find(e=>"enter-end"===e.value)||{expression:""}).expression));_(e,s,o,a,i,()=>{},h)}(e,n,r,t):t()}function y(e,t,n,i=!1){if(i)return t();if(e.__x_transition&&e.__x_transition.type===v)return;const r=d(e,n,"transition"),s=d(e,n,"show")[0];if(s&&s.modifiers.includes("transition")){let n=s.modifiers;if(n.includes("in")&&!n.includes("out"))return t();const i=n.includes("in")&&n.includes("out");(function(e,t,n,i){const r={duration:n?g(t,"duration",150):g(t,"duration",150)/2,origin:g(t,"origin","center"),first:{opacity:1,scale:100},second:{opacity:0,scale:g(t,"scale",95)}};x(e,t,()=>{},i,r,v)})(e,n=i?n.filter((e,t)=>t>n.indexOf("out")):n,i,t)}else r.some(e=>["leave","leave-start","leave-end"].includes(e.value))?function(e,t,n,i){const r=p((n.find(e=>"leave"===e.value)||{expression:""}).expression),s=p((n.find(e=>"leave-start"===e.value)||{expression:""}).expression),o=p((n.find(e=>"leave-end"===e.value)||{expression:""}).expression);_(e,r,s,o,()=>{},i,v)}(e,0,r,t):t()}function g(e,t,n){if(-1===e.indexOf(t))return n;const i=e[e.indexOf(t)+1];if(!i)return n;if("scale"===t&&!E(i))return n;if("duration"===t){let e=i.match(/([0-9]+)ms/);if(e)return e[1]}return"origin"===t&&["top","right","left","center","bottom"].includes(e[e.indexOf(t)+2])?[i,e[e.indexOf(t)+2]].join(" "):i}function x(e,t,n,i,r,s){e.__x_transition&&(cancelAnimationFrame(e.__x_transition.nextFrame),e.__x_transition.callback&&e.__x_transition.callback());const o=e.style.opacity,a=e.style.transform,l=e.style.transformOrigin,c=!t.includes("opacity")&&!t.includes("scale"),u=c||t.includes("opacity"),d=c||t.includes("scale"),f={start(){u&&(e.style.opacity=r.first.opacity),d&&(e.style.transform=`scale(${r.first.scale/100})`)},during(){d&&(e.style.transformOrigin=r.origin),e.style.transitionProperty=[u?"opacity":"",d?"transform":""].join(" ").trim(),e.style.transitionDuration=`${r.duration/1e3}s`,e.style.transitionTimingFunction="cubic-bezier(0.4, 0.0, 0.2, 1)"},show(){n()},end(){u&&(e.style.opacity=r.second.opacity),d&&(e.style.transform=`scale(${r.second.scale/100})`)},hide(){i()},cleanup(){u&&(e.style.opacity=o),d&&(e.style.transform=a),d&&(e.style.transformOrigin=l),e.style.transitionProperty=null,e.style.transitionDuration=null,e.style.transitionTimingFunction=null}};w(e,f,s)}function _(e,t,n,i,r,s,o){e.__x_transition&&(cancelAnimationFrame(e.__x_transition.nextFrame),e.__x_transition.callback&&e.__x_transition.callback());const a=e.__x_original_classes||[],l={start(){e.classList.add(...n)},during(){e.classList.add(...t)},show(){r()},end(){e.classList.remove(...n.filter(e=>!a.includes(e))),e.classList.add(...i)},hide(){s()},cleanup(){e.classList.remove(...t.filter(e=>!a.includes(e))),e.classList.remove(...i.filter(e=>!a.includes(e)))}};w(e,l,o)}function w(e,t,n){e.__x_transition={type:n,callback:O(()=>{t.hide(),e.isConnected&&t.cleanup(),delete e.__x_transition}),nextFrame:null},t.start(),t.during(),e.__x_transition.nextFrame=requestAnimationFrame(()=>{let n=1e3*Number(getComputedStyle(e).transitionDuration.replace(/,.*/,"").replace("s",""));0===n&&(n=1e3*Number(getComputedStyle(e).animationDuration.replace("s",""))),t.show(),e.__x_transition.nextFrame=requestAnimationFrame(()=>{t.end(),setTimeout(e.__x_transition.callback,n)})})}function E(e){return!isNaN(e)}function O(e){let t=!1;return function(){t||(t=!0,e.apply(this,arguments))}}function k(e,t,i,r,o){s(t,"x-for");let a=A("function"==typeof i?e.evaluateReturnExpression(t,i):i),l=function(e,t,n,i){let r=d(t,e,"if")[0];if(r&&!e.evaluateReturnExpression(t,r.expression))return[];return e.evaluateReturnExpression(t,n.items,i)}(e,t,a,o),c=t;l.forEach((i,s)=>{let u=function(e,t,i,r,s){let o=s?n({},s):{};o[e.item]=t,e.index&&(o[e.index]=i);e.collection&&(o[e.collection]=r);return o}(a,i,s,l,o()),f=function(e,t,n,i){let r=d(t,e,"bind").filter(e=>"key"===e.value)[0];return r?e.evaluateReturnExpression(t,r.expression,()=>i):n}(e,t,s,u),m=function(e,t){if(!e)return;if(e.__x_for_key===t)return e;let n=e;for(;n;){if(n.__x_for_key===t)return n.parentElement.insertBefore(n,e);n=!(!n.nextElementSibling||void 0===n.nextElementSibling.__x_for_key)&&n.nextElementSibling}}(c.nextElementSibling,f);m?(delete m.__x_for_key,m.__x_for=u,e.updateElements(m,()=>m.__x_for)):(b(m=function(e,t){let n=document.importNode(e.content,!0);return t.parentElement.insertBefore(n,t.nextElementSibling),t.nextElementSibling}(t,c),()=>{},e,r),m.__x_for=u,e.initializeElements(m,()=>m.__x_for)),(c=m).__x_for_key=f}),function(e,t){var n=!(!e.nextElementSibling||void 0===e.nextElementSibling.__x_for_key)&&e.nextElementSibling;for(;n;){let e=n,i=n.nextElementSibling;y(n,()=>{e.remove()},t),n=!(!i||void 0===i.__x_for_key)&&i}}(c,e)}function A(e){let t=/,([^,\}\]]*)(?:,([^,\}\]]*))?$/,n=e.match(/([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/);if(!n)return;let i={};i.items=n[2].trim();let r=n[1].trim().replace(/^\(|\)$/g,""),s=r.match(t);return s?(i.item=r.replace(t,"").trim(),i.index=s[1].trim(),s[2]&&(i.collection=s[2].trim())):i.item=r,i}function S(e,t,n,r,s,a,l){var c=e.evaluateReturnExpression(t,r,s);if("value"===n){if(me.ignoreFocusedForValueBinding&&document.activeElement.isSameNode(t))return;if(void 0===c&&r.match(/\./)&&(c=""),"radio"===t.type)void 0===t.attributes.value&&"bind"===a?t.value=c:"bind"!==a&&(t.checked=t.value==c);else if("checkbox"===t.type)"string"==typeof c&&"bind"===a?t.value=c:"bind"!==a&&(Array.isArray(c)?t.checked=c.some(e=>e==t.value):t.checked=!!c);else if("SELECT"===t.tagName)!function(e,t){const n=[].concat(t).map(e=>e+"");Array.from(e.options).forEach(e=>{e.selected=n.includes(e.value||e.text)})}(t,c);else{if(t.value===c)return;t.value=c}}else if("class"===n)if(Array.isArray(c)){const e=t.__x_original_classes||[];t.setAttribute("class",i(e.concat(c)).join(" "))}else if("object"==typeof c){Object.keys(c).sort((e,t)=>c[e]-c[t]).forEach(e=>{c[e]?p(e).forEach(e=>t.classList.add(e)):p(e).forEach(e=>t.classList.remove(e))})}else{const e=t.__x_original_classes||[],n=p(c);t.setAttribute("class",i(e.concat(n)).join(" "))}else n=l.includes("camel")?o(n):n,[null,void 0,!1].includes(c)?t.removeAttribute(n):!function(e){return["disabled","checked","required","readonly","hidden","open","selected","autofocus","itemscope","multiple","novalidate","allowfullscreen","allowpaymentrequest","formnovalidate","autoplay","controls","loop","muted","playsinline","default","ismap","reversed","async","defer","nomodule"].includes(e)}(n)?$(t,n,c):$(t,n,n)}function $(e,t,n){e.getAttribute(t)!=n&&e.setAttribute(t,n)}function P(e,t,n,i,r,s={}){const l={passive:i.includes("passive")};if(i.includes("camel")&&(n=o(n)),i.includes("away")){let o=a=>{t.contains(a.target)||t.offsetWidth<1&&t.offsetHeight<1||(C(e,r,a,s),i.includes("once")&&document.removeEventListener(n,o,l))};document.addEventListener(n,o,l)}else{let o=i.includes("window")?window:i.includes("document")?document:t,c=a=>{if(o!==window&&o!==document||document.body.contains(t)){if(!(function(e){return["keydown","keyup"].includes(e)}(n)&&function(e,t){let n=t.filter(e=>!["window","document","prevent","stop"].includes(e));if(n.includes("debounce")){let e=n.indexOf("debounce");n.splice(e,E((n[e+1]||"invalid-wait").split("ms")[0])?2:1)}if(0===n.length)return!1;if(1===n.length&&n[0]===D(e.key))return!1;const i=["ctrl","shift","alt","meta","cmd","super"].filter(e=>n.includes(e));if(n=n.filter(e=>!i.includes(e)),i.length>0){const t=i.filter(t=>("cmd"!==t&&"super"!==t||(t="meta"),e[`${t}Key`]));if(t.length===i.length&&n[0]===D(e.key))return!1}return!0}(a,i)||(i.includes("prevent")&&a.preventDefault(),i.includes("stop")&&a.stopPropagation(),i.includes("self")&&a.target!==t))){C(e,r,a,s).then(e=>{!1===e?a.preventDefault():i.includes("once")&&o.removeEventListener(n,c,l)})}}else o.removeEventListener(n,c,l)};if(i.includes("debounce")){let e=i[i.indexOf("debounce")+1]||"invalid-wait",t=E(e.split("ms")[0])?Number(e.split("ms")[0]):250;c=a(c,t)}o.addEventListener(n,c,l)}}function C(e,t,i,r){return e.evaluateCommandExpression(i.target,t,()=>n(n({},r()),{},{$event:i}))}function D(e){switch(e){case"/":return"slash";case" ":case"Spacebar":return"space";default:return e&&e.replace(/([a-z])([A-Z])/g,"$1-$2").replace(/[_\s]/,"-").toLowerCase()}}function j(e,t,n){return"radio"===e.type&&(e.hasAttribute("name")||e.setAttribute("name",n)),(n,i)=>{if(n instanceof CustomEvent&&n.detail)return n.detail;if("checkbox"===e.type){if(Array.isArray(i)){const e=t.includes("number")?T(n.target.value):n.target.value;return n.target.checked?i.concat([e]):i.filter(t=>t!==e)}return n.target.checked}if("select"===e.tagName.toLowerCase()&&e.multiple)return t.includes("number")?Array.from(n.target.selectedOptions).map(e=>{return T(e.value||e.text)}):Array.from(n.target.selectedOptions).map(e=>e.value||e.text);{const e=n.target.value;return t.includes("number")?T(e):t.includes("trim")?e.trim():e}}}function T(e){const t=e?parseFloat(e):null;return E(t)?t:e}const{isArray:L}=Array,{getPrototypeOf:N,create:z,defineProperty:R,defineProperties:F,isExtensible:I,getOwnPropertyDescriptor:M,getOwnPropertyNames:B,getOwnPropertySymbols:U,preventExtensions:q,hasOwnProperty:W}=Object,{push:K,concat:G,map:H}=Array.prototype;function V(e){return void 0===e}function Z(e){return"function"==typeof e}const J=new WeakMap;function Q(e,t){J.set(e,t)}const X=e=>J.get(e)||e;function Y(e,t){return e.valueIsObservable(t)?e.getProxy(t):t}function ee(e,t,n){G.call(B(n),U(n)).forEach(i=>{let r=M(n,i);r.configurable||(r=ue(e,r,Y)),R(t,i,r)}),q(t)}class te{constructor(e,t){this.originalTarget=t,this.membrane=e}get(e,t){const{originalTarget:n,membrane:i}=this,r=n[t],{valueObserved:s}=i;return s(n,t),i.getProxy(r)}set(e,t,n){const{originalTarget:i,membrane:{valueMutated:r}}=this;return i[t]!==n?(i[t]=n,r(i,t)):"length"===t&&L(i)&&r(i,t),!0}deleteProperty(e,t){const{originalTarget:n,membrane:{valueMutated:i}}=this;return delete n[t],i(n,t),!0}apply(e,t,n){}construct(e,t,n){}has(e,t){const{originalTarget:n,membrane:{valueObserved:i}}=this;return i(n,t),t in n}ownKeys(e){const{originalTarget:t}=this;return G.call(B(t),U(t))}isExtensible(e){const t=I(e);if(!t)return t;const{originalTarget:n,membrane:i}=this,r=I(n);return r||ee(i,e,n),r}setPrototypeOf(e,t){}getPrototypeOf(e){const{originalTarget:t}=this;return N(t)}getOwnPropertyDescriptor(e,t){const{originalTarget:n,membrane:i}=this,{valueObserved:r}=this.membrane;r(n,t);let s=M(n,t);if(V(s))return s;const o=M(e,t);return V(o)?((s=ue(i,s,Y)).configurable||R(e,t,s),s):o}preventExtensions(e){const{originalTarget:t,membrane:n}=this;return ee(n,e,t),q(t),!0}defineProperty(e,t,n){const{originalTarget:i,membrane:r}=this,{valueMutated:s}=r,{configurable:o}=n;if(W.call(n,"writable")&&!W.call(n,"value")){const e=M(i,t);n.value=e.value}return R(i,t,function(e){return W.call(e,"value")&&(e.value=X(e.value)),e}(n)),!1===o&&R(e,t,ue(r,n,Y)),s(i,t),!0}}function ne(e,t){return e.valueIsObservable(t)?e.getReadOnlyProxy(t):t}class ie{constructor(e,t){this.originalTarget=t,this.membrane=e}get(e,t){const{membrane:n,originalTarget:i}=this,r=i[t],{valueObserved:s}=n;return s(i,t),n.getReadOnlyProxy(r)}set(e,t,n){return!1}deleteProperty(e,t){return!1}apply(e,t,n){}construct(e,t,n){}has(e,t){const{originalTarget:n,membrane:{valueObserved:i}}=this;return i(n,t),t in n}ownKeys(e){const{originalTarget:t}=this;return G.call(B(t),U(t))}setPrototypeOf(e,t){}getOwnPropertyDescriptor(e,t){const{originalTarget:n,membrane:i}=this,{valueObserved:r}=i;r(n,t);let s=M(n,t);if(V(s))return s;const o=M(e,t);return V(o)?(s=ue(i,s,ne),W.call(s,"set")&&(s.set=void 0),s.configurable||R(e,t,s),s):o}preventExtensions(e){return!1}defineProperty(e,t,n){return!1}}function re(e){let t=void 0;return L(e)?t=[]:"object"==typeof e&&(t={}),t}const se=Object.prototype;function oe(e){if(null===e)return!1;if("object"!=typeof e)return!1;if(L(e))return!0;const t=N(e);return t===se||null===t||null===N(t)}const ae=(e,t)=>{},le=(e,t)=>{},ce=e=>e;function ue(e,t,n){const{set:i,get:r}=t;return W.call(t,"value")?t.value=n(e,t.value):(V(r)||(t.get=function(){return n(e,r.call(X(this)))}),V(i)||(t.set=function(t){i.call(X(this),e.unwrapProxy(t))})),t}class de{constructor(e){if(this.valueDistortion=ce,this.valueMutated=le,this.valueObserved=ae,this.valueIsObservable=oe,this.objectGraph=new WeakMap,!V(e)){const{valueDistortion:t,valueMutated:n,valueObserved:i,valueIsObservable:r}=e;this.valueDistortion=Z(t)?t:ce,this.valueMutated=Z(n)?n:le,this.valueObserved=Z(i)?i:ae,this.valueIsObservable=Z(r)?r:oe}}getProxy(e){const t=X(e),n=this.valueDistortion(t);if(this.valueIsObservable(n)){const i=this.getReactiveState(t,n);return i.readOnly===e?e:i.reactive}return n}getReadOnlyProxy(e){e=X(e);const t=this.valueDistortion(e);return this.valueIsObservable(t)?this.getReactiveState(e,t).readOnly:t}unwrapProxy(e){return X(e)}getReactiveState(e,t){const{objectGraph:n}=this;let i=n.get(t);if(i)return i;const r=this;return i={get reactive(){const n=new te(r,t),i=new Proxy(re(t),n);return Q(i,e),R(this,"reactive",{value:i}),i},get readOnly(){const n=new ie(r,t),i=new Proxy(re(t),n);return Q(i,e),R(this,"readOnly",{value:i}),i}},n.set(t,i),i}}class fe{constructor(e,t=null){this.$el=e;const n=this.$el.getAttribute("x-data"),i=""===n?"{}":n,r=this.$el.getAttribute("x-init");let s={$el:this.$el},o=t?t.$el:this.$el;Object.entries(me.magicProperties).forEach(([e,t])=>{Object.defineProperty(s,`$${e}`,{get:function(){return t(o)}})}),this.unobservedData=t?t.getUnobservedData():l(i,s);let{membrane:a,data:c}=this.wrapDataInObservable(this.unobservedData);var u;this.$data=c,this.membrane=a,this.unobservedData.$el=this.$el,this.unobservedData.$refs=this.getRefsProxy(),this.nextTickStack=[],this.unobservedData.$nextTick=(e=>{this.nextTickStack.push(e)}),this.watchers={},this.unobservedData.$watch=((e,t)=>{this.watchers[e]||(this.watchers[e]=[]),this.watchers[e].push(t)}),Object.entries(me.magicProperties).forEach(([e,t])=>{Object.defineProperty(this.unobservedData,`$${e}`,{get:function(){return t(o)}})}),this.showDirectiveStack=[],this.showDirectiveLastElement,t||me.onBeforeComponentInitializeds.forEach(e=>e(this)),r&&!t&&(this.pauseReactivity=!0,u=this.evaluateReturnExpression(this.$el,r),this.pauseReactivity=!1),this.initializeElements(this.$el),this.listenForNewElementsToInitialize(),"function"==typeof u&&u.call(this.$data),t||setTimeout(()=>{me.onComponentInitializeds.forEach(e=>e(this))},0)}getUnobservedData(){return function(e,t){let n=e.unwrapProxy(t),i={};return Object.keys(n).forEach(e=>{["$el","$refs","$nextTick","$watch"].includes(e)||(i[e]=n[e])}),i}(this.membrane,this.$data)}wrapDataInObservable(e){var t=this;let n=a(function(){t.updateElements(t.$el)},0);return function(e,t){let n=new de({valueMutated(e,n){t(e,n)}});return{data:n.getProxy(e),membrane:n}}(e,(e,i)=>{t.watchers[i]?t.watchers[i].forEach(t=>t(e[i])):Object.keys(t.watchers).filter(e=>e.includes(".")).forEach(n=>{let r=n.split(".");i===r[r.length-1]&&r.reduce((r,s)=>(Object.is(e,r)&&t.watchers[n].forEach(t=>t(e[i])),r[s]),t.getUnobservedData())}),t.pauseReactivity||n()})}walkAndSkipNestedComponents(e,t,n=(()=>{})){!function e(t,n){if(!1===n(t))return;let i=t.firstElementChild;for(;i;)e(i,n),i=i.nextElementSibling}(e,e=>e.hasAttribute("x-data")&&!e.isSameNode(this.$el)?(e.__x||n(e),!1):t(e))}initializeElements(e,t=(()=>{})){this.walkAndSkipNestedComponents(e,e=>void 0===e.__x_for_key&&(void 0===e.__x_inserted_me&&void this.initializeElement(e,t)),e=>{e.__x=new fe(e)}),this.executeAndClearRemainingShowDirectiveStack(),this.executeAndClearNextTickStack(e)}initializeElement(e,t){e.hasAttribute("class")&&d(e,this).length>0&&(e.__x_original_classes=p(e.getAttribute("class"))),this.registerListeners(e,t),this.resolveBoundAttributes(e,!0,t)}updateElements(e,t=(()=>{})){this.walkAndSkipNestedComponents(e,e=>{if(void 0!==e.__x_for_key&&!e.isSameNode(this.$el))return!1;this.updateElement(e,t)},e=>{e.__x=new fe(e)}),this.executeAndClearRemainingShowDirectiveStack(),this.executeAndClearNextTickStack(e)}executeAndClearNextTickStack(e){e===this.$el&&this.nextTickStack.length>0&&requestAnimationFrame(()=>{for(;this.nextTickStack.length>0;)this.nextTickStack.shift()()})}executeAndClearRemainingShowDirectiveStack(){this.showDirectiveStack.reverse().map(e=>new Promise(t=>{e(e=>{t(e)})})).reduce((e,t)=>e.then(()=>t.then(e=>e())),Promise.resolve(()=>{})),this.showDirectiveStack=[],this.showDirectiveLastElement=void 0}updateElement(e,t){this.resolveBoundAttributes(e,!1,t)}registerListeners(e,t){d(e,this).forEach(({type:i,value:r,modifiers:s,expression:o})=>{switch(i){case"on":P(this,e,r,s,o,t);break;case"model":!function(e,t,i,r,s){var o="select"===t.tagName.toLowerCase()||["checkbox","radio"].includes(t.type)||i.includes("lazy")?"change":"input";P(e,t,o,i,`${r} = rightSideOfExpression($event, ${r})`,()=>n(n({},s()),{},{rightSideOfExpression:j(t,i,r)}))}(this,e,s,o,t)}})}resolveBoundAttributes(e,t=!1,n){let i=d(e,this);i.forEach(({type:r,value:o,modifiers:a,expression:l})=>{switch(r){case"model":S(this,e,"value",l,n,r,a);break;case"bind":if("template"===e.tagName.toLowerCase()&&"key"===o)return;S(this,e,o,l,n,r,a);break;case"text":var c=this.evaluateReturnExpression(e,l,n);!function(e,t,n){void 0===t&&n.match(/\./)&&(t=""),e.innerText=t}(e,c,l);break;case"html":!function(e,t,n,i){t.innerHTML=e.evaluateReturnExpression(t,n,i)}(this,e,l,n);break;case"show":c=this.evaluateReturnExpression(e,l,n);!function(e,t,n,i,r=!1){const s=()=>{t.style.display="none"},o=()=>{1===t.style.length&&"none"===t.style.display?t.removeAttribute("style"):t.style.removeProperty("display")};if(!0===r)return void(n?o():s());const a=i=>{n?(("none"===t.style.display||t.__x_transition)&&b(t,()=>{o()},e),i(()=>{})):"none"!==t.style.display?y(t,()=>{i(()=>{s()})},e):i(()=>{})};i.includes("immediate")?a(e=>e()):(e.showDirectiveLastElement&&!e.showDirectiveLastElement.contains(t)&&e.executeAndClearRemainingShowDirectiveStack(),e.showDirectiveStack.push(a),e.showDirectiveLastElement=t)}(this,e,c,a,t);break;case"if":if(i.some(e=>"for"===e.type))return;c=this.evaluateReturnExpression(e,l,n);!function(e,t,n,i,r){s(t,"x-if");const o=t.nextElementSibling&&!0===t.nextElementSibling.__x_inserted_me;if(!n||o&&!t.__x_transition)!n&&o&&y(t.nextElementSibling,()=>{t.nextElementSibling.remove()},e,i);else{const n=document.importNode(t.content,!0);t.parentElement.insertBefore(n,t.nextElementSibling),b(t.nextElementSibling,()=>{},e,i),e.initializeElements(t.nextElementSibling,r),t.nextElementSibling.__x_inserted_me=!0}}(this,e,c,t,n);break;case"for":k(this,e,l,t,n);break;case"cloak":e.removeAttribute("x-cloak")}})}evaluateReturnExpression(e,t,i=(()=>{})){return l(t,this.$data,n(n({},i()),{},{$dispatch:this.getDispatchFunction(e)}))}evaluateCommandExpression(e,t,i=(()=>{})){return function(e,t,n={}){if("function"==typeof e)return Promise.resolve(e.call(t,n.$event));let i=Function;if(i=Object.getPrototypeOf(async function(){}).constructor,Object.keys(t).includes(e)){let i=new Function(["dataContext",...Object.keys(n)],`with(dataContext) { return ${e} }`)(t,...Object.values(n));return"function"==typeof i?Promise.resolve(i.call(t,n.$event)):Promise.resolve()}return Promise.resolve(new i(["dataContext",...Object.keys(n)],`with(dataContext) { ${e} }`)(t,...Object.values(n)))}(t,this.$data,n(n({},i()),{},{$dispatch:this.getDispatchFunction(e)}))}getDispatchFunction(e){return(t,n={})=>{e.dispatchEvent(new CustomEvent(t,{detail:n,bubbles:!0}))}}listenForNewElementsToInitialize(){const e=this.$el;new MutationObserver(e=>{for(let t=0;t<e.length;t++){const n=e[t].target.closest("[x-data]");if(n&&n.isSameNode(this.$el)){if("attributes"===e[t].type&&"x-data"===e[t].attributeName){const n=l(e[t].target.getAttribute("x-data")||"{}",{$el:this.$el});Object.keys(n).forEach(e=>{this.$data[e]!==n[e]&&(this.$data[e]=n[e])})}e[t].addedNodes.length>0&&e[t].addedNodes.forEach(e=>{1!==e.nodeType||e.__x_inserted_me||(!e.matches("[x-data]")||e.__x?this.initializeElements(e):e.__x=new fe(e))})}}}).observe(e,{childList:!0,attributes:!0,subtree:!0})}getRefsProxy(){var e=this;return new Proxy({},{get(t,n){return"$isAlpineProxy"===n||(e.walkAndSkipNestedComponents(e.$el,e=>{e.hasAttribute("x-ref")&&e.getAttribute("x-ref")===n&&(i=e)}),i);var i}})}}const me={version:"2.6.0",pauseMutationObserver:!1,magicProperties:{},onComponentInitializeds:[],onBeforeComponentInitializeds:[],ignoreFocusedForValueBinding:!1,start:async function(){r()||await new Promise(e=>{"loading"==document.readyState?document.addEventListener("DOMContentLoaded",e):e()}),this.discoverComponents(e=>{this.initializeComponent(e)}),document.addEventListener("turbolinks:load",()=>{this.discoverUninitializedComponents(e=>{this.initializeComponent(e)})}),this.listenForNewUninitializedComponentsAtRunTime(e=>{this.initializeComponent(e)})},discoverComponents:function(e){document.querySelectorAll("[x-data]").forEach(t=>{e(t)})},discoverUninitializedComponents:function(e,t=null){const n=(t||document).querySelectorAll("[x-data]");Array.from(n).filter(e=>void 0===e.__x).forEach(t=>{e(t)})},listenForNewUninitializedComponentsAtRunTime:function(e){const t=document.querySelector("body");new MutationObserver(e=>{if(!this.pauseMutationObserver)for(let t=0;t<e.length;t++)e[t].addedNodes.length>0&&e[t].addedNodes.forEach(e=>{1===e.nodeType&&(e.parentElement&&e.parentElement.closest("[x-data]")||this.discoverUninitializedComponents(e=>{this.initializeComponent(e)},e.parentElement))})}).observe(t,{childList:!0,attributes:!0,subtree:!0})},initializeComponent:function(e){if(!e.__x)try{e.__x=new fe(e)}catch(e){setTimeout(()=>{throw e},0)}},clone:function(e,t){t.__x||(t.__x=new fe(t,e))},addMagicProperty:function(e,t){this.magicProperties[e]=t},onComponentInitialized:function(e){this.onComponentInitializeds.push(e)},onBeforeComponentInitialized:function(e){this.onBeforeComponentInitializeds.push(e)}};return r()||(window.Alpine=me,window.deferLoadingAlpine?window.deferLoadingAlpine(function(){window.Alpine.start()}):window.Alpine.start()),me});
8
+ //# sourceMappingURL=/sm/54d8acf4bec59c2ac38179fad55c741f03c418f9ea483b114454c0827631f4ba.map
@@ -0,0 +1,139 @@
1
+ /* Layout. */
2
+ body {
3
+ padding: 0.5rem;
4
+ background: #C9D2E6;
5
+ font-family: 'Roboto', sans-serif;
6
+ }
7
+
8
+ .container {
9
+ margin: 0 auto;
10
+ max-width: 1000px;
11
+ padding: 2rem;
12
+ background: white;
13
+ }
14
+
15
+ /* Header. */
16
+ #logo {
17
+ display: block;
18
+ margin: 0 auto;
19
+ max-width: 100px;
20
+ }
21
+
22
+ /* Structure */
23
+ ul.classes,
24
+ ul.methods,
25
+ ul.reflections {
26
+ padding-left: 0;
27
+ }
28
+
29
+ li.class-container,
30
+ li.method-container {
31
+ list-style: none;
32
+ padding: 1rem;
33
+ border: 5px solid #dadcdc;
34
+ }
35
+
36
+ /* State. */
37
+ .status-row {
38
+ width: 100%;
39
+ display: flex;
40
+ align-items: center;
41
+ flex-direction: row;
42
+ color: white;
43
+ background: #A9B6D2;
44
+ }
45
+ .status-row.pass {
46
+ background: #008C32;
47
+ }
48
+ .status-row.fail {
49
+ background: #D04700;
50
+ }
51
+
52
+ /* Stats. */
53
+ .stats {
54
+ margin-left: auto;
55
+ }
56
+ .stat {
57
+ color: #efefef;
58
+ font-size: 3.5rem;
59
+ font-family: 'Merriweather', serif;
60
+ }
61
+
62
+ /* Class. */
63
+ .class {
64
+ padding: 2rem;
65
+ margin-bottom: 1rem;
66
+ }
67
+ .class:hover {
68
+ cursor: pointer;
69
+ }
70
+ .class h2 {
71
+ margin: 0;
72
+ }
73
+
74
+ /* Method. */
75
+ .method {
76
+ padding: 2rem;
77
+ margin-left: 1rem;
78
+ margin-bottom: 1rem;
79
+ }
80
+ .method:hover {
81
+ cursor: pointer;
82
+ }
83
+ .method .stat {
84
+ font-size: 2.5rem;
85
+ }
86
+
87
+ /* Reflection. */
88
+ .reflection {
89
+ list-style: none;
90
+ margin-left: 2rem;
91
+ display: flex;
92
+ flex-direction: row;
93
+ align-items: center;
94
+ background: #EFEFEF;
95
+ padding: 0.5rem 1.5rem;
96
+ margin-bottom: 0.3rem;
97
+ }
98
+ .reflection .time {
99
+ color: #777777;
100
+ margin-right: 2rem;
101
+ }
102
+
103
+ .info {
104
+ display: flex;
105
+ flex-direction: row;
106
+ align-items: center;
107
+ padding: 0.5rem 1rem;
108
+ border: 1px solid #aaa;
109
+ border-radius: 5px;
110
+ }
111
+ .info:not(:last-child) {
112
+ margin-right: 0.5rem;
113
+ }
114
+ .info h4 {
115
+ margin: 0;
116
+ color: #777777;
117
+ font-size: 1.2rem;
118
+ font-weight: normal;
119
+ }
120
+
121
+ .info-items {
122
+ display: flex;
123
+ flex-direction: row;
124
+ }
125
+ .info-item {
126
+ padding-left: 1rem;
127
+ padding-right: 1rem;
128
+ border-right: 1px solid #ccc;
129
+ }
130
+ .info-item:last-of-type {
131
+ padding-right: 0;
132
+ border-right: 0;
133
+ }
134
+ .info-item strong {
135
+ padding-bottom: 0.1rem;
136
+ }
137
+ .info-item pre {
138
+ margin: 0;
139
+ }
@@ -0,0 +1,210 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+
4
+ <head>
5
+ <meta charset="utf-8">
6
+ <title>Reflekt</title>
7
+ <meta name="description" content="Reflective testing results.">
8
+ <meta name="author" content="Maedi Prichard">
9
+ <meta name="viewport" content="width=device-width, initial-scale=1">
10
+ <link rel="stylesheet" href="style.css">
11
+ <link rel="shortcut icon" href="">
12
+ <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;700&display=swap" rel="stylesheet">
13
+ <link href="https://fonts.googleapis.com/css2?family=Merriweather&display=swap" rel="stylesheet">
14
+ </head>
15
+
16
+ <body>
17
+
18
+ <script>
19
+
20
+ // Reflection keys.
21
+ const TIME = "t";
22
+ const INPUT = "i";
23
+ const OUTPUT = "o";
24
+ const TYPE = "T";
25
+ const COUNT = "C";
26
+ const VALUE = "V";
27
+ const STATUS = "s";
28
+ const MESSAGE = "m";
29
+ // Reflection values.
30
+ const PASS = "p";
31
+ const FAIL = "f";
32
+
33
+ function getData() {
34
+
35
+ var reflections = JSON.parse(<%= @@reflekt_json %>);
36
+ console.log("REFLECTIONS:");
37
+ console.log(reflections);
38
+ var results = {};
39
+
40
+ if ('reflekt' in reflections) {
41
+ delete(reflections.reflekt);
42
+ }
43
+
44
+ // Classes.
45
+ for ([class_id, class_value] of Object.entries(reflections)) {
46
+
47
+ // Class pass rate.
48
+ results[class_id] = {
49
+ 'stats': {
50
+ 'pass_rate': undefined,
51
+ 'test_count': 0,
52
+ 'pass_count': 0
53
+ },
54
+ 'methods': {}
55
+ };
56
+
57
+ // Methods.
58
+ for ([method_id, method] of Object.entries(class_value)) {
59
+
60
+ // Method pass rate.
61
+ var pass_count = method.reduce(function(obj, v) {
62
+ obj[v[STATUS]] = (obj[v[STATUS]] || 0) + 1;
63
+ return obj;
64
+ }, {});
65
+
66
+ var pass_rate = (pass_count[PASS] / method.length) * 100;
67
+ results[class_id]['methods'][method_id] = {
68
+ 'stats': {
69
+ 'pass_rate': pass_rate,
70
+ 'test_count': method.length,
71
+ 'pass_count': pass_count[PASS]
72
+ }
73
+ };
74
+ if (pass_rate == 100) {
75
+ results[class_id]['methods'][method_id]['status'] = 'pass';
76
+ }
77
+ else if (pass_rate < 100) {
78
+ results[class_id]['methods'][method_id]['status'] = 'fail';
79
+ }
80
+
81
+ // Class pass rate.
82
+ results[class_id]['stats']['test_count'] += method.length;
83
+ results[class_id]['stats']['pass_count'] += pass_count[PASS];
84
+
85
+ }
86
+
87
+ // Class pass rate.
88
+ var class_stats = results[class_id]['stats'];
89
+ var pass_rate = (class_stats['pass_count'] / class_stats['test_count']) * 100;
90
+ class_stats['pass_rate'] = pass_rate;
91
+ if (pass_rate == 100) {
92
+ results[class_id]['status'] = 'pass';
93
+ }
94
+ else if (pass_rate < 100) {
95
+ results[class_id]['status'] = 'fail';
96
+ }
97
+ }
98
+
99
+ return {
100
+ reflections: reflections,
101
+ results: results
102
+ };
103
+ }
104
+
105
+ </script>
106
+
107
+ <div class="container" x-data="getData()">
108
+
109
+ <div id="header">
110
+ <svg id="logo" enable-background="new 0 0 500 500" viewBox="0 0 500 500" xmlns="http://www.w3.org/2000/svg">
111
+ <path d="m307.5 80.5h-115l-57.5 205h230z" fill="#0047d0"/>
112
+ <path d="m178 76.5-53.1-44-117.9 139 116 112z" fill="#d04800"/>
113
+ <path d="m190.4 467.5h115l57.5-168h-229z" fill="#0047d0" opacity=".7"/>
114
+ <path d="m177 467.5-81-85-92-197 115 113z" fill="#d04800" opacity=".7"/>
115
+ <g fill="#008c33"><path d="m322 76.5 53.1-44 118 139-116 112z"/>
116
+ <path d="m320 467.5 84-85 92-197-117 113z" opacity=".7"/>
117
+ </g>
118
+ </svg>
119
+ </div>
120
+
121
+ <ul class="classes">
122
+ <template x-for="[class_id, klass] in Object.entries(results)" :key="class_id">
123
+
124
+ <li class="class-container">
125
+
126
+ <div class="status-row class" x-bind:class="`${klass.status}`" @click="klass['show'] = !klass['show']" :aria-expanded="klass['show'] ? 'true' : 'false'" :class="{ 'active': klass['show'] }">
127
+ <h2 x-text="`${class_id}()`"></h2>
128
+ <div class="stats">
129
+ <div class="stat" x-text="`${klass.stats.pass_rate.toFixed(2)}%`"></div>
130
+ </div>
131
+ </div>
132
+
133
+ <ul class="methods" x-show="klass['show']">
134
+ <template x-for="[method_id, method] in Object.entries(klass['methods'])" :key="method_id">
135
+ <li class="method-container">
136
+
137
+ <div class="status-row method" x-bind:class="`${method.status}`" @click="method['show'] = !method['show']" :aria-expanded="method['show'] ? 'true' : 'false'" :class="{ 'active': method['show'] }">
138
+ <h3 x-text="`${method_id}()`"></h3>
139
+ <div class="stats">
140
+ <div class="stat" x-text="`${method.stats.pass_rate.toFixed(2)}%`"></div>
141
+ </div>
142
+ </div>
143
+
144
+ <ul class="reflections" x-show="method['show']">
145
+ <template x-for="[reflection_id, reflection] in Object.entries(reflections[class_id][method_id])">
146
+
147
+ <li class="reflection">
148
+
149
+ <div class="time" x-text="`${new Date(reflection.t * 1000).getFullYear()}/${new Date(reflection.t * 1000).getMonth() + 1}/${new Date(reflection.t * 1000).getDate()} ${new Date(reflection.t * 1000).getHours()}:${new Date(reflection.t * 1000).getMinutes()}:${new Date(reflection.t * 1000).getSeconds()}`"></div>
150
+
151
+ <template x-for="[input_id, input] in Object.entries(reflection.i)">
152
+
153
+ <div class="info">
154
+ <h4>Input</h4>
155
+ <div class="info-items">
156
+ <div class="info-item">
157
+ <strong>Type:</strong><div class="input" x-text="input.T"></div>
158
+ </div>
159
+ <template x-if="input.V != undefined">
160
+ <div class="info-item">
161
+ <strong>Value:</strong><pre><div class="output" x-text="input.V"></div></pre>
162
+ </div>
163
+ </template>
164
+ <template x-if="input.C != undefined">
165
+ <div class="info-item">
166
+ <strong>Count:</strong><div class="input" x-text="input.C"></div>
167
+ </div>
168
+ </template>
169
+ </div>
170
+ </div>
171
+
172
+ </template>
173
+
174
+ <div class="info">
175
+ <h4>Output</h4>
176
+ <div class="info-items">
177
+ <div class="info-item">
178
+ <strong>Type:</strong><div class="output" x-text="reflection.o.T"></div>
179
+ </div>
180
+ <template x-if="reflection.o.C != undefined">
181
+ <div class="info-item">
182
+ <strong>Count:</strong><div class="output" x-text="reflection.o.C"></div>
183
+ </div>
184
+ </template>
185
+ <div class="info-item">
186
+ <strong>Value:</strong><pre><div class="output" x-text="reflection.o.V"></div></pre>
187
+ </div>
188
+ </div>
189
+ </div>
190
+ </li>
191
+
192
+ </template>
193
+ </ul>
194
+
195
+ </li>
196
+ </template>
197
+ </ul>
198
+
199
+ </li>
200
+ </template>
201
+
202
+ </ul>
203
+
204
+ </div>
205
+
206
+ <script src="script.js"></script>
207
+
208
+ </body>
209
+
210
+ </html>
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: reflekt
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.7.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Maedi Prichard
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-07-21 00:00:00.000000000 Z
11
+ date: 2020-07-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rowdb
@@ -24,13 +24,16 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
- description: Reflective testing that's completely automated.
27
+ description: Testing that's completely automated.
28
28
  email: maediprichard@gmailcom
29
29
  executables: []
30
30
  extensions: []
31
31
  extra_rdoc_files: []
32
32
  files:
33
33
  - lib/reflekt.rb
34
+ - lib/web/script.js
35
+ - lib/web/style.css
36
+ - lib/web/template.html.erb
34
37
  homepage: https://github.com/maedi/reflekt
35
38
  licenses:
36
39
  - MPL-2.0
@@ -53,5 +56,5 @@ requirements: []
53
56
  rubygems_version: 3.0.2
54
57
  signing_key:
55
58
  specification_version: 4
56
- summary: Reflective testing that's completely automated.
59
+ summary: Reflective testing.
57
60
  test_files: []