Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Testing Opaleye without a live DB connection? #308

Closed
saurabhnanda opened this issue Jun 13, 2017 · 9 comments
Closed

Testing Opaleye without a live DB connection? #308

saurabhnanda opened this issue Jun 13, 2017 · 9 comments

Comments

@saurabhnanda
Copy link
Contributor

Most of the runtime errors with Opaleye are related to either misnamed tables/columns or incorrect DB (de)serialisation code. The former definitely needs a live DB connection to test, but is is possible to check the latter without a DB connection?

If I have a bunch of text files, which contain column values from the production DB, that Opaleye should be able to work with. Can I "feed" them to opaleye in such a way that it covers the maximum surface area without involving the DB?

Is this an Opaleye concern or is it really a pg-simple concern?

@tomjaguarpaw
Copy link
Owner

tomjaguarpaw commented Jun 13, 2017 via email

@saurabhnanda
Copy link
Contributor Author

The code given below assumes that a certain set of fields will be present in the HSTORE. However, since I'm talking to a legacy DB, there is another app that is actually populating the HSTORE. I want to be able to take the HSTORE string representations for a 100 rows from the production DB and ensure each of them roundtrips properly.

instance HStoreConverter Nouns where
  toHStore n = HStoreList
    [
      ("dep_label_singular", nounDepSingular n)
    , ("dep_label_plural", nounDepPlural n)
    , ("trip_label_singular", nounTripSingular n)
    , ("trip_label_plural", nounTripPlural n)
    , ("pax_label_singular", nounPaxSingular n)
    , ("pax_label_plural", nounPaxPlural n)
    , ("room_label_singular", nounRoomSingular n)
    , ("room_label_plural", nounRoomPlural n)
    ]

  fromHStore h = Nouns
    <$> (lookupHStore h "dep_label_singular")
    <*> (lookupHStore h "dep_label_plural")
    <*> (lookupHStore h "trip_label_singular")
    <*> (lookupHStore h "trip_label_plural")
    <*> (lookupHStore h "pax_label_singular")
    <*> (lookupHStore h "pax_label_plural")
    <*> (lookupHStore h "room_label_singular")
    <*> (lookupHStore h "room_label_plural")

instance QueryRunnerColumnDefault HStoreList Nouns where
  queryRunnerColumnDefault = queryRunnerColumn
    (unsafeCoerceColumn :: Column HStoreList -> Column PGJson)
    mkNounsFromHStoreList
    queryRunnerColumnDefault

instance FromField Nouns where
  fromField field mBS = fromHStore <$> (fromField field mBS) >>= \case
    Nothing -> fail "unable to decode hstore to Nouns"
    Just n -> pure n

instance QueryRunnerColumnDefault Nouns Nouns where
  queryRunnerColumnDefault = fieldQueryRunnerColumn

instance Default Constant Nouns (Column Nouns) where
  def = defaultHStoreConstant

Second problem: I have two versions of the QueryRunnerColumnDefault function, and till I actually execute a query, I don't know which one of the two will actually work during runtime:

instance QueryRunnerColumnDefault HStoreList Nouns where
  queryRunnerColumnDefault = queryRunnerColumn
    (unsafeCoerceColumn :: Column HStoreList -> Column PGJson)
    mkNounsFromHStoreList -- :: HStoreList -> Nouns (not Maybe Nouns)
    queryRunnerColumnDefault

---
instance QueryRunnerColumnDefault Properties Properties where
  queryRunnerColumnDefault = fieldQueryRunnerColumn

@tomjaguarpaw
Copy link
Owner

I'm still not really sure what you are trying to test. Are you trying to test that creating a Column Nouns with constant and then doing runQuery on it gives you back the original Nouns you started with?

@saurabhnanda
Copy link
Contributor Author

  • round-trip testing the handwritten Opaleye instances
  • round-trip testing existing data in production DB

@tomjaguarpaw
Copy link
Owner

Yes, I understand you say you are trying to test "round-trip of Opaleye instances", but I don't get exactly what that means to you. Please can you answer the question I asked before: "Are you trying to test that creating a Column Nouns with constant and then doing runQuery on it gives you back the original Nouns value you started with?". If you are not doing that, exactly what testing method are you using?

@tomjaguarpaw
Copy link
Owner

For example, are you using something like

roundTrip nouns = runQuery (pure (constant nouns))

and then checking that roundTrip nouns == [nouns]?

@saurabhnanda
Copy link
Contributor Author

"Are you trying to test that creating a Column Nouns with constant and then doing runQuery on it gives you back the original Nouns value you started with?

  • Creating a Noun via Quickcheck
  • Saving it to the DB via Opaleye
  • Reading it back via Opaleye
  • Checking if I get the same thing back as the originally created Nouns

That's part 1.

Part 2 is taking existing values from the production DB in some form (say, text file), which may NOT have been originally inserted via Opaleye. Trying to get Opaleye to read/parse these values and ensuring that a valid Nouns is generated.

@tomjaguarpaw
Copy link
Owner

Part 1 seems like it's testing two things:

a. That Opaleye writes and reads round trip properly
b. That Postgres writes and reads round trip properly

You probably don't need to test b! Why not skip the "saving to the DB" part and just do:

  • Creating a Nouns via Quickcheck
  • Reading it back via Opaleye
  • Checking if I get the same thing back as the originally created Nouns

I'm not sure what you mean in Part 2. If the values already exist in the DB how and why did they get into a text file? What does it mean to get Opaleye to read/parse something from a text file?

@tomjaguarpaw
Copy link
Owner

This issue looks stale so I'm closing it. Feel free to reopen if necessary.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants