Code Monkey home page Code Monkey logo

Comments (7)

ggorlen avatar ggorlen commented on August 27, 2024 2

If you do use an existing SQL kata, be sure to avoid exposing the solution in the preloaded code file. It's easy for a code warrior to read the file in the sample tests and view the solution. Also, drop and recreate the database per it block so that there's no surprising state shared across cases.

Here's an opinionated suggestion of how to test SQL which is similar to the "insert example" button in the new kata editor. In both cases, sample tests are explicitly visible to the code warrior rather than buried in the interface with compare_with, which many challenges use and abuse. Even if the challenger is not familiar with Ruby, it's less magical and easier to debug when exposed. They're always free to ignore the test cases. I prefer a close to 1:1 ratio between it block and expect calls so the challenger can localize their problem easily.

Disadvantages of this approach are that the challenger might be surprised or confused by the Ruby code, so offering an explanatory note at the end of the instructions can go a long way to mitigating this. Another possible downside is that the test file can become verbose, so you can strategically move some of the content to helper functions in the preloaded file.

Other than Codewars' run_sql function, the optional diff table code and interactions with the DB object, the code uses normal RSpec comparisons on an array of hashes.

Random tests are important to include for the submission to prevent cheating and can use Faker and Ruby's Random class.

Example instructions:

Write a query to retrieve all rows from the widgets table where the varchar widget name column starts with the substring "foo". ...Include examples, schema images, etc...

Complete solution:

SELECT * FROM widgets WHERE widgets.name LIKE 'foo%';

Initial solution:

-- Write your query here

Preloaded code:

def show_diff_table(actual, expected)
  if actual.empty?
    puts "<LOG::Results: Actual>No rows returned"
    puts "<TAB:TABLE:Results: Expected>#{expected.to_json()}"
  else
    daff_data = DaffWrapper.new(
      actual, 
      expected, 
      index: true
    ).serializable
    Display.daff_table(
      daff_data, 
      label: "Diff", 
      tab: true, 
      allow_preview: true
    )
  end
end

Test cases and example test cases:

describe "Query tests" do
  after(:each) {DB.drop_table?(:widgets)}
  before(:each) do
    DB.create_table(:widgets) do
      primary_key(:id)
      varchar(:name)
    end
  end
  
  it "should work on an example test" do
    DB[:widgets].insert(name: "foo")
    DB[:widgets].insert(name: "quux")
    DB[:widgets].insert(name: "foobar")
    expected = [{:id => 1, :name => "foo"}, 
                {:id => 3, :name => "foobar"}]
    actual = run_sql.to_a()
    show_diff_table(actual, expected)
    expect(actual).to eq(expected)
  end
end

from docs.

Blind4Basics avatar Blind4Basics commented on August 27, 2024 1

thx! 👍 (unforunately, I cannot suggest anything since I didn't ever write a sql test site... ;/ )

PR: #105. If wanna take a quick look to it. ;)

cheers & thx again.

from docs.

Blind4Basics avatar Blind4Basics commented on August 27, 2024 1

thx! I updated the PR.

from docs.

Blind4Basics avatar Blind4Basics commented on August 27, 2024

You can forfeit an existing kata, then open a fork of an existing solution to get the full example/structure

from docs.

Blind4Basics avatar Blind4Basics commented on August 27, 2024

@ggorlen : could you provide an example of random tests with this, plz?

from docs.

ggorlen avatar ggorlen commented on August 27, 2024

Sure, either Faker or rand/sample works to generate mock data. Then run the reference query on the database and assert the comparison of the result arrays as normal:

# ...
  it "should work on a random test" do
    40.times do
      name = (1..rand(1..4)).map {"foo".chars.sample}.join
      DB[:widgets].insert(name: name)
    end
    
    ref_soln_query = "SELECT * FROM widgets WHERE widgets.name LIKE 'foo%';"
    expected = DB[ref_soln_query].to_a()
    actual = run_sql.to_a()
    show_diff_table(actual, expected)
    expect(actual).to eq(expected)
  end
# ...

Happy to hear any improvements/suggestions you might have.

from docs.

ggorlen avatar ggorlen commented on August 27, 2024

There's a problem with the approach as I originally posted. The way show_diff_table and run_sql interact causes the table to fail to render when the select statement returns no rows. I've updated the example to handle this case. Hopefully it's the only edge case but we might want to hold off on #105 for a bit until it can be better validated. Luckily, the approach is being exercised in the field so I have reason to believe any issues will surface soon.

from docs.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.