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

Add XPath translate() function #395

Merged
merged 4 commits into from
Jan 9, 2019
Merged

Add XPath translate() function #395

merged 4 commits into from
Jan 9, 2019

Conversation

tiritea
Copy link
Contributor

@tiritea tiritea commented Jan 3, 2019

Closes # https://forum.opendatakit.org/t/add-xpath-translate-function/17017

What has been done to verify that this works as intended?

tested under Android Studio simulator running ODK Collect v1.18.0 (dirty), using test examples described on http://www.xsltfunctions.com/xsl/fn_translate.html (and those added to testEval testcases), and compared results running same against Enketo.

Why is this the best possible solution? Were any other approaches considered?

Implements XPath standardized function (which is arguably best solution). Implements identical XPath behavior as exists already in Enketo and libxml2.

BTW, I also tried an implementation that avoided using a StringBuilder, and instead tried to exploit existing java String replace()/replaceAll() functions, but this ended up much messier, required multiple re-instantiations of String objects, and ultimately did not handle simultaneous interchanging translations correctly (eg 'x' --> 'y' and 'y' --> 'x').

Are there any risks to merging this code? If so, what are they?

Introduces entirely new XPath function and does not touch or modify any existing javaRosa function or behavior. Can only be used by new forms that exploit this new function in their XPath expressions, so no risk to existing forms.

@codecov-io
Copy link

codecov-io commented Jan 3, 2019

Codecov Report

Merging #395 into master will increase coverage by 0.04%.
The diff coverage is 92.85%.

Impacted file tree graph

@@             Coverage Diff              @@
##             master     #395      +/-   ##
============================================
+ Coverage     48.31%   48.35%   +0.04%     
- Complexity     2871     2875       +4     
============================================
  Files           239      239              
  Lines         13516    13530      +14     
  Branches       2625     2629       +4     
============================================
+ Hits           6530     6543      +13     
  Misses         6148     6148              
- Partials        838      839       +1
Impacted Files Coverage Δ Complexity Δ
src/org/javarosa/xpath/expr/XPathFuncExpr.java 55.74% <92.85%> (+0.82%) 166 <0> (+4) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update aa47832...6f336a3. Read the comment docs.

Copy link
Contributor

@ggalmazor ggalmazor left a comment

Choose a reason for hiding this comment

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

Thanks, @tiritea. This is looking good :)

if (fromPos == -1) {
// no mapping for this char, so just add it to result unchanged
result.append(from);
} else if (fromPos < toChars.length()) {
Copy link
Contributor

Choose a reason for hiding this comment

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

toChars.length() could be pre-computed before the for block to avoid computing it each loop iteration.

Copy link
Contributor Author

@tiritea tiritea Jan 3, 2019

Choose a reason for hiding this comment

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

Yes, I had thought about doing that, but then saw that this level of for loop optimization wasnt't being performed elsewhere in javaRosa; eg in toNumeric():

653 for (int i = 0; i < s.length(); i++) {...

So I assumed the preference was readability vs micro-optimization?

OK. I see what you are referring to now.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done. Good catch. Thnx.

BTW I left the other potential candidate for this optimization - namely the for loop terminating expression - unchanged, for internal consistency with existing toNumeric().

testEval("translate('hello','lo','LO')", "heLLO");
testEval("translate('hello world','hello','')", "wrd");
testEval("translate('hello wor,ld',' ,',', ')", "hello,wor ld");
testEval("translate('2019/01/02','/','-')", "2019-01-02");
Copy link
Contributor

Choose a reason for hiding this comment

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

Neat! Thanks for thinking about the tests! :)

@yanokwa
Copy link
Member

yanokwa commented Jan 4, 2019

It'd be good for this to be documented in the docs. The bare minimum should be an issue is filed at https://github.com/opendatakit/docs/issues/new!

@tiritea
Copy link
Contributor Author

tiritea commented Jan 4, 2019

My plan is to doc this translate() together with substring-before() and substring-after() in one PR. Hence I was waiting for this one to be approved before proceeding with updating docs. But I can open a doc issue in mean time.

@tiritea
Copy link
Contributor Author

tiritea commented Jan 9, 2019

Are we waiting on me for anything before merging this? If we can get it in before 16th we might be able to rev javaRosa to including this [and the new substring-before() & substring-after() functions] for next Collect release.

@ggalmazor
Copy link
Contributor

Normally we would try the PR in Collect as a sort of QA phase before merging. Do you have any form we could use to test this?

In any case, I'd say we merge it because It's a narrow changeset and it has automated tests. If no one complains by the end of day I can merge this.

@tiritea
Copy link
Contributor Author

tiritea commented Jan 9, 2019

Do you have any form we could use to test this?

Only the one I posted to the Forum: https://forum.opendatakit.org/t/add-xpath-translate-function/17017/3

Sorry. I didn't mean to appear impatient. I just wanted to make sure there wasn't something waiting on me to move it along... I think I covered all same bases as my other PR that got merged, but then I've already violated numerous procedural 'protocols' on both! :-)

@ggalmazor
Copy link
Contributor

Sure, don't worry! I think you're right. I didn't remember the previous PR with the substring functions. Let's merge this one.

@ggalmazor ggalmazor merged commit 1e57b99 into getodk:master Jan 9, 2019
@tiritea
Copy link
Contributor Author

tiritea commented Jan 9, 2019

I didn't remember the previous PR with the substring functions.

You mean you don't remember the beer you owe me!!!??? Hurmph.

;-)

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

Successfully merging this pull request may close these issues.

4 participants