Files
old-gem/coverage/index.html
2020-02-05 13:40:37 +01:00

1768 lines
49 KiB
HTML

<!DOCTYPE html>
<html xmlns='http://www.w3.org/1999/xhtml'>
<head>
<title>Code coverage for Pg searchable</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<script src='./assets/0.10.2/application.js' type='text/javascript'></script>
<link href='./assets/0.10.2/application.css' media='screen, projection, print' rel='stylesheet' type='text/css'>
<link rel="shortcut icon" type="image/png" href="./assets/0.10.2/favicon_red.png" />
<link rel="icon" type="image/png" href="./assets/0.10.2/favicon.png" />
</head>
<body>
<div id="loading">
<img src="./assets/0.10.2/loading.gif" alt="loading"/>
</div>
<div id="wrapper" style="display:none;">
<div class="timestamp">Generated <abbr class="timeago" title="2020-02-04T15:37:05+01:00">2020-02-04T15:37:05+01:00</abbr></div>
<ul class="group_tabs"></ul>
<div id="content">
<div class="file_list_container" id="AllFiles">
<h2>
<span class="group_name">All Files</span>
(<span class="covered_percent"><span class="red">24.18%</span></span>
covered at
<span class="covered_strength">
<span class="red">
0.22
</span>
</span> hits/line)
</h2>
<a name="AllFiles"></a>
<div>
<b>3</b> files in total.
<b>91</b> relevant lines.
<span class="green"><b>22</b> lines covered</span> and
<span class="red"><b>69</b> lines missed </span>
</div>
<table class="file_list">
<thead>
<tr>
<th>File</th>
<th>% covered</th>
<th>Lines</th>
<th>Relevant Lines</th>
<th>Lines covered</th>
<th>Lines missed</th>
<th>Avg. Hits / Line</th>
</tr>
</thead>
<tbody>
<tr>
<td class="strong"><a href="#753228502df7d7eba3c0631f5c2586671ab90064" class="src_link" title="lib/pg_searchable_regex.rb">lib/pg_searchable_regex.rb</a></td>
<td class="red strong">10.53 %</td>
<td>76</td>
<td>38</td>
<td>4</td>
<td>34</td>
<td>0.1</td>
</tr>
<tr>
<td class="strong"><a href="#ce19b53ff8fa35fd6a57aa6b7ede25d3648dd01c" class="src_link" title="lib/text_to_sql_query.rb">lib/text_to_sql_query.rb</a></td>
<td class="green strong">100.0 %</td>
<td>93</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>0.0</td>
</tr>
<tr>
<td class="strong"><a href="#1f620dc5aa56fc59374eab391bb6c70e9b12c49b" class="src_link" title="lib/text_to_tsquery.rb">lib/text_to_tsquery.rb</a></td>
<td class="red strong">33.96 %</td>
<td>99</td>
<td>53</td>
<td>18</td>
<td>35</td>
<td>0.3</td>
</tr>
</tbody>
</table>
</div>
</div>
<div id="footer">
Generated by <a href="http://github.com/colszowka/simplecov">simplecov</a> v0.16.1
and simplecov-html v0.10.2<br/>
using RSpec
</div>
<div class="source_files">
<div class="source_table" id="753228502df7d7eba3c0631f5c2586671ab90064">
<div class="header">
<h3>lib/pg_searchable_regex.rb</h3>
<h4><span class="red">10.53 %</span> covered</h4>
<div>
<b>38</b> relevant lines.
<span class="green"><b>4</b> lines covered</span> and
<span class="red"><b>34</b> lines missed.</span>
</div>
</div>
<pre>
<ol>
<li class="never" data-hits="" data-linenumber="1">
<code class="ruby"># frozen_string_literal: true</code>
</li>
<li class="never" data-hits="" data-linenumber="2">
<code class="ruby"></code>
</li>
<li class="covered" data-hits="1" data-linenumber="3">
<span class="hits">1</span>
<code class="ruby">require &#39;active_support&#39;</code>
</li>
<li class="covered" data-hits="1" data-linenumber="4">
<span class="hits">1</span>
<code class="ruby">require &#39;squeel&#39;</code>
</li>
<li class="covered" data-hits="1" data-linenumber="5">
<span class="hits">1</span>
<code class="ruby">require_relative &#39;./text_to_tsquery&#39;</code>
</li>
<li class="covered" data-hits="1" data-linenumber="6">
<span class="hits">1</span>
<code class="ruby">require_relative &#39;./text_to_sql_query&#39;</code>
</li>
<li class="never" data-hits="" data-linenumber="7">
<code class="ruby"></code>
</li>
<li class="missed" data-hits="0" data-linenumber="8">
<code class="ruby">module PgSearchable</code>
</li>
<li class="missed" data-hits="0" data-linenumber="9">
<code class="ruby"> extend ActiveSupport::Concern</code>
</li>
<li class="never" data-hits="" data-linenumber="10">
<code class="ruby"></code>
</li>
<li class="missed" data-hits="0" data-linenumber="11">
<code class="ruby"> included do</code>
</li>
<li class="missed" data-hits="0" data-linenumber="12">
<code class="ruby"> def update_pg_search_cache</code>
</li>
<li class="never" data-hits="" data-linenumber="13">
<code class="ruby"> # kept just for compatibility with pg_searchable </code>
</li>
<li class="never" data-hits="" data-linenumber="14">
<code class="ruby"> # noop in this implementation</code>
</li>
<li class="never" data-hits="" data-linenumber="15">
<code class="ruby"> end</code>
</li>
<li class="never" data-hits="" data-linenumber="16">
<code class="ruby"> end</code>
</li>
<li class="never" data-hits="" data-linenumber="17">
<code class="ruby"></code>
</li>
<li class="missed" data-hits="0" data-linenumber="18">
<code class="ruby"> class_methods do</code>
</li>
<li class="missed" data-hits="0" data-linenumber="19">
<code class="ruby"> def pg_search(</code>
</li>
<li class="never" data-hits="" data-linenumber="20">
<code class="ruby"> fields: [],</code>
</li>
<li class="never" data-hits="" data-linenumber="21">
<code class="ruby"> fields_mappings: {}, </code>
</li>
<li class="never" data-hits="" data-linenumber="22">
<code class="ruby"> cache: nil,</code>
</li>
<li class="never" data-hits="" data-linenumber="23">
<code class="ruby"> language: &#39;english&#39;,</code>
</li>
<li class="never" data-hits="" data-linenumber="24">
<code class="ruby"> scope: &#39;scope_search&#39;,</code>
</li>
<li class="never" data-hits="" data-linenumber="25">
<code class="ruby"> skip_callback: false,</code>
</li>
<li class="never" data-hits="" data-linenumber="26">
<code class="ruby"> wildcard: true,</code>
</li>
<li class="never" data-hits="" data-linenumber="27">
<code class="ruby"> external_cache_data: nil,</code>
</li>
<li class="never" data-hits="" data-linenumber="28">
<code class="ruby"> joins: [],</code>
</li>
<li class="never" data-hits="" data-linenumber="29">
<code class="ruby"> default_field: &quot;&quot;</code>
</li>
<li class="never" data-hits="" data-linenumber="30">
<code class="ruby"> )</code>
</li>
<li class="missed" data-hits="0" data-linenumber="31">
<code class="ruby"> @ts_search_fields = fields</code>
</li>
<li class="missed" data-hits="0" data-linenumber="32">
<code class="ruby"> @ts_search_fields_mappings = fields_mappings</code>
</li>
<li class="missed" data-hits="0" data-linenumber="33">
<code class="ruby"> @ts_cache_field = cache</code>
</li>
<li class="missed" data-hits="0" data-linenumber="34">
<code class="ruby"> @ts_language = language</code>
</li>
<li class="missed" data-hits="0" data-linenumber="35">
<code class="ruby"> @ts_scope_method = scope</code>
</li>
<li class="missed" data-hits="0" data-linenumber="36">
<code class="ruby"> @ts_skip_cache_update = skip_callback</code>
</li>
<li class="missed" data-hits="0" data-linenumber="37">
<code class="ruby"> @ts_wildcard = wildcard</code>
</li>
<li class="missed" data-hits="0" data-linenumber="38">
<code class="ruby"> @ts_joins = joins</code>
</li>
<li class="missed" data-hits="0" data-linenumber="39">
<code class="ruby"> @default_field = (default_field.to_sym || fields.first)</code>
</li>
<li class="missed" data-hits="0" data-linenumber="40">
<code class="ruby"> ts_add_scope</code>
</li>
<li class="never" data-hits="" data-linenumber="41">
<code class="ruby"> end</code>
</li>
<li class="never" data-hits="" data-linenumber="42">
<code class="ruby"></code>
</li>
<li class="missed" data-hits="0" data-linenumber="43">
<code class="ruby"> def ts_add_scope</code>
</li>
<li class="missed" data-hits="0" data-linenumber="44">
<code class="ruby"> class_eval do</code>
</li>
<li class="missed" data-hits="0" data-linenumber="45">
<code class="ruby"> scope ts_scope_method, -&gt;(value) { ts_search(value) }</code>
</li>
<li class="never" data-hits="" data-linenumber="46">
<code class="ruby"> end</code>
</li>
<li class="never" data-hits="" data-linenumber="47">
<code class="ruby"> end</code>
</li>
<li class="never" data-hits="" data-linenumber="48">
<code class="ruby"></code>
</li>
<li class="missed" data-hits="0" data-linenumber="49">
<code class="ruby"> def ts_search(value)</code>
</li>
<li class="missed" data-hits="0" data-linenumber="50">
<code class="ruby"> return if @ts_search_fields.blank? || value.blank?</code>
</li>
<li class="missed" data-hits="0" data-linenumber="51">
<code class="ruby"> TextToSqlQuery.new(value, @ts_search_fields, @default_field, @ts_search_fields_mappings).where_clause( includes(@ts_joins).references(:all))</code>
</li>
<li class="never" data-hits="" data-linenumber="52">
<code class="ruby"> end</code>
</li>
<li class="never" data-hits="" data-linenumber="53">
<code class="ruby"></code>
</li>
<li class="missed" data-hits="0" data-linenumber="54">
<code class="ruby"> def should_update_cache_field?</code>
</li>
<li class="missed" data-hits="0" data-linenumber="55">
<code class="ruby"> !@ts_skip_cache_update &amp;&amp; @ts_cache_field.present?</code>
</li>
<li class="never" data-hits="" data-linenumber="56">
<code class="ruby"> end</code>
</li>
<li class="never" data-hits="" data-linenumber="57">
<code class="ruby"></code>
</li>
<li class="missed" data-hits="0" data-linenumber="58">
<code class="ruby"> def ts_cache_field</code>
</li>
<li class="missed" data-hits="0" data-linenumber="59">
<code class="ruby"> @ts_cache_field</code>
</li>
<li class="never" data-hits="" data-linenumber="60">
<code class="ruby"> end</code>
</li>
<li class="never" data-hits="" data-linenumber="61">
<code class="ruby"></code>
</li>
<li class="missed" data-hits="0" data-linenumber="62">
<code class="ruby"> def ts_scope_method</code>
</li>
<li class="missed" data-hits="0" data-linenumber="63">
<code class="ruby"> @ts_scope_method</code>
</li>
<li class="never" data-hits="" data-linenumber="64">
<code class="ruby"> end</code>
</li>
<li class="never" data-hits="" data-linenumber="65">
<code class="ruby"></code>
</li>
<li class="missed" data-hits="0" data-linenumber="66">
<code class="ruby"> def ts_cache_method</code>
</li>
<li class="missed" data-hits="0" data-linenumber="67">
<code class="ruby"> @ts_cache_method</code>
</li>
<li class="never" data-hits="" data-linenumber="68">
<code class="ruby"> end</code>
</li>
<li class="never" data-hits="" data-linenumber="69">
<code class="ruby"></code>
</li>
<li class="missed" data-hits="0" data-linenumber="70">
<code class="ruby"> def ts_fields_to_vector(extra_data = [])</code>
</li>
<li class="missed" data-hits="0" data-linenumber="71">
<code class="ruby"> field_to_vector = -&gt;(field) { &quot;to_tsvector(&#39;#{@ts_language}&#39;, coalesce(#{field}::text, &#39;&#39;))&quot; }</code>
</li>
<li class="missed" data-hits="0" data-linenumber="72">
<code class="ruby"> data_to_vector = -&gt;(data) { &quot;to_tsvector(&#39;#{@ts_language}&#39;, &#39;#{data}&#39;)&quot; }</code>
</li>
<li class="missed" data-hits="0" data-linenumber="73">
<code class="ruby"> (@ts_search_fields.map(&amp;field_to_vector) + extra_data.map(&amp;data_to_vector)).join(&#39; || &#39;)</code>
</li>
<li class="never" data-hits="" data-linenumber="74">
<code class="ruby"> end</code>
</li>
<li class="never" data-hits="" data-linenumber="75">
<code class="ruby"> end</code>
</li>
<li class="never" data-hits="" data-linenumber="76">
<code class="ruby">end</code>
</li>
</ol>
</pre>
</div>
<div class="source_table" id="ce19b53ff8fa35fd6a57aa6b7ede25d3648dd01c">
<div class="header">
<h3>lib/text_to_sql_query.rb</h3>
<h4><span class="green">100.0 %</span> covered</h4>
<div>
<b>0</b> relevant lines.
<span class="green"><b>0</b> lines covered</span> and
<span class="red"><b>0</b> lines missed.</span>
</div>
</div>
<pre>
<ol>
<li class="never" data-hits="" data-linenumber="1">
<code class="ruby">require &#39;./parser&#39;</code>
</li>
<li class="never" data-hits="" data-linenumber="2">
<code class="ruby"></code>
</li>
<li class="never" data-hits="" data-linenumber="3">
<code class="ruby">class TextToSqlQuery</code>
</li>
<li class="never" data-hits="" data-linenumber="4">
<code class="ruby"> def initialize(text, fields, default_field, fields_mappings = {})</code>
</li>
<li class="never" data-hits="" data-linenumber="5">
<code class="ruby"> @text = text.to_s.strip</code>
</li>
<li class="never" data-hits="" data-linenumber="6">
<code class="ruby"> @fields = fields.map(&amp;:to_sym)</code>
</li>
<li class="never" data-hits="" data-linenumber="7">
<code class="ruby"> @default_field = default_field.to_sym</code>
</li>
<li class="never" data-hits="" data-linenumber="8">
<code class="ruby"> @fields_mappings = fields_mappings.merge(@fields.reduce({}) do |mappings, field|</code>
</li>
<li class="never" data-hits="" data-linenumber="9">
<code class="ruby"> _table_name, field_name = field.to_s.split(&#39;.&#39;)</code>
</li>
<li class="never" data-hits="" data-linenumber="10">
<code class="ruby"> mappings[field_name.to_sym] = field</code>
</li>
<li class="never" data-hits="" data-linenumber="11">
<code class="ruby"> mappings</code>
</li>
<li class="never" data-hits="" data-linenumber="12">
<code class="ruby"> end)</code>
</li>
<li class="never" data-hits="" data-linenumber="13">
<code class="ruby"> fields_mappings.each do |field, value|</code>
</li>
<li class="never" data-hits="" data-linenumber="14">
<code class="ruby"> @fields_mappings[field] = value if @fields_mappings[field]</code>
</li>
<li class="never" data-hits="" data-linenumber="15">
<code class="ruby"> end</code>
</li>
<li class="never" data-hits="" data-linenumber="16">
<code class="ruby"> end</code>
</li>
<li class="never" data-hits="" data-linenumber="17">
<code class="ruby"></code>
</li>
<li class="never" data-hits="" data-linenumber="18">
<code class="ruby"> def where_clause</code>
</li>
<li class="never" data-hits="" data-linenumber="19">
<code class="ruby"> @parser = Query.new</code>
</li>
<li class="never" data-hits="" data-linenumber="20">
<code class="ruby"> @parsed_tree = @parser.parse(@text)</code>
</li>
<li class="never" data-hits="" data-linenumber="21">
<code class="ruby"> generate_sql @parsed_tree</code>
</li>
<li class="never" data-hits="" data-linenumber="22">
<code class="ruby"> end</code>
</li>
<li class="never" data-hits="" data-linenumber="23">
<code class="ruby"></code>
</li>
<li class="never" data-hits="" data-linenumber="24">
<code class="ruby"> private</code>
</li>
<li class="never" data-hits="" data-linenumber="25">
<code class="ruby"></code>
</li>
<li class="never" data-hits="" data-linenumber="26">
<code class="ruby"> def generate_sql(tree)</code>
</li>
<li class="never" data-hits="" data-linenumber="27">
<code class="ruby"> first_key = tree.keys.first</code>
</li>
<li class="never" data-hits="" data-linenumber="28">
<code class="ruby"> node_value = tree[first_key]</code>
</li>
<li class="never" data-hits="" data-linenumber="29">
<code class="ruby"> case first_key</code>
</li>
<li class="never" data-hits="" data-linenumber="30">
<code class="ruby"> when :DEFAULT_COLUMN</code>
</li>
<li class="never" data-hits="" data-linenumber="31">
<code class="ruby"> escaped_node_value = handle_special_chars node_value</code>
</li>
<li class="never" data-hits="" data-linenumber="32">
<code class="ruby"> [&quot;#{@default_field.to_s} ILIKE ?&quot;, &quot;%#{escaped_node_value}%&quot;]</code>
</li>
<li class="never" data-hits="" data-linenumber="33">
<code class="ruby"> when :OPERATOR_OR</code>
</li>
<li class="never" data-hits="" data-linenumber="34">
<code class="ruby"> generate_expression_for_logical_operator(:OR, node_value)</code>
</li>
<li class="never" data-hits="" data-linenumber="35">
<code class="ruby"> when :OPERATOR_AND</code>
</li>
<li class="never" data-hits="" data-linenumber="36">
<code class="ruby"> generate_expression_for_logical_operator(:AND, node_value)</code>
</li>
<li class="never" data-hits="" data-linenumber="37">
<code class="ruby"> when :OPERATOR_NOT</code>
</li>
<li class="never" data-hits="" data-linenumber="38">
<code class="ruby"> not_array = generate_sql node_value</code>
</li>
<li class="never" data-hits="" data-linenumber="39">
<code class="ruby"></code>
</li>
<li class="never" data-hits="" data-linenumber="40">
<code class="ruby"> if not_array.length &lt; 2</code>
</li>
<li class="never" data-hits="" data-linenumber="41">
<code class="ruby"> raise &quot;There should be more than 1 element for expression following NOT operator&quot;</code>
</li>
<li class="never" data-hits="" data-linenumber="42">
<code class="ruby"> end</code>
</li>
<li class="never" data-hits="" data-linenumber="43">
<code class="ruby"></code>
</li>
<li class="never" data-hits="" data-linenumber="44">
<code class="ruby"> not_expression = not_array.first</code>
</li>
<li class="never" data-hits="" data-linenumber="45">
<code class="ruby"> not_params = not_array[1..]</code>
</li>
<li class="never" data-hits="" data-linenumber="46">
<code class="ruby"></code>
</li>
<li class="never" data-hits="" data-linenumber="47">
<code class="ruby"> [&quot;NOT #{not_expression}&quot;] + not_params</code>
</li>
<li class="never" data-hits="" data-linenumber="48">
<code class="ruby"></code>
</li>
<li class="never" data-hits="" data-linenumber="49">
<code class="ruby"> else</code>
</li>
<li class="never" data-hits="" data-linenumber="50">
<code class="ruby"> # key is column name</code>
</li>
<li class="never" data-hits="" data-linenumber="51">
<code class="ruby"> escaped_node_value = handle_special_chars node_value</code>
</li>
<li class="never" data-hits="" data-linenumber="52">
<code class="ruby"> mapping = @fields_mappings[first_key.to_sym]</code>
</li>
<li class="never" data-hits="" data-linenumber="53">
<code class="ruby"> if mapping.nil?</code>
</li>
<li class="never" data-hits="" data-linenumber="54">
<code class="ruby"> raise &quot;Unknown field &#39;#{first_key.to_s}&#39;&quot;</code>
</li>
<li class="never" data-hits="" data-linenumber="55">
<code class="ruby"> else</code>
</li>
<li class="never" data-hits="" data-linenumber="56">
<code class="ruby"> [&quot;#{mapping.to_s} ILIKE ?&quot;, &quot;%#{escaped_node_value}%&quot;]</code>
</li>
<li class="never" data-hits="" data-linenumber="57">
<code class="ruby"> end</code>
</li>
<li class="never" data-hits="" data-linenumber="58">
<code class="ruby"> end</code>
</li>
<li class="never" data-hits="" data-linenumber="59">
<code class="ruby"> end</code>
</li>
<li class="never" data-hits="" data-linenumber="60">
<code class="ruby"></code>
</li>
<li class="never" data-hits="" data-linenumber="61">
<code class="ruby"> def generate_expression_for_logical_operator(operator, operator_array)</code>
</li>
<li class="never" data-hits="" data-linenumber="62">
<code class="ruby"> if operator_array.length != 2</code>
</li>
<li class="never" data-hits="" data-linenumber="63">
<code class="ruby"> raise &quot;There should be two array elements for #{operator.to_s} operator&quot;</code>
</li>
<li class="never" data-hits="" data-linenumber="64">
<code class="ruby"> end</code>
</li>
<li class="never" data-hits="" data-linenumber="65">
<code class="ruby"></code>
</li>
<li class="never" data-hits="" data-linenumber="66">
<code class="ruby"> first_operand = generate_sql operator_array.first</code>
</li>
<li class="never" data-hits="" data-linenumber="67">
<code class="ruby"> second_operand = generate_sql operator_array.last</code>
</li>
<li class="never" data-hits="" data-linenumber="68">
<code class="ruby"></code>
</li>
<li class="never" data-hits="" data-linenumber="69">
<code class="ruby"> if first_operand.length &lt; 2</code>
</li>
<li class="never" data-hits="" data-linenumber="70">
<code class="ruby"> raise &#39;There should be more than 1 element in first operand array&#39;</code>
</li>
<li class="never" data-hits="" data-linenumber="71">
<code class="ruby"> end</code>
</li>
<li class="never" data-hits="" data-linenumber="72">
<code class="ruby"></code>
</li>
<li class="never" data-hits="" data-linenumber="73">
<code class="ruby"> if second_operand.length &lt; 2</code>
</li>
<li class="never" data-hits="" data-linenumber="74">
<code class="ruby"> raise &#39;There should be more than 1 element in second operand array&#39;</code>
</li>
<li class="never" data-hits="" data-linenumber="75">
<code class="ruby"> end</code>
</li>
<li class="never" data-hits="" data-linenumber="76">
<code class="ruby"></code>
</li>
<li class="never" data-hits="" data-linenumber="77">
<code class="ruby"> first_operand_expression = first_operand.first</code>
</li>
<li class="never" data-hits="" data-linenumber="78">
<code class="ruby"> first_operand_params = first_operand[1..]</code>
</li>
<li class="never" data-hits="" data-linenumber="79">
<code class="ruby"></code>
</li>
<li class="never" data-hits="" data-linenumber="80">
<code class="ruby"> second_operand_expression = second_operand.first</code>
</li>
<li class="never" data-hits="" data-linenumber="81">
<code class="ruby"> second_operand_params = second_operand[1..]</code>
</li>
<li class="never" data-hits="" data-linenumber="82">
<code class="ruby"></code>
</li>
<li class="never" data-hits="" data-linenumber="83">
<code class="ruby"> [&quot;(#{first_operand_expression} #{operator.to_s} #{second_operand_expression})&quot;] + first_operand_params + second_operand_params</code>
</li>
<li class="never" data-hits="" data-linenumber="84">
<code class="ruby"> end</code>
</li>
<li class="never" data-hits="" data-linenumber="85">
<code class="ruby"></code>
</li>
<li class="never" data-hits="" data-linenumber="86">
<code class="ruby"> def handle_special_chars(text)</code>
</li>
<li class="never" data-hits="" data-linenumber="87">
<code class="ruby"> result = text.gsub(/\&quot;/, &#39;&#39;)</code>
</li>
<li class="never" data-hits="" data-linenumber="88">
<code class="ruby"> result.gsub!(/\_/, &#39;\_&#39;)</code>
</li>
<li class="never" data-hits="" data-linenumber="89">
<code class="ruby"> result.tr!(&#39;\\&#39;, &#39;\\&#39;)</code>
</li>
<li class="never" data-hits="" data-linenumber="90">
<code class="ruby"> result.gsub!(/%/, &#39;\%&#39;)</code>
</li>
<li class="never" data-hits="" data-linenumber="91">
<code class="ruby"> result</code>
</li>
<li class="never" data-hits="" data-linenumber="92">
<code class="ruby"> end</code>
</li>
<li class="never" data-hits="" data-linenumber="93">
<code class="ruby">end</code>
</li>
</ol>
</pre>
</div>
<div class="source_table" id="1f620dc5aa56fc59374eab391bb6c70e9b12c49b">
<div class="header">
<h3>lib/text_to_tsquery.rb</h3>
<h4><span class="red">33.96 %</span> covered</h4>
<div>
<b>53</b> relevant lines.
<span class="green"><b>18</b> lines covered</span> and
<span class="red"><b>35</b> lines missed.</span>
</div>
</div>
<pre>
<ol>
<li class="never" data-hits="" data-linenumber="1">
<code class="ruby"># frozen_string_literal: true</code>
</li>
<li class="never" data-hits="" data-linenumber="2">
<code class="ruby"></code>
</li>
<li class="never" data-hits="" data-linenumber="3">
<code class="ruby"># transforms &quot;english like&quot; text queries into a tsquery operation</code>
</li>
<li class="never" data-hits="" data-linenumber="4">
<code class="ruby"># https://www.postgresql.org/docs/9.5/textsearch-controls.html#TEXTSEARCH-PARSING-QUERIES</code>
</li>
<li class="covered" data-hits="1" data-linenumber="5">
<span class="hits">1</span>
<code class="ruby">class TextToTsquery</code>
</li>
<li class="covered" data-hits="1" data-linenumber="6">
<span class="hits">1</span>
<code class="ruby"> attr_reader :text</code>
</li>
<li class="never" data-hits="" data-linenumber="7">
<code class="ruby"></code>
</li>
<li class="covered" data-hits="1" data-linenumber="8">
<span class="hits">1</span>
<code class="ruby"> def initialize(text, wildcard: true)</code>
</li>
<li class="missed" data-hits="0" data-linenumber="9">
<code class="ruby"> @text = text.to_s.strip</code>
</li>
<li class="missed" data-hits="0" data-linenumber="10">
<code class="ruby"> @wildcard = wildcard</code>
</li>
<li class="missed" data-hits="0" data-linenumber="11">
<code class="ruby"> @exact_matches = []</code>
</li>
<li class="missed" data-hits="0" data-linenumber="12">
<code class="ruby"> validate!</code>
</li>
<li class="never" data-hits="" data-linenumber="13">
<code class="ruby"> end</code>
</li>
<li class="never" data-hits="" data-linenumber="14">
<code class="ruby"></code>
</li>
<li class="covered" data-hits="1" data-linenumber="15">
<span class="hits">1</span>
<code class="ruby"> EXACT_WORD_CHAR = &#39;§&#39;.freeze</code>
</li>
<li class="never" data-hits="" data-linenumber="16">
<code class="ruby"></code>
</li>
<li class="covered" data-hits="1" data-linenumber="17">
<span class="hits">1</span>
<code class="ruby"> def tsquery</code>
</li>
<li class="missed" data-hits="0" data-linenumber="18">
<code class="ruby"> @tsquery = @text</code>
</li>
<li class="missed" data-hits="0" data-linenumber="19">
<code class="ruby"> strip_exact_words</code>
</li>
<li class="missed" data-hits="0" data-linenumber="20">
<code class="ruby"> remove_duplicated_spaces</code>
</li>
<li class="missed" data-hits="0" data-linenumber="21">
<code class="ruby"> transform_or_into_operator</code>
</li>
<li class="missed" data-hits="0" data-linenumber="22">
<code class="ruby"> transform_and_into_operator</code>
</li>
<li class="missed" data-hits="0" data-linenumber="23">
<code class="ruby"> strip_spaces_from_parenthesis</code>
</li>
<li class="missed" data-hits="0" data-linenumber="24">
<code class="ruby"> transform_remaining_spaces_into_and_operator</code>
</li>
<li class="missed" data-hits="0" data-linenumber="25">
<code class="ruby"> transform_keywords</code>
</li>
<li class="missed" data-hits="0" data-linenumber="26">
<code class="ruby"> join_operators_with_and</code>
</li>
<li class="missed" data-hits="0" data-linenumber="27">
<code class="ruby"> remove_partial_match_from_not_keywords</code>
</li>
<li class="missed" data-hits="0" data-linenumber="28">
<code class="ruby"> add_exact_words</code>
</li>
<li class="missed" data-hits="0" data-linenumber="29">
<code class="ruby"> @tsquery</code>
</li>
<li class="never" data-hits="" data-linenumber="30">
<code class="ruby"> end</code>
</li>
<li class="never" data-hits="" data-linenumber="31">
<code class="ruby"></code>
</li>
<li class="covered" data-hits="1" data-linenumber="32">
<span class="hits">1</span>
<code class="ruby"> def validate!</code>
</li>
<li class="missed" data-hits="0" data-linenumber="33">
<code class="ruby"> parenthesis_error unless self.class.valid_search_parenthesis?(@text)</code>
</li>
<li class="never" data-hits="" data-linenumber="34">
<code class="ruby"> end</code>
</li>
<li class="never" data-hits="" data-linenumber="35">
<code class="ruby"></code>
</li>
<li class="covered" data-hits="1" data-linenumber="36">
<span class="hits">1</span>
<code class="ruby"> def self.valid_search_parenthesis?(text)</code>
</li>
<li class="never" data-hits="" data-linenumber="37">
<code class="ruby"> text.split(&#39;&#39;).reduce(0) do |acc, char|</code>
</li>
<li class="missed" data-hits="0" data-linenumber="38">
<code class="ruby"> return false if acc &lt; 0</code>
</li>
<li class="never" data-hits="" data-linenumber="39">
<code class="ruby"></code>
</li>
<li class="missed" data-hits="0" data-linenumber="40">
<code class="ruby"> if char == &#39;(&#39;</code>
</li>
<li class="missed" data-hits="0" data-linenumber="41">
<code class="ruby"> acc + 1</code>
</li>
<li class="never" data-hits="" data-linenumber="42">
<code class="ruby"> elsif char == &#39;)&#39;</code>
</li>
<li class="missed" data-hits="0" data-linenumber="43">
<code class="ruby"> acc - 1</code>
</li>
<li class="never" data-hits="" data-linenumber="44">
<code class="ruby"> else</code>
</li>
<li class="missed" data-hits="0" data-linenumber="45">
<code class="ruby"> acc</code>
</li>
<li class="never" data-hits="" data-linenumber="46">
<code class="ruby"> end</code>
</li>
<li class="missed" data-hits="0" data-linenumber="47">
<code class="ruby"> end.zero?</code>
</li>
<li class="never" data-hits="" data-linenumber="48">
<code class="ruby"> end</code>
</li>
<li class="never" data-hits="" data-linenumber="49">
<code class="ruby"></code>
</li>
<li class="covered" data-hits="1" data-linenumber="50">
<span class="hits">1</span>
<code class="ruby"> def parenthesis_error</code>
</li>
<li class="missed" data-hits="0" data-linenumber="51">
<code class="ruby"> raise ArgumentError, &quot;incorrect number/order of parenthesis in search query: &#39;#{@text}&#39;&quot;</code>
</li>
<li class="never" data-hits="" data-linenumber="52">
<code class="ruby"> end</code>
</li>
<li class="never" data-hits="" data-linenumber="53">
<code class="ruby"></code>
</li>
<li class="covered" data-hits="1" data-linenumber="54">
<span class="hits">1</span>
<code class="ruby"> def strip_exact_words</code>
</li>
<li class="missed" data-hits="0" data-linenumber="55">
<code class="ruby"> @exact_matches &lt;&lt; Regexp.last_match(1) while @tsquery.sub!(/&quot;(.*?)&quot;/, EXACT_WORD_CHAR)</code>
</li>
<li class="never" data-hits="" data-linenumber="56">
<code class="ruby"> end</code>
</li>
<li class="never" data-hits="" data-linenumber="57">
<code class="ruby"></code>
</li>
<li class="covered" data-hits="1" data-linenumber="58">
<span class="hits">1</span>
<code class="ruby"> def remove_duplicated_spaces</code>
</li>
<li class="missed" data-hits="0" data-linenumber="59">
<code class="ruby"> @tsquery = @tsquery.gsub(/\s+/, &#39; &#39;)</code>
</li>
<li class="never" data-hits="" data-linenumber="60">
<code class="ruby"> end</code>
</li>
<li class="never" data-hits="" data-linenumber="61">
<code class="ruby"></code>
</li>
<li class="never" data-hits="" data-linenumber="62">
<code class="ruby"> # transforms or/OR/|/|| into | operator</code>
</li>
<li class="covered" data-hits="1" data-linenumber="63">
<span class="hits">1</span>
<code class="ruby"> def transform_or_into_operator</code>
</li>
<li class="missed" data-hits="0" data-linenumber="64">
<code class="ruby"> @tsquery = @tsquery.gsub(/ ((or|\|+) )+/i, &#39;|&#39;).gsub(/ *\|+ */, &#39;|&#39;)</code>
</li>
<li class="never" data-hits="" data-linenumber="65">
<code class="ruby"> end</code>
</li>
<li class="never" data-hits="" data-linenumber="66">
<code class="ruby"></code>
</li>
<li class="never" data-hits="" data-linenumber="67">
<code class="ruby"> # transforms and/AND/&amp;/&amp;&amp; into &amp; operator</code>
</li>
<li class="covered" data-hits="1" data-linenumber="68">
<span class="hits">1</span>
<code class="ruby"> def transform_and_into_operator</code>
</li>
<li class="missed" data-hits="0" data-linenumber="69">
<code class="ruby"> @tsquery = @tsquery.gsub(/ ((and|\&amp;+) )+/i, &#39;&amp;&#39;)</code>
</li>
<li class="never" data-hits="" data-linenumber="70">
<code class="ruby"> end</code>
</li>
<li class="never" data-hits="" data-linenumber="71">
<code class="ruby"></code>
</li>
<li class="covered" data-hits="1" data-linenumber="72">
<span class="hits">1</span>
<code class="ruby"> def strip_spaces_from_parenthesis</code>
</li>
<li class="missed" data-hits="0" data-linenumber="73">
<code class="ruby"> @tsquery = @tsquery.gsub(/ *([()]) */, &#39;\1&#39;)</code>
</li>
<li class="never" data-hits="" data-linenumber="74">
<code class="ruby"> end</code>
</li>
<li class="never" data-hits="" data-linenumber="75">
<code class="ruby"></code>
</li>
<li class="covered" data-hits="1" data-linenumber="76">
<span class="hits">1</span>
<code class="ruby"> def transform_remaining_spaces_into_and_operator</code>
</li>
<li class="missed" data-hits="0" data-linenumber="77">
<code class="ruby"> @tsquery = @tsquery.tr(&#39; &#39;, &#39;&amp;&#39;)</code>
</li>
<li class="never" data-hits="" data-linenumber="78">
<code class="ruby"> end</code>
</li>
<li class="never" data-hits="" data-linenumber="79">
<code class="ruby"></code>
</li>
<li class="never" data-hits="" data-linenumber="80">
<code class="ruby"> # adds :* for partial match of words</code>
</li>
<li class="covered" data-hits="1" data-linenumber="81">
<span class="hits">1</span>
<code class="ruby"> def transform_keywords</code>
</li>
<li class="missed" data-hits="0" data-linenumber="82">
<code class="ruby"> keyword = @wildcard ? &#39;\1:*&#39; : &#39;\1:&#39;</code>
</li>
<li class="missed" data-hits="0" data-linenumber="83">
<code class="ruby"> @tsquery = @tsquery.gsub(/([^#{EXACT_WORD_CHAR}|&amp;!())]+)/, keyword)</code>
</li>
<li class="never" data-hits="" data-linenumber="84">
<code class="ruby"> end</code>
</li>
<li class="never" data-hits="" data-linenumber="85">
<code class="ruby"></code>
</li>
<li class="never" data-hits="" data-linenumber="86">
<code class="ruby"> # adds &amp; between operations</code>
</li>
<li class="covered" data-hits="1" data-linenumber="87">
<span class="hits">1</span>
<code class="ruby"> def join_operators_with_and</code>
</li>
<li class="missed" data-hits="0" data-linenumber="88">
<code class="ruby"> @tsquery = @tsquery.gsub(/:(\**)\!/, &#39;:\1&amp;!&#39;).gsub(/:(\**)\(/, &#39;:\1&amp;(&#39;).gsub(/\&amp;+/, &#39;&amp;&#39;)</code>
</li>
<li class="never" data-hits="" data-linenumber="89">
<code class="ruby"> end</code>
</li>
<li class="never" data-hits="" data-linenumber="90">
<code class="ruby"></code>
</li>
<li class="never" data-hits="" data-linenumber="91">
<code class="ruby"> # removes partial match from NOT operations</code>
</li>
<li class="covered" data-hits="1" data-linenumber="92">
<span class="hits">1</span>
<code class="ruby"> def remove_partial_match_from_not_keywords</code>
</li>
<li class="missed" data-hits="0" data-linenumber="93">
<code class="ruby"> @tsquery = @tsquery.gsub(/\!([^|&amp;!())]+):\**/, &#39;!\1&#39;)</code>
</li>
<li class="never" data-hits="" data-linenumber="94">
<code class="ruby"> end</code>
</li>
<li class="never" data-hits="" data-linenumber="95">
<code class="ruby"></code>
</li>
<li class="covered" data-hits="1" data-linenumber="96">
<span class="hits">1</span>
<code class="ruby"> def add_exact_words</code>
</li>
<li class="missed" data-hits="0" data-linenumber="97">
<code class="ruby"> @exact_matches.each { |phrase| @tsquery = @tsquery.sub(EXACT_WORD_CHAR, &quot;&#39;#{phrase}&#39;&quot;) }</code>
</li>
<li class="never" data-hits="" data-linenumber="98">
<code class="ruby"> end</code>
</li>
<li class="never" data-hits="" data-linenumber="99">
<code class="ruby">end</code>
</li>
</ol>
</pre>
</div>
</div>
</div>
</body>
</html>