Skip to content

Commit

Permalink
Merge branch '__rultor'
Browse files Browse the repository at this point in the history
  • Loading branch information
rultor committed Aug 13, 2020
2 parents 7ede5bc + 3a9bd8e commit 6004964
Show file tree
Hide file tree
Showing 10 changed files with 215 additions and 5 deletions.
6 changes: 2 additions & 4 deletions aibolit/ast_framework/computed_fields_catalog/nodes_filter.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,9 @@ def nodes_filter_factory(

def filter(base_node: ASTNode) -> Iterator[ASTNode]:
base_field = getattr(base_node, base_field_name)
if isinstance(base_field, list) and all(
isinstance(item, ASTNode) for item in base_field
):
if isinstance(base_field, list):
for node in base_field:
if node.node_type in node_types:
if isinstance(node, ASTNode) and node.node_type in node_types:
yield node
else:
raise RuntimeError(
Expand Down
4 changes: 3 additions & 1 deletion aibolit/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from aibolit.metrics.maxDiameter.max_diam_of_tree import MaxDiamOfTree as M6
from aibolit.metrics.ncss.ncss import NCSSMetric as M2
from aibolit.metrics.spaces.SpaceCounter import IndentationCounter as M3
from aibolit.metrics.NumberMethods.NumberMethods import NumberMethods as M8
from aibolit.patterns.array_as_argument.array_as_argument import ArrayAsArgument as P22
from aibolit.patterns.assert_in_code.assert_in_code import AssertInCode as P1
from aibolit.patterns.assign_null_finder.assign_null_finder import NullAssignment as P28
Expand Down Expand Up @@ -165,7 +166,8 @@ def get_patterns_config():
{"name": "Cognitive Complexity", "code": "M4", "make": lambda: M4()},
{"name": "LCOM4", "code": "M5", "make": lambda: M5()},
{"name": "Max diameter of AST", "code": "M6", "make": lambda: M6()},
{"name": "Number of variables", "code": "M7", "make": lambda: M7()}
{"name": "Number of variables", "code": "M7", "make": lambda: M7()},
{"name": "Number of methods", "code": "M8", "make": lambda: M8()}
],
"target": {

Expand Down
34 changes: 34 additions & 0 deletions aibolit/metrics/NumberMethods/NumberMethods.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# The MIT License (MIT)
#
# Copyright (c) 2020 Aibolit
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

from aibolit.ast_framework import AST, ASTNodeType
from aibolit.utils.ast_builder import build_ast


class NumberMethods:
def value(self, filename: str) -> int:
metric = 0
ast = AST.build_from_javalang(build_ast(filename))
for class_node in ast.get_proxy_nodes(ASTNodeType.CLASS_DECLARATION):
for method_node in class_node.methods:
metric += 1
return metric
Empty file.
Empty file.
25 changes: 25 additions & 0 deletions test/metrics/NumberMethods/nested.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// This Java code is taken from a public GitHub repository
// and is used inside Aibolit only for integration testing
// purposes. The code is never compiled or executed.


class LengthStringComparator implements Comparator<String> {
boolean validate() { // +1
return new Object() {
boolean check(Struct struct) {
if (!struct.valid()) return false;
for(Struct child : struct.children()) {
if (!check(child)) return false;
}
return true;
}
}.check(_struct);
}

public static void main(String[] args) // +1
{
int test = 3;
main(test);
}

}
39 changes: 39 additions & 0 deletions test/metrics/NumberMethods/one.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// This Java code is taken from a public GitHub repository
// and is used inside Aibolit only for integration testing
// purposes. The code is never compiled or executed.


import java.util.ArrayList;
import java.util.List;

public class Hospital {

public static List<Instance> readDataGet(String file) throws FileNotFoundException { // +1
List<Instance> dataset = new ArrayList<Instance>();
Scanner scanner = null;
try {
scanner = new Scanner(new File(file));
while(scanner.hasNextLine()) {
String line = scanner.nextLine();
if (line.startsWith("#")) {
continue; // +1
}
String[] columns = line.split("\\s+");

// skip first column and last column is the label
int i = 1;
int[] data = new int[columns.length-2];
for (i=1; i<columns.length-1; i++) {
data[i-1] = Integer.parseInt(columns[i]);
}
int label = Integer.parseInt(columns[i]);
Instance instance = new Instance(label, data);
dataset.add(instance);
}
} finally {
if (scanner != null)
scanner.close();
}
return dataset;
}
}
45 changes: 45 additions & 0 deletions test/metrics/NumberMethods/several.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// This Java code is taken from a public GitHub repository
// and is used inside Aibolit only for integration testing
// purposes. The code is never compiled or executed.


class LengthStringComparator implements Comparator<String> {
public void recursionFucn() { // +1
System.out.println("Miss me?!");
recursionFucn();
}

public int fact(int n) // +1
{
// wrong base case (it may cause
// stack overflow).
if (n == 100)
return 1;

else
return n*fact(n-1);
}

static void printFun(int test) // +1
{
if (test < 1)
return;

else {
System.out.printf("%d ", test);

// Statement 2
printFun(test - 1);

System.out.printf("%d ", test);
return;
}
}

public static void main(String[] args) // +1
{
int test = 3;
printFun(test);
}

}
21 changes: 21 additions & 0 deletions test/metrics/NumberMethods/simple.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// This Java code is taken from a public GitHub repository
// and is used inside Aibolit only for integration testing
// purposes. The code is never compiled or executed.


class Test {
public static void main(String[] arg) { // +1
int a = 1;
if ( a && b && c || d || e && f) {
a = 1;
}
}

public static void main(String[] arg) { // +1
int a = 1;
if ( a && !(b && c)) {
a = 1;
}
}

}
46 changes: 46 additions & 0 deletions test/metrics/NumberMethods/test_number_methods.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# The MIT License (MIT)
#
# Copyright (c) 2020 Aibolit
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

import os
from unittest import TestCase
from aibolit.metrics.NumberMethods.NumberMethods import NumberMethods
from pathlib import Path


class TestCognitive(TestCase):
dir_path = Path(os.path.realpath(__file__)).parent

def test_one(self):
metric = NumberMethods().value(Path(self.dir_path, 'one.java'))
self.assertEqual(metric, 1)

def test_simple(self):
metric = NumberMethods().value(Path(self.dir_path, 'simple.java'))
self.assertEqual(metric, 2)

def test_nested(self):
metric = NumberMethods().value(Path(self.dir_path, 'nested.java'))
self.assertEqual(metric, 2)

def test_several(self):
metric = NumberMethods().value(Path(self.dir_path, 'several.java'))
self.assertEqual(metric, 4)

1 comment on commit 6004964

@0pdd
Copy link
Collaborator

@0pdd 0pdd commented on 6004964 Aug 13, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wasn't able to retrieve PDD puzzles from the code base and submit them to GitHub. If you think that it's a bug on our side, please submit it to yegor256/0pdd:

set -x && set -e && set -o pipefail && cd /tmp/0pdd20200730-13-157q04g/cqfn/aibolit && pdd -v -f /tmp/20200813-25048-vhh1pg [1]: + set -e + set -o pipefail + cd /tmp/0pdd20200730-13-157q04g/cqfn/aibolit + pdd -v -f /tmp/20200813-25048-vhh1pg Found 10 lines in...

Please, copy and paste this stack trace to GitHub:

UserError
set -x && set -e && set -o pipefail && cd /tmp/0pdd20200730-13-157q04g/cqfn/aibolit && pdd -v -f /tmp/20200813-25048-vhh1pg [1]:
+ set -e
+ set -o pipefail
+ cd /tmp/0pdd20200730-13-157q04g/cqfn/aibolit
+ pdd -v -f /tmp/20200813-25048-vhh1pg

Found 10 lines in /tmp/0pdd20200730-13-157q04g/cqfn/aibolit/.pdd
My version is 0.20.5
Ruby version is 2.6.0 at x86_64-linux
Reading .
Excluding test/**/*
Excluding test/**/*
Excluding stubs/**/*
Excluding aibolit/metrics/halsteadvolume/target/**/*
Excluding scripts/target/**/*
230 file(s) found, 8088 excluded
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/binary_files/halstead.jar is a binary file (10595980 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/binary_files/model.pkl is a binary file (16409448 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/binary_files/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/utils/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/ast_framework/computed_fields_catalog/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/patterns/non_final_class/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/patterns/array_as_argument/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/patterns/private_static_method/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/patterns/nested_blocks/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/patterns/supermethod/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/patterns/many_primary_ctors/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/patterns/send_null/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/patterns/method_siblings/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/patterns/er_class/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/patterns/assert_in_code/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/patterns/public_static_method/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/patterns/protected_method/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/patterns/non_final_argument/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/patterns/bidirect_index/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/patterns/mutable_index/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/patterns/classic_setter/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/patterns/non_final_attribute/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/patterns/redundant_catch/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/patterns/string_concat/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/patterns/implements_multi/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/patterns/empty_rethrow/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/patterns/multiple_while/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/patterns/multiple_try/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/patterns/var_siblings/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/patterns/loop_outsider/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/patterns/var_decl_diff/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/patterns/return_null/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/patterns/force_type_casting_finder/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/patterns/var_middle/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/patterns/partially_synchronized_methods/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/patterns/if_return_if_detection/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/patterns/assign_null_finder/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/patterns/instanceof/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/patterns/null_check/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/patterns/hybrid_constructor/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/patterns/method_chaining/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/patterns/joined_validation/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/metrics/local_methods_calls/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/metrics/cognitiveC/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/metrics/number_variables/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/metrics/entropy/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/metrics/maxDiameter/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/metrics/external_methods_called/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/metrics/spaces/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/metrics/lcom4/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/metrics/RFC/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/metrics/loc/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/metrics/fanout/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/metrics/mda/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/metrics/NumberMethods/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/metrics/countLeaves/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/metrics/cc/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/ml_pipeline/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/wp/sections/motivation.tex is a binary file (1 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/wp/sections/.gitkeep is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/wp/how_it_works_diagram_5.jpg is a binary file (71972 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/wp/logo.png is a binary file (208813 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/logo.png is a binary file (208813 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/uml/recommendation_pipeline.png is a binary file (223568 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/uml/train_pipeline.png is a binary file (167130 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/uml/classes_diagram.png is a binary file (190488 bytes)
Reading appveyor.yml...
Reading .gitignore...
Reading README.md...
Reading .gitattributes...
Reading MANIFEST.in...
Reading .rultor.yml...
Reading aibolit/types_decl.py...
Reading aibolit/__main__.py...
Reading aibolit/utils/lines.py...
Reading aibolit/utils/utils.py...
Reading aibolit/utils/ast_builder.py...
Reading aibolit/utils/encoding_detector.py...
Reading aibolit/utils/java_parser.py...
Reading aibolit/utils/scope_status.py...
Reading aibolit/utils/cfg_builder.py...
Reading aibolit/utils/filter.py...
Reading aibolit/utils/cohesiongraph.py...
Reading aibolit/config.py...
Reading aibolit/model/model.py...
Reading aibolit/model/stats.py...
Reading aibolit/ast_framework/ast.py...
Reading aibolit/ast_framework/scope.py...
Reading aibolit/ast_framework/computed_fields_catalog/nodes_filter.py...
Reading aibolit/ast_framework/computed_fields_catalog/standard_fields.py...
Reading aibolit/ast_framework/computed_fields_catalog/chained_fields.py...
Reading aibolit/ast_framework/scope_extractors.py...
ERROR: aibolit/ast_framework/scope_extractors.py; puzzle at line #198; TODO found, but puzzle can't be parsed, most probably because TODO is not followed by a puzzle marker, as this page explains: https://github.com/yegor256/pdd#how-to-format
If you can't understand the cause of this issue or you don't know how to fix it, please submit a GitHub issue, we will try to help you: https://github.com/yegor256/pdd/issues. This tool is still in its beta version and we will appreciate your feedback. Here is where you can find more documentation: https://github.com/yegor256/pdd/blob/master/README.md.
Exit code is 1

/app/objects/git_repo.rb:66:in `rescue in block in xml'
/app/objects/git_repo.rb:63:in `block in xml'
/app/vendor/ruby-2.6.0/lib/ruby/2.6.0/tempfile.rb:295:in `open'
/app/objects/git_repo.rb:62:in `xml'
/app/objects/puzzles.rb:36:in `deploy'
/app/objects/job.rb:38:in `proceed'
/app/objects/job_starred.rb:33:in `proceed'
/app/objects/job_recorded.rb:32:in `proceed'
/app/objects/job_emailed.rb:35:in `proceed'
/app/objects/job_commiterrors.rb:36:in `proceed'
/app/objects/job_detached.rb:48:in `exclusive'
/app/objects/job_detached.rb:36:in `block in proceed'
/app/objects/job_detached.rb:36:in `fork'
/app/objects/job_detached.rb:36:in `proceed'
/app/0pdd.rb:358:in `block in <top (required)>'
/app/vendor/bundle/ruby/2.6.0/gems/sinatra-2.0.4/lib/sinatra/base.rb:1635:in `call'
/app/vendor/bundle/ruby/2.6.0/gems/sinatra-2.0.4/lib/sinatra/base.rb:1635:in `block in compile!'
/app/vendor/bundle/ruby/2.6.0/gems/sinatra-2.0.4/lib/sinatra/base.rb:992:in `block (3 levels) in route!'
/app/vendor/bundle/ruby/2.6.0/gems/sinatra-2.0.4/lib/sinatra/base.rb:1011:in `route_eval'
/app/vendor/bundle/ruby/2.6.0/gems/sinatra-2.0.4/lib/sinatra/base.rb:992:in `block (2 levels) in route!'
/app/vendor/bundle/ruby/2.6.0/gems/sinatra-2.0.4/lib/sinatra/base.rb:1040:in `block in process_route'
/app/vendor/bundle/ruby/2.6.0/gems/sinatra-2.0.4/lib/sinatra/base.rb:1038:in `catch'
/app/vendor/bundle/ruby/2.6.0/gems/sinatra-2.0.4/lib/sinatra/base.rb:1038:in `process_route'
/app/vendor/bundle/ruby/2.6.0/gems/sinatra-2.0.4/lib/sinatra/base.rb:990:in `block in route!'
/app/vendor/bundle/ruby/2.6.0/gems/sinatra-2.0.4/lib/sinatra/base.rb:989:in `each'
/app/vendor/bundle/ruby/2.6.0/gems/sinatra-2.0.4/lib/sinatra/base.rb:989:in `route!'
/app/vendor/bundle/ruby/2.6.0/gems/sinatra-2.0.4/lib/sinatra/base.rb:1097:in `block in dispatch!'
/app/vendor/bundle/ruby/2.6.0/gems/sinatra-2.0.4/lib/sinatra/base.rb:1076:in `block in invoke'
/app/vendor/bundle/ruby/2.6.0/gems/sinatra-2.0.4/lib/sinatra/base.rb:1076:in `catch'
/app/vendor/bundle/ruby/2.6.0/gems/sinatra-2.0.4/lib/sinatra/base.rb:1076:in `invoke'
/app/vendor/bundle/ruby/2.6.0/gems/sinatra-2.0.4/lib/sinatra/base.rb:1094:in `dispatch!'
/app/vendor/bundle/ruby/2.6.0/gems/sinatra-2.0.4/lib/sinatra/base.rb:924:in `block in call!'
/app/vendor/bundle/ruby/2.6.0/gems/sinatra-2.0.4/lib/sinatra/base.rb:1076:in `block in invoke'
/app/vendor/bundle/ruby/2.6.0/gems/sinatra-2.0.4/lib/sinatra/base.rb:1076:in `catch'
/app/vendor/bundle/ruby/2.6.0/gems/sinatra-2.0.4/lib/sinatra/base.rb:1076:in `invoke'
/app/vendor/bundle/ruby/2.6.0/gems/sinatra-2.0.4/lib/sinatra/base.rb:924:in `call!'
/app/vendor/bundle/ruby/2.6.0/gems/sinatra-2.0.4/lib/sinatra/base.rb:913:in `call'
/app/vendor/bundle/ruby/2.6.0/gems/rack-protection-2.0.4/lib/rack/protection/xss_header.rb:18:in `call'
/app/vendor/bundle/ruby/2.6.0/gems/rack-protection-2.0.4/lib/rack/protection/path_traversal.rb:16:in `call'
/app/vendor/bundle/ruby/2.6.0/gems/rack-protection-2.0.4/lib/rack/protection/json_csrf.rb:26:in `call'
/app/vendor/bundle/ruby/2.6.0/gems/rack-protection-2.0.4/lib/rack/protection/base.rb:50:in `call'
/app/vendor/bundle/ruby/2.6.0/gems/rack-protection-2.0.4/lib/rack/protection/base.rb:50:in `call'
/app/vendor/bundle/ruby/2.6.0/gems/rack-protection-2.0.4/lib/rack/protection/frame_options.rb:31:in `call'
/app/vendor/bundle/ruby/2.6.0/gems/rack-2.0.6/lib/rack/logger.rb:15:in `call'
/app/vendor/bundle/ruby/2.6.0/gems/rack-2.0.6/lib/rack/common_logger.rb:33:in `call'
/app/vendor/bundle/ruby/2.6.0/gems/sinatra-2.0.4/lib/sinatra/base.rb:231:in `call'
/app/vendor/bundle/ruby/2.6.0/gems/sinatra-2.0.4/lib/sinatra/base.rb:224:in `call'
/app/vendor/bundle/ruby/2.6.0/gems/rack-2.0.6/lib/rack/head.rb:12:in `call'
/app/vendor/bundle/ruby/2.6.0/gems/rack-2.0.6/lib/rack/method_override.rb:22:in `call'
/app/vendor/bundle/ruby/2.6.0/gems/sinatra-2.0.4/lib/sinatra/base.rb:194:in `call'
/app/vendor/bundle/ruby/2.6.0/gems/sinatra-2.0.4/lib/sinatra/base.rb:1957:in `call'
/app/vendor/bundle/ruby/2.6.0/gems/sinatra-2.0.4/lib/sinatra/base.rb:1502:in `block in call'
/app/vendor/bundle/ruby/2.6.0/gems/sinatra-2.0.4/lib/sinatra/base.rb:1729:in `synchronize'
/app/vendor/bundle/ruby/2.6.0/gems/sinatra-2.0.4/lib/sinatra/base.rb:1502:in `call'
/app/vendor/bundle/ruby/2.6.0/gems/rack-2.0.6/lib/rack/handler/webrick.rb:86:in `service'
/app/vendor/ruby-2.6.0/lib/ruby/2.6.0/webrick/httpserver.rb:140:in `service'
/app/vendor/ruby-2.6.0/lib/ruby/2.6.0/webrick/httpserver.rb:96:in `run'
/app/vendor/ruby-2.6.0/lib/ruby/2.6.0/webrick/server.rb:307:in `block in start_thread'

Please sign in to comment.