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

[Hotfix] Invalid Semver Error #37

Open
wants to merge 17 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
language: node_js
node_js:
- "7"
cache: yarn
- "8"
cache: yarn
56 changes: 56 additions & 0 deletions __tests__/__snapshots__/android-kotlin.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,62 @@ class TestModuleModule(reactContext: ReactApplicationContext) : ReactContextBase
"
`;

exports[`Android/Kotlin: Combined creates a TemplateModule.kt with github RN version 1`] = `
"// Created by react-native-create-bridge

package com.testapp.testmodule

import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.bridge.ReactContextBaseJavaModule
import com.facebook.react.bridge.ReactMethod
import com.facebook.react.bridge.WritableMap
import com.facebook.react.modules.core.DeviceEventManagerModule

import java.util.Map

class TestModuleModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {

init {
// Here we're saving the context we passed into the constructor to a variable so we can emit events
// https://facebook.github.io/react-native/docs/native-modules-android.html#the-toast-module
reactContext = context
}

override fun getName(): String {
// Tell React the name of the module
// https://facebook.github.io/react-native/docs/native-components-android.html#1-create-the-viewmanager-subclass
return REACT_CLASS
}

override fun getConstants(): Map<String, Any>? {
// Export any constants to be used in your native module
// https://facebook.github.io/react-native/docs/native-modules-android.html#the-toast-module
val reactConstants = Map<String, Any>()
constants.put(\\"EXAMPLE_CONSTANT\\", \\"example\\")

return constants
}

@ReactMethod
fun exampleMethod () {
// An example native method that you will expose to React
// https://facebook.github.io/react-native/docs/native-modules-android.html#the-toast-module
}

companion object {
val REACT_CLASS = \\"TestModule\\"
private var reactContext: ReactApplicationContext = null

private fun emitDeviceEvent(eventName: String, eventData: WritableMap?) {
// A method for emitting from the native side to JS
// https://facebook.github.io/react-native/docs/native-modules-android.html#sending-events-to-javascript
reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java).emit(eventName, eventData)
}
}
}
"
`;

exports[`Android/Kotlin: Combined creates a TemplatePackage.kt 1`] = `
"// Created by react-native-create-bridge

Expand Down
20 changes: 20 additions & 0 deletions __tests__/__snapshots__/javascript.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,26 @@ export default {
"
`;

exports[`JS: Semver correctly parses React Native version 1`] = `
"// Created by react-native-create-bridge

import React, { Component } from 'react'
import { requireNativeComponent } from 'react-native'

const SemverModule = requireNativeComponent('SemverModule', SemverModuleView)

export default class SemverModuleView extends Component {
render () {
return <SemverModule {...this.props} />
}
}

SemverModuleView.propTypes = {
exampleProp: React.PropTypes.string
}
"
`;

exports[`JS: UI Components creates a TemplateNativeView.js 1`] = `
"// Created by react-native-create-bridge

Expand Down
13 changes: 13 additions & 0 deletions __tests__/android-kotlin.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,13 @@ describe('Android/Kotlin: Combined', () => {
rnVersion: '0.47.2',
};

const githubConfig = {
templateName,
packageName: templateName.toLowerCase(),
app: 'testapp',
rnVersion: 'https://github.com/facebook/react-native#master',
};

it('creates a TemplateManager.kt', async () => {
const fileData = await readFile('TemplateManager.kt', readDirPath);
const parsedFile = parseFile(fileData, config);
Expand All @@ -93,4 +100,10 @@ describe('Android/Kotlin: Combined', () => {
const parsedFile = parseFile(fileData, config);
expect(parsedFile).toMatchSnapshot();
});

it('creates a TemplateModule.kt with github RN version', async () => {
const fileData = await readFile('TemplateModule.kt', readDirPath);
const parsedFile = parseFile(fileData, githubConfig);
expect(parsedFile).toMatchSnapshot();
});
});
20 changes: 20 additions & 0 deletions __tests__/javascript.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,23 @@ describe('JS: UI Components', () => {
expect(parsedFile).toMatchSnapshot();
});
});

describe('JS: Semver', () => {
const config = {
templateName: 'SemverModule',
rnVersion: "^0.49.1"
}
const readDirPath = path.join(
__dirname,
'..',
'templates',
'ui-components',
'js',
);

it('correctly parses React Native version', async () => {
const fileData = await readFile('TemplateNativeView.js', readDirPath);
const parsedFile = parseFile(fileData, config);
expect(parsedFile).toMatchSnapshot();
});
});
10 changes: 9 additions & 1 deletion src/file-operations.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const path = require("path");
const fs = require("mz/fs");
const compareVersions = require("compare-versions");
const semver = require("../utils/semver");

const pkg = require(path.join(process.cwd(), "package.json"));

Expand All @@ -17,9 +18,16 @@ function readFile(file, readDirPath) {
function parseFile(fileData, { templateName, packageName, app, rnVersion }) {
let kotlinPackage;
let javaPackage;
let version;

try {
version = semver(rnVersion);
} catch (e) {
version = "0.0.0";
}

// TODO: figure out a better way to handle one off breaking changes
if (rnVersion && compareVersions(rnVersion, "0.47.2") < 0) {
if (rnVersion && compareVersions(version, "0.47.2") < 0) {
kotlinPackage = `
override fun createJSModules(): List<Class<out JavaScriptModule>> {
return emptyList()
Expand Down
16 changes: 16 additions & 0 deletions utils/semver.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
const semverRegExp = /\bv?(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)(?:-[\da-z-]+(?:\.[\da-z-]+)*)?(?:\+[\da-z-]+(?:\.[\da-z-]+)*)?\b/ig;
const validSemver = /^v?(?:\d+)(\.(?:[x*]|\d+)(\.(?:[x*]|\d+)(?:-[\da-z\-]+(?:\.[\da-z\-]+)*)?(?:\+[\da-z\-]+(?:\.[\da-z\-]+)*)?)?)?$/i;

module.exports = function(version) {
if (typeof version !== "string") {
throw new TypeError("Invalid argument expected string");
}

const extractedVersion = version.match(semverRegExp);

if (extractedVersion && extractedVersion[0]) return extractedVersion[0];

if (!validSemver.test(version)) {
throw new Error("Invalid argument not valid semver");
}
}
Loading