diff --git a/example/src/TapRatingScreen.tsx b/example/src/TapRatingScreen.tsx
index 7b7082b..8f08d0f 100644
--- a/example/src/TapRatingScreen.tsx
+++ b/example/src/TapRatingScreen.tsx
@@ -51,6 +51,7 @@ class TapRatingScreen extends Component {
diff --git a/package.json b/package.json
index 5a6e6e0..0a24c40 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@rn-vui/ratings",
- "version": "0.4.2",
+ "version": "0.4.3",
"description": "..",
"source": "./src/index.tsx",
"main": "./lib/module/index.js",
@@ -71,6 +71,7 @@
"@react-native/babel-preset": "0.78.2",
"@react-native/eslint-config": "^0.78.0",
"@release-it/conventional-changelog": "^9.0.2",
+ "@testing-library/react-native": "^13.2.0",
"@types/jest": "^29.5.5",
"@types/react": "^19.0.12",
"commitlint": "^19.6.1",
@@ -84,6 +85,7 @@
"react-dom": "19.0.0",
"react-native": "0.79.1",
"react-native-builder-bob": "^0.40.7",
+ "react-test-renderer": "19.0.0",
"release-it": "^17.10.0",
"typescript": "^5.2.2"
},
@@ -140,7 +142,7 @@
[
"module",
{
- "esm": true
+ "esm": false
}
],
[
diff --git a/src/SwipeRating.tsx b/src/SwipeRating.tsx
index 0377d0a..12ff1c9 100644
--- a/src/SwipeRating.tsx
+++ b/src/SwipeRating.tsx
@@ -123,12 +123,12 @@ export type SwipeRatingProps = {
/**
* Callback method when the user starts rating.
*/
- onStartRating?: Function;
+ onStartRating?: (value: number) => void;
/**
* Callback method when the user finishes rating. Gives you the final rating value as a whole number
*/
- onFinishRating?: Function;
+ onFinishRating?: (value: number) => void;
/**
* Displays the Built-in Rating UI to show the rating value in real-time
@@ -404,9 +404,10 @@ const SwipeRating: React.FC = ({
const renderRatings = React.useMemo(() => {
const source = TYPES[type]?.source;
return Array.from({ length: ratingCount }, (_, index) => (
-
+
= ({
}, [ratingCount, imageSize, ratingColor, type]);
return (
-
+
{showRating && (
-
+
Rating:{' '}
@@ -443,7 +451,11 @@ const SwipeRating: React.FC = ({
)}
-
+
{
diff --git a/src/TapRating.tsx b/src/TapRating.tsx
index d821c03..db2df28 100644
--- a/src/TapRating.tsx
+++ b/src/TapRating.tsx
@@ -43,7 +43,7 @@ export type TapRatingProps = {
reviewColor?: string;
/**
- * Size value for review.
+ * Size value for review text.
*
* @default 40
*/
@@ -120,6 +120,7 @@ const TapRating: React.FunctionComponent = ({
showRating = true,
reviewColor = 'rgba(230, 196, 46, 1)',
reviewSize = 25,
+ size: reviewImageSize = 40,
defaultRating = 3,
starContainerStyle,
ratingContainerStyle,
@@ -163,7 +164,7 @@ const TapRating: React.FunctionComponent = ({
isDisabled={isDisabled}
selectedColor={selectedColor}
unSelectedColor={unSelectedColor}
- size={reviewSize}
+ size={reviewImageSize}
starImage={starImage}
starStyle={starStyle}
/>
@@ -173,19 +174,22 @@ const TapRating: React.FunctionComponent = ({
return (
{showRating && (
{reviews[position - 1]}
)}
{renderStars(rating_array)}
diff --git a/src/__tests__/SwipeRating.test.tsx b/src/__tests__/SwipeRating.test.tsx
new file mode 100644
index 0000000..170da3c
--- /dev/null
+++ b/src/__tests__/SwipeRating.test.tsx
@@ -0,0 +1,88 @@
+import { render } from '@testing-library/react-native';
+import SwipeRating from '../SwipeRating';
+
+describe('SwipeRating', () => {
+ it('should export SwipeRating', () => {
+ const SwipeRatingLocal = require('../SwipeRating');
+ expect(SwipeRatingLocal).toBeDefined();
+ });
+
+ it('should match snapshot', () => {
+ const { toJSON } = render(); //to ensure default props are not changed
+ expect(toJSON()).toMatchSnapshot();
+ });
+
+ it('should render with custom props', () => {
+ const ratingsCount = 9;
+
+ const { getAllByTestId } = render(
+
+ );
+ const stars = getAllByTestId('RNVUI__Star');
+ expect(stars).toHaveLength(ratingsCount);
+ });
+
+ it('should render with different type', () => {
+ const heartImage = require('../images/heart.png');
+ const { getAllByTestId } = render();
+ const swipeRatings = getAllByTestId('RNVUI__Star-image');
+
+ swipeRatings.forEach((swipeRating) => {
+ expect(swipeRating.props.source).toEqual(heartImage); // Check if the image source is the heart image
+ });
+ });
+
+ // it('should render with custom image', () => {
+ // const customImage = require('../images/bell.png');
+ // const { getAllByTestId } = render(
+ //
+ // );
+ // const swipeRatings = getAllByTestId('RNVUI__Star-image');
+
+ // swipeRatings.forEach((swipeRating) => {
+ // expect(swipeRating.props.source).toEqual(customImage); // Check if the image source is the custom image
+ // });
+ // });
+
+ it('should render with custom star color', () => {
+ const customStarColor = 'red';
+ const { getAllByTestId } = render(
+
+ );
+ const stars = getAllByTestId('RNVUI__Star-image');
+ stars.forEach((star) => {
+ expect(star.props.style.tintColor).toBe(customStarColor);
+ });
+ });
+
+ it('should render with custom star size', () => {
+ const customStarSize = 50;
+ const { getAllByTestId } = render(
+
+ );
+ const stars = getAllByTestId('RNVUI__Star-image');
+ stars.forEach((star) => {
+ expect(star.props.style.width).toBe(customStarSize);
+ expect(star.props.style.height).toBe(customStarSize);
+ });
+ });
+
+ it('should show the correct number of stars', () => {
+ const ratingsCount = 5;
+ const { getAllByTestId } = render(
+
+ );
+ const stars = getAllByTestId('RNVUI__Star');
+ expect(stars).toHaveLength(ratingsCount);
+ });
+
+ //show rating should show the text
+ it('should show the correct rating text', () => {
+ const ratingsCount = 5;
+ const { getByTestId } = render(
+
+ );
+ const ratingText = getByTestId('RNVUI__SwipeRating-showRating');
+ expect(ratingText).toBeTruthy();
+ });
+});
diff --git a/src/__tests__/TapRating.test.tsx b/src/__tests__/TapRating.test.tsx
new file mode 100644
index 0000000..f24a9c5
--- /dev/null
+++ b/src/__tests__/TapRating.test.tsx
@@ -0,0 +1,154 @@
+import { fireEvent, render } from '@testing-library/react-native';
+import TapRating from '../TapRating';
+
+describe('TapRating Aka AirbnbRating', () => {
+ it('should export SwipeRating', () => {
+ const TapRatingLocal = require('../TapRating');
+ expect(TapRatingLocal).toBeDefined();
+ });
+
+ it('should match snapshot', () => {
+ const { toJSON } = render(); //to ensure default props are not changed
+ expect(toJSON()).toMatchSnapshot();
+ });
+
+ it('show rating true should show rating', () => {
+ const { getByTestId } = render();
+ const ratingText = getByTestId('RNVUI__TapRating-showRating');
+ expect(ratingText).toBeOnTheScreen();
+ });
+
+ it('number of stars should match count prop', () => {
+ const { getAllByTestId } = render();
+ const ratingStar = getAllByTestId('RNVUI__Star');
+ expect(ratingStar).toHaveLength(4);
+ });
+
+ it('should show reviews', () => {
+ const defaultRating = 1;
+ const ratingReviews = ['Terrible', 'Bad', 'Okay', 'Good', 'Great'];
+
+ const { getByTestId } = render(
+
+ );
+ const ratingText = getByTestId('RNVUI__TapRating-showRating');
+ expect(ratingText).toBeOnTheScreen();
+ expect(ratingText).toHaveTextContent(
+ ratingReviews[defaultRating - 1] || ''
+ );
+ });
+
+ it('review size should match reviewSize prop', () => {
+ const reviewSize = 32;
+ const { getByTestId } = render();
+ const ratingText = getByTestId('RNVUI__TapRating-showRating');
+ expect(ratingText.props.style.fontSize).toBe(reviewSize);
+ });
+
+ it('rating image size should should match image size', () => {
+ const imageSize = 32;
+ const { getAllByTestId } = render();
+ const ratingStars = getAllByTestId('RNVUI__Star-image');
+ ratingStars.forEach((star) => {
+ expect(star.props.style.width).toBe(imageSize);
+ expect(star.props.style.height).toBe(imageSize);
+ });
+ });
+
+ it('should call onFinishRating with the correct rating when rating is selected', () => {
+ const pressableRating = 2;
+ const onFinishRating = jest.fn();
+ const { getAllByTestId } = render(
+
+ );
+ const ratingStars = getAllByTestId('RNVUI__Star');
+ fireEvent.press(ratingStars[pressableRating - 1]);
+ expect(onFinishRating).toHaveBeenCalledWith(pressableRating);
+ });
+
+ it('should not call onFinishRating when isDisabled is true', () => {
+ const onFinishRating = jest.fn();
+ const { getAllByTestId } = render(
+
+ );
+ const ratingStars = getAllByTestId('RNVUI__Star');
+ fireEvent.press(ratingStars[0]);
+ expect(onFinishRating).not.toHaveBeenCalled();
+ });
+
+ //image test
+ it('should use custom star image', () => {
+ const customStarImage = require('../images/bell.png');
+ const { getAllByTestId } = render(
+
+ );
+ const ratingStars = getAllByTestId('RNVUI__Star-image');
+ ratingStars.forEach((star) => {
+ expect(star.props.source).toEqual(customStarImage);
+ });
+ });
+
+ it('selected color should match selectedColor prop', () => {
+ const selectedColor = 'red';
+ const { getAllByTestId } = render(
+
+ );
+ const ratingStars = getAllByTestId('RNVUI__Star-image');
+ ratingStars.forEach((star) => {
+ expect(star.props.style.tintColor).toBe(selectedColor);
+ });
+ });
+
+ it('unselected color should match unSelectedColor prop', () => {
+ const unSelectedColor = 'blue';
+ const { getAllByTestId } = render(
+
+ );
+ const ratingStars = getAllByTestId('RNVUI__Star-image');
+ ratingStars.forEach((star) => {
+ expect(star.props.style.tintColor).toBe(unSelectedColor);
+ });
+ });
+ it('should apply custom star style', () => {
+ const customStarStyle = { backgroundColor: '#aabbcc' };
+ const { getAllByTestId } = render(
+
+ );
+ const ratingStars = getAllByTestId('RNVUI__Star-image');
+ ratingStars.forEach((star) => {
+ expect(star.props.style.backgroundColor).toEqual(
+ customStarStyle.backgroundColor
+ );
+ });
+ });
+
+ it('should apply custom rating container style', () => {
+ const customContainerStyle = { backgroundColor: '#aabbcc' };
+ const { getByTestId } = render(
+
+ );
+ const ratingContainer = getByTestId('RNVUI__TapRating');
+ expect(ratingContainer.props.style.backgroundColor).toEqual(
+ customContainerStyle.backgroundColor
+ );
+ });
+
+ it('should apply custom star container style', () => {
+ const customStarContainerStyle = { backgroundColor: '#aabbcc' };
+ const { getByTestId } = render(
+
+ );
+ const ratingContainer = getByTestId('RNVUI__TapRating-starContainer');
+ expect(ratingContainer.props.style.backgroundColor).toEqual(
+ customStarContainerStyle.backgroundColor
+ );
+ });
+});
diff --git a/src/__tests__/__snapshots__/SwipeRating.test.tsx.snap b/src/__tests__/__snapshots__/SwipeRating.test.tsx.snap
new file mode 100644
index 0000000..55cbd1a
--- /dev/null
+++ b/src/__tests__/__snapshots__/SwipeRating.test.tsx.snap
@@ -0,0 +1,198 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`SwipeRating should match snapshot 1`] = `
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+`;
diff --git a/src/__tests__/__snapshots__/TapRating.test.tsx.snap b/src/__tests__/__snapshots__/TapRating.test.tsx.snap
new file mode 100644
index 0000000..1c3e836
--- /dev/null
+++ b/src/__tests__/__snapshots__/TapRating.test.tsx.snap
@@ -0,0 +1,330 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`TapRating Aka AirbnbRating should match snapshot 1`] = `
+
+
+ Okay
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+`;
diff --git a/src/__tests__/index.test.tsx b/src/__tests__/index.test.tsx
index bf84291..3b06bc9 100644
--- a/src/__tests__/index.test.tsx
+++ b/src/__tests__/index.test.tsx
@@ -1 +1,7 @@
-it.todo('write a test');
+describe('index', () => {
+ it('should export Rating and AirbnbRating', () => {
+ const { Rating, AirbnbRating } = require('../index');
+ expect(Rating).toBeDefined();
+ expect(AirbnbRating).toBeDefined();
+ });
+});
diff --git a/src/components/Star.tsx b/src/components/Star.tsx
index 792c2f7..eed8e92 100644
--- a/src/components/Star.tsx
+++ b/src/components/Star.tsx
@@ -55,9 +55,15 @@ const Star: React.FunctionComponent = ({
fill && selectedColor === null ? STAR_SELECTED_IMAGE : starImage;
return (
-
+
=29.0.0"
+ react: ">=18.2.0"
+ react-native: ">=0.71"
+ react-test-renderer: ">=18.2.0"
+ peerDependenciesMeta:
+ jest:
+ optional: true
+ checksum: fa2f59353b27a5afea72c04296e94e597b7e20f09f7e69d5dd1693da15bdeabfdd1ba655b1e194dbf5727b9dfa92de5af06ec77484b3392aab96dab4f7c05e44
+ languageName: node
+ linkType: hard
+
"@tootallnate/quickjs-emscripten@npm:^0.23.0":
version: 0.23.0
resolution: "@tootallnate/quickjs-emscripten@npm:0.23.0"
@@ -10088,7 +10110,7 @@ __metadata:
languageName: node
linkType: hard
-"min-indent@npm:^1.0.1":
+"min-indent@npm:^1.0.0, min-indent@npm:^1.0.1":
version: 1.0.1
resolution: "min-indent@npm:1.0.1"
checksum: bfc6dd03c5eaf623a4963ebd94d087f6f4bbbfd8c41329a7f09706b0cb66969c4ddd336abeb587bc44bc6f08e13bf90f0b374f9d71f9f01e04adc2cd6f083ef1
@@ -11446,6 +11468,13 @@ __metadata:
languageName: node
linkType: hard
+"react-is@npm:^19.0.0":
+ version: 19.1.0
+ resolution: "react-is@npm:19.1.0"
+ checksum: 3eb4eac7f09bf178bdc6fa98d384f5f243b85de7c99679a88b0154ead4d818ad94386ccb00ea31ec52409ffd13299057f5ec6ca2eaec06f9f7eddc1ad4832332
+ languageName: node
+ linkType: hard
+
"react-native-builder-bob@npm:^0.40.7":
version: 0.40.7
resolution: "react-native-builder-bob@npm:0.40.7"
@@ -11596,6 +11625,18 @@ __metadata:
languageName: node
linkType: hard
+"react-test-renderer@npm:19.0.0":
+ version: 19.0.0
+ resolution: "react-test-renderer@npm:19.0.0"
+ dependencies:
+ react-is: ^19.0.0
+ scheduler: ^0.25.0
+ peerDependencies:
+ react: ^19.0.0
+ checksum: 2e1e527588c69e822b7aa25262c9f4a48161ede9cee5109b88228ecafbd91ce82f7afed176645efcba903ba5a43d05842a8229cdde220049e42a0cf679715dbc
+ languageName: node
+ linkType: hard
+
"react@npm:19.0.0":
version: 19.0.0
resolution: "react@npm:19.0.0"
@@ -11698,6 +11739,16 @@ __metadata:
languageName: node
linkType: hard
+"redent@npm:^3.0.0":
+ version: 3.0.0
+ resolution: "redent@npm:3.0.0"
+ dependencies:
+ indent-string: ^4.0.0
+ strip-indent: ^3.0.0
+ checksum: fa1ef20404a2d399235e83cc80bd55a956642e37dd197b4b612ba7327bf87fa32745aeb4a1634b2bab25467164ab4ed9c15be2c307923dd08b0fe7c52431ae6b
+ languageName: node
+ linkType: hard
+
"redent@npm:^4.0.0":
version: 4.0.0
resolution: "redent@npm:4.0.0"
@@ -12842,6 +12893,15 @@ __metadata:
languageName: node
linkType: hard
+"strip-indent@npm:^3.0.0":
+ version: 3.0.0
+ resolution: "strip-indent@npm:3.0.0"
+ dependencies:
+ min-indent: ^1.0.0
+ checksum: 18f045d57d9d0d90cd16f72b2313d6364fd2cb4bf85b9f593523ad431c8720011a4d5f08b6591c9d580f446e78855c5334a30fb91aa1560f5d9f95ed1b4a0530
+ languageName: node
+ linkType: hard
+
"strip-indent@npm:^4.0.0":
version: 4.0.0
resolution: "strip-indent@npm:4.0.0"